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