FP8: solo+mute undo
authorRobin Gareus <robin@gareus.org>
Fri, 5 May 2017 13:26:52 +0000 (15:26 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 5 May 2017 13:26:52 +0000 (15:26 +0200)
Eventually this should be moved into libardour: Mixer undo history.
the tentative solution is specifically ifdef'ed FP8_MUTESOLO_UNDO.

libs/surfaces/faderport8/actions.cc
libs/surfaces/faderport8/callbacks.cc
libs/surfaces/faderport8/faderport8.h

index a0711f599ed0e934921da10d51fdefb12af32745..a14c516c3c0cdb27d717f523ad70e3508ce9fc76 100644 (file)
@@ -67,7 +67,11 @@ FaderPort8::setup_actions ()
        BindAction (BtnUndo, "Editor", "undo");
        BindAction (BtnRedo, "Editor", "redo");
 
+#ifdef FP8_MUTESOLO_UNDO
+       BindMethod (BtnSoloClear, button_solo_clear);
+#else
        BindAction (BtnSoloClear, "Main", "cancel-solo");
+#endif
        BindMethod (BtnMuteClear, button_mute_clear);
 
        BindMethod (FP8Controls::BtnArmAll, button_arm_all);
@@ -242,6 +246,44 @@ FaderPort8::button_varispeed (bool ffw)
        session->request_transport_speed (speed, false);
 }
 
+#ifdef FP8_MUTESOLO_UNDO
+void
+FaderPort8::button_solo_clear ()
+{
+       bool soloing = session->soloing() || session->listening();
+       if (soloing) {
+               StripableList all;
+               session->get_stripables (all);
+               for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
+                       if ((*i)->is_master() || (*i)->is_auditioner() || (*i)->is_monitor()) {
+                               continue;
+                       }
+                       boost::shared_ptr<AutomationControl> ac = (*i)->solo_control();
+                       if (ac && ac->get_value () > 0) {
+                               _solo_state.push_back (boost::weak_ptr<AutomationControl>(ac));
+                       }
+               }
+               AccessAction ("Main", "cancel-solo");
+       } else {
+               /* restore solo */
+               boost::shared_ptr<ControlList> cl (new ControlList);
+               for (std::vector <boost::weak_ptr<AutomationControl> >::const_iterator i = _solo_state.begin(); i != _solo_state.end(); ++i) {
+                       boost::shared_ptr<AutomationControl> ac = (*i).lock();
+                       if (!ac) {
+                               continue;
+                       }
+                       if (ac->automation_state() == Touch && !ac->touching ()) {
+                               ac->start_touch (ac->session().transport_frame());
+                       }
+                       cl->push_back (ac);
+               }
+               if (!cl->empty()) {
+                       session->set_controls (cl, 1.0, PBD::Controllable::NoGroup);
+               }
+       }
+}
+#endif
+
 void
 FaderPort8::button_mute_clear ()
 {
@@ -249,18 +291,46 @@ FaderPort8::button_mute_clear ()
        session->get_stripables (all);
        boost::shared_ptr<ControlList> cl (new ControlList);
        for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
-               if ((*i)->is_master() || (*i)->is_monitor()) {
+               if ((*i)->is_auditioner() || (*i)->is_monitor()) {
                        continue;
                }
                boost::shared_ptr<AutomationControl> ac = (*i)->mute_control();
                if (ac && ac->get_value () > 0) {
-                       if (ac->automation_state() == Touch && !ac->touching ()) {
-                               ac->start_touch (ac->session().transport_frame());
-                       }
                        cl->push_back (ac);
                }
        }
-       session->set_controls (cl, 0.0, PBD::Controllable::UseGroup);
+
+       bool mute = false;
+#ifdef FP8_MUTESOLO_UNDO
+       if (cl->empty ()) {
+               /* restore mute */
+               for (std::vector <boost::weak_ptr<AutomationControl> >::const_iterator i = _mute_state.begin(); i != _mute_state.end(); ++i) {
+                       boost::shared_ptr<AutomationControl> ac = (*i).lock();
+                       if (ac) {
+                               cl->push_back (ac);
+                       }
+               }
+               mute = true;
+       } else {
+               /* save muted control IDs */
+               _mute_state.clear ();
+               for (ControlList::const_iterator i = cl->begin (); i != cl->end (); ++i) {
+                       _mute_state.push_back (boost::weak_ptr<AutomationControl>(*i));
+               }
+       }
+#endif
+
+       if (cl->empty ()) {
+               return;
+       }
+
+       for (ControlList::const_iterator i = cl->begin (); i != cl->end (); ++i) {
+               if ((*i)->automation_state() == Touch && !(*i)->touching ()) {
+                       (*i)->start_touch ((*i)->session().transport_frame());
+               }
+       }
+
+       session->set_controls (cl, mute ? 1.0 : 0.0, mute ? PBD::Controllable::NoGroup : PBD::Controllable::UseGroup);
 }
 
 void
index 72aa8228bf29af1c8c8ba2aa6027823019d4fc15..fa822bb8dfc9c87fb00ace83a7fcfa8dadf922a5 100644 (file)
@@ -184,7 +184,13 @@ FaderPort8::notify_history_changed ()
 void
 FaderPort8::notify_solo_changed ()
 {
-       _ctrls.button (FP8Controls::BtnSoloClear).set_active (session->soloing() || session->listening());
+       bool soloing = session->soloing() || session->listening();
+       _ctrls.button (FP8Controls::BtnSoloClear).set_active (soloing);
+#ifdef FP8_MUTESOLO_UNDO
+       if (soloing) {
+               _solo_state.clear ();
+       }
+#endif
 }
 
 void
@@ -193,7 +199,7 @@ FaderPort8::notify_mute_changed ()
        bool muted = false;
        boost::shared_ptr<RouteList> rl = session->get_routes();
        for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
-               if ((*i)->is_master() || (*i)->is_monitor()) {
+               if ((*i)->is_auditioner() || (*i)->is_monitor()) {
                        continue;
                }
                boost::shared_ptr<MuteControl> mc = (*i)->mute_control();
@@ -202,5 +208,10 @@ FaderPort8::notify_mute_changed ()
                        break;
                }
        }
+#ifdef FP8_MUTESOLO_UNDO
+       if (muted) {
+               _mute_state.clear ();
+       }
+#endif
        _ctrls.button (FP8Controls::BtnMuteClear).set_active (muted);
 }
index e4809e6d2da64d0e15b4d80fdc0a3bda1d9901b3..aa1fb8a1fc666b05efd693675c3a91bd538528bd 100644 (file)
 #ifndef ardour_surface_faderport8_h
 #define ardour_surface_faderport8_h
 
+// allow to undo "mute clear", "solo clear"
+// eventually this should use some libardour mixer history/undo
+#define FP8_MUTESOLO_UNDO
+
 #include <list>
 #include <map>
 #include <glibmm/threads.h>
@@ -243,6 +247,9 @@ private:
        void button_loop ();
        void button_metronom ();
        void button_varispeed (bool);
+#ifdef FP8_MUTESOLO_UNDO
+       void button_solo_clear ();
+#endif
        void button_mute_clear ();
        void button_arm (bool);
        void button_arm_all ();
@@ -255,6 +262,12 @@ private:
        void encoder_navigate (bool, int);
        void encoder_parameter (bool, int);
 
+       /* mute undo history */
+#ifdef FP8_MUTESOLO_UNDO
+       std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _mute_state;
+       std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _solo_state;
+#endif
+
        /* user bound actions */
        void button_user (bool, FP8Controls::ButtonId);