Make foldback bus match foldback sends namewise
[ardour.git] / libs / ardour / ardour / presentation_info.h
index 465371005b5041700193e30880ad121db23c4d21..de728138cc87ed19c0ed161eece95f5b5ec77b0e 100644 (file)
 
 #include <stdint.h>
 
+#include "pbd/signals.h"
+#include "pbd/stateful.h"
+#include "pbd/properties.h"
+
 #include "ardour/libardour_visibility.h"
 
 class XMLNode;
 
 namespace ARDOUR {
 
-class LIBARDOUR_API PresentationInfo
+namespace Properties {
+       LIBARDOUR_API extern PBD::PropertyDescriptor<uint32_t> order;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<uint32_t> color;
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> selected;
+       /* we use this; declared in region.cc */
+       LIBARDOUR_API extern PBD::PropertyDescriptor<bool> hidden;
+}
+
+class LIBARDOUR_API PresentationInfo : public PBD::Stateful
 {
   public:
 
@@ -58,27 +70,6 @@ class LIBARDOUR_API PresentationInfo
         * makes it show only busses, or only MIDI tracks. At that point, the
         * ordering on the surface differs from the ordering in the GUI.
         *
-        * The ordering is given via a combination of an object type and a
-        * simple numeric position within that type. The object types at this
-        * time are:
-        *
-        *     Route
-        *        - object has inputs and outputs; processes data
-        *     Output
-        *        - Route used to connect to outside the application (MasterOut, MonitorOut)
-        *     Special
-        *        - special type of Route (e.g. Auditioner)
-        *     VCA
-        *        - no data flows through; control only
-        *
-        * Objects with a numeric order of zero are considered unsorted. This
-        * applies (for now) to special objects such as the master out,
-        * auditioner and monitor out.  The rationale here is that the GUI
-        * presents these objects in special ways, rather than as part of some
-        * (potentially) re-orderable container. The same is true for hardware
-        * surfaces, where the master fader (for instance) is typically
-        * separate and distinct from anything else.
-        *
         * There are several pathways for the order being set:
         *
         *   - object created during session loading from XML
@@ -102,11 +93,6 @@ class LIBARDOUR_API PresentationInfo
         * 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
@@ -115,7 +101,6 @@ class LIBARDOUR_API PresentationInfo
         *
         */
 
-
        enum Flag {
                /* Type information */
                AudioTrack = 0x1,
@@ -123,104 +108,57 @@ class LIBARDOUR_API PresentationInfo
                AudioBus = 0x4,
                MidiBus = 0x8,
                VCA = 0x10,
-
-               /* These need to be at the high end */
-               MasterOut = 0x800,
-               MonitorOut = 0x1000,
-               Auditioner = 0x2000,
-
+               MasterOut = 0x20,
+               MonitorOut = 0x40,
+               Auditioner = 0x80,
                /* These are for sharing Stripable states between the GUI and other
                 * user interfaces/control surfaces
                 */
-               Selected = 0x4000,
-               Hidden = 0x8000,
-
+               Hidden = 0x100,
                /* single bit indicates that the group order is set */
-               GroupOrderSet = 0x100000000,
-
-               /* Masks */
-
-               GroupMask = (AudioTrack|MidiTrack|AudioBus|MidiBus|VCA),
-               SpecialMask = (MasterOut|MonitorOut|Auditioner),
-               StatusMask = (Selected|Hidden),
+               OrderSet = 0x400,
+               /* bus type for monitor mixes */
+               FoldbackBus = 0x2000,
+
+               /* special mask to delect out "state" bits */
+               StatusMask = (Hidden),
+               /* special mask to delect select type bits */
+               TypeMask = (AudioBus|AudioTrack|MidiTrack|MidiBus|VCA|MasterOut|MonitorOut|Auditioner|FoldbackBus)
        };
 
-       static const Flag Route;
-       static const Flag Track;
-       static const Flag Bus;
+       static const Flag AllStripables; /* mask to use for any route or VCA (but not auditioner) */
+       static const Flag MixerStripables; /* mask to use for any route or VCA (but not auditioner or foldbackbus) */
+       static const Flag AllRoutes; /* mask to use for any route include master+monitor, but not auditioner */
+       static const Flag MixerRoutes; /* mask to use for any route include master+monitor, but not auditioner or foldbackbus*/
+       static const Flag Route;     /* mask for any route (bus or track */
+       static const Flag Track;     /* mask to use for any track */
+       static const Flag Bus;       /* mask to use for any bus */
 
        typedef uint32_t order_t;
-       typedef uint64_t global_order_t;
+       typedef uint32_t color_t;
 
-       PresentationInfo (Flag f) : _order (0), _flags (Flag (f & ~GroupOrderSet)) { /* GroupOrderSet is not set */ }
-       PresentationInfo (order_t o, Flag f) : _order (o), _flags (Flag (f | GroupOrderSet)) { /* GroupOrderSet is set */ }
+       PresentationInfo (Flag f);
+       PresentationInfo (order_t o, Flag f);
+       PresentationInfo (PresentationInfo const &);
 
        static const order_t max_order;
 
-       order_t  group_order() const { return _order; }
-       global_order_t global_order () const {
-               if (_flags & Route) {
-
-                       /* set all bits related to Route so that all Routes
-                          sort together, with order() in the range of
-                          64424509440..68719476735
-
-                          Consider the following arrangement:
-
-                          Track   1
-                          Bus     1
-                          Track   2
-                          ---------
-                          VCA     1
-                          ---------
-                          Master
-                          ---------
-                          Monitor
-
-                          these translate into the following
-
-                          _order  |  _flags            | global_order()
-                          --------------------------------------
-                          1       |   0x1   AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|1 = 64424509441
-                          2       |   0x2   AudioBus   | ((0x1|0x2|0x4|0x8)<<32)|2 = 64424509442
-                          3       |   0x1   AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|3 = 64424509443
-
-                          1       |   0x10  VCA        | ((0x10)<<32)|1 = 68719476737
-
-                          0       |   0x800 Master     | (0x800<<32) = 8796093022208
-
-                          0       |   0x1000 Monitor   | (0x1000<<32) = 17592186044416
-
-                       */
-
-                       return (((global_order_t) (_flags | Route)) << (8*sizeof(order_t))) | _order;
-               } else {
-                       return (((global_order_t) _flags) << (8*sizeof(order_t))) | _order;
-               }
-       }
-
        PresentationInfo::Flag flags() const { return _flags; }
+       order_t  order() const { return _order; }
+       color_t  color() const { return _color; }
 
-       bool order_set() const { return _order != 0; }
+       bool color_set() const;
 
-       /* these objects have no defined order */
-       bool special () const { return _flags & SpecialMask; }
+       void set_color (color_t);
+       void set_hidden (bool yn);
+       void set_flags (Flag f) { _flags = f; }
 
-       /* detect group order set/not set */
-       bool unordered() const { return !(_flags & GroupOrderSet); }
-       bool ordered() const { return _flags & GroupOrderSet; }
+       bool order_set() const { return _flags & OrderSet; }
 
-       void set_flag (PresentationInfo::Flag f) {
-               _flags = PresentationInfo::Flag (_flags | f);
-       }
-
-       void unset_flag (PresentationInfo::Flag f) {
-               _flags = PresentationInfo::Flag (_flags & ~f);
-       }
+       int selection_cnt() const { return _selection_cnt; }
 
-       void set_flags (Flag f) {
-               _flags = f;
-       }
+       bool hidden() const { return _flags & Hidden; }
+       bool special(bool with_master = true) const { return _flags & ((with_master ? MasterOut : 0)|MonitorOut|Auditioner); }
 
        bool flag_match (Flag f) const {
                /* no flags, match all */
@@ -247,53 +185,90 @@ class LIBARDOUR_API PresentationInfo
                        return true;
                }
                if (f == Route && (_flags & Route)) {
-                       /* any kind of route */
+                       /* any kind of route, but not master, monitor in
+                          or auditioner.
+                        */
                        return true;
                }
 
-               return f == _flags;
-       }
+               if (f == AllRoutes && (_flags & AllRoutes)) {
+                       /* any kind of route, but not auditioner. Ask for that
+                          specifically.
+                       */
+                       return true;
+               }
 
-       std::string to_string () const;
+               if (f == AllStripables && (_flags & AllStripables)) {
+                       /* any kind of stripable, but not auditioner. Ask for that
+                          specifically.
+                       */
+                       return true;
+               }
 
-       uint64_t to_integer () const {
-               return ((uint64_t) _flags << (8*sizeof(order_t))) | _order;
-       }
+               /* check for any matching type bits.
+                *
+                * Do comparisoon without status mask or order set bits - we
+                * already checked that above.
+                */
 
-       bool operator< (PresentationInfo const& other) const {
-               return global_order() < other.global_order();
+               return ((f & TypeMask) & _flags);
        }
 
-       PresentationInfo& operator= (std::string const& str) {
-               parse (str);
-               return *this;
-       }
-
-       bool match (PresentationInfo const& other) const {
-               return (_order == other.group_order()) && flag_match (other.flags());
-       }
+       int set_state (XMLNode const&, int);
+       XMLNode& get_state ();
 
        bool operator==(PresentationInfo const& other) {
-               return (_order == other.group_order()) && (_flags == other.flags());
+               return (_order == other.order()) && (_flags == other.flags());
        }
 
        bool operator!=(PresentationInfo const& other) {
-               return (_order != other.group_order()) || (_flags != other.flags());
+               return (_order != other.order()) || (_flags != other.flags());
        }
 
+       PresentationInfo& operator= (PresentationInfo const& other);
+
        static Flag get_flags (XMLNode const& node);
+       static std::string state_node_name;
+
+       /* for things concerned about *any* PresentationInfo.
+        */
+
+       static PBD::Signal1<void,PBD::PropertyChange const &> Change;
+       static void send_static_change (const PBD::PropertyChange&);
+
+       static void make_property_quarks ();
+
+  protected:
+       friend class ChangeSuspender;
+       static void suspend_change_signal ();
+       static void unsuspend_change_signal ();
+
+  public:
+       class ChangeSuspender {
+          public:
+               ChangeSuspender() {
+                       PresentationInfo::suspend_change_signal ();
+               }
+               ~ChangeSuspender() {
+                       PresentationInfo::unsuspend_change_signal ();
+               }
+       };
 
   protected:
        friend class Stripable;
-       void set_group_order (order_t order) { _order = order; _flags = Flag (_flags|GroupOrderSet); }
+       void set_order (order_t order);
 
   private:
        order_t _order;
        Flag    _flags;
+       color_t _color;
+       int     _selection_cnt;
+
+       static PBD::PropertyChange _pending_static_changes;
+       static Glib::Threads::Mutex static_signal_lock;
+       static int _change_signal_suspended;
 
-       PresentationInfo (std::string const & str);
-       int parse (std::string const&);
-       int parse (order_t, Flag f);
+       static int selection_counter;
 };
 
 }