NO-OP: <tab> after <space> fixes in libs
[ardour.git] / libs / ardour / ardour / presentation_info.h
1 /*
2     Copyright (C) 2016 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __libardour_presentation_info_h__
21 #define __libardour_presentation_info_h__
22
23 #include <iostream>
24 #include <string>
25
26 #include <stdint.h>
27
28 #include "pbd/signals.h"
29 #include "pbd/stateful.h"
30 #include "pbd/properties.h"
31
32 #include "ardour/libardour_visibility.h"
33
34 class XMLNode;
35
36 namespace ARDOUR {
37
38 namespace Properties {
39         LIBARDOUR_API extern PBD::PropertyDescriptor<uint32_t> order;
40         LIBARDOUR_API extern PBD::PropertyDescriptor<uint32_t> color;
41         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> selected;
42         /* we use this; declared in region.cc */
43         LIBARDOUR_API extern PBD::PropertyDescriptor<bool> hidden;
44 }
45
46 class LIBARDOUR_API PresentationInfo : public PBD::Stateful
47 {
48   public:
49
50         /* a PresentationInfo object exists to share information between
51          * different user interfaces (e.g. GUI and a Mackie Control surface)
52          * about:
53          *
54          *     - ordering
55          *     - selection status
56          *     - visibility
57          *     - object identity
58          *
59          * ORDERING
60          *
61          * One UI takes control of ordering by setting the "order" value for
62          * the PresentationInfo component of every Stripable object. In Ardour,
63          * this is done by the GUI (mostly because it is very hard for the user
64          * to re-order things on a control surface).
65          *
66          * Ordering is a complex beast, however. Different user interfaces may
67          * display things in different ways. For example, the GUI of Ardour
68          * allows the user to mix busses in between tracks. A control surface
69          * may do the same, but may also allow the user to press a button that
70          * makes it show only busses, or only MIDI tracks. At that point, the
71          * ordering on the surface differs from the ordering in the GUI.
72          *
73          * There are several pathways for the order being set:
74          *
75          *   - object created during session loading from XML
76          *   - numeric order will be set during ::set_state(), based on
77          *   - type will be set during ctor call
78          *
79          *   - object created in response to user request
80          *   - numeric order will be set by Session, before adding to container.
81          *   - type set during ctor call
82          *
83          *
84          * OBJECT IDENTITY
85          *
86          * Control surfaces/protocols often need to be able to get a handle on
87          * an object identified only abstractly, such as the "5th audio track"
88          * or "the master out". A PresentationInfo object uniquely identifies
89          * all objects in this way through the combination of its _order member
90          * and part of its _flags member. The _flags member identifies the type
91          * of object, as well as selection/hidden status. The type may never
92          * change after construction (not strictly the constructor itself, but
93          * a more generalized notion of construction, as in "ready to use").
94          *
95          * VISIBILITY
96          *
97          * When an object is hidden, its _flags member will have the Hidden
98          * bit set.
99          *
100          *
101          */
102
103         enum Flag {
104                 /* Type information */
105                 AudioTrack = 0x1,
106                 MidiTrack = 0x2,
107                 AudioBus = 0x4,
108                 MidiBus = 0x8,
109                 VCA = 0x10,
110                 MasterOut = 0x20,
111                 MonitorOut = 0x40,
112                 Auditioner = 0x80,
113 #ifdef MIXBUS
114                 Mixbus = 0x1000,
115 #endif
116                 /* These are for sharing Stripable states between the GUI and other
117                  * user interfaces/control surfaces
118                  */
119                 Hidden = 0x100,
120 #ifdef MIXBUS
121                 MixbusEditorHidden = 0x800,
122 #endif
123                 /* single bit indicates that the group order is set */
124                 OrderSet = 0x400,
125
126                 /* bus type for monitor mixes */
127                 FoldbackBus = 0x2000,
128
129                 /* special mask to delect out "state" bits */
130                 StatusMask = (Hidden),
131                 /* special mask to delect select type bits */
132                 TypeMask = (AudioBus|AudioTrack|MidiTrack|MidiBus|VCA|MasterOut|MonitorOut|Auditioner|FoldbackBus)
133         };
134
135         static const Flag AllStripables; /* mask to use for any route or VCA (but not auditioner) */
136         static const Flag MixerStripables; /* mask to use for any route or VCA (but not auditioner or foldbackbus) */
137         static const Flag AllRoutes; /* mask to use for any route include master+monitor, but not auditioner */
138         static const Flag MixerRoutes; /* mask to use for any route include master+monitor, but not auditioner or foldbackbus*/
139         static const Flag Route;     /* mask for any route (bus or track */
140         static const Flag Track;     /* mask to use for any track */
141         static const Flag Bus;       /* mask to use for any bus */
142
143         typedef uint32_t order_t;
144         typedef uint32_t color_t;
145
146         PresentationInfo (Flag f);
147         PresentationInfo (order_t o, Flag f);
148         PresentationInfo (PresentationInfo const &);
149
150         static const order_t max_order;
151
152         PresentationInfo::Flag flags() const { return _flags; }
153         order_t  order() const { return _order; }
154         color_t  color() const { return _color; }
155
156         bool color_set() const;
157
158         void set_color (color_t);
159         void set_hidden (bool yn);
160         void set_flags (Flag f) { _flags = f; }
161
162         bool order_set() const { return _flags & OrderSet; }
163
164         int selection_cnt() const { return _selection_cnt; }
165
166         bool hidden() const { return _flags & Hidden; }
167         bool special(bool with_master = true) const { return _flags & ((with_master ? MasterOut : 0)|MonitorOut|Auditioner); }
168
169         bool flag_match (Flag f) const {
170                 /* no flags, match all */
171
172                 if (f == Flag (0)) {
173                         return true;
174                 }
175
176                 if (f & StatusMask) {
177                         /* status bits set, must match them */
178                         if ((_flags & StatusMask) != (f & StatusMask)) {
179                                 return false;
180                         }
181                 }
182
183                 /* Generic flags in f, match the right stuff */
184
185                 if (f == Bus && (_flags & Bus)) {
186                         /* some kind of bus */
187                         return true;
188                 }
189                 if (f == Track && (_flags & Track)) {
190                         /* some kind of track */
191                         return true;
192                 }
193                 if (f == Route && (_flags & Route)) {
194                         /* any kind of route, but not master, monitor in
195                            or auditioner.
196                          */
197                         return true;
198                 }
199
200                 if (f == AllRoutes && (_flags & AllRoutes)) {
201                         /* any kind of route, but not auditioner. Ask for that
202                            specifically.
203                         */
204                         return true;
205                 }
206
207                 if (f == AllStripables && (_flags & AllStripables)) {
208                         /* any kind of stripable, but not auditioner. Ask for that
209                            specifically.
210                         */
211                         return true;
212                 }
213
214                 /* check for any matching type bits.
215                  *
216                  * Do comparisoon without status mask or order set bits - we
217                  * already checked that above.
218                  */
219
220                 return ((f & TypeMask) & _flags);
221         }
222
223         int set_state (XMLNode const&, int);
224         XMLNode& get_state ();
225
226         bool operator==(PresentationInfo const& other) {
227                 return (_order == other.order()) && (_flags == other.flags());
228         }
229
230         bool operator!=(PresentationInfo const& other) {
231                 return (_order != other.order()) || (_flags != other.flags());
232         }
233
234         PresentationInfo& operator= (PresentationInfo const& other);
235
236         static Flag get_flags (XMLNode const& node);
237         static std::string state_node_name;
238
239         /* for things concerned about *any* PresentationInfo.
240          */
241
242         static PBD::Signal1<void,PBD::PropertyChange const &> Change;
243         static void send_static_change (const PBD::PropertyChange&);
244
245         static void make_property_quarks ();
246
247   protected:
248         friend class ChangeSuspender;
249         static void suspend_change_signal ();
250         static void unsuspend_change_signal ();
251
252   public:
253         class ChangeSuspender {
254           public:
255                 ChangeSuspender() {
256                         PresentationInfo::suspend_change_signal ();
257                 }
258                 ~ChangeSuspender() {
259                         PresentationInfo::unsuspend_change_signal ();
260                 }
261         };
262
263   protected:
264         friend class Stripable;
265         void set_order (order_t order);
266
267   private:
268         order_t _order;
269         Flag    _flags;
270         color_t _color;
271         int     _selection_cnt;
272
273         static PBD::PropertyChange _pending_static_changes;
274         static Glib::Threads::Mutex static_signal_lock;
275         static int _change_signal_suspended;
276
277         static int selection_counter;
278 };
279
280 }
281
282 std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
283
284 #endif /* __libardour_presentation_info_h__ */