Mark Sequence as edited when one of its parent ControlSet's ControlLists is changed.
[ardour.git] / gtk2_ardour / mixer_ui.cc
index 0484db6fe720b4ae19476d10a745106bc048d402..4d6f7119cc72b9ac5528a7ed7a1de675165aee5c 100644 (file)
 
 #include <gtkmm2ext/gtk_ui.h>
 #include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/stop_signal.h>
+#include <gtkmm2ext/tearoff.h>
 #include <gtkmm2ext/window_title.h>
 
-#include "ardour/audio_diskstream.h"
 #include "ardour/audio_track.h"
 #include "ardour/plugin_manager.h"
 #include "ardour/route_group.h"
@@ -42,6 +41,7 @@
 #include "keyboard.h"
 #include "mixer_ui.h"
 #include "mixer_strip.h"
+#include "monitor_section.h"
 #include "plugin_selector.h"
 #include "ardour_ui.h"
 #include "prompter.h"
@@ -66,6 +66,7 @@ Mixer_UI::Mixer_UI ()
 {
        _strip_width = Config->get_default_narrow_ms() ? Narrow : Wide;
        track_menu = 0;
+        _monitor_section = 0;
        route_group_context_menu = 0;
        no_track_list_redisplay = false;
        in_group_row_change = false;
@@ -74,7 +75,7 @@ Mixer_UI::Mixer_UI ()
        strip_redisplay_does_not_sync_order_keys = false;
        ignore_sync = false;
 
-       Route::SyncOrderKeys.connect (*this, boost::bind (&Mixer_UI::sync_order_keys, this, _1));
+       Route::SyncOrderKeys.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
 
        scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
        scroller_base.set_name ("MixerWindow");
@@ -251,7 +252,13 @@ Mixer_UI::Mixer_UI ()
 
        auto_rebinding = FALSE;
 
+       MixerStrip::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::remove_strip, this, _1), gui_context());
+
+        MonitorSection::setup_knob_images ();
+
+#ifndef DEFER_PLUGIN_SELECTOR_LOAD
        _plugin_selector = new PluginSelector (PluginManager::the_manager ());
+#endif
 }
 
 Mixer_UI::~Mixer_UI ()
@@ -309,9 +316,29 @@ Mixer_UI::add_strip (RouteList& routes)
                boost::shared_ptr<Route> route = (*x);
 
                if (route->is_hidden()) {
-                       return;
+                       continue;
                }
 
+                if (route->is_monitor()) {
+                        if (!_monitor_section) {
+                                _monitor_section = new MonitorSection (_session);
+                                out_packer.pack_end (_monitor_section->tearoff(), false, false);
+                        } else {
+                                _monitor_section->set_session (_session);
+                        }
+
+                        _monitor_section->tearoff().show_all ();
+
+                        XMLNode* mnode = ARDOUR_UI::instance()->tearoff_settings (X_("monitor-section"));
+                        if (mnode) {
+                                _monitor_section->tearoff().set_state (*mnode);
+                        }
+
+                        /* no regular strip shown for control out */
+
+                        continue;
+                }
+
                strip = new MixerStrip (*this, _session, route);
                strips.push_back (strip);
 
@@ -333,9 +360,8 @@ Mixer_UI::add_strip (RouteList& routes)
                        route->set_order_key (N_("signal"), track_model->children().size()-1);
                }
 
-               route->NameChanged.connect (*this,  boost::bind (&Mixer_UI::strip_name_changed, this, strip));
+               route->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
 
-               strip->GoingAway.connect (*this, boost::bind (&Mixer_UI::remove_strip, this, strip));
                strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
                strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
        }
@@ -350,7 +376,14 @@ Mixer_UI::add_strip (RouteList& routes)
 void
 Mixer_UI::remove_strip (MixerStrip* strip)
 {
-       ENSURE_GUI_THREAD (*this, &Mixer_UI::remove_strip, strip)
+       if (_session && _session->deletion_in_progress()) {
+               /* its all being taken care of */
+               return;
+       }
+
+       ENSURE_GUI_THREAD (*this, &Mixer_UI::remove_strip, strip);
+
+       cerr << "Mixer UI removing strip for " << strip << endl;
 
        TreeModel::Children rows = track_model->children();
        TreeModel::Children::iterator ri;
@@ -476,15 +509,17 @@ Mixer_UI::set_session (Session* sess)
 
        initial_track_display ();
 
-       _session->RouteAdded.connect (_session_connections, boost::bind (&Mixer_UI::add_strip, this, _1));
-       _session->route_group_added.connect (_session_connections, boost::bind (&Mixer_UI::add_route_group, this, _1));
-       _session->route_group_removed.connect (_session_connections, boost::bind (&Mixer_UI::route_groups_changed, this));
-       _session->config.ParameterChanged.connect (_session_connections, boost::bind (&Mixer_UI::parameter_changed, this, _1));
+       _session->RouteAdded.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_strip, this, _1), gui_context());
+       _session->route_group_added.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::add_route_group, this, _1), gui_context());
+       _session->route_group_removed.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
+       _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context());
+
+       Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::parameter_changed, this, _1), gui_context ());
 
        route_groups_changed ();
 
        if (_visible) {
-              show_window();
+               show_window();
        }
 
        start_updating ();
@@ -497,6 +532,17 @@ Mixer_UI::session_going_away ()
 
        group_model->clear ();
        _selection.clear ();
+       track_model->clear ();
+
+       for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) {
+               delete (*i);
+       }
+
+        if (_monitor_section) {
+                _monitor_section->tearoff().hide_visible ();
+        }
+
+       strips.clear ();
 
        WindowTitle title(Glib::get_application_name());
        title += _("Mixer");
@@ -580,7 +626,7 @@ Mixer_UI::set_all_strips_visibility (bool yn)
                        continue;
                }
 
-               if (strip->route()->is_master() || strip->route()->is_control()) {
+               if (strip->route()->is_master() || strip->route()->is_monitor()) {
                        continue;
                }
 
@@ -608,7 +654,7 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn)
                        continue;
                }
 
-               if (strip->route()->is_master() || strip->route()->is_control()) {
+               if (strip->route()->is_master() || strip->route()->is_monitor()) {
                        continue;
                }
 
@@ -731,7 +777,7 @@ Mixer_UI::redisplay_track_list ()
 
                        if (strip->packed()) {
 
-                               if (strip->route()->is_master() || strip->route()->is_control()) {
+                               if (strip->route()->is_master() || strip->route()->is_monitor()) {
                                        out_packer.reorder_child (*strip, -1);
                                } else {
                                        strip_packer.reorder_child (*strip, -1); /* put at end */
@@ -739,7 +785,7 @@ Mixer_UI::redisplay_track_list ()
 
                        } else {
 
-                               if (strip->route()->is_master() || strip->route()->is_control()) {
+                               if (strip->route()->is_master() || strip->route()->is_monitor()) {
                                        out_packer.pack_start (*strip, false, false);
                                } else {
                                        strip_packer.pack_start (*strip, false, false);
@@ -752,7 +798,7 @@ Mixer_UI::redisplay_track_list ()
 
                        strip->set_marked_for_display (false);
 
-                       if (strip->route()->is_master() || strip->route()->is_control()) {
+                       if (strip->route()->is_master() || strip->route()->is_monitor()) {
                                /* do nothing, these cannot be hidden */
                        } else {
                                if (strip->packed()) {
@@ -950,7 +996,7 @@ Mixer_UI::track_display_button_press (GdkEventButton* ev)
                        MixerStrip* strip = (*iter)[track_columns.strip];
                        if (strip) {
 
-                               if (!strip->route()->is_master() && !strip->route()->is_control()) {
+                               if (!strip->route()->is_master() && !strip->route()->is_monitor()) {
                                        bool visible = (*iter)[track_columns.visible];
                                        (*iter)[track_columns.visible] = !visible;
                                }
@@ -989,9 +1035,13 @@ Mixer_UI::build_track_menu ()
 }
 
 void
-Mixer_UI::strip_name_changed (MixerStrip* mx)
+Mixer_UI::strip_property_changed (const PropertyChange& what_changed, MixerStrip* mx)
 {
-       ENSURE_GUI_THREAD (*this, &Mixer_UI::strip_name_changed, mx)
+       if (!what_changed.contains (ARDOUR::Properties::name)) {
+               return;
+       }
+
+       ENSURE_GUI_THREAD (*this, &Mixer_UI::strip_name_changed, what_changed, mx)
 
        TreeModel::Children rows = track_model->children();
        TreeModel::Children::iterator i;
@@ -1115,7 +1165,17 @@ Mixer_UI::route_groups_changed ()
 void
 Mixer_UI::new_route_group ()
 {
-       _session->add_route_group (new RouteGroup (*_session, "", RouteGroup::Active, (RouteGroup::Property) (RouteGroup::Gain |RouteGroup::Mute | RouteGroup::Solo)));
+       PropertyList plist;
+
+       plist.add (Properties::active, true);
+       plist.add (Properties::gain, true);
+       plist.add (Properties::mute, true);
+       plist.add (Properties::solo, true);
+
+       RouteGroup* g = new RouteGroup (*_session, "");
+       g->set_properties (plist);
+
+       _session->add_route_group (g);
 }
 
 void
@@ -1144,14 +1204,12 @@ Mixer_UI::remove_selected_route_group ()
 }
 
 void
-Mixer_UI::group_flags_changed (void* src, RouteGroup* group)
+Mixer_UI::route_group_property_changed (RouteGroup* group, const PropertyChange& change)
 {
        if (in_group_row_change) {
                return;
        }
 
-       ENSURE_GUI_THREAD (*this, &Mixer_UI::group_flags_changed, src, group)
-
        /* force an update of any mixer strips that are using this group,
           otherwise mix group names don't change in mixer strips
        */
@@ -1178,7 +1236,9 @@ Mixer_UI::group_flags_changed (void* src, RouteGroup* group)
 
        in_group_row_change = false;
 
-       _group_tabs->set_dirty ();
+       if (change.contains (Properties::name)) {
+               _group_tabs->set_dirty ();
+       }
 }
 
 void
@@ -1252,7 +1312,7 @@ Mixer_UI::add_route_group (RouteGroup* group)
                focus = true;
        }
 
-       group->FlagsChanged.connect (*this,  boost::bind (&Mixer_UI::group_flags_changed, this, _1, group));
+       group->PropertyChanged.connect (*this, invalidator (*this), ui_bind (&Mixer_UI::route_group_property_changed, this, group, _1), gui_context());
 
        if (focus) {
                TreeViewColumn* col = group_display.get_column (0);
@@ -1554,6 +1614,11 @@ Mixer_UI::parameter_changed (string const & p)
                } else {
                        _group_tabs->hide ();
                }
+       } else if (p == "default-narrow_ms") {
+               bool const s = Config->get_default_narrow_ms ();
+               for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
+                       (*i)->set_width_enum (s ? Narrow : Wide, this);
+               }
        }
 }
 
@@ -1566,5 +1631,10 @@ Mixer_UI::set_route_group_activation (RouteGroup* g, bool a)
 PluginSelector*
 Mixer_UI::plugin_selector()
 {
+#ifdef DEFER_PLUGIN_SELECTOR_LOAD
+       if (!_plugin_selector)
+               _plugin_selector = new PluginSelector (PluginManager::the_manager ());
+#endif
+
        return _plugin_selector;
 }