13
0

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(
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());

View 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;
};

View 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

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_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);

View 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;