OSC: change group sharing to individual commands
[ardour.git] / libs / widgets / ardour_button.cc
index 9687427608024c1da6181750a363b365688556c5..145d46d94c8a97920bdabf7a422ce4b21e981e4f 100644 (file)
@@ -55,7 +55,7 @@ ArdourButton::Element ArdourButton::default_elements = ArdourButton::Element (Ar
 ArdourButton::Element ArdourButton::led_default_elements = ArdourButton::Element (ArdourButton::default_elements|ArdourButton::Indicator);
 ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::Element (ArdourButton::Edge|ArdourButton::Body|ArdourButton::Indicator);
 
-ArdourButton::ArdourButton (Element e)
+ArdourButton::ArdourButton (Element e, bool toggle)
        : _sizing_text("")
        , _markup (false)
        , _elements (e)
@@ -87,6 +87,7 @@ ArdourButton::ArdourButton (Element e)
        , led_inset_pattern (0)
        , _led_rect (0)
        , _act_on_release (true)
+       , _auto_toggle (toggle)
        , _led_left (false)
        , _distinct_led_click (false)
        , _hovering (false)
@@ -103,7 +104,7 @@ ArdourButton::ArdourButton (Element e)
        signal_grab_broken_event().connect (sigc::mem_fun (*this, &ArdourButton::on_grab_broken_event));
 }
 
-ArdourButton::ArdourButton (const std::string& str, Element e)
+ArdourButton::ArdourButton (const std::string& str, Element e, bool toggle)
        : _sizing_text("")
        , _markup (false)
        , _elements (e)
@@ -133,6 +134,7 @@ ArdourButton::ArdourButton (const std::string& str, Element e)
        , led_inset_pattern (0)
        , _led_rect (0)
        , _act_on_release (true)
+       , _auto_toggle (toggle)
        , _led_left (false)
        , _distinct_led_click (false)
        , _hovering (false)
@@ -221,13 +223,7 @@ ArdourButton::set_sizing_text (const std::string& str)
                return;
        }
        _sizing_text = str;
-       if (!is_realized()) {
-               return;
-       }
-       ensure_layout ();
-       if (_layout) {
-               queue_resize ();
-       }
+       queue_resize ();
 }
 
 void
@@ -624,6 +620,11 @@ ArdourButton::on_size_request (Gtk::Requisition* req)
                         * of text.
                         */
 
+               } else if (_layout_ellipsize_width > 0 && _sizing_text.empty()) {
+
+                       req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0));
+                       req->width += _layout_ellipsize_width / PANGO_SCALE;
+
                } else /*if (!_text.empty() || !_sizing_text.empty()) */ {
 
                        req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0));
@@ -859,6 +860,10 @@ ArdourButton::on_button_press_event (GdkEventButton *ev)
 {
        focus_handler (this);
 
+       if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS) {
+               return _fallthrough_to_parent ? false : true;
+       }
+
        if (ev->button == 1 && (_elements & Indicator) && _led_rect && _distinct_led_click) {
                if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width &&
                    ev->y >= _led_rect->y && ev->y < _led_rect->y + _led_rect->height) {
@@ -877,18 +882,22 @@ ArdourButton::on_button_press_event (GdkEventButton *ev)
                if (_action) {
                        _action->activate ();
                        return true;
+               } else if (_auto_toggle) {
+                       set_active (!get_active ());
+                       signal_clicked ();
+                       return true;
                }
        }
 
-       if (_fallthrough_to_parent)
-               return false;
-
-       return true;
+       return _fallthrough_to_parent ? false : true;
 }
 
 bool
 ArdourButton::on_button_release_event (GdkEventButton *ev)
 {
+       if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS) {
+               return _fallthrough_to_parent ? false : true;
+       }
        if (ev->button == 1 && _hovering && (_elements & Indicator) && _led_rect && _distinct_led_click) {
                if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width &&
                    ev->y >= _led_rect->y && ev->y < _led_rect->y + _led_rect->height) {
@@ -901,6 +910,9 @@ ArdourButton::on_button_release_event (GdkEventButton *ev)
        CairoWidget::set_dirty ();
 
        if (ev->button == 1 && _hovering) {
+               if (_act_on_release && _auto_toggle && !_action) {
+                       set_active (!get_active ());
+               }
                signal_clicked ();
                if (_act_on_release) {
                        if (_action) {
@@ -910,10 +922,7 @@ ArdourButton::on_button_release_event (GdkEventButton *ev)
                }
        }
 
-       if (_fallthrough_to_parent)
-               return false;
-
-       return true;
+       return _fallthrough_to_parent ? false : true;
 }
 
 void
@@ -1111,6 +1120,9 @@ ArdourButton::on_key_release_event (GdkEventKey *ev) {
        if (_act_on_release && _focused &&
                        (ev->keyval == GDK_space || ev->keyval == GDK_Return))
        {
+               if (_auto_toggle && !_action) {
+                               set_active (!get_active ());
+               }
                signal_clicked();
                if (_action) {
                        _action->activate ();
@@ -1125,6 +1137,9 @@ ArdourButton::on_key_press_event (GdkEventKey *ev) {
        if (!_act_on_release && _focused &&
                        (ev->keyval == GDK_space || ev->keyval == GDK_Return))
        {
+               if (_auto_toggle && !_action) {
+                               set_active (!get_active ());
+               }
                signal_clicked();
                if (_action) {
                        _action->activate ();