use new action map API instead of ActionManager::get_action
[ardour.git] / gtk2_ardour / mixer_ui.cc
index 255df8f3f6ef7d55c61d4fbea2c37b9ac3ac3f5b..8b856d40bd350ee278ab3aa63734660793445612 100644 (file)
@@ -100,19 +100,19 @@ Mixer_UI::instance ()
 
 Mixer_UI::Mixer_UI ()
        : Tabbable (_content, _("Mixer"))
+       , ActionMapOwner (X_("mixer"))
        , no_track_list_redisplay (false)
        , in_group_row_change (false)
        , track_menu (0)
        , _monitor_section (0)
        , _plugin_selector (0)
        , _strip_width (UIConfiguration::instance().get_default_narrow_ms() ? Narrow : Wide)
+       , _spill_scroll_position (0)
        , ignore_reorder (false)
        , _in_group_rebuild_or_clear (false)
        , _route_deletion_in_progress (false)
        , _maximised (false)
-       , _show_mixer_list (true)
        , _strip_selection_change_without_scroll (false)
-       , myactions (X_("mixer"))
        , _selection (*this, *this)
 {
        register_actions ();
@@ -153,6 +153,14 @@ Mixer_UI::Mixer_UI ()
        strip_packer.pack_end (scroller_base, true, true);
        strip_packer.pack_end (add_button, false, false);
 
+#ifdef MIXBUS
+       /* create a drop-shadow at the end of the mixer strips */
+       mb_shadow.set_size_request( 4, -1 );
+       mb_shadow.set_name("EditorWindow");
+       mb_shadow.show();
+       strip_packer.pack_end (mb_shadow, false, false);
+#endif
+
        _group_tabs = new MixerGroupTabs (this);
        VBox* b = manage (new VBox);
        b->set_spacing (0);
@@ -222,7 +230,6 @@ Mixer_UI::Mixer_UI ()
        favorite_plugins_display.set_headers_visible (true);
        favorite_plugins_display.set_rules_hint (true);
        favorite_plugins_display.set_can_focus (false);
-       favorite_plugins_display.set_tooltip_column (0);
        favorite_plugins_display.add_object_drag (favorite_plugins_columns.plugin.index(), "PluginFavoritePtr");
        favorite_plugins_display.set_drag_column (favorite_plugins_columns.name.index());
        favorite_plugins_display.add_drop_targets (target_list);
@@ -231,6 +238,9 @@ Mixer_UI::Mixer_UI ()
        favorite_plugins_display.signal_drop.connect (sigc::mem_fun (*this, &Mixer_UI::plugin_drop));
        favorite_plugins_display.signal_row_expanded().connect (sigc::mem_fun (*this, &Mixer_UI::save_favorite_ui_state));
        favorite_plugins_display.signal_row_collapsed().connect (sigc::mem_fun (*this, &Mixer_UI::save_favorite_ui_state));
+       if (UIConfiguration::instance().get_use_tooltips()) {
+               favorite_plugins_display.set_tooltip_column (0);
+       }
        favorite_plugins_model->signal_row_has_child_toggled().connect (sigc::mem_fun (*this, &Mixer_UI::sync_treeview_favorite_ui_state));
 
        favorite_plugins_scroller.add (favorite_plugins_display);
@@ -353,6 +363,7 @@ Mixer_UI::Mixer_UI ()
 #endif
 
        PluginManager::instance ().PluginListChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::plugin_list_changed, this), gui_context());
+       PluginManager::instance ().PluginStatusChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::plugin_list_changed, this), gui_context());
        ARDOUR::Plugin::PresetsChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::refill_favorite_plugins, this), gui_context());
 }
 
@@ -366,6 +377,16 @@ Mixer_UI::~Mixer_UI ()
        delete track_menu;
 }
 
+struct MixerStripSorter {
+       bool operator() (const MixerStrip* ms_a, const MixerStrip* ms_b)
+       {
+               boost::shared_ptr<ARDOUR::Stripable> const& a = ms_a->stripable ();
+               boost::shared_ptr<ARDOUR::Stripable> const& b = ms_b->stripable ();
+               return ARDOUR::Stripable::Sorter(true)(a, b);
+       }
+};
+
+
 void
 Mixer_UI::escape ()
 {
@@ -550,6 +571,8 @@ Mixer_UI::add_stripables (StripableList& slist)
                                                if (mnode) {
                                                        _monitor_section->tearoff().set_state (*mnode);
                                                }
+                                               
+                                               set_monitor_action_sensitivity(true);
                                        }
 
                                        out_packer.pack_end (_monitor_section->tearoff(), false, false);
@@ -631,16 +654,24 @@ Mixer_UI::deselect_all_strip_processors ()
 }
 
 void
-Mixer_UI::select_all_tracks ()
+Mixer_UI::select_none ()
 {
-       PublicEditor::instance().select_all_tracks ();
+       _selection.clear_routes();
+       deselect_all_strip_processors();
 }
 
 void
-Mixer_UI::select_none ()
+Mixer_UI::select_next_strip ()
 {
-       _selection.clear_routes();
        deselect_all_strip_processors();
+       _session->selection().select_next_stripable (true, false);
+}
+
+void
+Mixer_UI::select_prev_strip ()
+{
+       deselect_all_strip_processors();
+       _session->selection().select_prev_stripable (true, false);
 }
 
 void
@@ -903,15 +934,6 @@ Mixer_UI::axis_view_by_control (boost::shared_ptr<AutomationControl> c) const
        return 0;
 }
 
-struct MixerStripSorter {
-       bool operator() (const MixerStrip* ms_a, const MixerStrip* ms_b)
-       {
-               boost::shared_ptr<ARDOUR::Stripable> const& a = ms_a->stripable ();
-               boost::shared_ptr<ARDOUR::Stripable> const& b = ms_b->stripable ();
-               return ARDOUR::Stripable::Sorter(true)(a, b);
-       }
-};
-
 bool
 Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip)
 {
@@ -1432,6 +1454,9 @@ Mixer_UI::redisplay_track_list ()
        if (ss) {
                boost::shared_ptr<VCA> sv = boost::dynamic_pointer_cast<VCA> (ss);
                if (sv) {
+                       if (_spill_scroll_position <= 0 && scroller.get_hscrollbar()) {
+                               _spill_scroll_position = scroller.get_hscrollbar()->get_adjustment()->get_value();
+                       }
                        spill_redisplay (sv);
                        return;
                }
@@ -1502,14 +1527,38 @@ Mixer_UI::redisplay_track_list ()
        /* update visibility of VCA assign buttons */
 
        if (n_masters == 0) {
+               //show/hide the channelstrip VCA assign buttons on channelstrips:
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::remove_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
+
+               Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleVCAPane");
+               if (act) {
+                       act->set_sensitive (false);
+               }
+
+               //remove the VCA packer, but don't change our prior setting for show/hide:
                vca_vpacker.hide ();
        } else {
+               //show/hide the channelstrip VCA assign buttons on channelstrips:
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::add_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
-               vca_vpacker.show ();
+
+               Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleVCAPane");
+               assert (act);
+               act->set_sensitive (true);
+
+               //if we were showing VCAs before, show them now:
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               assert (tact);
+               showhide_vcas (  tact->get_active () );
        }
 
        _group_tabs->set_dirty ();
+
+       if (_spill_scroll_position > 0 && scroller.get_hscrollbar()) {
+               Adjustment* adj = scroller.get_hscrollbar()->get_adjustment();
+               adj->set_value (max (adj->get_lower(), min (adj->get_upper(), _spill_scroll_position)));
+       }
+       _spill_scroll_position = 0;
+
 }
 
 void
@@ -1558,18 +1607,7 @@ void
 Mixer_UI::initial_track_display ()
 {
        StripableList sl;
-
-       boost::shared_ptr<RouteList> routes = _session->get_routes();
-
-       for (RouteList::iterator r = routes->begin(); r != routes->end(); ++r) {
-               sl.push_back (*r);
-       }
-
-       VCAList vcas = _session->vca_manager().vcas();
-
-       for (VCAList::iterator v = vcas.begin(); v != vcas.end(); ++v) {
-               sl.push_back (boost::dynamic_pointer_cast<Stripable> (*v));
-       }
+       _session->get_stripables (sl);
 
        sl.sort (PresentationInfoMixerSorter());
 
@@ -1667,10 +1705,10 @@ Mixer_UI::build_track_menu ()
        items.push_back (MenuElem (_("Hide All"), sigc::mem_fun(*this, &Mixer_UI::hide_all_routes)));
        items.push_back (MenuElem (_("Show All Audio Tracks"), sigc::mem_fun(*this, &Mixer_UI::show_all_audiotracks)));
        items.push_back (MenuElem (_("Hide All Audio Tracks"), sigc::mem_fun(*this, &Mixer_UI::hide_all_audiotracks)));
-       items.push_back (MenuElem (_("Show All Audio Busses"), sigc::mem_fun(*this, &Mixer_UI::show_all_audiobus)));
-       items.push_back (MenuElem (_("Hide All Audio Busses"), sigc::mem_fun(*this, &Mixer_UI::hide_all_audiobus)));
        items.push_back (MenuElem (_("Show All Midi Tracks"), sigc::mem_fun (*this, &Mixer_UI::show_all_miditracks)));
        items.push_back (MenuElem (_("Hide All Midi Tracks"), sigc::mem_fun (*this, &Mixer_UI::hide_all_miditracks)));
+       items.push_back (MenuElem (_("Show All Busses"), sigc::mem_fun(*this, &Mixer_UI::show_all_audiobus)));
+       items.push_back (MenuElem (_("Hide All Busses"), sigc::mem_fun(*this, &Mixer_UI::hide_all_audiobus)));
 
 }
 
@@ -1901,19 +1939,38 @@ Mixer_UI::route_group_property_changed (RouteGroup* group, const PropertyChange&
 }
 
 void
-Mixer_UI::show_mixer_list (bool yn)
+Mixer_UI::toggle_mixer_list ()
+{
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMixerList");
+       if (act) {
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               showhide_mixer_list (tact->get_active());
+       }
+}
+
+void
+Mixer_UI::showhide_mixer_list (bool yn)
 {
        if (yn) {
                list_vpacker.show ();
        } else {
                list_vpacker.hide ();
        }
+}
 
-       _show_mixer_list = yn;
+void
+Mixer_UI::toggle_monitor_section ()
+{
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMonitorSection");
+       if (act) {
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               showhide_monitor_section (tact->get_active());
+       }
 }
 
+
 void
-Mixer_UI::show_monitor_section (bool yn)
+Mixer_UI::showhide_monitor_section (bool yn)
 {
        if (!monitor_section()) {
                return;
@@ -1929,6 +1986,49 @@ Mixer_UI::show_monitor_section (bool yn)
        }
 }
 
+void
+Mixer_UI::toggle_vcas ()
+{
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleVCAPane");
+       if (act) {
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               showhide_vcas (tact->get_active());
+       }
+}
+
+void
+Mixer_UI::showhide_vcas (bool yn)
+{
+       if (yn) {
+               vca_vpacker.show();
+       } else {
+               vca_vpacker.hide();
+       }
+}
+
+#ifdef MIXBUS
+void
+Mixer_UI::toggle_mixbuses ()
+{
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMixbusPane");
+       if (act) {
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               showhide_mixbuses (tact->get_active());
+       }
+}
+
+void
+Mixer_UI::showhide_mixbuses (bool on)
+{
+       if (on) {
+               mb_vpacker.show();
+       } else {
+               mb_vpacker.hide();
+       }
+}
+#endif
+
+
 void
 Mixer_UI::route_group_name_edit (const std::string& path, const std::string& new_text)
 {
@@ -2136,9 +2236,10 @@ Mixer_UI::set_state (const XMLNode& node, int version)
        }
 
        if (node.get_property ("show-mixer-list", yn)) {
-               Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleMixerList"));
+               Glib::RefPtr<Action> act = myactions.find_action (X_("Mixer"), X_("ToggleMixerList"));
                assert (act);
                Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               assert (tact);
 
                /* do it twice to force the change */
                tact->set_active (!yn);
@@ -2146,13 +2247,41 @@ Mixer_UI::set_state (const XMLNode& node, int version)
        }
 
        if (node.get_property ("monitor-section-visible", yn)) {
-               Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
+               Glib::RefPtr<Action> act = myactions.find_action (X_("Mixer"), X_("ToggleMonitorSection"));
+               assert (act);
                Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               assert (tact);
+
+               /* do it twice to force the change */
+               tact->set_active (!yn);
+               tact->set_active (yn);
+       }
+
+       if (node.get_property ("show-vca-pane", yn)) {
+               Glib::RefPtr<Action> act = myactions.find_action (X_("Mixer"), X_("ToggleVCAPane"));
+               assert (act);
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               assert (tact);
+
                /* do it twice to force the change */
+               tact->set_active (!yn);
                tact->set_active (yn);
-               show_monitor_section (yn);
        }
 
+#ifdef MIXBUS
+       if (node.get_property ("show-mixbus-pane", yn)) {
+               Glib::RefPtr<Action> act = myactions.find_action (X_("Mixer"), X_("ToggleMixbusPane"));
+               assert (act);
+               Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+               assert (tact);
+
+               /* do it twice to force the change */
+               tact->set_active (!yn);
+               tact->set_active (yn);
+       }
+
+#endif
+
        //check for the user's plugin_order file
        XMLNode plugin_order_new(X_("PO"));
        if (PluginManager::instance().load_plugin_order_file(plugin_order_new)) {
@@ -2239,13 +2368,25 @@ Mixer_UI::get_state ()
 
        node->set_property ("narrow-strips", (_strip_width == Narrow));
        node->set_property ("show-mixer", _visible);
-       node->set_property ("show-mixer-list", _show_mixer_list);
        node->set_property ("maximised", _maximised);
 
-       Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
-       Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
-       assert (tact);
-       node->set_property ("monitor-section-visible", tact->get_active ());
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMixerList");
+       assert (act); Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+       assert (tact); node->set_property ("show-mixer-list", tact->get_active ());
+
+       act = myactions.find_action ("Mixer", "ToggleMonitorSection");
+       assert (act); tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+       assert (tact); node->set_property ("monitor-section-visible", tact->get_active ());
+
+       act = myactions.find_action ("Mixer", "ToggleVCAPane");
+       assert (act); tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+       assert (tact); node->set_property ("show-vca-pane", tact->get_active ());
+
+#ifdef MIXBUS
+       act = myactions.find_action ("Mixer", "ToggleMixbusPane");
+       assert (act); tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
+       assert (tact); node->set_property ("show-mixbus-pane", tact->get_active ());
+#endif
 
        return *node;
 }
@@ -2268,6 +2409,11 @@ Mixer_UI::scroll_left ()
                if (i->get_widget() == & add_button) {
                        continue;
                }
+#ifdef MIXBUS
+               if (i->get_widget() == &mb_shadow) {
+                       continue;
+               }
+#endif
                lm += i->get_widget()->get_width ();
                if (lm >= lp) {
                        lm -= i->get_widget()->get_width ();
@@ -2295,6 +2441,11 @@ Mixer_UI::scroll_right ()
                if (i->get_widget() == & add_button) {
                        continue;
                }
+#ifdef MIXBUS
+               if (i->get_widget() == &mb_shadow) {
+                       continue;
+               }
+#endif
                lm += i->get_widget()->get_width ();
                if (lm > lp + 1) {
                        break;
@@ -2482,10 +2633,39 @@ Mixer_UI::set_axis_targets_for_operation ()
 
 }
 
+void
+Mixer_UI::set_monitor_action_sensitivity (bool yn)
+{
+       // TODO use ActionMap::find_toggle_action()->set_*();
+       Glib::RefPtr<Action> act;
+       Glib::RefPtr<ToggleAction> tact;
+
+       act = ActionManager::get_action (X_("Monitor"), "UseMonitorSection");
+       tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+       tact->set_active (yn);
+
+       act = ActionManager::get_action (X_("Monitor"), "monitor-cut-all");
+       tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+       tact->set_sensitive (yn);
+
+       act = ActionManager::get_action (X_("Monitor"), "monitor-dim-all");
+       tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+       tact->set_sensitive (yn);
+
+       act = ActionManager::get_action (X_("Monitor"), "monitor-mono");
+       tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+       tact->set_sensitive (yn);
+}
+
 void
 Mixer_UI::monitor_section_going_away ()
 {
+       /* Set sensitivity based on existence of the monitor bus  */
+       
+       set_monitor_action_sensitivity(false);
+       
        if (_monitor_section) {
+
                XMLNode* ui_node = Config->extra_xml(X_("UI"));
                /* immediate state save.
                 *
@@ -2563,16 +2743,18 @@ Mixer_UI::restore_mixer_space ()
 void
 Mixer_UI::monitor_section_attached ()
 {
-       Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMonitorSection");
+       assert (act); act->set_sensitive (true);
+
        Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
-       act->set_sensitive (true);
-       show_monitor_section (tact->get_active ());
+       assert (tact);
+       showhide_monitor_section (  tact->get_active () );
 }
 
 void
 Mixer_UI::monitor_section_detached ()
 {
-       Glib::RefPtr<Action> act = ActionManager::get_action ("Common", "ToggleMonitorSection");
+       Glib::RefPtr<Action> act = myactions.find_action ("Mixer", "ToggleMonitorSection");
        act->set_sensitive (false);
 }
 
@@ -3050,13 +3232,25 @@ Mixer_UI::register_actions ()
        myactions.register_action (group, "toggle-processors", _("Toggle Selected Processors"), sigc::mem_fun (*this, &Mixer_UI::toggle_processors));
        myactions.register_action (group, "ab-plugins", _("Toggle Selected Plugins"), sigc::mem_fun (*this, &Mixer_UI::ab_plugins));
        myactions.register_action (group, "select-none", _("Deselect all strips and processors"), sigc::mem_fun (*this, &Mixer_UI::select_none));
-       myactions.register_action (group, "select-all-tracks", _("Select All Tracks"), sigc::mem_fun (*this, &Mixer_UI::select_all_tracks));
+
+       myactions.register_action (group, "select-next-stripable", _("Select Next Mixer Strip"), sigc::mem_fun (*this, &Mixer_UI::select_next_strip));
+       myactions.register_action (group, "select-prev-stripable", _("Scroll Previous Mixer Strip"), sigc::mem_fun (*this, &Mixer_UI::select_prev_strip));
 
        myactions.register_action (group, "scroll-left", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &Mixer_UI::scroll_left));
        myactions.register_action (group, "scroll-right", _("Scroll Mixer Window to the right"), sigc::mem_fun (*this, &Mixer_UI::scroll_right));
 
        myactions.register_action (group, "toggle-midi-input-active", _("Toggle MIDI Input Active for Mixer-Selected Tracks/Busses"),
                                   sigc::bind (sigc::mem_fun (*this, &Mixer_UI::toggle_midi_input_active), false));
+
+       myactions.register_toggle_action (group, X_("ToggleMixerList"), _("Mixer: Show Mixer List"), sigc::mem_fun (*this, &Mixer_UI::toggle_mixer_list));
+
+       myactions.register_toggle_action (group, X_("ToggleVCAPane"), _("Mixer: Show VCAs"), sigc::mem_fun (*this, &Mixer_UI::toggle_vcas));
+
+#ifdef MIXBUS
+       myactions.register_toggle_action (group, X_("ToggleMixbusPane"), _("Mixer: Show Mixbuses"), sigc::mem_fun (*this, &Mixer_UI::toggle_mixbus_pane));
+#endif
+
+       myactions.register_toggle_action (group, X_("ToggleMonitorSection"), _("Mixer: Show Monitor Section"), sigc::mem_fun (*this, &Mixer_UI::toggle_monitor_section));
 }
 
 void