summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-05-10 08:52:33 +0100
committerPaul Davis <paul@linuxaudiosystems.com>2017-05-10 08:52:55 +0100
commitbcbdd858faff38b9b22573284f07bdb35b76140b (patch)
treede0f3d0ab6b3ffdc4bc88d651de132ac608ed5ee
parent86149840a1a3950a86dec2a8c0daa974e23e54c2 (diff)
Selection::get_stripables() needs to recurse into an Automatable's child Automatables when looking for for an Automation Control
It also needs renaming (to come)
-rw-r--r--libs/ardour/ardour/automatable.h19
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/route.cc20
-rw-r--r--libs/ardour/selection.cc4
4 files changed, 43 insertions, 2 deletions
diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h
index cde527bed6..4e7c11d51c 100644
--- a/libs/ardour/ardour/automatable.h
+++ b/libs/ardour/ardour/automatable.h
@@ -55,10 +55,27 @@ public:
boost::shared_ptr<Evoral::Control> control_factory(const Evoral::Parameter& id);
boost::shared_ptr<AutomationControl> automation_control (PBD::ID const & id) const;
+ /* derived classes need to provide some way to search their own child
+ automatable's for a control. normally, we'd just make the method
+ above virtual, and let them override it. But that wouldn't
+ differentiate the "check children" and "just your own" cases.
+
+ We could theoretically just overload the above method with an extra
+ "bool recurse = default", but the rules of name hiding for C++ mean
+ that making a method virtual will hide other overloaded versions of
+ the same name. This means that virtual automation_control (PBD::ID
+ const &) would hide automation_control (Evoral::Parameter const &
+ id).
+
+ So, skip around all that with a different name.
+ */
+ virtual boost::shared_ptr<AutomationControl> automation_control_recurse (PBD::ID const & id) const {
+ return automation_control (id);
+ }
+
boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id) {
return automation_control (id, false);
}
-
boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id, bool create_if_missing);
boost::shared_ptr<const AutomationControl> automation_control (const Evoral::Parameter& id) const;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 794f87d607..e916bc403e 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -220,6 +220,8 @@ public:
RoutePinWindowProxy * pinmgr_proxy () const { return _pinmgr_proxy; }
void set_pingmgr_proxy (RoutePinWindowProxy* wp) { _pinmgr_proxy = wp ; }
+ boost::shared_ptr<AutomationControl> automation_control_recurse (PBD::ID const & id) const;
+
/* special processors */
boost::shared_ptr<InternalSend> monitor_send() const { return _monitor_send; }
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 82ce635511..c6e3f157b3 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -5450,3 +5450,23 @@ Route::clear_all_solo_state ()
{
_solo_control->clear_all_solo_state ();
}
+
+boost::shared_ptr<AutomationControl>
+Route::automation_control_recurse (PBD::ID const & id) const
+{
+ boost::shared_ptr<AutomationControl> ac = Automatable::automation_control (id);
+
+ if (ac) {
+ return ac;
+ }
+
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+
+ for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ if ((ac = (*i)->automation_control (id))) {
+ return ac;
+ }
+ }
+
+ return boost::shared_ptr<AutomationControl> ();
+}
diff --git a/libs/ardour/selection.cc b/libs/ardour/selection.cc
index 1c0e89fdf0..2286c83751 100644
--- a/libs/ardour/selection.cc
+++ b/libs/ardour/selection.cc
@@ -217,9 +217,11 @@ CoreSelection::get_stripables (StripableAutomationControls& sc) const
boost::shared_ptr<AutomationControl> c;
if (!s) {
+ /* some global automation control, not owned by a Stripable */
c = session.automation_control_by_id ((*x).controllable);
} else {
- c = s->automation_control ((*x).controllable);
+ /* automation control owned by a Stripable or one of its children */
+ c = s->automation_control_recurse ((*x).controllable);
}
if (s || c) {