use new shared cancel_all_solo() in Mackie code
[ardour.git] / libs / surfaces / control_protocol / control_protocol.cc
index f1b2f9f112b97f9cf3a434df2e5d520066a3cf6c..8c2a1217790063cd4650d6debddda2a54149f41e 100644 (file)
@@ -49,8 +49,20 @@ PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
 PBD::Signal0<void>          ControlProtocol::StepTracksDown;
 PBD::Signal0<void>          ControlProtocol::StepTracksUp;
 
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::AddStripableToSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::SetStripableSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::ToggleStripableSelection;
+PBD::Signal1<void,boost::shared_ptr<ARDOUR::Stripable> > ControlProtocol::RemoveStripableFromSelection;
+PBD::Signal0<void>          ControlProtocol::ClearStripableSelection;
+
 PBD::Signal1<void,StripableNotificationListPtr> ControlProtocol::StripableSelectionChanged;
 
+Glib::Threads::Mutex ControlProtocol::first_selected_mutex;
+boost::weak_ptr<Stripable> ControlProtocol::_first_selected_stripable;
+StripableNotificationList ControlProtocol::_last_selected;
+bool ControlProtocol::selection_connected = false;
+PBD::ScopedConnection ControlProtocol::selection_connection;
+
 const std::string ControlProtocol::state_node_name ("Protocol");
 
 ControlProtocol::ControlProtocol (Session& s, string str)
@@ -58,6 +70,12 @@ ControlProtocol::ControlProtocol (Session& s, string str)
        , _name (str)
        , _active (false)
 {
+       if (!selection_connected) {
+               /* this is all static, connect it only once (and early), for all ControlProtocols */
+
+               StripableSelectionChanged.connect_same_thread (selection_connection, boost::bind (&ControlProtocol::stripable_selection_changed, _1));
+               selection_connected = true;
+       }
 }
 
 ControlProtocol::~ControlProtocol ()
@@ -324,3 +342,37 @@ ControlProtocol::set_state (XMLNode const & node, int /* version */)
 
        return 0;
 }
+
+boost::shared_ptr<Stripable>
+ControlProtocol::first_selected_stripable ()
+{
+       Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+       return _first_selected_stripable.lock();
+}
+
+void
+ControlProtocol::set_first_selected_stripable (boost::shared_ptr<Stripable> s)
+{
+       Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+       _first_selected_stripable = s;
+}
+
+void
+ControlProtocol::stripable_selection_changed (StripableNotificationListPtr sp)
+{
+       bool had_selection = !_last_selected.empty();
+
+       _last_selected = *sp;
+
+       {
+               Glib::Threads::Mutex::Lock lm (first_selected_mutex);
+
+               if (!_last_selected.empty()) {
+                       if (!had_selection) {
+                               _first_selected_stripable = _last_selected.front().lock();
+                       }
+               } else {
+                       _first_selected_stripable = boost::weak_ptr<Stripable>();
+               }
+       }
+}