key stroke (left/right arrow) and wheel (left/right, shift-down/up) scrolling in...
[ardour.git] / gtk2_ardour / mixer_ui.cc
index 07c6f7c9bbeb11703eccc010f3e9a693802f1363..e2946f823b495f2b490c4cfca989315cad4b4062 100644 (file)
@@ -312,7 +312,9 @@ Mixer_UI::add_strip (Session::RouteList& routes)
                route->name_changed.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
 
                strip->GoingAway.connect (bind (mem_fun(*this, &Mixer_UI::remove_strip), strip));
-               
+#ifdef GTKOSX
+               strip->WidthChanged.connect (mem_fun(*this, &Mixer_UI::queue_draw_all_strips));
+#endif 
                strip->signal_button_release_event().connect (bind (mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
        }
 
@@ -743,6 +745,30 @@ Mixer_UI::redisplay_track_list ()
        }
 }
 
+#ifdef GTKOSX
+void
+Mixer_UI::queue_draw_all_strips ()
+{
+       TreeModel::Children rows = track_model->children();
+       TreeModel::Children::iterator i;
+       long order;
+
+       for (order = 0, i = rows.begin(); i != rows.end(); ++i, ++order) {
+               MixerStrip* strip = (*i)[track_columns.strip];
+
+               if (strip == 0) {
+                       continue;
+               }
+
+               bool visible = (*i)[track_columns.visible];
+               
+               if (visible) {
+                       strip->queue_draw();
+               }
+       }
+}
+#endif
+
 void
 Mixer_UI::set_auto_rebinding( bool val )
 {
@@ -761,16 +787,7 @@ Mixer_UI::set_auto_rebinding( bool val )
 void 
 Mixer_UI::toggle_auto_rebinding() 
 {
-       if (auto_rebinding)
-       {
-               set_auto_rebinding( FALSE );
-       }
-       
-       else
-       {
-               set_auto_rebinding( TRUE );
-       }
-
+       set_auto_rebinding (!auto_rebinding);
        auto_rebind_midi_controls();
 }
 
@@ -896,6 +913,9 @@ Mixer_UI::track_display_button_press (GdkEventButton* ev)
                                        bool visible = (*iter)[track_columns.visible];
                                        (*iter)[track_columns.visible] = !visible;
                                }
+#ifdef GTKOSX
+                               track_display.queue_draw();
+#endif
                        }
                }
                return true;
@@ -958,6 +978,9 @@ Mixer_UI::build_mix_group_context_menu ()
        items.push_back (MenuElem (_("Activate All"), mem_fun(*this, &Mixer_UI::activate_all_mix_groups)));
        items.push_back (MenuElem (_("Disable All"), mem_fun(*this, &Mixer_UI::disable_all_mix_groups)));
        items.push_back (SeparatorElem());
+       items.push_back (MenuElem (_("Show All"), mem_fun(*this, &Mixer_UI::show_all_mix_groups)));
+       items.push_back (MenuElem (_("Hide All"), mem_fun(*this, &Mixer_UI::hide_all_mix_groups)));
+       items.push_back (SeparatorElem());
        items.push_back (MenuElem (_("Add group"), mem_fun(*this, &Mixer_UI::new_mix_group)));
        
 }
@@ -991,6 +1014,9 @@ Mixer_UI::group_display_button_press (GdkEventButton* ev)
                        if ((iter = group_model->get_iter (path))) {
                                if ((group = (*iter)[group_columns.group]) != 0) {
                                        // edit_mix_group (group);
+#ifdef GTKOSX
+                                       group_display.queue_draw();
+#endif
                                        return true;
                                }
                        }
@@ -1002,6 +1028,9 @@ Mixer_UI::group_display_button_press (GdkEventButton* ev)
                if ((iter = group_model->get_iter (path))) {
                        bool active = (*iter)[group_columns.active];
                        (*iter)[group_columns.active] = !active;
+#ifdef GTKOSX
+                       group_display.queue_draw();
+#endif
                        return true;
                }
                break;
@@ -1010,6 +1039,9 @@ Mixer_UI::group_display_button_press (GdkEventButton* ev)
                if ((iter = group_model->get_iter (path))) {
                        bool visible = (*iter)[group_columns.visible];
                        (*iter)[group_columns.visible] = !visible;
+#ifdef GTKOSX
+                       group_display.queue_draw();
+#endif
                        return true;
                }
                break;
@@ -1030,6 +1062,8 @@ Mixer_UI::activate_all_mix_groups ()
        }
 }
 
+
+
 void
 Mixer_UI::disable_all_mix_groups ()
 {
@@ -1039,6 +1073,24 @@ Mixer_UI::disable_all_mix_groups ()
        }
 }
 
+void
+Mixer_UI::show_all_mix_groups ()
+{
+       Gtk::TreeModel::Children children = group_model->children();
+       for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
+               (*iter)[group_columns.visible] = true;
+       }
+}
+
+void
+Mixer_UI::hide_all_mix_groups ()
+{
+       Gtk::TreeModel::Children children = group_model->children();
+       for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
+               (*iter)[group_columns.visible] = false;
+       }
+}
+
 void
 Mixer_UI::mix_groups_changed ()
 {
@@ -1048,15 +1100,6 @@ Mixer_UI::mix_groups_changed ()
 
        group_model->clear ();
 
-       {
-               TreeModel::Row row;
-               row = *(group_model->append());
-               row[group_columns.active] = false;
-               row[group_columns.visible] = true;
-               row[group_columns.text] = (_("-all-"));
-               row[group_columns.group] = 0;
-       }
-
        session->foreach_mix_group (mem_fun (*this, &Mixer_UI::add_mix_group));
 }
 
@@ -1195,7 +1238,18 @@ Mixer_UI::add_mix_group (RouteGroup* group)
 
        TreeModel::Row row = *(group_model->append());
        row[group_columns.active] = group->is_active();
-       row[group_columns.visible] = true;
+
+       row[group_columns.visible] = false;
+
+       for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) {
+               if ((*i)->mix_group() == group) {
+                       if ((*i)->marked_for_display()) {
+                               row[group_columns.visible] = true;
+                       }
+                       break;
+               }
+       }
+
        row[group_columns.group] = group;
        if (!group->name().empty()) {
                row[group_columns.text] = group->name();
@@ -1258,25 +1312,47 @@ Mixer_UI::set_state (const XMLNode& node)
        const XMLProperty* prop;
        XMLNode* geometry;
        
-       if ((geometry = find_named_node (node, "geometry")) == 0) {
+       m_width = default_width;
+       m_height = default_height;
+       m_root_x = 1;
+       m_root_y = 1;
+       
+       if ((geometry = find_named_node (node, "geometry")) != 0) {
 
-               m_width = default_width;
-               m_height = default_height;
-               m_root_x = 1;
-               m_root_y = 1;
+               XMLProperty* prop;
 
-       } else {
+               if ((prop = geometry->property("x_size")) == 0) {
+                       prop = geometry->property ("x-size");
+               }
+               if (prop) {
+                       m_width = atoi(prop->value());
+               }
+               if ((prop = geometry->property("y_size")) == 0) {
+                       prop = geometry->property ("y-size");
+               }
+               if (prop) {
+                       m_height = atoi(prop->value());
+               }
 
-               m_width = atoi(geometry->property("x_size")->value().c_str());
-               m_height = atoi(geometry->property("y_size")->value().c_str());
-               m_root_x = atoi(geometry->property("x_pos")->value().c_str());
-               m_root_y = atoi(geometry->property("y_pos")->value().c_str());
+               if ((prop = geometry->property ("x_pos")) == 0) {
+                       prop = geometry->property ("x-pos");
+               }
+               if (prop) {
+                       m_root_x = atoi (prop->value());
+                       
+               }
+               if ((prop = geometry->property ("y_pos")) == 0) {
+                       prop = geometry->property ("y-pos");
+               }
+               if (prop) {
+                       m_root_y = atoi (prop->value());
+               }
        }
 
        set_window_pos_and_size ();
 
        if ((prop = node.property ("narrow-strips"))) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        set_strip_width (Narrow);
                } else {
                        set_strip_width (Wide);
@@ -1284,7 +1360,7 @@ Mixer_UI::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("show-mixer"))) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                       _visible = true;
                }
        }
@@ -1346,12 +1422,24 @@ Mixer_UI::pane_allocation_handler (Allocation& alloc, Gtk::Paned* which)
        int width, height;
        static int32_t done[3] = { 0, 0, 0 };
 
-       if ((geometry = find_named_node (*node, "geometry")) == 0) {
-               width = default_width;
-               height = default_height;
-       } else {
-               width = atoi(geometry->property("x_size")->value());
-               height = atoi(geometry->property("y_size")->value());
+       width = default_width;
+       height = default_height;
+
+       if ((geometry = find_named_node (*node, "geometry")) != 0) {
+
+
+               if ((prop = geometry->property ("x_size")) == 0) {
+                       prop = geometry->property ("x-size");
+               }
+               if (prop) {
+                       width = atoi (prop->value());
+               }
+               if ((prop = geometry->property ("y_size")) == 0) {
+                       prop = geometry->property ("y-size");
+               }
+               if (prop) {
+                       height = atoi (prop->value());
+               }
        }
 
        if (which == static_cast<Gtk::Paned*> (&rhs_pane1)) {
@@ -1390,8 +1478,66 @@ Mixer_UI::pane_allocation_handler (Allocation& alloc, Gtk::Paned* which)
        }
 }
 
+void
+Mixer_UI::scroll_left () 
+{
+       Adjustment* adj = scroller.get_hscrollbar()->get_adjustment();
+       /* stupid GTK: can't rely on clamping across versions */
+       scroller.get_hscrollbar()->set_value (max (adj->get_lower(), adj->get_value() - adj->get_step_increment()));
+}
+
+void
+Mixer_UI::scroll_right ()
+{
+       Adjustment* adj = scroller.get_hscrollbar()->get_adjustment();
+       /* stupid GTK: can't rely on clamping across versions */
+       scroller.get_hscrollbar()->set_value (min (adj->get_upper(), adj->get_value() + adj->get_step_increment()));
+}
+
 bool
 Mixer_UI::on_key_press_event (GdkEventKey* ev)
 {
+       switch (ev->keyval) {
+       case GDK_Left:
+               scroll_left ();
+               return true;
+
+       case GDK_Right:
+               scroll_right ();
+               return true;
+
+       default:
+               break;
+       }
+
        return key_press_focus_accelerator_handler (*this, ev);
 }
+
+bool
+Mixer_UI::on_scroll_event (GdkEventScroll* ev)
+{
+       switch (ev->direction) {
+       case GDK_SCROLL_LEFT:
+               scroll_left ();
+               return true;
+       case GDK_SCROLL_UP:
+               if (ev->state & Keyboard::TertiaryModifier) {
+                       scroll_left ();
+                       return true;
+               }
+               return false;
+
+       case GDK_SCROLL_RIGHT:
+               scroll_right ();
+               return true;
+
+       case GDK_SCROLL_DOWN:
+               if (ev->state & Keyboard::TertiaryModifier) {
+                       scroll_right ();
+                       return true;
+               }
+               return false;
+       }
+
+       return false;
+}