Ardour  9.0-pre0-582-g084a23a80d
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 #ifdef MIXBUS
123  MixbusEditorHidden = 0x800,
124  Mixbus = 0x1000,
125 #endif
126  /* bus type for monitor mixes */
127  FoldbackBus = 0x2000,
128 
129  /* has TriggerBox, show on TriggerUI page */
130  TriggerTrack = 0x4000,
131 
132  /* bus is the surround master */
133  SurroundMaster = 0x8000,
134 
135  /* special mask to delect out "state" bits */
136 #ifdef MIXBUS
137  StatusMask = (Hidden | MixbusEditorHidden | TriggerTrack),
138 #else
139  StatusMask = (Hidden | TriggerTrack),
140 #endif
141 
142  /* dedicated [output] busses */
143  MainBus = (MasterOut|MonitorOut|FoldbackBus|SurroundMaster),
144 
145  /* These can exist only once and require special attention to be removed */
146  Singleton = (MasterOut|MonitorOut|SurroundMaster),
147 
148  /* special mask to delect select type bits */
149  TypeMask = (AudioBus|AudioTrack|MidiTrack|MidiBus|VCA|MasterOut|MonitorOut|Auditioner|FoldbackBus|SurroundMaster)
150  };
151 
152  static const Flag AllStripables; /* mask to use for any route or VCA (but not auditioner) */
153  static const Flag MixerStripables; /* mask to use for any route or VCA (but not auditioner or foldbackbus) */
154  static const Flag AllRoutes; /* mask to use for any route include master+monitor, but not auditioner */
155  static const Flag MixerRoutes; /* mask to use for any route include master+monitor, but not auditioner or foldbackbus*/
156  static const Flag Route; /* mask for any route (bus or track */
157  static const Flag Track; /* mask to use for any track */
158  static const Flag Bus; /* mask to use for any bus */
159  static const Flag MidiIndicatingFlags; /* MidiTrack or MidiBus */
160 
161  typedef uint32_t order_t;
162  typedef uint32_t color_t;
163 
167 
168  static const order_t max_order;
169 
170  PresentationInfo::Flag flags() const { return _flags; }
171  order_t order() const { return _order; }
172  color_t color() const { return _color; }
173 
174  bool color_set() const;
175 
177  void set_hidden (bool yn);
178  void set_trigger_track (bool yn);
179  void set_flags (Flag f) { _flags = f; }
180 
181  bool order_set() const { return _flags & OrderSet; }
182 
183  int selection_cnt() const { return _selection_cnt; }
184 
185  bool hidden() const { return _flags & Hidden; }
186  bool trigger_track () const { return _flags & TriggerTrack; }
187  bool special(bool with_master = true) const { return _flags & ((with_master ? MasterOut : 0)|SurroundMaster|MonitorOut|Auditioner); }
188 
189  bool flag_match (Flag f) const {
190  /* no flags, match all */
191 
192  if (f == Flag (0)) {
193  return true;
194  }
195 
196  if (f & StatusMask) {
197  /* status bits set, must match them */
198  if ((_flags & StatusMask) != (f & StatusMask)) {
199  return false;
200  }
201  }
202 
203  /* Generic flags in f, match the right stuff */
204 
205  if (f == Bus && (_flags & Bus)) {
206  /* some kind of bus */
207  return true;
208  }
209  if (f == Track && (_flags & Track)) {
210  /* some kind of track */
211  return true;
212  }
213  if (f == Route && (_flags & Route)) {
214  /* any kind of route, but not master, monitor in
215  or auditioner.
216  */
217  return true;
218  }
219 
220  if (f == AllRoutes && (_flags & AllRoutes)) {
221  /* any kind of route, but not auditioner. Ask for that
222  specifically.
223  */
224  return true;
225  }
226 
227  if (f == AllStripables && (_flags & AllStripables)) {
228  /* any kind of stripable, but not auditioner. Ask for that
229  specifically.
230  */
231  return true;
232  }
233 
234  /* check for any matching type bits.
235  *
236  * Do comparisoon without status mask or order set bits - we
237  * already checked that above.
238  */
239 
240  return ((f & TypeMask) & _flags);
241  }
242 
243  int set_state (XMLNode const&, int);
244  XMLNode& get_state () const;
245 
246  bool operator==(PresentationInfo const& other) {
247  return (_order == other.order()) && (_flags == other.flags());
248  }
249 
250  bool operator!=(PresentationInfo const& other) {
251  return (_order != other.order()) || (_flags != other.flags());
252  }
253 
254  PresentationInfo& operator= (PresentationInfo const& other);
255 
256  static Flag get_flags (XMLNode const& node);
257  static Flag get_flags2X3X (XMLNode const& node);
258  static std::string state_node_name;
259 
260  /* for things concerned about *any* PresentationInfo.
261  */
262 
263  static PBD::Signal<void(PBD::PropertyChange const &)> Change;
265 
266  static void make_property_quarks ();
267 
268  protected:
269  friend class ChangeSuspender;
270  static void suspend_change_signal ();
271  static void unsuspend_change_signal ();
272 
273  public:
275  public:
278  }
281  }
282  };
283 
284  protected:
285  friend class Stripable;
287 
288  private:
293 
295  static Glib::Threads::Mutex static_signal_lock;
296  static std::atomic<int> _change_signal_suspended;
297 
298  static int selection_counter;
299 };
300 
301 }
302 
303 namespace std {
304 std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
305 }
306 
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