Audacity  3.0.3
Track.h
Go to the documentation of this file.
1 /*!********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  @file Track.h
6  @brief declares abstract base class Track, TrackList, and iterators over TrackList
7 
8  Dominic Mazzoni
9 
10 **********************************************************************/
11 
12 #ifndef __AUDACITY_TRACK__
13 #define __AUDACITY_TRACK__
14 
15 
16 
17 
18 
19 #include <vector>
20 #include <list>
21 #include <functional>
22 #include <wx/event.h> // to inherit wxCommandEvent
23 #include <wx/longlong.h>
24 
25 #include "ClientData.h"
26 #include "SampleFormat.h"
27 #include "XMLTagHandler.h"
28 
29 #ifdef __WXMSW__
30 #pragma warning(disable:4284)
31 #endif
32 
33 class wxTextFile;
34 class CommonTrackCell;
35 class Track;
36 class AudioTrack;
37 class PlayableTrack;
38 class ProjectSettings;
39 class LabelTrack;
40 class TimeTrack;
41 class WaveTrack;
42 class NoteTrack;
43 class AudacityProject;
44 
45 using TrackArray = std::vector< Track* >;
46 using WaveTrackArray = std::vector < std::shared_ptr< WaveTrack > > ;
47 using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
48 
49 using NoteTrackConstArray = std::vector < std::shared_ptr< const NoteTrack > >;
50 
51 class TrackList;
52 
53 using ListOfTracks = std::list< std::shared_ptr< Track > >;
54 
56 
59 std::pair< ListOfTracks::iterator, ListOfTracks* >;
60 
61 inline bool operator == (const TrackNodePointer &a, const TrackNodePointer &b)
62 { return a.second == b.second && a.first == b.first; }
63 
64 inline bool operator != (const TrackNodePointer &a, const TrackNodePointer &b)
65 { return !(a == b); }
66 
68 enum class TrackKind
69 {
70  None,
71  Wave,
72  Note,
73  Label,
74  Time,
75  Audio,
76  Playable,
77  All
78 };
79 
81 
83 constexpr bool CompatibleTrackKinds( TrackKind desired, TrackKind actual )
84 {
85  return
86  (desired == actual)
87  ||
88  (desired == TrackKind::All)
89  ||
90  (desired == TrackKind::Audio && actual == TrackKind::Wave)
91 #ifdef USE_MIDI
92  ||
93  (desired == TrackKind::Audio && actual == TrackKind::Note)
94 #endif
95  ||
96  (desired == TrackKind::Playable && actual == TrackKind::Wave)
97 #ifdef EXPERIMENTAL_MIDI_OUT
98  ||
99  (desired == TrackKind::Playable && actual == TrackKind::Note)
100 #endif
101  ;
102 }
103 
105 namespace TrackTyper {
106  template<typename, TrackKind> struct Pair;
108  using List = std::tuple<
116  // New classes can be added easily to this list
117  >;
119  template<typename...> struct Lookup {};
121  template<typename TrackType, TrackKind Here, typename... Rest>
122  struct Lookup< TrackType, std::tuple< Pair<TrackType, Here>, Rest... > > {
123  static constexpr TrackKind value() {
124  return Here;
125  }
126  };
128  template<typename TrackType, typename NotHere, typename... Rest>
129  struct Lookup< TrackType, std::tuple< NotHere, Rest... > > {
130  static constexpr TrackKind value() {
131  return Lookup< TrackType, std::tuple< Rest... > >::value();
132  }
133  };
134 };
135 
137 template<typename TrackType> constexpr TrackKind track_kind ()
138 {
139  using namespace TrackTyper;
141 }
142 
143 // forward declarations, so we can make them friends
144 template<typename T>
145  typename std::enable_if< std::is_pointer<T>::value, T >::type
146  track_cast(Track *track);
147 
148 template<typename T>
149  typename std::enable_if<
150  std::is_pointer<T>::value &&
151  std::is_const< typename std::remove_pointer< T >::type >::value,
152  T
153  >::type
154  track_cast(const Track *track);
155 
157 
164 class TrackId
165 {
166 public:
167  TrackId() : mValue(-1) {}
168  explicit TrackId (long value) : mValue(value) {}
169 
170  bool operator == (const TrackId &other) const
171  { return mValue == other.mValue; }
172 
173  bool operator != (const TrackId &other) const
174  { return mValue != other.mValue; }
175 
176  // Define this in case you want to key a std::map on TrackId
177  // The operator does not mean anything else
178  bool operator < (const TrackId &other) const
179  { return mValue < other.mValue; }
180 
181 private:
182  long mValue;
183 };
184 
186 struct AUDACITY_DLL_API TrackIntervalData {
188 };
189 
191 
193 public:
194 
196  ConstTrackInterval( double start, double end,
197  std::unique_ptr<TrackIntervalData> pExtra = {} )
198  : start{ start }, end{ end }, pExtra{ std::move( pExtra ) }
199  {
200  wxASSERT( start <= end );
201  }
202 
205 
206  double Start() const { return start; }
207  double End() const { return end; }
208  const TrackIntervalData *Extra() const { return pExtra.get(); }
209 
210 private:
211  double start, end;
212 protected:
213  // TODO C++17: use std::any instead
214  std::unique_ptr< TrackIntervalData > pExtra;
215 };
216 
218 
220 public:
222 
225 
226  TrackIntervalData *Extra() const { return pExtra.get(); }
227 };
228 
232 >;
233 
235 class AUDACITY_DLL_API Track /* not final */
236  : public XMLTagHandler
237  , public AttachedTrackObjects
238  , public std::enable_shared_from_this<Track> // see SharedPointer()
239 {
240 public:
241 
243  enum class LinkType : int {
244  None = 0, //< No linkage
245  Group = 2, //< Tracks are grouped together
246  Aligned, //< Tracks are grouped and changes should be synchronized
247  };
248 
249 private:
250 
251  friend class TrackList;
252 
253  private:
255  LinkType mLinkType{ LinkType::None };
256 
257  protected:
258  std::weak_ptr<TrackList> mList;
259 
262  int mIndex;
263  wxString mName;
264  wxString mDefaultName;
265 
266  private:
267  bool mSelected;
268 
269  public:
270 
273 
275  {
276  LeftChannel = 0,
277  RightChannel = 1,
278  MonoChannel = 2
279  };
280 
281  TrackId GetId() const { return mId; }
282  private:
283  void SetId( TrackId id ) { mId = id; }
284  public:
285 
286  // Given a bare pointer, find a shared_ptr. Undefined results if the track
287  // is not yet managed by a shared_ptr. Undefined results if the track is
288  // not really of the subclass. (That is, trusts the caller and uses static
289  // not dynamic casting.)
290  template<typename Subclass = Track>
291  inline std::shared_ptr<Subclass> SharedPointer()
292  {
293  // shared_from_this is injected into class scope by base class
294  // std::enable_shared_from_this<Track>
295  return std::static_pointer_cast<Subclass>( shared_from_this() );
296  }
297 
298  template<typename Subclass = const Track>
299  inline auto SharedPointer() const -> typename
300  std::enable_if<
301  std::is_const<Subclass>::value, std::shared_ptr<Subclass>
302  >::type
303  {
304  // shared_from_this is injected into class scope by base class
305  // std::enable_shared_from_this<Track>
306  return std::static_pointer_cast<Subclass>( shared_from_this() );
307  }
308 
309  // Static overloads of SharedPointer for when the pointer may be null
310  template<typename Subclass = Track>
311  static inline std::shared_ptr<Subclass> SharedPointer( Track *pTrack )
312  { return pTrack ? pTrack->SharedPointer<Subclass>() : nullptr; }
313 
314  template<typename Subclass = const Track>
315  static inline std::shared_ptr<Subclass> SharedPointer( const Track *pTrack )
316  { return pTrack ? pTrack->SharedPointer<Subclass>() : nullptr; }
317 
318  // Find anything registered with TrackList::RegisterPendingChangedTrack and
319  // not yet cleared or applied; if no such exists, return this track
320  std::shared_ptr<Track> SubstitutePendingChangedTrack();
321  std::shared_ptr<const Track> SubstitutePendingChangedTrack() const;
322 
323  // If this track is a pending changed track, return the corresponding
324  // original; else return this track
325  std::shared_ptr<const Track> SubstituteOriginalTrack() const;
326 
329  using Intervals = std::vector< Interval >;
331  using ConstIntervals = std::vector< ConstInterval >;
332 
334  virtual bool SupportsBasicEditing() const;
335 
336  using Holder = std::shared_ptr<Track>;
337 
339 
340  virtual Holder PasteInto( AudacityProject & ) const = 0;
341 
343 
346  virtual ConstIntervals GetIntervals() const;
347 
351  virtual Intervals GetIntervals();
352 
353  public:
354  mutable wxSize vrulerSize;
355 
356  // These are exposed only for the purposes of the TrackView class, to
357  // initialize the pointer on demand
358  const std::shared_ptr<CommonTrackCell> &GetTrackView();
359  void SetTrackView( const std::shared_ptr<CommonTrackCell> &pView );
360 
361  // These are exposed only for the purposes of the TrackControls class, to
362  // initialize the pointer on demand
363  const std::shared_ptr<CommonTrackCell> &GetTrackControls();
364  void SetTrackControls( const std::shared_ptr<CommonTrackCell> &pControls );
365 
366  // Return another, associated TrackPanelCell object that implements the
367 
368  int GetIndex() const;
369  void SetIndex(int index);
370 
371 public:
372  static void FinishCopy (const Track *n, Track *dest);
373 
374  // For use when loading a file. Return true if ok, else make repair
375  virtual bool LinkConsistencyCheck();
376 
377  bool HasOwner() const { return static_cast<bool>(GetOwner());}
378 
379  std::shared_ptr<TrackList> GetOwner() const { return mList.lock(); }
380 
381  LinkType GetLinkType() const noexcept;
383  bool IsAlignedWithLeader() const;
384 
385 protected:
386 
387  void SetLinkType(LinkType linkType);
388  void DoSetLinkType(LinkType linkType) noexcept;
389  void SetChannel(ChannelType c) noexcept;
390 private:
391 
392  Track* GetLinkedTrack() const;
394  bool HasLinkedTrack() const noexcept;
395 
396 
397 
399  TrackNodePointer GetNode() const;
401  void SetOwner
402  (const std::weak_ptr<TrackList> &list, TrackNodePointer node);
403 
404  // Keep in Track
405 
406  protected:
407  ChannelType mChannel;
408  double mOffset;
409 
410  public:
411 
412  Track();
413  Track(const Track &orig);
414 
415  virtual ~ Track();
416 
417  void Init(const Track &orig);
418 
419  // public nonvirtual duplication function that invokes Clone():
420  virtual Holder Duplicate() const;
421 
422  // Called when this track is merged to stereo with another, and should
423  // take on some parameters of its partner.
424  virtual void Merge(const Track &orig);
425 
426  wxString GetName() const { return mName; }
427  void SetName( const wxString &n );
428  wxString GetDefaultName() const { return mDefaultName; }
429  void SetDefaultName( const wxString &n ) { mDefaultName = n; }
430 
431  bool GetSelected() const { return mSelected; }
432 
433  virtual void SetSelected(bool s);
434 
435  // The argument tells whether the last undo history state should be
436  // updated for the appearance change
437  void EnsureVisible( bool modifyState = false );
438 
439 public:
440 
441  virtual ChannelType GetChannel() const { return mChannel;}
442  virtual double GetOffset() const = 0;
443 
444  void Offset(double t) { SetOffset(GetOffset() + t); }
445  virtual void SetOffset (double o) { mOffset = o; }
446 
447  virtual void SetPan( float ){ ;}
448  virtual void SetPanFromChannelType(){ ;};
449 
450  // Create a NEW track and modify this track
451  // Return non-NULL or else throw
452  // May assume precondition: t0 <= t1
453  virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
454 
455  // Create a NEW track and don't modify this track
456  // Return non-NULL or else throw
457  // Note that subclasses may want to distinguish tracks stored in a clipboard
458  // from those stored in a project
459  // May assume precondition: t0 <= t1
460  virtual Holder Copy
461  (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard = true) const = 0;
462 
463  // May assume precondition: t0 <= t1
464  virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
465 
466  virtual void Paste(double WXUNUSED(t), const Track * WXUNUSED(src)) = 0;
467 
468  // This can be used to adjust a sync-lock selected track when the selection
469  // is replaced by one of a different length.
470  virtual void SyncLockAdjust(double oldT1, double newT1);
471 
472  // May assume precondition: t0 <= t1
473  virtual void Silence(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
474 
475  // May assume precondition: t0 <= t1
476  virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len)) = 0;
477 
478 private:
479  // Subclass responsibility implements only a part of Duplicate(), copying
480  // the track data proper (not associated data such as for groups and views):
481  virtual Holder Clone() const = 0;
482 
483  virtual TrackKind GetKind() const { return TrackKind::None; }
484 
485  template<typename T>
486  friend typename std::enable_if< std::is_pointer<T>::value, T >::type
487  track_cast(Track *track);
488  template<typename T>
489  friend typename std::enable_if<
490  std::is_pointer<T>::value &&
491  std::is_const< typename std::remove_pointer< T >::type >::value,
492  T
493  >::type
494  track_cast(const Track *track);
495 
496 public:
497  bool SameKindAs(const Track &track) const
498  { return GetKind() == track.GetKind(); }
499 
501  template < typename R = void >
502  using Continuation = std::function< R() >;
505 
506 private:
508  template< typename ...Params >
509  struct Executor{};
510 
512 
513  struct Dispatcher {
515  template< typename R, typename ConcreteType,
516  typename Function, typename ...Functions >
518  {
520  using Tail = Executor< R, ConcreteType, Functions... >;
522  enum : unsigned { SetUsed = Tail::SetUsed << 1 };
523 
525  R operator ()
526  (const Track *pTrack,
527  const Function &, const Functions &...functions)
528  { return Tail{}( pTrack, functions... ); }
529  };
530 
532  template< typename R, typename BaseClass, typename ConcreteType,
533  typename Function, typename ...Functions >
534  struct applicable1
535  {
537  enum : unsigned { SetUsed = 1u };
538 
540  R operator ()
541  (const Track *pTrack,
542  const Function &function, const Functions &...)
543  { return function( (BaseClass *)pTrack ); }
544  };
545 
547  template< typename R, typename BaseClass, typename ConcreteType,
548  typename Function, typename ...Functions >
549  struct applicable2
550  {
552  using Tail = Executor< R, ConcreteType, Functions... >;
554  enum : unsigned { SetUsed = (Tail::SetUsed << 1) | 1u };
555 
557  R operator ()
558  (const Track *pTrack, const Function &function,
559  const Functions &...functions)
560  {
561  auto continuation = Continuation<R>{ [&] {
562  return Tail{}( pTrack, functions... );
563  } };
564  return function( (BaseClass *)pTrack, continuation );
565  }
566  };
567 
569  template< typename ... > struct Switch {};
570 
572 
573  template< typename R, typename ConcreteType >
574  struct Switch< R, ConcreteType >
575  {
577  template< typename Function, typename ...Functions >
578  static auto test()
579  -> inapplicable< R, ConcreteType, Function, Functions... >;
580  };
581 
583 
584  template< typename R, typename ConcreteType,
585  typename BaseClass, typename ...BaseClasses >
586  struct Switch< R, ConcreteType, BaseClass, BaseClasses... >
587  {
589  using Retry = Switch< R, ConcreteType, BaseClasses... >;
590 
592 
594  template< typename Function, typename ...Functions >
595  static auto test( const void * )
596  -> decltype( Retry::template test< Function, Functions... >() );
597 
599 
602  template< typename Function, typename ...Functions >
603  static auto test( std::true_type * )
604  -> decltype(
605  (void) std::declval<Function>()
606  ( (BaseClass*)nullptr ),
607  applicable1< R, BaseClass, ConcreteType,
608  Function, Functions... >{}
609  );
610 
612 
616  template< typename Function, typename ...Functions >
617  static auto test( std::true_type * )
618  -> decltype(
619  (void) std::declval<Function>()
620  ( (BaseClass*)nullptr,
621  std::declval< Continuation<R> >() ),
622  applicable2< R, BaseClass, ConcreteType,
623  Function, Functions... >{}
624  );
625 
627  static constexpr bool Compatible = CompatibleTrackKinds(
628  track_kind<BaseClass>(), track_kind<ConcreteType>() );
630  template< typename Function, typename ...Functions >
631  static auto test()
632  -> decltype(
633  test< Function, Functions... >(
634  (std::integral_constant<bool, Compatible>*)nullptr) );
635  };
636  };
637 
639  template< typename R, typename ConcreteType >
640  struct Executor< R, ConcreteType >
641  {
643  enum : unsigned { SetUsed = 0 };
645  R operator () (const void *) { return R{}; }
646  };
647 
649  template< typename ConcreteType >
650  struct Executor< void, ConcreteType >
651  {
653  enum : unsigned { SetUsed = 0 };
655  void operator () (const void *) { }
656  };
657 
659 
660  template< typename R, typename ConcreteType,
661  typename Function, typename ...Functions >
662  struct Executor< R, ConcreteType, Function, Functions... >
663  : decltype(
664  Dispatcher::Switch< R, ConcreteType,
665  Track, AudioTrack, PlayableTrack,
666  WaveTrack, LabelTrack, TimeTrack,
667  NoteTrack >
668  ::template test<Function, Functions... >())
669  {};
670 
672 
673  template< typename R, typename ConcreteType,
674  typename Function, typename ...Functions >
675  struct Executor< R, const ConcreteType, Function, Functions... >
676  : decltype(
677  Dispatcher::Switch< R, ConcreteType,
678  const Track, const AudioTrack, const PlayableTrack,
679  const WaveTrack, const LabelTrack, const TimeTrack,
680  const NoteTrack >
681  ::template test<Function, Functions... >())
682  {};
683 
684 public:
685 
687 
705  template<
706  typename R = void,
707  typename ...Functions
708  >
709  R TypeSwitch( const Functions &...functions )
710  {
711  using WaveExecutor =
712  Executor< R, WaveTrack, Functions... >;
713  using NoteExecutor =
714  Executor< R, NoteTrack, Functions... >;
715  using LabelExecutor =
716  Executor< R, LabelTrack, Functions... >;
717  using TimeExecutor =
718  Executor< R, TimeTrack, Functions... >;
719  using DefaultExecutor =
721  enum { All = sizeof...( functions ) };
722 
723  static_assert(
724  (1u << All) - 1u ==
725  (WaveExecutor::SetUsed |
726  NoteExecutor::SetUsed |
727  LabelExecutor::SetUsed |
728  TimeExecutor::SetUsed),
729  "Uncallable case in Track::TypeSwitch"
730  );
731 
732  switch (GetKind()) {
733  case TrackKind::Wave:
734  return WaveExecutor{} (this, functions...);
735 #if defined(USE_MIDI)
736  case TrackKind::Note:
737  return NoteExecutor{} (this, functions...);
738 #endif
739  case TrackKind::Label:
740  return LabelExecutor{}(this, functions...);
741  case TrackKind::Time:
742  return TimeExecutor{} (this, functions...);
743  default:
744  return DefaultExecutor{} (this);
745  }
746  }
747 
751  template<
752  typename R = void,
753  typename ...Functions
754  >
755  R TypeSwitch(const Functions &...functions) const
756  {
757  using WaveExecutor =
758  Executor< R, const WaveTrack, Functions... >;
759  using NoteExecutor =
760  Executor< R, const NoteTrack, Functions... >;
761  using LabelExecutor =
762  Executor< R, const LabelTrack, Functions... >;
763  using TimeExecutor =
764  Executor< R, const TimeTrack, Functions... >;
765  using DefaultExecutor =
767  enum { All = sizeof...( functions ) };
768 
769  static_assert(
770  (1u << All) - 1u ==
771  (WaveExecutor::SetUsed |
772  NoteExecutor::SetUsed |
773  LabelExecutor::SetUsed |
774  TimeExecutor::SetUsed),
775  "Uncallable case in Track::TypeSwitch"
776  );
777 
778  switch (GetKind()) {
779  case TrackKind::Wave:
780  return WaveExecutor{} (this, functions...);
781 #if defined(USE_MIDI)
782  case TrackKind::Note:
783  return NoteExecutor{} (this, functions...);
784 #endif
785  case TrackKind::Label:
786  return LabelExecutor{}(this, functions...);
787  case TrackKind::Time:
788  return TimeExecutor{} (this, functions...);
789  default:
790  return DefaultExecutor{} (this);
791  }
792  }
793 
794  // XMLTagHandler callback methods -- NEW virtual for writing
795  virtual void WriteXML(XMLWriter &xmlFile) const = 0;
796 
797  // Returns true if an error was encountered while trying to
798  // open the track from XML
799  virtual bool GetErrorOpening() { return false; }
800 
801  virtual double GetStartTime() const = 0;
802  virtual double GetEndTime() const = 0;
803 
804  // Checks if sync-lock is on and any track in its sync-lock group is selected.
805  bool IsSyncLockSelected() const;
806 
807  // Send an event to listeners when state of the track changes
808  // To do: define values for the argument to distinguish different parts
809  // of the state, perhaps with wxNewId
810  void Notify( int code = -1 );
811 
812  // An always-true predicate useful for defining iterators
813  bool Any() const;
814 
815  // Frequently useful operands for + and -
816  bool IsSelected() const;
817  bool IsSelectedOrSyncLockSelected() const;
818  bool IsLeader() const;
819  bool IsSelectedLeader() const;
820 
821  // Cause this track and following ones in its TrackList to adjust
822  void AdjustPositions();
823 
824  // Serialize, not with tags of its own, but as attributes within a tag.
825  void WriteCommonXMLAttributes(
826  XMLWriter &xmlFile, bool includeNameAndSelected = true) const;
827 
828  // Return true iff the attribute is recognized.
829  bool HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value);
830 
831 protected:
832  std::shared_ptr<CommonTrackCell> mpView;
833  std::shared_ptr<CommonTrackCell> mpControls;
834 };
835 
837 class AUDACITY_DLL_API AudioTrack /* not final */ : public Track
838 {
839 public:
841  : Track{} {}
842  AudioTrack(const Track &orig) : Track{ orig } {}
843 
844  // Serialize, not with tags of its own, but as attributes within a tag.
845  void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const {}
846 
847  // Return true iff the attribute is recognized.
848  bool HandleXMLAttribute(const wxChar * /*attr*/, const wxChar * /*value*/)
849  { return false; }
850 };
851 
853 class AUDACITY_DLL_API PlayableTrack /* not final */ : public AudioTrack
854 {
855 public:
857  : AudioTrack{} {}
858  PlayableTrack(const Track &orig) : AudioTrack{ orig } {}
859 
860  bool GetMute () const { return mMute; }
861  bool GetSolo () const { return mSolo; }
862  bool GetNotMute () const { return !mMute; }
863  bool GetNotSolo () const { return !mSolo; }
864  void SetMute (bool m);
865  void SetSolo (bool s);
866 
867  void Init( const PlayableTrack &init );
868  void Merge( const Track &init ) override;
869 
870  // Serialize, not with tags of its own, but as attributes within a tag.
871  void WriteXMLAttributes(XMLWriter &xmlFile) const;
872 
873  // Return true iff the attribute is recognized.
874  bool HandleXMLAttribute(const wxChar *attr, const wxChar *value);
875 
876 protected:
877  bool mMute { false };
878  bool mSolo { false };
879 };
880 
882 
889 template<typename T>
890  inline typename std::enable_if< std::is_pointer<T>::value, T >::type
892 {
893  using BareType = typename std::remove_pointer< T >::type;
894  if (track &&
895  CompatibleTrackKinds( track_kind<BareType>(), track->GetKind() ))
896  return reinterpret_cast<T>(track);
897  else
898  return nullptr;
899 }
900 
903 template<typename T>
904  inline typename std::enable_if<
905  std::is_pointer<T>::value &&
906  std::is_const< typename std::remove_pointer< T >::type >::value,
907  T
908  >::type
909  track_cast(const Track *track)
910 {
911  using BareType = typename std::remove_pointer< T >::type;
912  if (track &&
913  CompatibleTrackKinds( track_kind<BareType>(), track->GetKind() ))
914  return reinterpret_cast<T>(track);
915  else
916  return nullptr;
917 }
918 
919 template < typename TrackType > struct TrackIterRange;
920 
922 
929 template <
930  typename TrackType
931 > class TrackIter
932  : public ValueIterator< TrackType *, std::bidirectional_iterator_tag >
933 {
934 public:
936 
937  using FunctionType = std::function< bool(
938  typename std::add_pointer<
939  typename std::add_const<
940  typename std::remove_pointer<
941  TrackType
942  >::type
943  >::type
944  >::type
945  ) >;
946 
949  TrackNodePointer begin,
950  TrackNodePointer iter,
951  TrackNodePointer end,
952  FunctionType pred = {}
953  )
954  : mBegin( begin ), mIter( iter ), mEnd( end )
955  , mPred( std::move(pred) )
956  {
957  // Establish the class invariant
958  if (this->mIter != this->mEnd && !this->valid())
959  this->operator ++ ();
960  }
961 
963 
965  template < typename Predicate2 >
966  TrackIter Filter( const Predicate2 &pred2 ) const
967  {
968  return { this->mBegin, this->mIter, this->mEnd, pred2 };
969  }
970 
972 
974  template < typename TrackType2 >
975  auto Filter() const
976  -> typename std::enable_if<
977  std::is_base_of< TrackType, TrackType2 >::value &&
978  (!std::is_const<TrackType>::value ||
979  std::is_const<TrackType2>::value),
980  TrackIter< TrackType2 >
981  >::type
982  {
983  return { this->mBegin, this->mIter, this->mEnd, this->mPred };
984  }
985 
986  const FunctionType &GetPredicate() const
987  { return this->mPred; }
988 
990 
992  {
993  // Maintain the class invariant
994  if (this->mIter != this->mEnd) do
995  ++this->mIter.first;
996  while (this->mIter != this->mEnd && !this->valid() );
997  return *this;
998  }
999 
1002  {
1003  TrackIter result { *this };
1004  this-> operator ++ ();
1005  return result;
1006  }
1007 
1009 
1011  {
1012  // Maintain the class invariant
1013  do {
1014  if (this->mIter == this->mBegin)
1015  // Go circularly
1016  this->mIter = this->mEnd;
1017  else
1018  --this->mIter.first;
1019  } while (this->mIter != this->mEnd && !this->valid() );
1020  return *this;
1021  }
1022 
1025  {
1026  TrackIter result { *this };
1027  this->operator -- ();
1028  return result;
1029  }
1030 
1032 
1033  TrackType *operator * () const
1034  {
1035  if (this->mIter == this->mEnd)
1036  return nullptr;
1037  else
1038  // Other methods guarantee that the cast is correct
1039  // (provided no operations on the TrackList invalidated
1040  // underlying iterators or replaced the tracks there)
1041  return static_cast< TrackType * >( &**this->mIter.first );
1042  }
1043 
1046  long amount
1047  ) const
1048  {
1049  auto copy = *this;
1050  std::advance( copy, amount );
1051  return copy;
1052  }
1053 
1055  friend inline bool operator == (TrackIter a, TrackIter b)
1056  {
1057  // Assume the predicate is not stateful. Just compare the iterators.
1058  return
1059  a.mIter == b.mIter
1060  // Assume this too:
1061  // && a.mBegin == b.mBegin && a.mEnd == b.mEnd
1062  ;
1063  }
1064 
1066  friend inline bool operator != (TrackIter a, TrackIter b)
1067  {
1068  return !(a == b);
1069  }
1070 
1071 private:
1076  bool valid() const
1078  {
1079  // assume mIter != mEnd
1080  const auto pTrack = track_cast< TrackType * >( &**this->mIter.first );
1081  if (!pTrack)
1082  return false;
1083  return !this->mPred || this->mPred( pTrack );
1084  }
1085 
1088 
1094 };
1095 
1097 template <
1098  typename TrackType // Track or a subclass, maybe const-qualified
1100  : public IteratorRange< TrackIter< TrackType > >
1101 {
1103  ( const TrackIter< TrackType > &begin,
1104  const TrackIter< TrackType > &end )
1105  : IteratorRange< TrackIter< TrackType > >
1106  ( begin, end )
1107  {}
1108 
1109  // Conjoin the filter predicate with another predicate
1110  // Read + as "and"
1111  template< typename Predicate2 >
1112  TrackIterRange operator + ( const Predicate2 &pred2 ) const
1113  {
1114  const auto &pred1 = this->first.GetPredicate();
1115  using Function = typename TrackIter<TrackType>::FunctionType;
1116  const auto &newPred = pred1
1117  ? Function{ [=] (typename Function::argument_type track) {
1118  return pred1(track) && pred2(track);
1119  } }
1120  : Function{ pred2 };
1121  return {
1122  this->first.Filter( newPred ),
1123  this->second.Filter( newPred )
1124  };
1125  }
1126 
1127  // Specify the added conjunct as a pointer to member function
1128  // Read + as "and"
1129  template< typename R, typename C >
1130  TrackIterRange operator + ( R ( C ::* pmf ) () const ) const
1131  {
1132  return this->operator + ( std::mem_fn( pmf ) );
1133  }
1134 
1135  // Conjoin the filter predicate with the negation of another predicate
1136  // Read - as "and not"
1137  template< typename Predicate2 >
1138  TrackIterRange operator - ( const Predicate2 &pred2 ) const
1139  {
1140  using ArgumentType =
1141  typename TrackIterRange::iterator::FunctionType::argument_type;
1142  auto neg = [=] (ArgumentType track) { return !pred2( track ); };
1143  return this->operator + ( neg );
1144  }
1145 
1146  // Specify the negated conjunct as a pointer to member function
1147  // Read - as "and not"
1148  template< typename R, typename C >
1149  TrackIterRange operator - ( R ( C ::* pmf ) () const ) const
1150  {
1151  return this->operator + ( std::not1( std::mem_fn( pmf ) ) );
1152  }
1153 
1154  template< typename TrackType2 >
1156  {
1157  return {
1158  this-> first.template Filter< TrackType2 >(),
1159  this->second.template Filter< TrackType2 >()
1160  };
1161  }
1162 
1163  TrackIterRange StartingWith( const Track *pTrack ) const
1164  {
1165  auto newBegin = this->find( pTrack );
1166  // More careful construction is needed so that the independent
1167  // increment and decrement of each iterator in the NEW pair
1168  // has the expected behavior at boundaries of the range
1169  return {
1170  { newBegin.mIter, newBegin.mIter, this->second.mEnd,
1171  this->first.GetPredicate() },
1172  { newBegin.mIter, this->second.mIter, this->second.mEnd,
1173  this->second.GetPredicate() }
1174  };
1175  }
1176 
1177  TrackIterRange EndingAfter( const Track *pTrack ) const
1178  {
1179  const auto newEnd = this->reversal().find( pTrack ).base();
1180  // More careful construction is needed so that the independent
1181  // increment and decrement of each iterator in the NEW pair
1182  // has the expected behavior at boundaries of the range
1183  return {
1184  { this->first.mBegin, this->first.mIter, newEnd.mIter,
1185  this->first.GetPredicate() },
1186  { this->first.mBegin, newEnd.mIter, newEnd.mIter,
1187  this->second.GetPredicate() }
1188  };
1189  }
1190 
1191  // Exclude one given track
1192  TrackIterRange Excluding ( const TrackType *pExcluded ) const
1193  {
1194  return this->operator - (
1195  [=](const Track *pTrack){ return pExcluded == pTrack; } );
1196  }
1197 
1199  template< typename ...Functions >
1200  void Visit(const Functions &...functions)
1201  {
1202  for (auto track : *this)
1203  track->TypeSwitch(functions...);
1204  }
1205 
1207 
1208  template< typename Flag, typename ...Functions >
1209  void VisitWhile(Flag &flag, const Functions &...functions)
1210  {
1211  if ( flag ) for (auto track : *this) {
1212  track->TypeSwitch(functions...);
1213  if (!flag)
1214  break;
1215  }
1216  }
1217 };
1218 
1219 
1221 struct TrackListEvent : public wxCommandEvent
1222 {
1223  explicit
1225  wxEventType commandType,
1226  const std::weak_ptr<Track> &pTrack = {}, int code = -1)
1227  : wxCommandEvent{ commandType }
1228  , mpTrack{ pTrack }
1229  , mCode{ code }
1230  {}
1231 
1232  TrackListEvent( const TrackListEvent& ) = default;
1233 
1234  wxEvent *Clone() const override {
1235  // wxWidgets will own the event object
1236  return safenew TrackListEvent(*this); }
1237 
1238  std::weak_ptr<Track> mpTrack;
1239  int mCode;
1240 };
1241 
1243 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1244  EVT_TRACKLIST_SELECTION_CHANGE, TrackListEvent);
1245 
1247 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1248  EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent);
1249 
1251 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1252  EVT_TRACKLIST_TRACK_REQUEST_VISIBLE, TrackListEvent);
1253 
1255 
1256 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1257  EVT_TRACKLIST_PERMUTED, TrackListEvent);
1258 
1260 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1261  EVT_TRACKLIST_RESIZING, TrackListEvent);
1262 
1264 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1265  EVT_TRACKLIST_ADDITION, TrackListEvent);
1266 
1268 
1269 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
1270  EVT_TRACKLIST_DELETION, TrackListEvent);
1271 
1275 class AUDACITY_DLL_API TrackList final
1276  : public wxEvtHandler
1277  , public ListOfTracks
1278  , public std::enable_shared_from_this<TrackList>
1279  , public ClientData::Base
1280 {
1281  // privatize this, make you use Add instead:
1282  using ListOfTracks::push_back;
1283 
1284  // privatize this, make you use Swap instead:
1285  using ListOfTracks::swap;
1286 
1287  // Disallow copy
1288  TrackList(const TrackList &that) = delete;
1289  TrackList &operator= (const TrackList&) = delete;
1290 
1291  // No need for move, disallow it
1292  TrackList(TrackList &&that) = delete;
1293  TrackList& operator= (TrackList&&) = delete;
1294 
1295  void clear() = delete;
1296 
1297  public:
1298  static TrackList &Get( AudacityProject &project );
1299  static const TrackList &Get( const AudacityProject &project );
1300 
1301  // Create an empty TrackList
1302  // Don't call directly -- use Create() instead
1303  explicit TrackList( AudacityProject *pOwner );
1304 
1305  // Create an empty TrackList
1306  static std::shared_ptr<TrackList> Create( AudacityProject *pOwner );
1307 
1308  // Move is defined in terms of Swap
1309  void Swap(TrackList &that);
1310 
1311  // Destructor
1312  virtual ~TrackList();
1313 
1314  // Find the owning project, which may be null
1315  AudacityProject *GetOwner() { return mOwner; }
1316  const AudacityProject *GetOwner() const { return mOwner; }
1317 
1318  // Iteration
1319 
1320  // Hide the inherited begin() and end()
1323  using value_type = Track *;
1324  iterator begin() { return Any().begin(); }
1325  iterator end() { return Any().end(); }
1326  const_iterator begin() const { return Any().begin(); }
1327  const_iterator end() const { return Any().end(); }
1328  const_iterator cbegin() const { return begin(); }
1329  const_iterator cend() const { return end(); }
1330 
1332  template < typename TrackType = Track >
1333  auto Find(Track *pTrack)
1335  {
1336  if (!pTrack || pTrack->GetOwner().get() != this)
1337  return EndIterator<TrackType>();
1338  else
1339  return MakeTrackIterator<TrackType>( pTrack->GetNode() );
1340  }
1341 
1343 
1344  template < typename TrackType = const Track >
1345  auto Find(const Track *pTrack) const
1346  -> typename std::enable_if< std::is_const<TrackType>::value,
1348  >::type
1349  {
1350  if (!pTrack || pTrack->GetOwner().get() != this)
1351  return EndIterator<TrackType>();
1352  else
1353  return MakeTrackIterator<TrackType>( pTrack->GetNode() );
1354  }
1355 
1356  // If the track is not an audio track, or not one of a group of channels,
1357  // return the track itself; else return the first channel of its group --
1358  // in either case as an iterator that will only visit other leader tracks.
1359  // (Generalizing away from the assumption of at most stereo)
1360  TrackIter< Track > FindLeader( Track *pTrack );
1361 
1363  FindLeader( const Track *pTrack ) const
1364  {
1365  return const_cast<TrackList*>(this)->
1366  FindLeader( const_cast<Track*>(pTrack) ).Filter< const Track >();
1367  }
1368 
1369 
1370  template < typename TrackType = Track >
1371  auto Any()
1373  {
1374  return Tracks< TrackType >();
1375  }
1376 
1377  template < typename TrackType = const Track >
1378  auto Any() const
1379  -> typename std::enable_if< std::is_const<TrackType>::value,
1380  TrackIterRange< TrackType >
1381  >::type
1382  {
1383  return Tracks< TrackType >();
1384  }
1385 
1386  // Abbreviating some frequently used cases
1387  template < typename TrackType = Track >
1388  auto Selected()
1390  {
1391  return Tracks< TrackType >( &Track::IsSelected );
1392  }
1393 
1394  template < typename TrackType = const Track >
1395  auto Selected() const
1396  -> typename std::enable_if< std::is_const<TrackType>::value,
1397  TrackIterRange< TrackType >
1398  >::type
1399  {
1400  return Tracks< TrackType >( &Track::IsSelected );
1401  }
1402 
1403 
1404  template < typename TrackType = Track >
1405  auto Leaders()
1407  {
1408  return Tracks< TrackType >( &Track::IsLeader );
1409  }
1410 
1411  template < typename TrackType = const Track >
1412  auto Leaders() const
1413  -> typename std::enable_if< std::is_const<TrackType>::value,
1414  TrackIterRange< TrackType >
1415  >::type
1416  {
1417  return Tracks< TrackType >( &Track::IsLeader );
1418  }
1419 
1420 
1421  template < typename TrackType = Track >
1424  {
1425  return Tracks< TrackType >( &Track::IsSelectedLeader );
1426  }
1427 
1428  template < typename TrackType = const Track >
1429  auto SelectedLeaders() const
1430  -> typename std::enable_if< std::is_const<TrackType>::value,
1431  TrackIterRange< TrackType >
1432  >::type
1433  {
1434  return Tracks< TrackType >( &Track::IsSelectedLeader );
1435  }
1436 
1437 
1438  template<typename TrackType>
1439  static auto SingletonRange( TrackType *pTrack )
1441  {
1442  return pTrack->GetOwner()->template Any<TrackType>()
1443  .StartingWith( pTrack ).EndingAfter( pTrack );
1444  }
1445 
1446 
1448  SyncLockGroup( Track *pTrack );
1449 
1451  SyncLockGroup( const Track *pTrack )
1452  {
1453  return SyncLockGroup(const_cast<Track*>(pTrack)).Filter<const Track>();
1454  }
1455 
1456 private:
1457  Track *DoAddToHead(const std::shared_ptr<Track> &t);
1458  Track *DoAdd(const std::shared_ptr<Track> &t);
1459 
1460  template< typename TrackType, typename InTrackType >
1463  {
1464  // Assume iterator filters leader tracks
1465  if (*iter1) {
1466  return {
1467  iter1.Filter( &Track::Any )
1468  .template Filter<TrackType>(),
1469  (++iter1).Filter( &Track::Any )
1470  .template Filter<TrackType>()
1471  };
1472  }
1473  else
1474  // empty range
1475  return {
1476  iter1.template Filter<TrackType>(),
1477  iter1.template Filter<TrackType>()
1478  };
1479  }
1480 
1481 public:
1482  // Find an iterator range of channels including the given track.
1483  template< typename TrackType >
1484  static auto Channels( TrackType *pTrack )
1486  {
1487  return Channels_<TrackType>( pTrack->GetOwner()->FindLeader(pTrack) );
1488  }
1489 
1490  friend class Track;
1491 
1493  void Permute(const std::vector<TrackNodePointer> &permutation);
1494 
1495  Track *FindById( TrackId id );
1496 
1498  template<typename TrackKind>
1499  TrackKind *AddToHead( const std::shared_ptr< TrackKind > &t )
1500  { return static_cast< TrackKind* >( DoAddToHead( t ) ); }
1501 
1502  template<typename TrackKind>
1503  TrackKind *Add( const std::shared_ptr< TrackKind > &t )
1504  { return static_cast< TrackKind* >( DoAdd( t ) ); }
1505 
1507  void UnlinkChannels(Track& track);
1516  bool MakeMultiChannelTrack(Track& first, int nChannels, bool aligned);
1517 
1520  ListOfTracks::value_type Replace(
1521  Track * t, const ListOfTracks::value_type &with);
1522 
1525 
1527  void Clear(bool sendEvent = true);
1528 
1529  bool CanMoveUp(Track * t) const;
1530  bool CanMoveDown(Track * t) const;
1531 
1532  bool MoveUp(Track * t);
1533  bool MoveDown(Track * t);
1534  bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); }
1535 
1537  bool Contains(const Track * t) const;
1538 
1539  // Return non-null only if the weak pointer is not, and the track is
1540  // owned by this list; constant time.
1541  template <typename Subclass>
1542  std::shared_ptr<Subclass> Lock(const std::weak_ptr<Subclass> &wTrack)
1543  {
1544  auto pTrack = wTrack.lock();
1545  if (pTrack) {
1546  auto pList = pTrack->mList.lock();
1547  if (pTrack && this == pList.get())
1548  return pTrack;
1549  }
1550  return {};
1551  }
1552 
1553  bool empty() const;
1554  size_t size() const;
1555 
1556  double GetStartTime() const;
1557  double GetEndTime() const;
1558 
1559  double GetMinOffset() const;
1560 
1561 private:
1562 
1563  // Visit all tracks satisfying a predicate, mutative access
1564  template <
1565  typename TrackType = Track,
1566  typename Pred =
1568  >
1569  auto Tracks( const Pred &pred = {} )
1571  {
1572  auto b = getBegin(), e = getEnd();
1573  return { { b, b, e, pred }, { b, e, e, pred } };
1574  }
1575 
1576  // Visit all tracks satisfying a predicate, const access
1577  template <
1578  typename TrackType = const Track,
1579  typename Pred =
1581  >
1582  auto Tracks( const Pred &pred = {} ) const
1583  -> typename std::enable_if< std::is_const<TrackType>::value,
1585  >::type
1586  {
1587  auto b = const_cast<TrackList*>(this)->getBegin();
1588  auto e = const_cast<TrackList*>(this)->getEnd();
1589  return { { b, b, e, pred }, { b, e, e, pred } };
1590  }
1591 
1592  Track *GetPrev(Track * t, bool linked = false) const;
1593  Track *GetNext(Track * t, bool linked = false) const;
1594 
1595  std::pair<Track *, Track *> FindSyncLockGroup(Track *pMember) const;
1596 
1597  template < typename TrackType >
1600  {
1601  auto b = const_cast<TrackList*>(this)->getBegin();
1602  auto e = const_cast<TrackList*>(this)->getEnd();
1603  return { b, iter, e };
1604  }
1605 
1606  template < typename TrackType >
1608  EndIterator() const
1609  {
1610  auto e = const_cast<TrackList*>(this)->getEnd();
1611  return { e, e, e };
1612  }
1613 
1614  TrackIterRange< Track > EmptyRange() const;
1615 
1616  bool isNull(TrackNodePointer p) const
1617  { return (p.second == this && p.first == ListOfTracks::end())
1618  || (p.second == &mPendingUpdates && p.first == mPendingUpdates.end()); }
1620  { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
1621  const_cast<TrackList*>(this)}; }
1623  { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
1624  const_cast<TrackList*>(this)}; }
1625 
1628  {
1629  if ( isNull(p) )
1630  return p;
1631  auto q = p;
1632  ++q.first;
1633  return q;
1634  }
1635 
1638  {
1639  if (p == getBegin())
1640  return getEnd();
1641  else {
1642  auto q = p;
1643  --q.first;
1644  return q;
1645  }
1646  }
1647 
1648  void RecalcPositions(TrackNodePointer node);
1649  void SelectionEvent( const std::shared_ptr<Track> &pTrack );
1650  void PermutationEvent(TrackNodePointer node);
1651  void DataEvent( const std::shared_ptr<Track> &pTrack, int code );
1652  void EnsureVisibleEvent(
1653  const std::shared_ptr<Track> &pTrack, bool modifyState );
1654  void DeletionEvent(TrackNodePointer node = {});
1655  void AdditionEvent(TrackNodePointer node);
1656  void ResizingEvent(TrackNodePointer node);
1657 
1658  void SwapNodes(TrackNodePointer s1, TrackNodePointer s2);
1659 
1660  // Nondecreasing during the session.
1661  // Nonpersistent.
1662  // Used to assign ids to added tracks.
1663  static long sCounter;
1664 
1665 public:
1666  using Updater = std::function< void(Track &dest, const Track &src) >;
1667  // Start a deferred update of the project.
1668  // The return value is a duplicate of the given track.
1669  // While ApplyPendingTracks or ClearPendingTracks is not yet called,
1670  // there may be other direct changes to the project that push undo history.
1671  // Meanwhile the returned object can accumulate other changes for a deferred
1672  // push, and temporarily shadow the actual project track for display purposes.
1673  // The Updater function, if not null, merges state (from the actual project
1674  // into the pending track) which is not meant to be overridden by the
1675  // accumulated pending changes.
1676  // To keep the display consistent, the Y and Height values, minimized state,
1677  // and Linked state must be copied, and this will be done even if the
1678  // Updater does not do it.
1679  // Pending track will have the same TrackId as the actual.
1680  // Pending changed tracks will not occur in iterations.
1681  std::shared_ptr<Track> RegisterPendingChangedTrack(
1682  Updater updater,
1683  Track *src
1684  );
1685 
1686  // Like the previous, but for a NEW track, not a replacement track. Caller
1687  // supplies the track, and there are no updates.
1688  // Pending track will have an unassigned TrackId.
1689  // Pending changed tracks WILL occur in iterations, always after actual
1690  // tracks, and in the sequence that they were added. They can be
1691  // distinguished from actual tracks by TrackId.
1692  void RegisterPendingNewTrack( const std::shared_ptr<Track> &pTrack );
1693 
1694  // Invoke the updaters of pending tracks. Pass any exceptions from the
1695  // updater functions.
1696  void UpdatePendingTracks();
1697 
1698  // Forget pending track additions and changes;
1699  // if requested, give back the pending added tracks.
1700  void ClearPendingTracks( ListOfTracks *pAdded = nullptr );
1701 
1702  // Change the state of the project.
1703  // Strong guarantee for project state in case of exceptions.
1704  // Will always clear the pending updates.
1705  // Return true if the state of the track list really did change.
1706  bool ApplyPendingTracks();
1707 
1708  bool HasPendingTracks() const;
1709 
1710 private:
1712 
1714 
1717  std::vector< Updater > mUpdaters;
1718 };
1719 
1720 #endif
XMLWriter
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:23
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
TrackList::isNull
bool isNull(TrackNodePointer p) const
Definition: Track.h:1616
track_kind
constexpr TrackKind track_kind()
Metafunction from track subtype (as template parameter) to enum value.
Definition: Track.h:137
Init
Definition: ModuleManager.h:152
WaveTrackArray
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:48
TrackIntervalData::~TrackIntervalData
virtual ~TrackIntervalData()
ConstTrackInterval::operator=
ConstTrackInterval & operator=(ConstTrackInterval &&)=default
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:49
Track::SharedPointer
auto SharedPointer() const -> typename std::enable_if< std::is_const< Subclass >::value, std::shared_ptr< Subclass > >::type
Definition: Track.h:299
TrackTyper
Metaprogramming enabling track_cast even when the subclasses are incomplete types.
Definition: Track.h:105
TrackList::EndIterator
TrackIter< TrackType > EndIterator() const
Definition: Track.h:1608
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
Track::GetDefaultName
wxString GetDefaultName() const
Definition: Track.h:428
Track::SetId
void SetId(TrackId id)
Definition: Track.h:283
Track::Continuation
std::function< R() > Continuation
Type of arguments passed as optional second parameter to TypeSwitch() cases.
Definition: Track.h:502
PlayableTrack::PlayableTrack
PlayableTrack(const Track &orig)
Definition: Track.h:858
TrackList::Selected
auto Selected() const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIterRange< TrackType > >::type
Definition: Track.h:1395
PlayableTrack::GetSolo
bool GetSolo() const
Definition: Track.h:861
Track::mSelected
bool mSelected
Definition: Track.h:267
PlayableTrack::GetMute
bool GetMute() const
Definition: Track.h:860
TrackKind::None
@ None
no class
ConstTrackInterval::ConstTrackInterval
ConstTrackInterval(double start, double end, std::unique_ptr< TrackIntervalData > pExtra={})
Definition: Track.h:196
flag
static std::once_flag flag
Definition: WaveformView.cpp:1119
TrackList::getEnd
TrackNodePointer getEnd() const
Definition: Track.h:1619
Track::GetEndTime
virtual double GetEndTime() const =0
TrackList::Lock
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1542
Track::ConstIntervals
std::vector< ConstInterval > ConstIntervals
Definition: Track.h:331
TrackIter
Iterator over only members of a TrackList of the specified subtype, optionally filtered by a predicat...
Definition: Track.h:933
TrackId::operator==
bool operator==(const TrackId &other) const
Definition: Track.h:170
TrackList::SelectedLeaders
auto SelectedLeaders() const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIterRange< TrackType > >::type
Definition: Track.h:1429
TrackKind::Playable
@ Playable
nonleaf
TrackIter::GetPredicate
const FunctionType & GetPredicate() const
Definition: Track.h:986
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1484
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1280
ConstTrackInterval::End
double End() const
Definition: Track.h:207
TrackId::operator!=
bool operator!=(const TrackId &other) const
Definition: Track.h:173
Track::Dispatcher::Switch< R, ConcreteType >::test
static auto test() -> inapplicable< R, ConcreteType, Function, Functions... >
No BaseClass of ConcreteType is acceptable to Function.
TrackIntervalData
Optional extra information about an interval, appropriate to a subtype of Track.
Definition: Track.h:186
Track::Merge
virtual void Merge(const Track &orig)
Definition: Track.cpp:107
operator==
bool operator==(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:61
TrackList::Leaders
auto Leaders() const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIterRange< TrackType > >::type
Definition: Track.h:1412
Track::SharedPointer
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:291
Track::Cut
virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1))=0
IteratorRange
A convenience for use with range-for.
Definition: MemoryX.h:380
TrackListEvent::TrackListEvent
TrackListEvent(wxEventType commandType, const std::weak_ptr< Track > &pTrack={}, int code=-1)
Definition: Track.h:1224
Track::Dispatcher::applicable1
Second, nonrecursive case of metafunction, generates operator () that calls function without fallthro...
Definition: Track.h:535
TrackList::Tracks
auto Tracks(const Pred &pred={}) const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIterRange< TrackType > >::type
Definition: Track.h:1582
NoteTrackConstArray
std::vector< std::shared_ptr< const NoteTrack > > NoteTrackConstArray
Definition: MIDIPlay.cpp:370
Track::InsertSilence
virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len))=0
TrackId::mValue
long mValue
Definition: Track.h:182
TrackList::TrackList
TrackList(TrackList &&that)=delete
Track::GetOwner
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:379
ClientData::Base
A convenient default parameter for class template Site.
Definition: ClientData.h:28
TrackTyper::Lookup< TrackType, std::tuple< NotHere, Rest... > >::value
static constexpr TrackKind value()
Definition: Track.h:130
TrackList::Add
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1503
TrackList::Find
auto Find(Track *pTrack) -> TrackIter< TrackType >
Turn a pointer into a TrackIter (constant time); get end iterator if this does not own the track.
Definition: Track.h:1333
Track::SetPanFromChannelType
virtual void SetPanFromChannelType()
Definition: Track.h:448
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
TrackIterRange::VisitWhile
void VisitWhile(Flag &flag, const Functions &...functions)
See Track::TypeSwitch.
Definition: Track.h:1209
Track::Paste
virtual void Paste(double WXUNUSED(t), const Track *WXUNUSED(src))=0
AudioTrack::HandleXMLAttribute
bool HandleXMLAttribute(const wxChar *, const wxChar *)
Definition: Track.h:848
Track::Any
bool Any() const
Definition: Track.cpp:370
Track::SharedPointer
static std::shared_ptr< Subclass > SharedPointer(Track *pTrack)
Definition: Track.h:311
AudioTrack::AudioTrack
AudioTrack(const Track &orig)
Definition: Track.h:842
Track::SetOffset
virtual void SetOffset(double o)
Definition: Track.h:445
TrackInterval
A start and an end time, and mutative access to optional extra information.
Definition: Track.h:219
TrackIterRange::TrackIterRange
TrackIterRange(const TrackIter< TrackType > &begin, const TrackIter< TrackType > &end)
Definition: Track.h:1103
ClientData.h
Utility ClientData::Site to register hooks into a host class that attach client data.
TrackInterval::Extra
TrackIntervalData * Extra() const
Definition: Track.h:226
TrackList::SelectedLeaders
auto SelectedLeaders() -> TrackIterRange< TrackType >
Definition: Track.h:1422
Track::Dispatcher::inapplicable
First, recursive case of metafunction, defers generation of operator ()
Definition: Track.h:518
Track::Dispatcher::Switch< R, ConcreteType, BaseClass, BaseClasses... >::test
static auto test() -> decltype(test< Function, Functions... >((std::integral_constant< bool, Compatible > *) nullptr))
undefined function used in decltype only to compute a type, using other overloads
Track::mDefaultName
wxString mDefaultName
Definition: Track.h:264
RefreshCode::EnsureVisible
@ EnsureVisible
Definition: RefreshCode.h:31
Track::mpControls
std::shared_ptr< CommonTrackCell > mpControls
Definition: Track.h:833
TrackList::MakeTrackIterator
TrackIter< TrackType > MakeTrackIterator(TrackNodePointer iter) const
Definition: Track.h:1599
ClientData::SkipCopying
@ SkipCopying
ignore the source and leave empty
Definition: ClientDataHelpers.h:34
TrackIterRange::Filter
TrackIterRange< TrackType2 > Filter() const
Definition: Track.h:1155
TrackListEvent::TrackListEvent
TrackListEvent(const TrackListEvent &)=default
TrackIter::TrackIter
TrackIter(TrackNodePointer begin, TrackNodePointer iter, TrackNodePointer end, FunctionType pred={})
Constructor, usually not called directly except by methods of TrackList.
Definition: Track.h:948
TrackList::end
iterator end()
Definition: Track.h:1325
TrackKind::All
@ All
the root class
TrackIterRange::Excluding
TrackIterRange Excluding(const TrackType *pExcluded) const
Definition: Track.h:1192
TrackIter::mPred
FunctionType mPred
Optional filter
Definition: Track.h:1093
PlayableTrack::GetNotMute
bool GetNotMute() const
Definition: Track.h:862
TrackList::Move
bool Move(Track *t, bool up)
Definition: Track.h:1534
Track::mName
wxString mName
Definition: Track.h:263
TrackList::end
const_iterator end() const
Definition: Track.h:1327
Track::GetStartTime
virtual double GetStartTime() const =0
Track::Dispatcher::Switch< R, ConcreteType, BaseClass, BaseClasses... >::test
static auto test(std::true_type *) -> decltype((void) std::declval< Function >()((BaseClass *) nullptr, std::declval< Continuation< R > >()), applicable2< R, BaseClass, ConcreteType, Function, Functions... >
overload when upcast of ConcreteType* works, with sfinae'd return type
Definition: Track.h:617
TrackList::cend
const_iterator cend() const
Definition: Track.h:1329
TrackList::mUpdaters
std::vector< Updater > mUpdaters
This is in correspondence with mPendingUpdates.
Definition: Track.h:1717
Track::GetErrorOpening
virtual bool GetErrorOpening()
Definition: Track.h:799
Track::Track
Track()
Definition: Track.cpp:49
TrackId::operator<
bool operator<(const TrackId &other) const
Definition: Track.h:178
TrackList::mPendingUpdates
ListOfTracks mPendingUpdates
Shadow tracks holding append-recording in progress; need to put them into a list so that GetLink() wo...
Definition: Track.h:1715
Track::mList
std::weak_ptr< TrackList > mList
Definition: Track.h:258
TrackList::Updater
std::function< void(Track &dest, const Track &src) > Updater
Definition: Track.h:1666
AudioTrack::WriteXMLAttributes
void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const
Definition: Track.h:845
XMLTagHandler.h
Track::mId
TrackId mId
Identifies the track only in-session, not persistently.
Definition: Track.h:254
TrackIter::operator++
TrackIter & operator++()
Safe to call even when at the end.
Definition: Track.h:991
Track::GetId
TrackId GetId() const
Definition: Track.h:281
TrackKind::Time
@ Time
TrackListEvent
Notification of changes in individual tracks of TrackList, or of TrackList's composition.
Definition: Track.h:1222
TrackIter::valid
bool valid() const
Test satisfaction of the invariant, while initializing, incrementing, or decrementing.
Definition: Track.h:1077
Track::Offset
void Offset(double t)
Definition: Track.h:444
TrackKind::Audio
@ Audio
nonleaf
TrackIter::operator!=
friend bool operator!=(TrackIter a, TrackIter b)
Compares only current positions, assuming same beginnings and ends.
Definition: Track.h:1066
Track::Holder
std::shared_ptr< Track > Holder
Definition: Track.h:336
BasicUI::Get
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:26
Track::SetDefaultName
void SetDefaultName(const wxString &n)
Definition: Track.h:429
TrackList::mOwner
AudacityProject * mOwner
Definition: Track.h:1711
TrackIter::advance
TrackIter advance(long amount) const
This might be called operator + , but it's not constant-time as with a random access iterator.
Definition: Track.h:1045
operator!=
bool operator!=(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:64
TrackList::begin
iterator begin()
Definition: Track.h:1324
TrackIter::operator==
friend bool operator==(TrackIter a, TrackIter b)
Compares only current positions, assuming same beginnings and ends.
Definition: Track.h:1055
TrackIter::FunctionType
std::function< bool(typename std::add_pointer< typename std::add_const< typename std::remove_pointer< TrackType >::type >::type >::type) > FunctionType
Type of predicate taking pointer to const TrackType.
Definition: Track.h:945
ListOfTracks
std::list< std::shared_ptr< Track > > ListOfTracks
Definition: Track.h:53
TrackList::FindLeader
TrackIter< const Track > FindLeader(const Track *pTrack) const
Definition: Track.h:1363
Track::SameKindAs
bool SameKindAs(const Track &track) const
Definition: Track.h:497
TrackIter::Filter
auto Filter() const -> typename std::enable_if< std::is_base_of< TrackType, TrackType2 >::value &&(!std::is_const< TrackType >::value||std::is_const< TrackType2 >::value), TrackIter< TrackType2 > >::type
Return an iterator for a subclass of TrackType (and not removing const) with same predicate.
Definition: Track.h:975
Track::Silence
virtual void Silence(double WXUNUSED(t0), double WXUNUSED(t1))=0
Track::GetOffset
virtual double GetOffset() const =0
TrackTyper::Lookup
Variadic template implements metafunction with specializations, to associate enum values with types.
Definition: Track.h:119
Track::mpView
std::shared_ptr< CommonTrackCell > mpView
Definition: Track.h:832
TrackNodePointer
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Pairs a std::list iterator and a pointer to a list, for comparison purposes.
Definition: Track.h:59
TrackList::AddToHead
TrackKind * AddToHead(const std::shared_ptr< TrackKind > &t)
Add a Track, giving it a fresh id.
Definition: Track.h:1499
Track::GetKind
virtual TrackKind GetKind() const
Definition: Track.h:483
AudioTrack
Track subclass holding data representing sound (as notes, or samples, or ...)
Definition: Track.h:838
ConstTrackInterval
A start and an end time, and non-mutative access to optional extra information.
Definition: Track.h:192
Track::Clone
virtual Holder Clone() const =0
TrackIterRange::operator-
TrackIterRange operator-(const Predicate2 &pred2) const
Definition: Track.h:1138
ClientData::Site
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:220
CompatibleTrackKinds
constexpr bool CompatibleTrackKinds(TrackKind desired, TrackKind actual)
Compile-time function on enum values.
Definition: Track.h:83
wxDECLARE_EXPORTED_EVENT
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_TRACKLIST_SELECTION_CHANGE, TrackListEvent)
Posted when the set of selected tracks changes.
Track::Fallthrough
Continuation<> Fallthrough
Type of arguments passed as optional second parameter to TypeSwitch<void>() cases.
Definition: Track.h:504
Track::IsSelected
bool IsSelected() const
Definition: Track.cpp:373
TrackTyper::Lookup< TrackType, std::tuple< Pair< TrackType, Here >, Rest... > >::value
static constexpr TrackKind value()
Definition: Track.h:123
TrackIter::Filter
TrackIter Filter(const Predicate2 &pred2) const
Return an iterator that replaces the predicate.
Definition: Track.h:966
TrackList::GetOwner
const AudacityProject * GetOwner() const
Definition: Track.h:1316
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
TrackList::Any
auto Any() const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIterRange< TrackType > >::type
Definition: Track.h:1378
TrackId::TrackId
TrackId()
Definition: Track.h:167
ConstTrackInterval::Extra
const TrackIntervalData * Extra() const
Definition: Track.h:208
Track::IsSelectedLeader
bool IsSelectedLeader() const
Definition: Track.cpp:384
TrackIter::operator--
TrackIter & operator--()
Safe to call even when at the beginning.
Definition: Track.h:1010
Track::Dispatcher::Switch< R, ConcreteType, BaseClass, BaseClasses... >::test
static auto test(const void *) -> decltype(Retry::template test< Function, Functions... >())
Catch-all overload of undefined function used in decltype only.
PlayableTrack::GetNotSolo
bool GetNotSolo() const
Definition: Track.h:863
Track::SetPan
virtual void SetPan(float)
Definition: Track.h:447
TrackIterRange
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:1101
PlayableTrack
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:854
TrackListEvent::Clone
wxEvent * Clone() const override
Definition: Track.h:1234
TrackList::getBegin
TrackNodePointer getBegin() const
Definition: Track.h:1622
anonymous_namespace{ProjectSettings.cpp}::Notify
void Notify(AudacityProject &project, ProjectSettings::EventCode code, long previousValue)
Definition: ProjectSettings.cpp:25
TrackList::TrackList
TrackList(const TrackList &that)=delete
TrackTyper::List
std::tuple< Pair< Track, TrackKind::All >, Pair< AudioTrack, TrackKind::Audio >, Pair< PlayableTrack, TrackKind::Playable >, Pair< LabelTrack, TrackKind::Label >, Pair< NoteTrack, TrackKind::Note >, Pair< TimeTrack, TrackKind::Time >, Pair< WaveTrack, TrackKind::Wave > > List
Compile-time map from types to enum values.
Definition: Track.h:117
XMLTagHandler
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:62
Track::GetSelected
bool GetSelected() const
Definition: Track.h:431
Track::Intervals
std::vector< Interval > Intervals
Definition: Track.h:329
AudioTrack::AudioTrack
AudioTrack()
Definition: Track.h:840
Track::mIndex
int mIndex
0-based position of this track in its TrackList
Definition: Track.h:262
TrackIterRange::StartingWith
TrackIterRange StartingWith(const Track *pTrack) const
Definition: Track.h:1163
ConstTrackInterval::end
double end
Definition: Track.h:211
TrackKind
TrackKind
Enumerates all subclasses of Track (not just the leaf classes) and the None value.
Definition: Track.h:69
TrackList::GetOwner
AudacityProject * GetOwner()
Definition: Track.h:1315
id
int id
Definition: WaveTrackControls.cpp:577
TrackList::clear
void clear()=delete
ConstTrackInterval::pExtra
std::unique_ptr< TrackIntervalData > pExtra
Definition: Track.h:214
Track::WriteXML
virtual void WriteXML(XMLWriter &xmlFile) const =0
Track::TypeSwitch
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:709
TrackId
An in-session identifier of track objects across undo states. It does not persist between sessions.
Definition: Track.h:165
TrackList::begin
const_iterator begin() const
Definition: Track.h:1326
TrackArray
std::vector< Track * > TrackArray
Definition: Track.h:45
AttachedTrackObjects
ClientData::Site< Track, ClientData::Base, ClientData::SkipCopying, std::shared_ptr > AttachedTrackObjects
Template generated base class for Track lets it host opaque UI related objects.
Definition: Track.h:232
TrackList::Leaders
auto Leaders() -> TrackIterRange< TrackType >
Definition: Track.h:1405
TrackList::sCounter
static long sCounter
Definition: Track.h:1663
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
Track::IsLeader
bool IsLeader() const
Definition: Track.cpp:379
Track::ChannelType
ChannelType
Definition: Track.h:275
Track::SharedPointer
static std::shared_ptr< Subclass > SharedPointer(const Track *pTrack)
Definition: Track.h:315
Track::Init
void Init(const Track &orig)
Definition: Track.cpp:70
TrackInterval::operator=
TrackInterval & operator=(TrackInterval &&)=default
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
TrackKind::Wave
@ Wave
TrackList::Find
auto Find(const Track *pTrack) const -> typename std::enable_if< std::is_const< TrackType >::value, TrackIter< TrackType > >::type
Turn a pointer into a TrackIter (constant time); get end iterator if this does not own the track.
Definition: Track.h:1345
TrackList::getNext
TrackNodePointer getNext(TrackNodePointer p) const
Move an iterator to the next node, if any; else stay at end.
Definition: Track.h:1627
ValueIterator
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
Definition: MemoryX.h:366
anonymous_namespace{EditMenus.cpp}::FinishCopy
void FinishCopy(const Track *n, const Track::Holder &dest, TrackList &list)
Definition: EditMenus.cpp:33
Track::GetChannel
virtual ChannelType GetChannel() const
Definition: Track.h:441
TrackList::getPrev
TrackNodePointer getPrev(TrackNodePointer p) const
Move an iterator to the previous node, if any; else wrap to end.
Definition: Track.h:1637
TrackInterval::TrackInterval
TrackInterval(TrackInterval &&)=default
TrackIterRange::Visit
void Visit(const Functions &...functions)
See Track::TypeSwitch.
Definition: Track.h:1200
Track::HasOwner
bool HasOwner() const
Definition: Track.h:377
Track::Clear
virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1))=0
TrackIterRange::operator+
TrackIterRange operator+(const Predicate2 &pred2) const
Definition: Track.h:1112
TrackList::Tracks
auto Tracks(const Pred &pred={}) -> TrackIterRange< TrackType >
Definition: Track.h:1569
TrackList::Channels_
static TrackIterRange< TrackType > Channels_(TrackIter< InTrackType > iter1)
Definition: Track.h:1462
TrackList::SyncLockGroup
static TrackIterRange< const Track > SyncLockGroup(const Track *pTrack)
Definition: Track.h:1451
ConstTrackInterval::start
double start
Definition: Track.h:211
TrackKind::Label
@ Label
TrackListEvent::mCode
int mCode
Definition: Track.h:1239
TrackIter::operator*
TrackType * operator*() const
Safe to call even when at the end.
Definition: Track.h:1033
TrackId::TrackId
TrackId(long value)
Definition: Track.h:168
TrackListEvent::mpTrack
std::weak_ptr< Track > mpTrack
Definition: Track.h:1238
PlayableTrack::PlayableTrack
PlayableTrack()
Definition: Track.h:856
ConstTrackInterval::Start
double Start() const
Definition: Track.h:206
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1371
TrackList::SingletonRange
static auto SingletonRange(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1439
ActiveProjects::Remove
void Remove(const FilePath &path)
TrackIter::mEnd
TrackNodePointer mEnd
Allows end of iteration to be detected without comparison to other TrackIter.
Definition: Track.h:1092
Track::TypeSwitch
R TypeSwitch(const Functions &...functions) const
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:755
safenew
#define safenew
Definition: MemoryX.h:10
Track::Copy
virtual Holder Copy(double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard=true) const =0
TrackList::cbegin
const_iterator cbegin() const
Definition: Track.h:1328
TrackIterRange::EndingAfter
TrackIterRange EndingAfter(const Track *pTrack) const
Definition: Track.h:1177
Track::LinkType
LinkType
For two tracks describes the type of the linkage.
Definition: Track.h:243
Track::Dispatcher::Switch< R, ConcreteType, BaseClass, BaseClasses... >::test
static auto test(std::true_type *) -> decltype((void) std::declval< Function >()((BaseClass *) nullptr), applicable1< R, BaseClass, ConcreteType, Function, Functions... >
overload when upcast of ConcreteType* works, with sfinae'd return type
Definition: Track.h:603
Track::Dispatcher
Helper for recursive case of metafunction implementing Track::TypeSwitch.
Definition: Track.h:513
Track::PasteInto
virtual Holder PasteInto(AudacityProject &) const =0
Find or create the destination track for a paste, maybe in a different project.
track_cast
std::enable_if< std::is_pointer< T >::value, T >::type track_cast(Track *track)
Encapsulate the checked down-casting of track pointers.
Definition: Track.h:891
TrackIter::mBegin
TrackNodePointer mBegin
Allows end of reverse iteration to be detected without comparison to other TrackIter.
Definition: Track.h:1090
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1388
TrackIter::mIter
TrackNodePointer mIter
Current position.
Definition: Track.h:1091
SampleFormat.h
TimeTrack
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
TrackTyper::Pair
Definition: Track.h:106
TrackKind::Note
@ Note
Track::Dispatcher::Switch
Variadic template implements metafunction with specializations, to choose among implementations of op...
Definition: Track.h:569
Track::Executor
Variadic template implements metafunction with specializations, to dispatch Track::TypeSwitch.
Definition: Track.h:509
CommonTrackCell
Definition: CommonTrackPanelCell.h:99
Track::Dispatcher::applicable2
Third, recursive case of metafunction, generates operator () that calls function with fallthrough.
Definition: Track.h:550
ProjectSettings
Holds various per-project settings values, and sends events to the project when certain values change...
Definition: ProjectSettings.h:60
Track::vrulerSize
wxSize vrulerSize
Definition: Track.h:354