libardour now has CoreSelection object to manage selection status of Stripables and...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 5 May 2017 11:31:21 +0000 (12:31 +0100)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 5 May 2017 17:56:25 +0000 (18:56 +0100)
26 files changed:
libs/ardour/ardour/automatable.h
libs/ardour/ardour/debug.h
libs/ardour/ardour/presentation_info.h
libs/ardour/ardour/route.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_handle.h
libs/ardour/ardour/stripable.h
libs/ardour/ardour/vca.h
libs/ardour/automatable.cc
libs/ardour/automation_control.cc
libs/ardour/debug.cc
libs/ardour/enums.cc
libs/ardour/luabindings.cc
libs/ardour/presentation_info.cc
libs/ardour/route.cc
libs/ardour/session.cc
libs/ardour/session_midi.cc
libs/ardour/session_state.cc
libs/ardour/stripable.cc
libs/ardour/track.cc
libs/ardour/vca.cc
libs/ardour/wscript
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/strip.cc
libs/surfaces/osc/osc.cc
libs/surfaces/push2/mix.cc

index ae2c8dd41f669e282af5f19d70dfe3b570bd2768..cde527bed69322e50d844010322fc35f58880c60 100644 (file)
@@ -54,6 +54,7 @@ public:
 
        boost::shared_ptr<Evoral::Control> control_factory(const Evoral::Parameter& id);
 
+       boost::shared_ptr<AutomationControl> automation_control (PBD::ID const & id) const;
        boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id) {
                return automation_control (id, false);
        }
index eff8305bf158e6ad90057a559b2d7413e34994e8..61903cd7245af49db798059bcbe4df1ba006c78b 100644 (file)
@@ -72,6 +72,7 @@ namespace PBD {
                LIBARDOUR_API extern DebugBits AudioEngine;
                LIBARDOUR_API extern DebugBits Soundcloud;
                LIBARDOUR_API extern DebugBits Butler;
+               LIBARDOUR_API extern DebugBits Selection;
                LIBARDOUR_API extern DebugBits GenericMidi;
                LIBARDOUR_API extern DebugBits BackendMIDI;
                LIBARDOUR_API extern DebugBits BackendAudio;
index 7c847e9fce8e9b7c263c739670d5909e0072b9d3..c508f8401a5ccd047317818569ddd4eb146e222f 100644 (file)
@@ -93,11 +93,6 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
         * change after construction (not strictly the constructor itself, but
         * a more generalized notion of construction, as in "ready to use").
         *
-        * SELECTION
-        *
-        * When an object is selected, its _flags member will have the Selected
-        * bit set.
-        *
         * VISIBILITY
         *
         * When an object is hidden, its _flags member will have the Hidden
@@ -119,13 +114,12 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
                /* These are for sharing Stripable states between the GUI and other
                 * user interfaces/control surfaces
                 */
-               Selected = 0x100,
-               Hidden = 0x200,
+               Hidden = 0x100,
                /* single bit indicates that the group order is set */
                OrderSet = 0x400,
 
                /* special mask to delect out "state" bits */
-               StatusMask = (Selected|Hidden),
+               StatusMask = (Hidden),
                /* special mask to delect select type bits */
                TypeMask = (AudioBus|AudioTrack|MidiTrack|MidiBus|VCA|MasterOut|MonitorOut|Auditioner)
        };
@@ -152,7 +146,6 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
        bool color_set() const;
 
        void set_color (color_t);
-       void set_selected (bool yn);
        void set_hidden (bool yn);
        void set_flags (Flag f) { _flags = f; }
 
@@ -161,7 +154,6 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
        int selection_cnt() const { return _selection_cnt; }
 
        bool hidden() const { return _flags & Hidden; }
-       bool selected() const { return _flags & Selected; }
        bool special() const { return _flags & (MasterOut|MonitorOut|Auditioner); }
 
        bool flag_match (Flag f) const {
@@ -238,6 +230,7 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
         */
 
        static PBD::Signal1<void,PBD::PropertyChange const &> Change;
+       static void send_static_change (const PBD::PropertyChange&);
 
        static void make_property_quarks ();
 
@@ -270,7 +263,6 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
        static PBD::PropertyChange _pending_static_changes;
        static Glib::Threads::Mutex static_signal_lock;
        static int _change_signal_suspended;
-       static void send_static_change (const PBD::PropertyChange&);
 
        static int selection_counter;
 };
index 9313df2f0cc07862ecf4416b818d7d5d549963da..794f87d607eb1b5b5fc54e45a6ea7a16103b9fd4 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
 
 #include <glibmm/threads.h>
 #include "pbd/fastlog.h"
@@ -89,9 +88,7 @@ class LIBARDOUR_API Route : public Stripable,
                             public Soloable,
                             public Muteable,
                             public Monitorable,
-                            public Automatable,
-                            public RouteGroupMember,
-                            public boost::enable_shared_from_this<Route>
+                            public RouteGroupMember
 {
 public:
 
index dfeb1d0834cb2cdc04b633c877fe1bf95a542530..f748adb15d251e849bc0e20e8677ec2ea80ea83f 100644 (file)
@@ -114,6 +114,7 @@ class Bundle;
 class Butler;
 class Click;
 class ControllableDescriptor;
+class CoreSelection;
 class Diskstream;
 class ExportHandler;
 class ExportStatus;
@@ -289,6 +290,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
                return routes.reader ();
        }
 
+       CoreSelection& selection () { return *_selection; }
+
        /* because the set of Stripables consists of objects managed
         * independently, in multiple containers within the Session (or objects
         * owned by the session), we fill out a list in-place rather than
@@ -323,6 +326,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        bool io_name_is_legal (const std::string&) const;
        boost::shared_ptr<Route> route_by_name (std::string) const;
        boost::shared_ptr<Route> route_by_id (PBD::ID) const;
+       boost::shared_ptr<Stripable> stripable_by_id (PBD::ID) const;
        boost::shared_ptr<Stripable> get_remote_nth_stripable (PresentationInfo::order_t n, PresentationInfo::Flag) const;
        boost::shared_ptr<Route> get_remote_nth_route (PresentationInfo::order_t n) const;
        boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt) const;
@@ -1060,6 +1064,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        boost::shared_ptr<Processor> processor_by_id (PBD::ID) const;
 
        boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
+       boost::shared_ptr<AutomationControl> automation_control_by_id (const PBD::ID&);
        boost::shared_ptr<PBD::Controllable> controllable_by_descriptor (const ARDOUR::ControllableDescriptor&);
 
        void add_controllable (boost::shared_ptr<PBD::Controllable>);
@@ -2088,6 +2093,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        void rewire_selected_midi (boost::shared_ptr<MidiTrack>);
        void rewire_midi_selection_ports ();
        boost::weak_ptr<MidiTrack> current_midi_target;
+
+       CoreSelection* _selection;
 };
 
 
index 330f1805cd4c4c4152f0c05a55470f2096c3e8b9..804bf004c25b6dc208da1a3b1cf6ead8b08aa13e 100644 (file)
@@ -47,6 +47,7 @@ class LIBARDOUR_API SessionHandlePtr
        virtual ~SessionHandlePtr () {}
 
        virtual void set_session (ARDOUR::Session *);
+       virtual ARDOUR::Session* session() const { return _session; }
 
   protected:
        ARDOUR::Session*          _session;
index 2484c263457c45afb0838da5324480996c01efee..7298a4807ee1322aff78dbad4e16b575f77a9c3b 100644 (file)
 #include <string>
 #include <boost/utility.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 
 #include "pbd/signals.h"
 
+#include "ardour/automatable.h"
 #include "ardour/presentation_info.h"
 #include "ardour/session_object.h"
 #include "ardour/libardour_visibility.h"
@@ -56,10 +58,13 @@ class RecordSafeControl;
  * and behaviour of the object.
  */
 
-class LIBARDOUR_API Stripable : public SessionObject {
-   public:
+class LIBARDOUR_API Stripable : public SessionObject,
+                                public Automatable,
+                                public boost::enable_shared_from_this<Stripable>
+{
+  public:
        Stripable (Session& session, std::string const & name, PresentationInfo const &);
-       virtual ~Stripable () {}
+       virtual ~Stripable ();
 
        /* XXX
           midi on/off
@@ -72,7 +77,7 @@ class LIBARDOUR_API Stripable : public SessionObject {
        int set_state (XMLNode const&, int);
 
        bool is_hidden() const { return _presentation_info.flags() & PresentationInfo::Hidden; }
-       bool is_selected() const { return _presentation_info.flags() & PresentationInfo::Selected; }
+       bool is_selected() const;
 
        PresentationInfo const & presentation_info () const { return _presentation_info; }
        PresentationInfo& presentation_info () { return _presentation_info; }
index 0977001927269b770c8376003a732d0f3f78f879..5cf06e4d698b5723b6bdd0aff55c23a5c62d3674 100644 (file)
@@ -28,7 +28,6 @@
 #include "pbd/controllable.h"
 #include "pbd/statefuldestructible.h"
 
-#include "ardour/automatable.h"
 #include "ardour/muteable.h"
 #include "ardour/monitorable.h"
 #include "ardour/recordable.h"
@@ -47,10 +46,9 @@ class MonitorControl;
 class LIBARDOUR_API VCA : public Stripable,
                           public Soloable,
                           public Muteable,
-                          public Automatable,
                           public Recordable,
-                          public Monitorable,
-                          public boost::enable_shared_from_this<VCA> {
+                          public Monitorable
+{
   public:
        VCA (Session& session,  int32_t num, const std::string& name);
        ~VCA();
index 7ad930f60b510284823cd85c78cd6f53b1d73bf0..00dcdec8f06338758a8e9911b075575d03763f49 100644 (file)
@@ -508,6 +508,21 @@ Automatable::control_factory(const Evoral::Parameter& param)
        return boost::shared_ptr<Evoral::Control>(control);
 }
 
+boost::shared_ptr<AutomationControl>
+Automatable::automation_control (PBD::ID const & id) const
+{
+       Controls::const_iterator li;
+
+       for (li = _controls.begin(); li != _controls.end(); ++li) {
+               boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (li->second);
+               if (ac && (ac->id() == id)) {
+                       return ac;
+               }
+       }
+
+       return boost::shared_ptr<AutomationControl>();
+}
+
 boost::shared_ptr<AutomationControl>
 Automatable::automation_control (const Evoral::Parameter& id, bool create)
 {
index 84c606cfd86812df2f066b56438db949fcc2bdd5..ffff120a239a7e9602833993c05ff211107374fe 100644 (file)
@@ -30,6 +30,7 @@
 #include "ardour/control_group.h"
 #include "ardour/event_type_map.h"
 #include "ardour/session.h"
+#include "ardour/selection.h"
 
 #include "pbd/i18n.h"
 
@@ -68,6 +69,7 @@ AutomationControl::AutomationControl(ARDOUR::Session&                          s
 
 AutomationControl::~AutomationControl ()
 {
+       _session.selection().remove_control_by_id (id());
        DropReferences (); /* EMIT SIGNAL */
 }
 
index 5c645a80959da749b6320f636f66b6570262b738..0f03475fe46d202ea22659f4e2c1b84a7e77bd8f 100644 (file)
@@ -68,6 +68,7 @@ PBD::DebugBits PBD::DEBUG::Ports = PBD::new_debug_bit ("Ports");
 PBD::DebugBits PBD::DEBUG::AudioEngine = PBD::new_debug_bit ("AudioEngine");
 PBD::DebugBits PBD::DEBUG::Soundcloud = PBD::new_debug_bit ("Soundcloud");
 PBD::DebugBits PBD::DEBUG::Butler = PBD::new_debug_bit ("Butler");
+PBD::DebugBits PBD::DEBUG::Selection = PBD::new_debug_bit ("selection");
 PBD::DebugBits PBD::DEBUG::GenericMidi = PBD::new_debug_bit ("genericmidi");
 
 PBD::DebugBits PBD::DEBUG::BackendMIDI = PBD::new_debug_bit ("backendmidi");
index 9e57f078d2fe7546bc95c9983caaf52dd5ed99f9..76d21021a120777ebf9dc1a317b7e03c0317e522 100644 (file)
@@ -722,7 +722,6 @@ setup_enum_writer ()
        REGISTER_CLASS_ENUM (PresentationInfo, MasterOut);
        REGISTER_CLASS_ENUM (PresentationInfo, MonitorOut);
        REGISTER_CLASS_ENUM (PresentationInfo, Auditioner);
-       REGISTER_CLASS_ENUM (PresentationInfo, Selected);
        REGISTER_CLASS_ENUM (PresentationInfo, Hidden);
        REGISTER_CLASS_ENUM (PresentationInfo, OrderSet);
        REGISTER_BITS (_PresentationInfo_Flag);
index d8464c8b837677b0fa82a48f4c72b2321c3ac6a4..bd7f8ada13b76fcfb8121e741288bbf47dabe59c 100644 (file)
@@ -1636,7 +1636,6 @@ LuaBindings::common (lua_State* L)
                .addConst ("MasterOut", ARDOUR::PresentationInfo::Flag(PresentationInfo::MasterOut))
                .addConst ("MonitorOut", ARDOUR::PresentationInfo::Flag(PresentationInfo::MonitorOut))
                .addConst ("Auditioner", ARDOUR::PresentationInfo::Flag(PresentationInfo::Auditioner))
-               .addConst ("Selected", ARDOUR::PresentationInfo::Flag(PresentationInfo::Selected))
                .addConst ("Hidden", ARDOUR::PresentationInfo::Flag(PresentationInfo::Hidden))
                .addConst ("GroupOrderSet", ARDOUR::PresentationInfo::Flag(PresentationInfo::OrderSet))
                .addConst ("StatusMask", ARDOUR::PresentationInfo::Flag(PresentationInfo::StatusMask))
index f269541de094867d5b566b11e1783f44f8651d33..d070f83220b14a1a74b5ff63e65ad045721f003d 100644 (file)
@@ -30,6 +30,7 @@
 #include "pbd/xml++.h"
 
 #include "ardour/presentation_info.h"
+#include "ardour/selection.h"
 
 #include "pbd/i18n.h"
 
@@ -47,7 +48,7 @@ PBD::Signal1<void,PropertyChange const &> PresentationInfo::Change;
 Glib::Threads::Mutex PresentationInfo::static_signal_lock;
 int PresentationInfo::_change_signal_suspended = 0;
 PBD::PropertyChange PresentationInfo::_pending_static_changes;
-int PresentationInfo::selection_counter = 0;
+int PresentationInfo::selection_counter= 0;
 
 namespace ARDOUR {
        namespace Properties {
@@ -240,22 +241,6 @@ PresentationInfo::color_set () const
        return _color != 0;
 }
 
-void
-PresentationInfo::set_selected (bool yn)
-{
-       if (yn != selected()) {
-               if (yn) {
-                       _flags = Flag (_flags | Selected);
-                       _selection_cnt = g_atomic_int_add (&selection_counter, 1);
-               } else {
-                       _flags = Flag (_flags & ~Selected);
-                       _selection_cnt = 0;
-               }
-               send_change (PropertyChange (Properties::selected));
-               send_static_change (PropertyChange (Properties::selected));
-       }
-}
-
 void
 PresentationInfo::set_hidden (bool yn)
 {
index ec54f83a9a28a7e26d96acac2ff5ca8d2035f1c1..82ce63551112dac839057b55d6e00cfb36ac2e86 100644 (file)
@@ -89,7 +89,6 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
        : Stripable (sess, name, PresentationInfo (flag))
        , GraphNode (sess._process_graph)
        , Muteable (sess, name)
-       , Automatable (sess)
        , _active (true)
        , _signal_latency (0)
        , _signal_latency_at_amp_position (0)
@@ -121,7 +120,7 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
 
 boost::weak_ptr<Route>
 Route::weakroute () {
-       return boost::weak_ptr<Route> (shared_from_this ());
+       return boost::weak_ptr<Route> (boost::dynamic_pointer_cast<Route> (shared_from_this ()));
 }
 
 int
@@ -970,7 +969,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
                flags &= mask;
 
                if (flags != None) {
-                       boost::optional<int> rv = PluginSetup (shared_from_this (), pi, flags);  /* EMIT SIGNAL */
+                       boost::optional<int> rv = PluginSetup (boost::dynamic_pointer_cast<Route>(shared_from_this ()), pi, flags);  /* EMIT SIGNAL */
                        int mode = rv.get_value_or (0);
                        switch (mode & 3) {
                                case 1:
@@ -3283,13 +3282,13 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool*
 bool
 Route::direct_feeds_according_to_graph (boost::shared_ptr<Route> other, bool* via_send_only)
 {
-       return _session._current_route_graph.has (shared_from_this (), other, via_send_only);
+       return _session._current_route_graph.has (boost::dynamic_pointer_cast<Route> (shared_from_this ()), other, via_send_only);
 }
 
 bool
 Route::feeds_according_to_graph (boost::shared_ptr<Route> other)
 {
-       return _session._current_route_graph.feeds (shared_from_this (), other);
+       return _session._current_route_graph.feeds (boost::dynamic_pointer_cast<Route> (shared_from_this ()), other);
 }
 
 /** Called from the (non-realtime) butler thread when the transport is stopped */
@@ -3338,7 +3337,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
                                        continue;
                                }
                                bool sends_only;
-                               bool does_feed = (*i)->direct_feeds_according_to_reality (shared_from_this(), &sends_only);
+                               bool does_feed = (*i)->direct_feeds_according_to_reality (boost::dynamic_pointer_cast<Route> (shared_from_this()), &sends_only);
                                if (does_feed && !sends_only) {
                                        if ((*i)->soloed()) {
                                                ++sbou;
@@ -3452,7 +3451,7 @@ Route::output_change_handler (IOChange change, void * /*src*/)
                                _solo_control->mod_solo_by_others_downstream (delta);
                                // Session::route_solo_changed() does not propagate indirect solo-changes
                                // propagate upstream to tracks
-                               boost::shared_ptr<Route> shared_this = shared_from_this();
+                               boost::shared_ptr<Route> shared_this = boost::dynamic_pointer_cast<Route> (shared_from_this());
                                for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
                                        if ((*i).get() == this || !can_solo()) {
                                                continue;
index 4ffb58566ed57038d5db5ab16fcea6b3be5fb6b2..3cf24ba581ca98083899c8eb007394be6b262983 100644 (file)
@@ -94,6 +94,7 @@
 #include "ardour/route_graph.h"
 #include "ardour/route_group.h"
 #include "ardour/send.h"
+#include "ardour/selection.h"
 #include "ardour/session.h"
 #include "ardour/session_directory.h"
 #include "ardour/session_playlists.h"
@@ -324,6 +325,7 @@ Session::Session (AudioEngine &eng,
        , _midi_ports (0)
        , _mmc (0)
        , _vca_manager (new VCAManager (*this))
+       , _selection (new CoreSelection (*this))
 {
        uint32_t sr = 0;
 
@@ -4388,6 +4390,22 @@ Session::route_by_id (PBD::ID id) const
        return boost::shared_ptr<Route> ((Route*) 0);
 }
 
+
+boost::shared_ptr<Stripable>
+Session::stripable_by_id (PBD::ID id) const
+{
+       StripableList sl;
+       get_stripables (sl);
+
+       for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
+               if ((*s)->id() == id) {
+                       return *s;
+               }
+       }
+
+       return boost::shared_ptr<Stripable>();
+}
+
 boost::shared_ptr<Processor>
 Session::processor_by_id (PBD::ID id) const
 {
@@ -4487,7 +4505,7 @@ Session::route_by_selected_count (uint32_t id) const
        RouteList::iterator i;
 
        for (i = r.begin(); i != r.end(); ++i) {
-               if ((*i)->presentation_info().selected()) {
+               if ((*i)->is_selected()) {
                        if (id == 0) {
                                return *i;
                        }
index b0fb9460110effc126220db4244fcc1a2210689f..081db24d2a0b881aa9ee7697a1369c37c40e02e4 100644 (file)
@@ -736,7 +736,7 @@ Session::midi_track_presentation_info_changed (PropertyChange const& what_change
 
        boost::shared_ptr<MidiTrack> new_midi_target (mt.lock ());
 
-       if (new_midi_target->presentation_info().selected()) {
+       if (new_midi_target->is_selected()) {
                rewire_selected_midi (new_midi_target);
        }
 }
index 581d6950c5d13c1a90884efb02a471a6c6543c84..b7fac84ffe43bbb45679e0c8203e63ee97903573 100644 (file)
 #include "ardour/revision.h"
 #include "ardour/route_group.h"
 #include "ardour/send.h"
+#include "ardour/selection.h"
 #include "ardour/session.h"
 #include "ardour/session_directory.h"
 #include "ardour/session_metadata.h"
@@ -1286,6 +1287,8 @@ Session::state (bool full_state)
 
        if (full_state) {
 
+               node->add_child_nocopy (_selection->get_state());
+
                if (_locations) {
                        node->add_child_nocopy (_locations->get_state());
                }
@@ -1649,6 +1652,10 @@ Session::set_state (const XMLNode& node, int version)
                }
        }
 
+       if ((child = find_named_node (node, X_("Selection")))) {
+               _selection->set_state (*child, version);
+       }
+
        update_route_record_state ();
 
        /* here beginneth the second phase ... */
@@ -3583,6 +3590,12 @@ Session::controllable_by_id (const PBD::ID& id)
        return boost::shared_ptr<Controllable>();
 }
 
+boost::shared_ptr<AutomationControl>
+Session::automation_control_by_id (const PBD::ID& id)
+{
+       return boost::dynamic_pointer_cast<AutomationControl> (controllable_by_id (id));
+}
+
 boost::shared_ptr<Controllable>
 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
 {
index c2f5b7239ad30c15712d64af434da6d43a2be670..c4f128b4e82096b865eb9d32a45da4f66aa66128 100644 (file)
 
 #include "pbd/compose.h"
 #include "pbd/convert.h"
+#include "pbd/i18n.h"
+
 
 #include "ardour/debug.h"
 #include "ardour/rc_configuration.h"
+#include "ardour/session.h"
+#include "ardour/selection.h"
 #include "ardour/stripable.h"
 
-#include "pbd/i18n.h"
-
 using namespace ARDOUR;
 using namespace PBD;
 using std::string;
 
 Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi)
        : SessionObject (s, name)
+       , Automatable (s)
        , _presentation_info (pi)
        , _active_color_picker (0)
 {
 }
 
+Stripable::~Stripable ()
+{
+       _session.selection().remove_stripable_by_id (id());
+}
+
 void
 Stripable::set_presentation_order (PresentationInfo::order_t order)
 {
@@ -103,3 +111,15 @@ Stripable::set_state (XMLNode const& node, int version)
 
        return 0;
 }
+
+bool
+Stripable::is_selected() const
+{
+       try {
+               boost::shared_ptr<const Stripable> s (shared_from_this());
+       } catch (...) {
+               std::cerr << "cannot shared-from-this for " << this << std::endl;
+               abort ();
+       }
+       return _session.selection().selected (shared_from_this());
+}
index 1d17d9238c12ce5713dab8341ee186d0086748a4..d7d9a0a9d14686b04ba78f8aba3521367b4d36e1 100644 (file)
@@ -65,7 +65,7 @@ Track::init ()
                 return -1;
         }
 
-       boost::shared_ptr<Route> rp (shared_from_this());
+        boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
        boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
 
        _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
index d056c855edd607a604f001f4d2557928cece4601..3eff1a6b4554512f1274a5ef99ada88dffda9927 100644 (file)
@@ -70,7 +70,6 @@ VCA::get_next_vca_number ()
 VCA::VCA (Session& s, int32_t num, const string& name)
        : Stripable (s, name, PresentationInfo (num, PresentationInfo::VCA))
        , Muteable (s, name)
-       , Automatable (s)
        , _number (num)
        , _gain_control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
 {
index 10984774260d2cd1be558b1845c444a309a58152..7148a26042e5a557dac007a0841daac659099eed 100644 (file)
@@ -194,6 +194,7 @@ libardour_sources = [
         'rb_effect.cc',
         'scene_change.cc',
         'search_paths.cc',
+        'selection.cc',
         'send.cc',
         'session.cc',
         'session_butler.cc',
index 62d0abab094069e678d793f1480e048dc16434c3..a359982799b183b044e0359e6f27d913e2a9c50f 100644 (file)
@@ -335,7 +335,7 @@ MackieControlProtocol::get_sorted_stripables()
                        }
                        break;
                case Selected: // For example: a group (this is USER)
-                       if (s->presentation_info().selected() && !s->presentation_info().hidden()) {
+                       if (s->is_selected() && !s->presentation_info().hidden()) {
                                sorted.push_back (s);
                        }
                        break;
@@ -2038,7 +2038,7 @@ MackieControlProtocol::select_range (uint32_t pressed)
                return;
        }
 
-       if (stripables.size() == 1 && ControlProtocol::last_selected().size() == 1 && stripables.front()->presentation_info().selected()) {
+       if (stripables.size() == 1 && ControlProtocol::last_selected().size() == 1 && stripables.front()->is_selected()) {
                /* cancel selection for one and only selected stripable */
                ToggleStripableSelection (stripables.front());
        } else {
index e396af575cd299f0fa6485603d81ef2c0a9c7c01..9a570f8227dd31c3eacf5921260a07d85f076aa6 100644 (file)
@@ -380,8 +380,8 @@ Strip::notify_property_changed (const PropertyChange& what_changed)
 
        if (what_changed.contains (ARDOUR::Properties::selected)) {
                if (_stripable) {
-                       _surface->write (_select->set_state (_stripable->presentation_info().selected()));
-                       _surface->mcp().update_selected (_stripable, _stripable->presentation_info().selected());
+                       _surface->write (_select->set_state (_stripable->is_selected()));
+                       _surface->mcp().update_selected (_stripable, _stripable->is_selected());
                }
        }
 }
index 5fe8e25f413bbf6a811a5b3862bf90ee09cab424..fae9db11e1a7d1160f949067e5201bf4a1d1924c 100644 (file)
@@ -3998,17 +3998,13 @@ OSC::get_sorted_stripables(std::bitset<32> types, bool cue)
                                                sorted.push_back (s);
                                        }
                                }
-                       } else
-                       if (types[3] && (s->presentation_info().flags() & PresentationInfo::MidiBus)) {
+                       } else if (types[3] && (s->presentation_info().flags() & PresentationInfo::MidiBus)) {
                                sorted.push_back (s);
-                       } else
-                       if (types[4] && (s->presentation_info().flags() & PresentationInfo::VCA)) {
+                       } else if (types[4] && (s->presentation_info().flags() & PresentationInfo::VCA)) {
                                sorted.push_back (s);
-                       } else
-                       if (types[8] && (s->presentation_info().flags() & PresentationInfo::Selected)) {
+                       } else if (types[8] && (s->is_selected())) {
                                sorted.push_back (s);
-                       } else
-                       if (types[9] && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
+                       } else if (types[9] && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
                                sorted.push_back (s);
                        }
                }
index 75b17f8c20b823b52665e0caad396d8167388cb3..4582cd0d301ff6306dd6f1894bff265c521af861 100644 (file)
@@ -448,7 +448,7 @@ MixLayout::stripable_property_change (PropertyChange const& what_changed, uint32
        if (what_changed.contains (Properties::color)) {
                lower_backgrounds[which]->set_fill_color (stripable[which]->presentation_info().color());
 
-               if (stripable[which]->presentation_info().selected()) {
+               if (stripable[which]->is_selected()) {
                        lower_text[which]->set_fill_color (contrasting_text_color (stripable[which]->presentation_info().color()));
                        /* might not be a MIDI track, in which case this will
                           do nothing
@@ -467,7 +467,7 @@ MixLayout::stripable_property_change (PropertyChange const& what_changed, uint32
                        return;
                }
 
-               if (stripable[which]->presentation_info().selected()) {
+               if (stripable[which]->is_selected()) {
                        show_selection (which);
                } else {
                        hide_selection (which);
@@ -581,7 +581,7 @@ MixLayout::switch_bank (uint32_t base)
                        stripable[n]->solo_control()->Changed.connect (stripable_connections, invalidator (*this), boost::bind (&MixLayout::solo_changed, this, n), &p2);
                        stripable[n]->mute_control()->Changed.connect (stripable_connections, invalidator (*this), boost::bind (&MixLayout::mute_changed, this, n), &p2);
 
-                       if (stripable[n]->presentation_info().selected()) {
+                       if (stripable[n]->is_selected()) {
                                show_selection (n);
                        } else {
                                hide_selection (n);
@@ -671,7 +671,7 @@ MixLayout::button_select_release ()
 
        for (int n = 0; n < 8; ++n) {
                if (stripable[n]) {
-                       if (stripable[n]->presentation_info().selected()) {
+                       if (stripable[n]->is_selected()) {
                                        selected = n;
                                        break;
                        }