Remove Timers to watch Controllable values

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.
This commit is contained in:
Robin Gareus 2017-07-15 20:50:26 +02:00
parent 69ecb0db70
commit 5aecfc5acb
5 changed files with 47 additions and 30 deletions

View file

@ -114,10 +114,13 @@ AutomationController::AutomationController(boost::shared_ptr<AutomationControl>
_adjustment->signal_value_changed().connect( _adjustment->signal_value_changed().connect(
sigc::mem_fun(*this, &AutomationController::value_adjusted)); sigc::mem_fun(*this, &AutomationController::value_adjusted));
_screen_update_connection = Timers::rapid_connect ( ac->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&AutomationController::display_effective_value, this), gui_context());
sigc::mem_fun (*this, &AutomationController::display_effective_value)); 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); add(*_widget);
show_all(); show_all();
@ -148,7 +151,14 @@ AutomationController::create(const Evoral::Parameter& param,
} }
void 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()); double const interface_value = _controllable->internal_to_interface(_controllable->get_value());

View file

@ -69,7 +69,8 @@ public:
Gtk::Adjustment* adjustment() { return _adjustment; } Gtk::Adjustment* adjustment() { return _adjustment; }
Gtk::Widget* widget() { return _widget; } Gtk::Widget* widget() { return _widget; }
void display_effective_value(); void display_effective_value ();
void automation_state_changed ();
void value_adjusted(); void value_adjusted();
void stop_updating (); void stop_updating ();
@ -93,7 +94,7 @@ private:
boost::shared_ptr<ARDOUR::AutomationControl> _controllable; boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
Gtk::Adjustment* _adjustment; Gtk::Adjustment* _adjustment;
sigc::connection _screen_update_connection; sigc::connection _screen_update_connection;
PBD::ScopedConnection _changed_connection; PBD::ScopedConnectionList _changed_connections;
bool _ignore_change; bool _ignore_change;
}; };

View file

@ -617,7 +617,8 @@ GainMeterBase::effective_gain_display ()
void void
GainMeterBase::gain_changed () 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 void
@ -813,14 +814,6 @@ GainMeterBase::gain_automation_state_changed ()
update_gain_sensitive (); update_gain_sensitive ();
gain_watching.disconnect(); 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 const ChanCount

View 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_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked));
_button.signal_led_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked_event)); _button.signal_led_clicked.connect (sigc::mem_fun (*this, &Control::button_clicked_event));
// dup. currently timers are used :( c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
//c->Changed.connect (_connection, MISSING_INVALIDATOR, 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 { } else {
@ -848,14 +851,13 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
_slider.set_default_value (normal); _slider.set_default_value (normal);
_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Control::slider_adjusted)); _adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &Control::slider_adjusted));
// dup. currently timers are used :( c->Changed.connect (_connections, invalidator (*this), boost::bind (&Control::control_changed, this), gui_context ());
//c->Changed.connect (_connection, MISSING_INVALIDATOR, 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 (); control_changed ();
set_tooltip (); set_tooltip ();
@ -865,7 +867,6 @@ ProcessorEntry::Control::Control (boost::shared_ptr<AutomationControl> c, string
ProcessorEntry::Control::~Control () ProcessorEntry::Control::~Control ()
{ {
timer_connection.disconnect ();
} }
void void
@ -923,6 +924,21 @@ ProcessorEntry::Control::button_clicked_event (GdkEventButton *ev)
button_clicked (); 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 void
ProcessorEntry::Control::control_changed () ProcessorEntry::Control::control_changed ()
{ {
@ -934,12 +950,9 @@ ProcessorEntry::Control::control_changed ()
_ignore_ui_adjustment = true; _ignore_ui_adjustment = true;
if (c->toggled ()) { if (c->toggled ()) {
_button.set_active (c->get_value() > 0.5); _button.set_active (c->get_value() > 0.5);
} else { } else {
// as long as rapid timers are used, only update the tooltip // Note: the _slider watches the controllable by itself
// if the value has changed.
const double nval = c->internal_to_interface (c->get_value ()); const double nval = c->internal_to_interface (c->get_value ());
if (_adjustment.get_value() != nval) { if (_adjustment.get_value() != nval) {
_adjustment.set_value (nval); _adjustment.set_value (nval);

View file

@ -219,6 +219,7 @@ private:
void button_clicked (); void button_clicked ();
void button_clicked_event (GdkEventButton *); void button_clicked_event (GdkEventButton *);
void control_changed (); void control_changed ();
void control_automation_state_changed ();
std::string state_id () const; std::string state_id () const;
void set_tooltip (); void set_tooltip ();
@ -230,10 +231,9 @@ private:
/* things for a button */ /* things for a button */
ArdourButton _button; ArdourButton _button;
bool _ignore_ui_adjustment; bool _ignore_ui_adjustment;
PBD::ScopedConnection _connection; PBD::ScopedConnectionList _connections;
bool _visible; bool _visible;
std::string _name; std::string _name;
sigc::connection timer_connection;
}; };
std::list<Control*> _controls; std::list<Control*> _controls;