Ardour  9.0-pre0-1699-gfaebc7ab35
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 #pragma once
22 
23 #include <iostream>
24 #include <string>
25 
26 #include <atomic>
27 #include <cstdint>
28 
29 #include "pbd/signals.h"
30 #include "pbd/stateful.h"
31 #include "pbd/properties.h"
32 
34 
35 class XMLNode;
36 
37 namespace ARDOUR {
38 
39 namespace Properties {
44  /* we use this; declared in region.cc */
46 }
47 
49 {
50  public:
51 
52  /* a PresentationInfo object exists to share information between
53  * different user interfaces (e.g. GUI and a Mackie Control surface)
54  * about:
55  *
56  * - ordering
57  * - selection status
58  * - visibility
59  * - object identity
60  *
61  * ORDERING
62  *
63  * One UI takes control of ordering by setting the "order" value for
64  * the PresentationInfo component of every Stripable object. In Ardour,
65  * this is done by the GUI (mostly because it is very hard for the user
66  * to re-order things on a control surface).
67  *
68  * Ordering is a complex beast, however. Different user interfaces may
69  * display things in different ways. For example, the GUI of Ardour
70  * allows the user to mix busses in between tracks. A control surface
71  * may do the same, but may also allow the user to press a button that
72  * makes it show only busses, or only MIDI tracks. At that point, the
73  * ordering on the surface differs from the ordering in the GUI.
74  *
75  * There are several pathways for the order being set:
76  *
77  * - object created during session loading from XML
78  * - numeric order will be set during ::set_state(), based on
79  * - type will be set during ctor call
80  *
81  * - object created in response to user request
82  * - numeric order will be set by Session, before adding to container.
83  * - type set during ctor call
84  *
85  *
86  * OBJECT IDENTITY
87  *
88  * Control surfaces/protocols often need to be able to get a handle on
89  * an object identified only abstractly, such as the "5th audio track"
90  * or "the master out". A PresentationInfo object uniquely identifies
91  * all objects in this way through the combination of its _order member
92  * and part of its _flags member. The _flags member identifies the type
93  * of object, as well as selection/hidden status. The type may never
94  * change after construction (not strictly the constructor itself, but
95  * a more generalized notion of construction, as in "ready to use").
96  *
97  * VISIBILITY
98  *
99  * When an object is hidden, its _flags member will have the Hidden
100  * bit set.
101  *
102  *
103  */
104 
105  enum Flag {
106  /* Type information */
107  AudioTrack = 0x1,
108  MidiTrack = 0x2,
109  AudioBus = 0x4,
110  MidiBus = 0x8,
111  VCA = 0x10,
112  MasterOut = 0x20,
113  MonitorOut = 0x40,
114  Auditioner = 0x80,
115  /* These are for sharing Stripable states between the GUI and other
116  * user interfaces/control surfaces
117  */
118  Hidden = 0x100,
119  /* single bit indicates that the group order is set */
120  OrderSet = 0x400,
121 
122  /* Mixbus specific */
123  MixbusEditorHidden = 0x800,
124  Mixbus = 0x1000,
125 
126  /* bus type for monitor mixes */
127  FoldbackBus = 0x2000,
128 
129  /* has TriggerBox, show on TriggerUI page */
130  TriggerTrack = 0x4000,
131 
132 #ifndef VBM
133  /* bus is the surround master */
134  SurroundMaster = 0x8000,
135 #else
136  SurroundMaster = 0, // for compatibility
137 #endif
138 
139  /* VBM */
140  V2Program = 0x4000, // deprecated (conflicts with TriggerTrack)
141  V2MixMinus = 0x8000, // deprecated (conflicts with SurroundMaster)
142  VBMProgram = 0x10000,
143  VBMMixMinus = 0x20000,
144 #ifdef VBM
145  VBMAny = 0x3c000,
146 #else
147  VBMAny = 0x30000,
148 #endif
149 
150  /* special mask to detect out "state" bits */
151  StatusMask = (Hidden | MixbusEditorHidden | TriggerTrack),
152 
153  /* dedicated [output] busses */
154  MainBus = (MasterOut|MonitorOut|FoldbackBus|SurroundMaster),
155 
156  /* These can exist only once and require special attention to be removed */
157  Singleton = (MasterOut|MonitorOut|SurroundMaster),
158 
159  /* special mask to detect select type bits */
160  TypeMask = (AudioBus|AudioTrack|MidiTrack|MidiBus|Mixbus|VCA|MasterOut|MonitorOut|Auditioner|FoldbackBus|SurroundMaster|VBMAny)
161  };
162 
163  static const Flag AllStripables; /* mask to use for any route or VCA (but not auditioner) */
164  static const Flag MixerStripables; /* mask to use for any route or VCA (but not auditioner or foldbackbus) */
165  static const Flag AllRoutes; /* mask to use for any route include master+monitor, but not auditioner */
166  static const Flag MixerRoutes; /* mask to use for any route include master+monitor, but not auditioner or foldbackbus*/
167  static const Flag Route; /* mask for any route (bus or track */
168  static const Flag Track; /* mask to use for any track */
169  static const Flag Bus; /* mask to use for any bus */
170  static const Flag MidiIndicatingFlags; /* MidiTrack or MidiBus */
171 
172  typedef uint32_t order_t;
173  typedef uint32_t color_t;
174 
178 
179  static const order_t max_order;
180 
181  PresentationInfo::Flag flags() const { return _flags; }
182  order_t order() const { return _order; }
183  color_t color() const { return _color; }
184 
185  bool color_set() const;
186 
188  void set_hidden (bool yn);
189  void set_trigger_track (bool yn);
190  void set_flags (Flag f) { _flags = f; }
191 
192  bool order_set() const { return _flags & OrderSet; }
193 
194  int selection_cnt() const { return _selection_cnt; }
195 
196  bool hidden() const { return _flags & Hidden; }
197  bool trigger_track () const { return _flags & TriggerTrack; }
198  bool special(bool with_master = true) const { return _flags & ((with_master ? MasterOut : 0)|SurroundMaster|MonitorOut|Auditioner); }
199 
200  bool flag_match (Flag f) const {
201  /* no flags, match all */
202 
203  if (f == Flag (0)) {
204  return true;
205  }
206 
207  if (f & StatusMask) {
208  /* status bits set, must match them */
209  if ((_flags & StatusMask) != (f & StatusMask)) {
210  return false;
211  }
212  }
213 
214  /* Generic flags in f, match the right stuff */
215 
216  if (f == Bus && (_flags & Bus)) {
217  /* some kind of bus */
218  return true;
219  }
220  if (f == Track && (_flags & Track)) {
221  /* some kind of track */
222  return true;
223  }
224  if (f == Route && (_flags & Route)) {
225  /* any kind of route, but not master, monitor in
226  or auditioner.
227  */
228  return true;
229  }
230 
231  if (f == AllRoutes && (_flags & AllRoutes)) {
232  /* any kind of route, but not auditioner. Ask for that
233  specifically.
234  */
235  return true;
236  }
237 
238  if (f == AllStripables && (_flags & AllStripables)) {
239  /* any kind of stripable, but not auditioner. Ask for that
240  specifically.
241  */
242  return true;
243  }
244 
245  /* check for any matching type bits.
246  *
247  * Do comparisoon without status mask or order set bits - we
248  * already checked that above.
249  */
250 
251  return ((f & TypeMask) & _flags);
252  }
253 
254  int set_state (XMLNode const&, int);
255  XMLNode& get_state () const;
256 
257  bool operator==(PresentationInfo const& other) {
258  return (_order == other.order()) && (_flags == other.flags());
259  }
260 
261  bool operator!=(PresentationInfo const& other) {
262  return (_order != other.order()) || (_flags != other.flags());
263  }
264 
265  PresentationInfo& operator= (PresentationInfo const& other);
266 
267  static Flag get_flags (XMLNode const& node);
268  static Flag get_flags2X3X (XMLNode const& node);
269  static std::string state_node_name;
270 
271  /* for things concerned about *any* PresentationInfo.
272  */
273 
274  static PBD::Signal<void(PBD::PropertyChange const &)> Change;
276 
277  static void make_property_quarks ();
278 
279  protected:
280  friend class ChangeSuspender;
281  static void suspend_change_signal ();
282  static void unsuspend_change_signal ();
283 
284  public:
286  public:
289  }
292  }
293  };
294 
295  protected:
296  friend class Stripable;
298 
299  private:
304 
306  static Glib::Threads::Mutex static_signal_lock;
307  static std::atomic<int> _change_signal_suspended;
308 
309  static int selection_counter;
310 };
311 
312 }
313 
314 namespace std {
315 std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
316 }
317 
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 PBD::Signal< void(PBD::PropertyChange const &)> Change
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
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