fix crash when trying to create a non-template track/bus with >2 channels; put MIDI...
[ardour.git] / gtk2_ardour / group_tabs.cc
index 7abd0d896535fa5ab1dc016a0aeba8116991cb8d..995d41dfef8b370ae5fe5a94882ce611ec1cbf21 100644 (file)
 #include "ardour/route_group.h"
 #include "route_group_dialog.h"
 #include "group_tabs.h"
+#include "keyboard.h"
 #include "i18n.h"
 
 using namespace std;
 using namespace Gtk;
 using namespace ARDOUR;
 
-GroupTabs::GroupTabs ()
-       : _session (0),
+GroupTabs::GroupTabs (Editor* e)
+       : EditorComponent (e),
          _dragging (0)
 {
 
 }
 
 void
-GroupTabs::set_session (Session* s)
+GroupTabs::connect_to_session (Session* s)
 {
-       _session = s;
-       s->RouteGroupChanged.connect (mem_fun (*this, &GroupTabs::set_dirty));
+       EditorComponent::connect_to_session (s);
+
+       _session_connections.push_back (_session->RouteGroupChanged.connect (mem_fun (*this, &GroupTabs::set_dirty)));
 }
 
 
@@ -64,11 +66,8 @@ GroupTabs::on_button_press_event (GdkEventButton* ev)
        Tab* prev;
        Tab* next;
        Tab* t = click_to_tab (p, &prev, &next);
-       if (t == 0) {
-               return false;
-       }
 
-       if (ev->button == 1) {
+       if (ev->button == 1 && t) {
 
                _dragging = t;
                _drag_moved = false;
@@ -78,14 +77,20 @@ GroupTabs::on_button_press_event (GdkEventButton* ev)
                _drag_from = p < h;
 
                if (_drag_from) {
+                       /* limit is the end of the previous tab */
                        _drag_limit = prev ? prev->to : 0;
                } else {
+                       /* limit is the start of the next tab */
                        _drag_limit = next ? next->from : extent ();
                }
 
        } else if (ev->button == 3) {
 
-               get_menu(t->group)->popup (ev->button, ev->time);
+               RouteGroup* g = t ? t->group : 0;
+               Menu* m = get_menu (g);
+               if (m) {
+                       m->popup (ev->button, ev->time);
+               }
                
        }
 
@@ -109,13 +114,15 @@ GroupTabs::on_motion_notify_event (GdkEventMotion* ev)
        if (_drag_from) {
                
                double f = _dragging->from + p - _drag_last;
-               
+
                if (f < _drag_limit) {
+                       /* limit drag in the `too big' direction */
                        f = _drag_limit;
                }
 
                double const t = _dragging->to - _dragging->last_ui_size;
                if (f > t) {
+                       /* limit drag in the `too small' direction */
                        f = t;
                }
                
@@ -126,11 +133,13 @@ GroupTabs::on_motion_notify_event (GdkEventMotion* ev)
                double t = _dragging->to + p - _drag_last;
 
                if (t > _drag_limit) {
+                       /* limit drag in the `too big' direction */
                        t = _drag_limit;
                }
 
                double const f = _dragging->from + _dragging->first_ui_size;
                if (t < f) {
+                       /* limit drag in the `too small' direction */
                        t = f;
                }
                
@@ -154,9 +163,23 @@ GroupTabs::on_button_release_event (GdkEventButton* ev)
        }
 
        if (!_drag_moved) {
-               _dragging->group->set_active (!_dragging->group->is_active (), this);
-               _dragging = 0;
+
+               if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
+
+                       /* edit */
+                       RouteGroupDialog d (_dragging->group, Gtk::Stock::APPLY);
+                       d.do_run ();
+
+               } else {
+               
+                       /* toggle active state */
+                       _dragging->group->set_active (!_dragging->group->is_active (), this);
+                       _dragging = 0;
+                       
+               }
+               
        } else {
+               /* finish drag */
                _dragging = 0;
                reflect_tabs (_tabs);
                set_dirty ();
@@ -187,9 +210,18 @@ GroupTabs::render (cairo_t* cr)
 }
 
 
+/** Convert a click position to a tab.
+ *  @param c Click position.
+ *  @param prev Filled in with the previous tab to the click, or 0.
+ *  @param next Filled in with the next tab after the click, or 0.
+ *  @return Tab under the click, or 0.
+ */
 GroupTabs::Tab *
 GroupTabs::click_to_tab (double c, Tab** prev, Tab** next)
 {
+       *prev = 0;
+       
        list<Tab>::iterator i = _tabs.begin ();
        while (i != _tabs.end() && (c < i->from || c > i->to)) {
                *prev = &(*i);