2 Copyright (C) 2016 Paul Davis
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.
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.
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.
20 #ifndef __libardour_presentation_info_h__
21 #define __libardour_presentation_info_h__
28 #include "pbd/signals.h"
29 #include "pbd/stateful.h"
30 #include "pbd/properties.h"
32 #include "ardour/libardour_visibility.h"
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;
46 class LIBARDOUR_API PresentationInfo : public PBD::Stateful
50 /* a PresentationInfo object exists to share information between
51 * different user interfaces (e.g. GUI and a Mackie Control surface)
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).
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.
73 * There are several pathways for the order being set:
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
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
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").
97 * When an object is hidden, its _flags member will have the Hidden
104 /* Type information */
116 /* These are for sharing Stripable states between the GUI and other
117 * user interfaces/control surfaces
121 MixbusEditorHidden = 0x800,
123 /* single bit indicates that the group order is set */
126 /* bus type for monitor mixes */
127 FoldbackBus = 0x2000,
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)
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 */
143 typedef uint32_t order_t;
144 typedef uint32_t color_t;
146 PresentationInfo (Flag f);
147 PresentationInfo (order_t o, Flag f);
148 PresentationInfo (PresentationInfo const &);
150 static const order_t max_order;
152 PresentationInfo::Flag flags() const { return _flags; }
153 order_t order() const { return _order; }
154 color_t color() const { return _color; }
156 bool color_set() const;
158 void set_color (color_t);
159 void set_hidden (bool yn);
160 void set_flags (Flag f) { _flags = f; }
162 bool order_set() const { return _flags & OrderSet; }
164 int selection_cnt() const { return _selection_cnt; }
166 bool hidden() const { return _flags & Hidden; }
167 bool special(bool with_master = true) const { return _flags & ((with_master ? MasterOut : 0)|MonitorOut|Auditioner); }
169 bool flag_match (Flag f) const {
170 /* no flags, match all */
176 if (f & StatusMask) {
177 /* status bits set, must match them */
178 if ((_flags & StatusMask) != (f & StatusMask)) {
183 /* Generic flags in f, match the right stuff */
185 if (f == Bus && (_flags & Bus)) {
186 /* some kind of bus */
189 if (f == Track && (_flags & Track)) {
190 /* some kind of track */
193 if (f == Route && (_flags & Route)) {
194 /* any kind of route, but not master, monitor in
200 if (f == AllRoutes && (_flags & AllRoutes)) {
201 /* any kind of route, but not auditioner. Ask for that
207 if (f == AllStripables && (_flags & AllStripables)) {
208 /* any kind of stripable, but not auditioner. Ask for that
214 /* check for any matching type bits.
216 * Do comparisoon without status mask or order set bits - we
217 * already checked that above.
220 return ((f & TypeMask) & _flags);
223 int set_state (XMLNode const&, int);
224 XMLNode& get_state ();
226 bool operator==(PresentationInfo const& other) {
227 return (_order == other.order()) && (_flags == other.flags());
230 bool operator!=(PresentationInfo const& other) {
231 return (_order != other.order()) || (_flags != other.flags());
234 PresentationInfo& operator= (PresentationInfo const& other);
236 static Flag get_flags (XMLNode const& node);
237 static std::string state_node_name;
239 /* for things concerned about *any* PresentationInfo.
242 static PBD::Signal1<void,PBD::PropertyChange const &> Change;
243 static void send_static_change (const PBD::PropertyChange&);
245 static void make_property_quarks ();
248 friend class ChangeSuspender;
249 static void suspend_change_signal ();
250 static void unsuspend_change_signal ();
253 class ChangeSuspender {
256 PresentationInfo::suspend_change_signal ();
259 PresentationInfo::unsuspend_change_signal ();
264 friend class Stripable;
265 void set_order (order_t order);
273 static PBD::PropertyChange _pending_static_changes;
274 static Glib::Threads::Mutex static_signal_lock;
275 static int _change_signal_suspended;
277 static int selection_counter;
282 std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
284 #endif /* __libardour_presentation_info_h__ */