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