Fix ArdourButton event sequence.

Always give ArdourButton a chance to handle Press or Release events if you override them.
This allows ArdourButtons to do the "Pressed" animation
And it now correctly eats the event so button clicks don't select the channelstrip.
This commit is contained in:
Ben Loftis 2014-08-28 10:31:57 -05:00
parent 3cc19c2cce
commit 3f297f7dab
11 changed files with 57 additions and 56 deletions

View File

@ -692,11 +692,11 @@ ArdourButton::on_button_release_event (GdkEventButton *ev)
if (_hovering) {
signal_clicked ();
signal_clicked ();
if (_act_on_release) {
if (_action) {
_action->activate ();
return true;
}
}
}

View File

@ -52,8 +52,6 @@ using namespace std;
ArdourDisplay::ArdourDisplay (Element e)
{
signal_button_press_event().connect (sigc::mem_fun(*this, &ArdourDisplay::on_mouse_pressed));
add_elements(e);
add_elements(ArdourButton::Menu);
add_elements(ArdourButton::Text);
@ -64,7 +62,7 @@ ArdourDisplay::~ArdourDisplay ()
}
bool
ArdourDisplay::on_mouse_pressed (GdkEventButton*)
ArdourDisplay::on_button_press_event (GdkEventButton*)
{
_menu.popup (1, gtk_get_current_event_time());
return true;

View File

@ -39,7 +39,7 @@ class ArdourDisplay : public ArdourButton
boost::shared_ptr<PBD::Controllable> get_controllable() { return binding_proxy.get_controllable(); }
void set_controllable (boost::shared_ptr<PBD::Controllable> c);
bool on_mouse_pressed (GdkEventButton*); //mousedown will pop up our preset menu
bool on_button_press_event (GdkEventButton*); //mousedown will pop up our preset menu
// bool on_button_press_event (GdkEventButton*);
// bool on_button_release_event (GdkEventButton*);
bool on_scroll_event (GdkEventScroll* ev);

View File

@ -52,7 +52,7 @@ using namespace std;
ArdourDropdown::ArdourDropdown (Element e)
{
signal_button_press_event().connect (sigc::mem_fun(*this, &ArdourDropdown::on_mouse_pressed));
// signal_button_press_event().connect (sigc::mem_fun(*this, &ArdourDropdown::on_mouse_pressed));
add_elements(e);
add_elements(ArdourButton::Menu);
@ -63,7 +63,7 @@ ArdourDropdown::~ArdourDropdown ()
}
bool
ArdourDropdown::on_mouse_pressed (GdkEventButton*)
ArdourDropdown::on_button_press_event (GdkEventButton*)
{
_menu.popup (1, gtk_get_current_event_time());
return true;

View File

@ -36,7 +36,7 @@ class ArdourDropdown : public ArdourButton
ArdourDropdown (Element e = default_elements);
virtual ~ArdourDropdown ();
bool on_mouse_pressed (GdkEventButton*);
bool on_button_press_event (GdkEventButton*);
void AddMenuElem (Gtk::Menu_Helpers::MenuElem e);

View File

@ -409,8 +409,8 @@ LevelMeterBase::setup_meters (int len, int initial_width, int thin_width)
meters[n].width = width;
meters[n].length = len;
meters[n].meter->add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
meters[n].meter->signal_button_press_event().connect (sigc::mem_fun (*this, &LevelMeterBase::meter_button_press));
meters[n].meter->signal_button_release_event().connect (sigc::mem_fun (*this, &LevelMeterBase::meter_button_release));
meters[n].meter->signal_button_press_event().connect (sigc::mem_fun (*this, &LevelMeterBase::meter_button_press), false);
meters[n].meter->signal_button_release_event().connect (sigc::mem_fun (*this, &LevelMeterBase::meter_button_release), false);
}
//pack_end (*meters[n].meter, false, false);

View File

@ -189,7 +189,7 @@ MixerStrip::init ()
solo_isolated_led->set_no_show_all (true);
solo_isolated_led->set_name (X_("solo isolate"));
solo_isolated_led->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
solo_isolated_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_isolate_button_release));
solo_isolated_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_isolate_button_release), false);
UI::instance()->set_tip (solo_isolated_led, _("Isolate Solo"), "");
solo_safe_led = manage (new ArdourButton (ArdourButton::led_default_elements));
@ -198,7 +198,7 @@ MixerStrip::init ()
solo_safe_led->set_no_show_all (true);
solo_safe_led->set_name (X_("solo safe"));
solo_safe_led->add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
solo_safe_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_safe_button_release));
solo_safe_led->signal_button_release_event().connect (sigc::mem_fun (*this, &RouteUI::solo_safe_button_release), false);
UI::instance()->set_tip (solo_safe_led, _("Lock Solo Status"), "");
solo_safe_led->set_text (_("Lock"));

View File

@ -108,13 +108,13 @@ MonitorSection::MonitorSection (Session* s)
ARDOUR_UI::Blink.connect (sigc::mem_fun (*this, &MonitorSection::do_blink));
rude_solo_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo));
rude_solo_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo), false);
UI::instance()->set_tip (rude_solo_button, _("When active, something is soloed.\nClick to de-solo everything"));
rude_iso_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_isolate));
rude_iso_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_isolate), false);
UI::instance()->set_tip (rude_iso_button, _("When active, something is solo-isolated.\nClick to de-isolate everything"));
rude_audition_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_audition));
rude_audition_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_audition), false);
UI::instance()->set_tip (rude_audition_button, _("When active, auditioning is active.\nClick to stop the audition"));
solo_in_place_button.set_name ("monitor section solo model");

View File

@ -176,7 +176,7 @@ RouteUI::init ()
rec_enable_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_release), false);
show_sends_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_press), false);
show_sends_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_release));
show_sends_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::show_sends_release), false);
solo_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::solo_press), false);
solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
@ -186,11 +186,11 @@ RouteUI::init ()
monitor_input_button->set_distinct_led_click (false);
monitor_disk_button->set_distinct_led_click (false);
monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press));
monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release));
monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press));
monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release));
monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
BusSendDisplayChanged.connect_same_thread (*this, boost::bind(&RouteUI::bus_send_display_changed, this, _1));
}
@ -323,6 +323,10 @@ RouteUI::mute_press (GdkEventButton* ev)
return true;
}
//if this is a binding action, let the ArdourButton handle it
if ( BindingProxy::is_bind_action(ev) )
return false;
multiple_mute_change = false;
if (Keyboard::is_context_menu_event (ev)) {
@ -338,14 +342,8 @@ RouteUI::mute_press (GdkEventButton* ev)
} else {
if (Keyboard::is_button2_event (ev)) {
// Primary-button2 click is the midi binding click
// button2-click is "momentary"
//give the button a chance to handle a midi binding
if (mute_button->on_button_press_event (ev)) {
return true;
}
_mute_release = new SoloMuteRelease (_route->muted ());
}
@ -494,6 +492,10 @@ RouteUI::solo_press(GdkEventButton* ev)
return true;
}
//if this is a binding action, let the ArdourButton handle it
if ( BindingProxy::is_bind_action(ev) )
return false;
multiple_solo_change = false;
if (Keyboard::is_context_menu_event (ev)) {
@ -512,11 +514,6 @@ RouteUI::solo_press(GdkEventButton* ev)
if (Keyboard::is_button2_event (ev)) {
// Give the button a chance to handle MIDI binding
if (solo_button->on_button_press_event (ev)) {
return true;
}
// button2-click is "momentary"
_solo_release = new SoloMuteRelease (_route->self_soloed());
}
@ -659,6 +656,10 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
return true;
}
//if this is a binding action, let the ArdourButton handle it
if ( BindingProxy::is_bind_action(ev) )
return false;
if (!_session->engine().connected()) {
MessageDialog msg (_("Not connected to AudioEngine - cannot engage record"));
msg.run ();
@ -771,25 +772,29 @@ RouteUI::update_monitoring_display ()
bool
RouteUI::monitor_input_press(GdkEventButton*)
{
return true;
printf("RouteUI monitor_input_press\n");
return false;
}
bool
RouteUI::monitor_input_release(GdkEventButton* ev)
{
printf("RouteUI monitor_input_release\n");
return monitor_release (ev, MonitorInput);
}
bool
RouteUI::monitor_disk_press (GdkEventButton*)
{
return true;
printf("RouteUI monitor_disk_press\n");
return false;
}
bool
RouteUI::monitor_disk_release (GdkEventButton* ev)
{
return monitor_release (ev, MonitorDisk);
printf("RouteUI monitor_disk_release\n");
monitor_release (ev, MonitorDisk);
}
bool
@ -839,7 +844,7 @@ RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
DisplaySuspender ds;
_session->set_monitoring (rl, mc, Session::rt_cleanup, true);
return true;
return false;
}
void
@ -1428,7 +1433,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
}
}
return true;
return false;
}
bool
@ -1436,7 +1441,6 @@ RouteUI::solo_safe_button_release (GdkEventButton* ev)
{
if (ev->button == 1) {
_route->set_solo_safe (!solo_safe_led->active_state(), this);
return true;
}
return false;
}
@ -2009,8 +2013,8 @@ RouteUI::setup_invert_buttons ()
for (uint32_t i = 0; i < to_add; ++i) {
ArdourButton* b = manage (new ArdourButton);
b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press));
b->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_release), i));
b->signal_button_press_event().connect (sigc::mem_fun (*this, &RouteUI::invert_press), false);
b->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &RouteUI::invert_release), i), false);
b->set_name (X_("invert button"));
if (to_add == 1) {

View File

@ -31,20 +31,17 @@ using namespace Gtkmm2ext;
using namespace std;
using namespace PBD;
guint BindingProxy::bind_button = 2;
guint BindingProxy::bind_statemask = Gdk::CONTROL_MASK;
BindingProxy::BindingProxy (boost::shared_ptr<Controllable> c)
: prompter (0),
controllable (c),
bind_button (2),
bind_statemask (Gdk::CONTROL_MASK)
controllable (c)
{
}
BindingProxy::BindingProxy ()
: prompter (0),
bind_button (2),
bind_statemask (Gdk::CONTROL_MASK)
: prompter (0)
{
}
@ -69,17 +66,17 @@ BindingProxy::set_bind_button_state (guint button, guint statemask)
bind_statemask = statemask;
}
void
BindingProxy::get_bind_button_state (guint &button, guint &statemask)
bool
BindingProxy::is_bind_action (GdkEventButton *ev)
{
button = bind_button;
statemask = bind_statemask;
return ( (ev->state & bind_statemask) && ev->button == bind_button );
}
bool
BindingProxy::button_press_handler (GdkEventButton *ev)
{
if (controllable && (ev->state & bind_statemask) && ev->button == bind_button) {
if ( controllable && is_bind_action(ev) ) {
if (Controllable::StartLearning (controllable.get())) {
string prompt = _("operate controller now");
if (prompter == 0) {

View File

@ -41,8 +41,8 @@ class LIBGTKMM2EXT_API BindingProxy : public sigc::trackable
virtual ~BindingProxy();
void set_bind_button_state (guint button, guint statemask);
void get_bind_button_state (guint &button, guint &statemask);
static bool is_bind_action (GdkEventButton *);
bool button_press_handler (GdkEventButton *);
boost::shared_ptr<PBD::Controllable> get_controllable() const { return controllable; }
@ -51,8 +51,10 @@ class LIBGTKMM2EXT_API BindingProxy : public sigc::trackable
protected:
Gtkmm2ext::PopUp* prompter;
boost::shared_ptr<PBD::Controllable> controllable;
guint bind_button;
guint bind_statemask;
static guint bind_button;
static guint bind_statemask;
PBD::ScopedConnection learning_connection;
void learning_finished ();
bool prompter_hiding (GdkEventAny *);