Remove Timers to watch Controllable values
authorRobin Gareus <robin@gareus.org>
Sat, 15 Jul 2017 18:50:26 +0000 (20:50 +0200)
committerRobin Gareus <robin@gareus.org>
Sun, 16 Jul 2017 14:58:00 +0000 (16:58 +0200)
Depend on Changed() signals alone, which are usually much less frequent
than rapid-timer events.

As side-effect we now need to make the widgets insensitive when
playing automation. Previously the user could not change the value because
the Timer periodically reset it.

gtk2_ardour/automation_controller.cc
gtk2_ardour/automation_controller.h
gtk2_ardour/gain_meter.cc
gtk2_ardour/processor_box.cc
gtk2_ardour/processor_box.h

index 3809dc215f41923758f54a78dc581aeec14104cc..6816bffa9344901591164bb0127e57cb777441f2 100644 (file)
@@ -114,10 +114,13 @@ AutomationController::AutomationController(boost::shared_ptr<AutomationControl>
        _adjustment->signal_value_changed().connect(
                sigc::mem_fun(*this, &AutomationController::value_adjusted));
 
-       _screen_update_connection = Timers::rapid_connect (
-                       sigc::mem_fun (*this, &AutomationController::display_effective_value));
+       ac->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&AutomationController::display_effective_value, this), gui_context());
+       display_effective_value ();
 
-       ac->Changed.connect (_changed_connection, invalidator (*this), boost::bind (&AutomationController::display_effective_value, this), gui_context());
+       if (ac->alist ()) {
+               ac->alist()->automation_state_changed.connect (_changed_connections, invalidator (*this), boost::bind (&AutomationController::automation_state_changed, this), gui_context());
+               automation_state_changed ();
+       }
 
        add(*_widget);
        show_all();
@@ -148,7 +151,14 @@ AutomationController::create(const Evoral::Parameter&             param,
 }
 
 void
-AutomationController::display_effective_value()
+AutomationController::automation_state_changed ()
+{
+       bool x = _controllable->alist()->automation_state() & Play;
+       _widget->set_sensitive (!x);
+}
+
+void
+AutomationController::display_effective_value ()
 {
        double const interface_value = _controllable->internal_to_interface(_controllable->get_value());
 
index 170e49ae0776451962617a95bff946128972d8a0..7c3641b2dfc1e059933b0961ce2489feb0787d4c 100644 (file)
@@ -69,7 +69,8 @@ public:
        Gtk::Adjustment* adjustment() { return _adjustment; }
        Gtk::Widget*     widget()     { return _widget; }
 
-       void display_effective_value();
+       void display_effective_value ();
+       void automation_state_changed ();
        void value_adjusted();
 
        void stop_updating ();
@@ -93,7 +94,7 @@ private:
        boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
        Gtk::Adjustment*                             _adjustment;
        sigc::connection                             _screen_update_connection;
-       PBD::ScopedConnection                        _changed_connection;
+       PBD::ScopedConnectionList                    _changed_connections;
        bool                                         _ignore_change;
 };
 
index 9bc31e97608c4e574b9ecc577c3d63630501321b..e60c6613eb2bb639e94d2d1d7fef8c3a71fb05d1 100644 (file)
@@ -617,7 +617,8 @@ GainMeterBase::effective_gain_display ()
 void
 GainMeterBase::gain_changed ()
 {
-       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&GainMeterBase::effective_gain_display, this));
+       ENSURE_GUI_THREAD (*this, &GainMeterBase::gain_automation_state_changed);
+       effective_gain_display ();
 }
 
 void
@@ -813,14 +814,6 @@ GainMeterBase::gain_automation_state_changed ()
        update_gain_sensitive ();
 
        gain_watching.disconnect();
-
-       if (automation_watch_required) {
-               /* start watching automation so that things move */
-               gain_watching = Timers::rapid_connect (sigc::mem_fun (*this, &GainMeterBase::effective_gain_display));
-       } else {
-               /* update once to get the correct value shown as we re-enter off/manual mode */
-               effective_gain_display();
-       }
 }
 
 const ChanCount
index eb5fa585c2152f8c5e699614ed0ee54a05180cf1..876165e5d30d00f5e53bd3d5e365153d3a5d3360 100644 (file)
@@ -823,8 +823,11 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
 
                _button.signal_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked));
                _button.signal_led_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked_event));
-               // dup. currently timers are used :(
-               //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+               c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+               if (c->alist ()) {
+                       c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+                       control_automation_state_changed ();
+               }
 
        } else {
 
@@ -848,14 +851,13 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
                _slider.set_default_value (normal);
 
                _adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Control::slider_adjusted));
-               // dup. currently timers are used :(
-               //c->Changed.connect (_connection, MISSING_INVALIDATOR, boost::bind (&Control::control_changed, this), gui_context ());
+               c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
+               if (c->alist ()) {
+                       c->alist()->automation_state_changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_automation_state_changed, this), gui_context());
+                       control_automation_state_changed ();
+               }
        }
 
-       // yuck, do we really need to do this?
-       // according to c404374 this is only needed for send automation
-       timer_connection = Timers::rapid_connect (sigc::mem_fun (*this, &Control::control_changed));
-
        control_changed ();
        set_tooltip ();
 
@@ -865,7 +867,6 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
 
 ProcessorEntry::Control::~Control ()
 {
-       timer_connection.disconnect ();
 }
 
 void
@@ -923,6 +924,21 @@ ProcessorEntry::Control::button_clicked_event (GdkEventButton *ev)
        button_clicked ();
 }
 
+void
+ProcessorEntry::Control::control_automation_state_changed ()
+{
+       boost::shared_ptr<AutomationControl> c = _control.lock ();
+       if (!c) {
+               return;
+       }
+       bool x = c->alist()->automation_state() & Play;
+       if (c->toggled ()) {
+               _button.set_sensitive (!x);
+       } else {
+               _slider.set_sensitive (!x);
+       }
+}
+
 void
 ProcessorEntry::Control::control_changed ()
 {
@@ -934,12 +950,9 @@ ProcessorEntry::Control::control_changed ()
        _ignore_ui_adjustment = true;
 
        if (c->toggled ()) {
-
                _button.set_active (c->get_value() > 0.5);
-
        } else {
-               // as long as rapid timers are used, only update the tooltip
-               // if the value has changed.
+               // Note: the _slider watches the controllable by itself
                const double nval = c->internal_to_interface (c->get_value ());
                if (_adjustment.get_value() != nval) {
                        _adjustment.set_value (nval);
index fa614f9b6f9aedf2e587af1cfd0030a64671a92f..527eba62ae581ecf0fe7c430b32a032100ec491b 100644 (file)
@@ -219,6 +219,7 @@ private:
                void button_clicked ();
                void button_clicked_event (GdkEventButton *);
                void control_changed ();
+               void control_automation_state_changed ();
                std::string state_id () const;
                void set_tooltip ();
 
@@ -230,10 +231,9 @@ private:
                /* things for a button */
                ArdourButton _button;
                bool _ignore_ui_adjustment;
-               PBD::ScopedConnection _connection;
+               PBD::ScopedConnectionList _connections;
                bool _visible;
                std::string _name;
-               sigc::connection timer_connection;
        };
 
        std::list<Control*> _controls;