+ boost::shared_ptr<ControlGroup> _group;
+
+ const ParameterDescriptor _desc;
+
+ bool check_rt (double val, Controllable::GroupControlDisposition gcd);
+
+ /* derived classes may reimplement this, but should either
+ call this explicitly inside their version OR make sure that the
+ Controllable::Changed signal is emitted when necessary.
+ */
+
+ virtual void actually_set_value (double value, PBD::Controllable::GroupControlDisposition);
+
+ private:
+ /* I am unclear on why we have to make ControlGroup a friend in order
+ to get access to the ::set_group() method when it is already
+ declared to be a friend in ControlGroupMember. Oh well.
+ */
+ friend class ControlGroup;
+ void set_group (boost::shared_ptr<ControlGroup>);
+};
+
+class SlavableAutomationControl : public AutomationControl
+{
+ public:
+ SlavableAutomationControl(ARDOUR::Session&,
+ const Evoral::Parameter& parameter,
+ const ParameterDescriptor& desc,
+ boost::shared_ptr<ARDOUR::AutomationList> l=boost::shared_ptr<ARDOUR::AutomationList>(),
+ const std::string& name="");
+
+ ~SlavableAutomationControl ();
+
+ double get_value () const;
+
+ void add_master (boost::shared_ptr<AutomationControl>);
+ void remove_master (boost::shared_ptr<AutomationControl>);
+ void clear_masters ();
+ bool slaved_to (boost::shared_ptr<AutomationControl>) const;
+ bool slaved () const;
+ std::vector<PBD::ID> masters () const;
+
+ PBD::Signal0<void> MasterStatusChange;
+
+ protected:
+
+ class MasterRecord {
+ public:
+ MasterRecord (boost::shared_ptr<AutomationControl> gc, double r)
+ : _master (gc)
+ , _ratio (r)
+ {}
+
+ boost::shared_ptr<AutomationControl> master() const { return _master; }
+ double ratio () const { return _ratio; }
+ void reset_ratio (double r) { _ratio = r; }
+
+ PBD::ScopedConnection connection;
+
+ private:
+ boost::shared_ptr<AutomationControl> _master;
+ double _ratio;
+
+ };
+
+ mutable Glib::Threads::RWLock master_lock;
+ typedef std::map<PBD::ID,MasterRecord> Masters;
+ Masters _masters;
+ PBD::ScopedConnectionList masters_connections;
+ virtual void master_changed (bool from_self, GroupControlDisposition gcd);
+ void master_going_away (boost::weak_ptr<AutomationControl>);
+ virtual void recompute_masters_ratios (double val) { /* do nothing by default */}
+ virtual double get_masters_value_locked () const;
+ double get_value_locked() const;
+