Audacity 3.2.0
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#ifndef __AUDACITY_TRACK__
12#define __AUDACITY_TRACK__
13
14#include <algorithm>
15#include <atomic>
16#include <utility>
17#include <list>
18#include <optional>
19#include <functional>
20#include <wx/longlong.h>
21
22#include "Channel.h"
23#include "Observer.h"
24// TrackAttachment needs to be a complete type for the Windows build, though
25// not the others, so there is a nested include here:
26#include "TrackAttachment.h"
27#include "TypeEnumerator.h"
28#include "TypeSwitch.h"
29#include "XMLTagHandler.h"
30
31#ifdef __WXMSW__
32#pragma warning(disable:4284)
33#endif
34
35class wxTextFile;
36class Track;
37class AudacityProject;
38
39using TrackArray = std::vector< Track* >;
40
41class TrackList;
42using TrackListHolder = std::shared_ptr<TrackList>;
43struct UndoStackElem;
44
45using ListOfTracks = std::list< std::shared_ptr< Track > >;
46
48
51std::pair< ListOfTracks::iterator, ListOfTracks* >;
52
53using ProgressReporter = std::function<void(double)>;
54
55inline bool operator == (const TrackNodePointer &a, const TrackNodePointer &b)
56{ return a.second == b.second && a.first == b.first; }
57
58inline bool operator != (const TrackNodePointer &a, const TrackNodePointer &b)
59{ return !(a == b); }
60
62BEGIN_TYPE_ENUMERATION(TrackTypeTag)
63
64
66
67#define ENUMERATE_TRACK_TYPE(T) ENUMERATE_TYPE(TrackTypeTag, T)
68
69// forward declarations, so we can make them friends
70template<typename T>
71 std::enable_if_t< std::is_pointer_v<T>, T >
72 track_cast(Track *track);
73
74template<typename T>
75 std::enable_if_t<
76 std::is_pointer_v<T> &&
77 std::is_const_v< std::remove_pointer_t< T > >,
78 T
79 >
80 track_cast(const Track *track);
81
83
91{
92public:
93 TrackId() : mValue(-1) {}
94 explicit TrackId (long value) : mValue(value) {}
95
96 bool operator == (const TrackId &other) const
97 { return mValue == other.mValue; }
98
99 bool operator != (const TrackId &other) const
100 { return mValue != other.mValue; }
101
102 // Define this in case you want to key a std::map on TrackId
103 // The operator does not mean anything else
104 bool operator < (const TrackId &other) const
105 { return mValue < other.mValue; }
106
107private:
108 long mValue;
109};
110
114>;
115
117class TRACK_API Track /* not final */
118 : public XMLTagHandler
119 , public AttachedTrackObjects
120 , public std::enable_shared_from_this<Track> // see SharedPointer()
121 , public ChannelGroup
122{
123protected:
125
130
131private:
132
133 friend class TrackList;
134
135 private:
137
138 protected:
139 std::weak_ptr<TrackList> mList;
141
143 int mIndex;
144
145 public:
146
149
150 TrackId GetId() const { return mId; }
151 private:
152 void SetId( TrackId id ) { mId = id; }
153 public:
154
155 // Given a bare pointer, find a shared_ptr. Undefined results if the track
156 // is not yet managed by a shared_ptr. Undefined results if the track is
157 // not really of the subclass. (That is, trusts the caller and uses static
158 // not dynamic casting.)
159 template<typename Subclass = Track>
160 inline std::shared_ptr<Subclass> SharedPointer()
161 {
162 // shared_from_this is injected into class scope by base class
163 // std::enable_shared_from_this<Track>
164 return std::static_pointer_cast<Subclass>( shared_from_this() );
165 }
166
167 template<typename Subclass = const Track>
168 inline auto SharedPointer() const ->
169 std::enable_if_t<
170 std::is_const_v<Subclass>, std::shared_ptr<Subclass>
171 >
172 {
173 // shared_from_this is injected into class scope by base class
174 // std::enable_shared_from_this<Track>
175 return std::static_pointer_cast<Subclass>( shared_from_this() );
176 }
177
178 // Static overloads of SharedPointer for when the pointer may be null
179 template<typename Subclass = Track>
180 static inline std::shared_ptr<Subclass> SharedPointer( Track *pTrack )
181 { return pTrack ? pTrack->SharedPointer<Subclass>() : nullptr; }
182
183 template<typename Subclass = const Track>
184 static inline std::shared_ptr<Subclass> SharedPointer( const Track *pTrack )
185 { return pTrack ? pTrack->SharedPointer<Subclass>() : nullptr; }
186
187 // Find anything registered with TrackList::RegisterPendingChangedTrack and
188 // not yet cleared or applied; if no such exists, return this track
189 std::shared_ptr<Track> SubstitutePendingChangedTrack();
190 std::shared_ptr<const Track> SubstitutePendingChangedTrack() const;
191
192 // If this track is a pending changed track, return the corresponding
193 // original; else return this track
194 std::shared_ptr<const Track> SubstituteOriginalTrack() const;
195
197
198 struct TypeNames {
199 wxString info;
200 wxString property;
202 };
203 struct TypeInfo {
205 bool concrete = false;
206 const TypeInfo *pBaseInfo = nullptr;
207
208 bool IsBaseOf(const TypeInfo &other) const
209 {
210 for (auto pInfo = &other;
211 pInfo; pInfo = pInfo->pBaseInfo)
212 if (this == pInfo)
213 return true;
214 return false;
215 }
216 };
217 virtual const TypeInfo &GetTypeInfo() const = 0;
218 static const TypeInfo &ClassTypeInfo();
219 virtual const TypeNames &GetTypeNames() const
220 { return GetTypeInfo().names; }
221
223 virtual bool SupportsBasicEditing() const;
224
225 using Holder = std::shared_ptr<Track>;
226
229
236 const = 0;
237
238public:
240
246 virtual bool LinkConsistencyFix(bool doFix = true);
247
250 { return const_cast<Track*>(this)->LinkConsistencyFix(false); }
251
252 bool HasOwner() const { return static_cast<bool>(GetOwner());}
253
254 std::shared_ptr<TrackList> GetOwner() const { return mList.lock(); }
255 inline TrackList* GetHolder() const;
256
257 LinkType GetLinkType() const noexcept;
258
259 ChannelGroupData &GetGroupData();
261 const ChannelGroupData &GetGroupData() const;
262
263protected:
264
268 void SetLinkType(LinkType linkType, bool completeList = true);
269
270private:
271 int GetIndex() const;
272 void SetIndex(int index);
273
277 void DoSetLinkType(LinkType linkType, bool completeList = true);
278
279 Track* GetLinkedTrack() const;
281 bool HasLinkedTrack() const noexcept;
282
284 TrackNodePointer GetNode() const;
286 void SetOwner
287 (const std::weak_ptr<TrackList> &list, TrackNodePointer node);
288
289 public:
290
291 Track();
292 Track(const Track &orig, ProtectedCreationArg&&);
293 Track& operator =(const Track &orig) = delete;
294
295 virtual ~ Track();
296
297 void Init(const Track &orig);
298
300
304 virtual TrackListHolder Duplicate() const;
305
307 const wxString &GetName() const;
308 void SetName( const wxString &n );
309
311 bool GetSelected() const;
312 virtual void SetSelected(bool s);
313
314public:
315
317
320 void OnProjectTempoChange(double newTempo);
321
323
329 virtual TrackListHolder Cut(double t0, double t1) = 0;
330
332
341 virtual TrackListHolder Copy(double t0, double t1, bool forClipboard = true)
342 const = 0;
343
348 virtual void Clear(double t0, double t1) = 0;
349
351
356 virtual void Paste(double t, const Track &src) = 0;
357
364 void Paste(double t, const TrackList &src);
365
368
371 virtual void SyncLockAdjust(double oldT1, double newT1);
372
373 // May assume precondition: t0 <= t1
377 virtual void
378 Silence(double t0, double t1, ProgressReporter reportProgress = {}) = 0;
379
384 virtual void InsertSilence(double t, double len) = 0;
385
386private:
389
396 virtual TrackListHolder Clone() const = 0;
397
398 template<typename T>
399 friend std::enable_if_t< std::is_pointer_v<T>, T >
400 track_cast(Track *track);
401 template<typename T>
402 friend std::enable_if_t<
403 std::is_pointer_v<T> &&
404 std::is_const_v< std::remove_pointer_t< T > >,
405 T
406 >
407 track_cast(const Track *track);
408
409public:
410 bool SameKindAs(const Track &track) const
411 { return &GetTypeInfo() == &track.GetTypeInfo(); }
412
417 template<typename R = void, typename ...Functions>
418 R TypeSwitch(const Functions &...functions)
419 {
420 struct Here : TrackTypeTag {};
421 // List more derived classes later
422 using TrackTypes =
424 return TypeSwitch::VDispatch<R, TrackTypes>(*this, functions...);
425 }
426
428 template<typename R = void, typename ...Functions>
429 R TypeSwitch(const Functions &...functions) const
430 {
431 struct Here : TrackTypeTag {};
432 // List more derived classes later
433 using namespace TypeList;
434 using TrackTypes = Map_t<Fn<std::add_const_t>,
436 return TypeSwitch::VDispatch<R, TrackTypes>(*this, functions...);
437 }
438
439 // XMLTagHandler callback methods -- NEW virtual for writing
440 virtual void WriteXML(XMLWriter &xmlFile) const = 0;
441
444
448 virtual std::optional<TranslatableString> GetErrorOpening() const;
449
450 // Send a notification to subscribers when state of the track changes
451 // To do: define values for the argument to distinguish different parts
452 // of the state
453 void Notify(bool allChannels, int code = -1);
454
455 // An always-true predicate useful for defining iterators
456 bool Any() const;
457
458 // Frequently useful operands for + and -
459 bool IsSelected() const;
460 bool IsLeader() const override;
461 bool IsSelectedLeader() const;
462
463 // Cause this track and following ones in its TrackList to adjust
464 void AdjustPositions();
465
466 // Serialize, not with tags of its own, but as attributes within a tag.
467 void WriteCommonXMLAttributes(
468 XMLWriter &xmlFile, bool includeNameAndSelected = true) const;
469
470 // Return true iff the attribute is recognized.
471 bool HandleCommonXMLAttribute(const std::string_view& attr, const XMLAttributeValueView& valueView);
472
473 const std::optional<double>& GetProjectTempo() const;
474
475protected:
480 const std::optional<double>& oldTempo, double newTempo) = 0;
481};
482
484
486template<typename Base = Track>
488 : public Base
489 , public Channel
490{
491public:
492 using Base::Base;
493 size_t NChannels() const override { return 1; }
494 std::shared_ptr<Channel> DoGetChannel(size_t iChannel) override
495 {
496 if (iChannel == 0) {
497 // Use aliasing constructor of std::shared_ptr
498 Channel *alias = this;
499 return { this->shared_from_this(), alias };
500 }
501 return {};
502 }
503protected:
504 ChannelGroup &DoGetChannelGroup() const override {
505 const Track &track = *this;
506 return const_cast<Track&>(track);
507 }
508};
509
512{
513public:
514 using Factory =
515 std::function<std::shared_ptr<TrackAttachment>(Track &, size_t)>;
516
519
520 // Override all the TrackAttachment virtuals and pass through to each
521 void CopyTo(Track &track) const override;
522 void Reparent(const std::shared_ptr<Track> &parent) override;
523 void WriteXMLAttributes(XMLWriter &writer) const override;
524 bool HandleXMLAttribute(
525 const std::string_view& attr, const XMLAttributeValueView& valueView)
526 override;
527
528protected:
532 static TrackAttachment &Get(
534 Track &track, size_t iChannel);
538 static TrackAttachment *Find(
540 Track *pTrack, size_t iChannel);
541
542private:
544 std::vector<std::shared_ptr<TrackAttachment>> mAttachments;
545};
546
548template<typename Attachment>
550{
551 static_assert(std::is_base_of_v<TrackAttachment, Attachment>);
552public:
553 ~ChannelAttachments() override = default;
554
558 static Attachment &Get(
560 Track &track, size_t iChannel)
561 {
562 return static_cast<Attachment&>(
564 }
568 static Attachment *Find(
570 Track *pTrack, size_t iChannel)
571 {
572 return static_cast<Attachment*>(
574 }
575
577
585 template<typename F,
586 typename sfinae = std::enable_if_t<std::is_convertible_v<
587 std::invoke_result_t<F, Track&, size_t>, std::shared_ptr<Attachment>
588 >>
589 >
590 explicit ChannelAttachments(Track &track, F &&f)
591 : ChannelAttachmentsBase{ track, std::forward<F>(f) }
592 {}
593};
594
596
603template<typename T>
604 inline std::enable_if_t< std::is_pointer_v<T>, T >
606{
607 using BareType = std::remove_pointer_t< T >;
608 if (track &&
609 BareType::ClassTypeInfo().IsBaseOf(track->GetTypeInfo() ))
610 return reinterpret_cast<T>(track);
611 else
612 return nullptr;
613}
614
617template<typename T>
618 inline std::enable_if_t<
619 std::is_pointer_v<T> && std::is_const_v< std::remove_pointer_t< T > >,
620 T
621 >
622 track_cast(const Track *track)
623{
624 using BareType = std::remove_pointer_t< T >;
625 if (track &&
626 BareType::ClassTypeInfo().IsBaseOf(track->GetTypeInfo() ))
627 return reinterpret_cast<T>(track);
628 else
629 return nullptr;
630}
631
632template < typename TrackType > struct TrackIterRange;
633
635
642template <
643 typename TrackType
645 : public ValueIterator< TrackType *, std::bidirectional_iterator_tag >
646{
647public:
649 using FunctionType = std::function< bool(
650 std::add_pointer_t< std::add_const_t< std::remove_pointer_t<TrackType> > >
651 ) >;
652
656 TrackNodePointer iter,
658 FunctionType pred = {}
659 )
660 : mBegin( begin ), mIter( iter ), mEnd( end )
661 , mPred( std::move(pred) )
662 {
663 // Establish the class invariant
664 if (this->mIter != this->mEnd && !this->valid())
665 this->operator ++ ();
666 }
667
669
671 template < typename Predicate2 >
672 TrackIter Filter( const Predicate2 &pred2 ) const
673 {
674 return { this->mBegin, this->mIter, this->mEnd, pred2 };
675 }
676
678
680 template < typename TrackType2 >
681 auto Filter() const
682 -> std::enable_if_t<
683 std::is_base_of_v< TrackType, TrackType2 > &&
684 (!std::is_const_v<TrackType> ||
685 std::is_const_v<TrackType2>),
686 TrackIter< TrackType2 >
687 >
688 {
689 return { this->mBegin, this->mIter, this->mEnd, this->mPred };
690 }
691
693 { return this->mPred; }
694
696
698 {
699 // Maintain the class invariant
700 if (this->mIter != this->mEnd) do
701 ++this->mIter.first;
702 while (this->mIter != this->mEnd && !this->valid() );
703 return *this;
704 }
705
708 {
709 TrackIter result { *this };
710 this-> operator ++ ();
711 return result;
712 }
713
715
717 {
718 // Maintain the class invariant
719 do {
720 if (this->mIter == this->mBegin)
721 // Go circularly
722 this->mIter = this->mEnd;
723 else
724 --this->mIter.first;
725 } while (this->mIter != this->mEnd && !this->valid() );
726 return *this;
727 }
728
731 {
732 TrackIter result { *this };
733 this->operator -- ();
734 return result;
735 }
736
738
739 TrackType *operator * () const
740 {
741 if (this->mIter == this->mEnd)
742 return nullptr;
743 else
744 // Other methods guarantee that the cast is correct
745 // (provided no operations on the TrackList invalidated
746 // underlying iterators or replaced the tracks there)
747 return static_cast< TrackType * >( &**this->mIter.first );
748 }
749
752 long amount
753 ) const
754 {
755 auto copy = *this;
756 std::advance( copy, amount );
757 return copy;
758 }
759
761 friend inline bool operator == (TrackIter a, TrackIter b)
762 {
763 // Assume the predicate is not stateful. Just compare the iterators.
764 return
765 a.mIter == b.mIter
766 // Assume this too:
767 // && a.mBegin == b.mBegin && a.mEnd == b.mEnd
768 ;
769 }
770
772 friend inline bool operator != (TrackIter a, TrackIter b)
773 {
774 return !(a == b);
775 }
776
777private:
783 bool valid() const
784 {
785 // assume mIter != mEnd
786 const auto pTrack = track_cast< TrackType * >( &**this->mIter.first );
787 if (!pTrack)
788 return false;
789 return !this->mPred || this->mPred( pTrack );
790 }
791
794
800};
801
803template <
804 typename TrackType // Track or a subclass, maybe const-qualified
806 : public IteratorRange< TrackIter< TrackType > >
807{
811 : IteratorRange< TrackIter< TrackType > >
812 ( begin, end )
813 {}
814
815 // Conjoin the filter predicate with another predicate
816 // Read + as "and"
817 template< typename Predicate2 >
818 TrackIterRange operator + ( const Predicate2 &pred2 ) const
819 {
820 const auto &pred1 = this->first.GetPredicate();
821 using Function = typename TrackIter<TrackType>::FunctionType;
822 const auto &newPred = pred1
823 ? Function{ [=] (typename Function::argument_type track) {
824 return pred1(track) && pred2(track);
825 } }
826 : Function{ pred2 };
827 return {
828 this->first.Filter( newPred ),
829 this->second.Filter( newPred )
830 };
831 }
832
833 // Specify the added conjunct as a pointer to member function
834 // Read + as "and"
835 template< typename R, typename C >
836 TrackIterRange operator + ( R ( C ::* pmf ) () const ) const
837 {
838 return this->operator + ( std::mem_fn( pmf ) );
839 }
840
841 // Conjoin the filter predicate with the negation of another predicate
842 // Read - as "and not"
843 template< typename Predicate2 >
844 TrackIterRange operator - ( const Predicate2 &pred2 ) const
845 {
846 using ArgumentType =
847 typename TrackIterRange::iterator::FunctionType::argument_type;
848 auto neg = [=] (ArgumentType track) { return !pred2( track ); };
849 return this->operator + ( neg );
850 }
851
852 // Specify the negated conjunct as a pointer to member function
853 // Read - as "and not"
854 template< typename R, typename C >
855 TrackIterRange operator - ( R ( C ::* pmf ) () const ) const
856 {
857 return this->operator + ( std::not1( std::mem_fn( pmf ) ) );
858 }
859
860 template< typename TrackType2 >
862 {
863 return {
864 this-> first.template Filter< TrackType2 >(),
865 this->second.template Filter< TrackType2 >()
866 };
867 }
868
869 TrackIterRange StartingWith( const Track *pTrack ) const
870 {
871 auto newBegin = this->find( pTrack );
872 // More careful construction is needed so that the independent
873 // increment and decrement of each iterator in the NEW pair
874 // has the expected behavior at boundaries of the range
875 return {
876 { newBegin.mIter, newBegin.mIter, this->second.mEnd,
877 this->first.GetPredicate() },
878 { newBegin.mIter, this->second.mIter, this->second.mEnd,
879 this->second.GetPredicate() }
880 };
881 }
882
883 TrackIterRange EndingAfter( const Track *pTrack ) const
884 {
885 const auto newEnd = this->reversal().find( pTrack ).base();
886 // More careful construction is needed so that the independent
887 // increment and decrement of each iterator in the NEW pair
888 // has the expected behavior at boundaries of the range
889 return {
890 { this->first.mBegin, this->first.mIter, newEnd.mIter,
891 this->first.GetPredicate() },
892 { this->first.mBegin, newEnd.mIter, newEnd.mIter,
893 this->second.GetPredicate() }
894 };
895 }
896
897 // Exclude one given track
898 TrackIterRange Excluding ( const TrackType *pExcluded ) const
899 {
900 return this->operator - (
901 [=](const Track *pTrack){ return pExcluded == pTrack; } );
902 }
903
905 template< typename ...Functions >
906 void Visit(const Functions &...functions)
907 {
908 for (auto track : *this)
909 track->TypeSwitch(functions...);
910 }
911
913
914 template< typename Flag, typename ...Functions >
915 void VisitWhile(Flag &flag, const Functions &...functions)
916 {
917 if ( flag ) for (auto track : *this) {
918 track->TypeSwitch(functions...);
919 if (!flag)
920 break;
921 }
922 }
923};
924
925
928{
929 enum Type {
932
935
937
939
942
945
947
951 };
952
954 const std::weak_ptr<Track> &pTrack = {}, int extra = -1)
955 : mType{ type }
956 , mpTrack{ pTrack }
957 , mExtra{ extra }
958 {}
959
960 TrackListEvent( const TrackListEvent& ) = default;
961
962 const Type mType;
963 const std::weak_ptr<Track> mpTrack;
964 const int mExtra;
965};
966
970class TRACK_API TrackList final
971 : public Observer::Publisher<TrackListEvent>
972 , private ListOfTracks
973 , public std::enable_shared_from_this<TrackList>
974 , public ClientData::Base
975{
976 // privatize this, make you use Add instead:
977 using ListOfTracks::push_back;
978
979 // privatize this, make you use Swap instead:
980 using ListOfTracks::swap;
981
982 // Disallow copy
983 TrackList(const TrackList &that) = delete;
984 TrackList &operator= (const TrackList&) = delete;
985
986 // No need for move, disallow it
987 TrackList(TrackList &&that) = delete;
989
990 void clear() = delete;
991
992 public:
994 static const TrackList &Get( const AudacityProject &project );
995
996 static TrackList *FindUndoTracks(const UndoStackElem &state);
997
998 // Create an empty TrackList
999 // Don't call directly -- use Create() instead
1000 explicit TrackList( AudacityProject *pOwner );
1001
1002 // Create an empty TrackList
1003 static TrackListHolder Create(AudacityProject *pOwner);
1004
1008 void Swap(TrackList &that);
1009
1010 // Destructor
1011 virtual ~TrackList();
1012
1013 // Find the owning project, which may be null
1014 AudacityProject *GetOwner() { return mOwner; }
1015 const AudacityProject *GetOwner() const { return mOwner; }
1016
1023 wxString MakeUniqueTrackName(const wxString& baseTrackName) const;
1024
1025 // Iteration
1026
1027 // Hide the inherited begin() and end()
1030
1032 iterator begin() { return Any().begin(); }
1033 iterator end() { return Any().end(); }
1034 const_iterator begin() const { return Any().begin(); }
1035 const_iterator end() const { return Any().end(); }
1036 const_iterator cbegin() const { return begin(); }
1037 const_iterator cend() const { return end(); }
1038
1039 // Reverse iteration
1040 using reverse_iterator = std::reverse_iterator<iterator>;
1041 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1042 reverse_iterator rbegin() { return Any().rbegin(); }
1043 reverse_iterator rend() { return Any().rend(); }
1044 const_reverse_iterator rbegin() const { return Any().rbegin(); }
1045 const_reverse_iterator rend() const { return Any().rend(); }
1046 const_reverse_iterator crbegin() const { return rbegin(); }
1047 const_reverse_iterator crend() const { return rend(); }
1048
1051 TrackIter<Track> DoFind(Track *pTrack);
1052
1053 // If the track is not an audio track, or not one of a group of channels,
1054 // return the track itself; else return the first channel of its group --
1055 // in either case as an iterator that will only visit other leader tracks.
1056 // (Generalizing away from the assumption of at most stereo)
1057 TrackIter<Track> Find(Track *pTrack);
1058
1059 TrackIter<const Track> Find(const Track *pTrack) const
1060 {
1061 return const_cast<TrackList*>(this)->
1062 Find(const_cast<Track*>(pTrack)).Filter<const Track>();
1063 }
1064
1065
1066private:
1068 iterator Begin() { return Tracks<Track>().begin(); }
1070 iterator End() { return Tracks<Track>().end(); }
1071
1073 const_iterator Begin() const { return Tracks<const Track>().begin(); }
1075 const_iterator End() const { return Tracks<const Track>().end(); }
1076
1077public:
1078 template < typename TrackType = Track >
1079 auto Any()
1081 {
1082 return Tracks< TrackType >( &Track::IsLeader );
1083 }
1084
1085 template < typename TrackType = const Track >
1086 auto Any() const
1087 -> std::enable_if_t< std::is_const_v<TrackType>,
1088 TrackIterRange< TrackType >
1089 >
1090 {
1091 return Tracks< TrackType >( &Track::IsLeader );
1092 }
1093
1094
1095 template <typename TrackType = Track>
1097 {
1098 return Tracks<TrackType>(&Track::IsSelectedLeader);
1099 }
1100
1101 template <typename TrackType = const Track>
1102 auto Selected() const
1103 -> std::enable_if_t<std::is_const_v<TrackType>, TrackIterRange<TrackType>>
1104 {
1105 return Tracks<TrackType>(&Track::IsSelectedLeader);
1106 }
1107
1108
1109 template<typename TrackType>
1110 static auto SingletonRange( TrackType *pTrack )
1112 {
1113 return pTrack->GetOwner()->template Tracks<TrackType>()
1114 .StartingWith( pTrack ).EndingAfter( pTrack );
1115 }
1116
1117
1118private:
1119 Track *DoAddToHead(const std::shared_ptr<Track> &t);
1120 Track *DoAdd(const std::shared_ptr<Track> &t);
1121
1122 template< typename TrackType, typename InTrackType >
1125 {
1126 // Assume iterator filters leader tracks
1127 if (*iter1) {
1128 return {
1129 iter1.Filter( &Track::Any )
1130 .template Filter<TrackType>(),
1131 (++iter1).Filter( &Track::Any )
1132 .template Filter<TrackType>()
1133 };
1134 }
1135 else
1136 // empty range
1137 return {
1138 iter1.template Filter<TrackType>(),
1139 iter1.template Filter<TrackType>()
1140 };
1141 }
1142
1143public:
1144 // Find an iterator range of channels including the given track.
1145 template< typename TrackType >
1146 static auto Channels( TrackType *pTrack )
1148 {
1149 return Channels_<TrackType>(pTrack->GetHolder()->Find(pTrack));
1150 }
1151
1153 static size_t NChannels(const Track &track)
1154 {
1155 return Channels(&track).size();
1156 }
1157
1160 static Track* SwapChannels(Track &track);
1161
1162 friend class Track;
1163
1167 void Insert(const Track* before, TrackList&& trackList);
1168
1173 void Permute(const std::vector<Track *> &tracks);
1174
1175 Track *FindById( TrackId id );
1176
1178 template<typename TrackKind>
1179 TrackKind *AddToHead( const std::shared_ptr< TrackKind > &t )
1180 { return static_cast< TrackKind* >( DoAddToHead( t ) ); }
1181
1182 template<typename TrackKind>
1183 TrackKind *Add( const std::shared_ptr< TrackKind > &t )
1184 { return static_cast< TrackKind* >( DoAdd( t ) ); }
1185
1187 std::vector<Track*> UnlinkChannels(Track& track);
1194 bool MakeMultiChannelTrack(Track& first, int nChannels);
1195
1207 TrackListHolder ReplaceOne(Track &t, TrackList &&with);
1208
1210
1213 void Remove(Track &track);
1214
1216 void Clear(bool sendEvent = true);
1217
1218 bool CanMoveUp(Track * t) const;
1219 bool CanMoveDown(Track * t) const;
1220
1221 bool MoveUp(Track * t);
1222 bool MoveDown(Track * t);
1223 bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); }
1224
1225 // Return non-null only if the weak pointer is not, and the track is
1226 // owned by this list; constant time.
1227 template <typename Subclass>
1228 std::shared_ptr<Subclass> Lock(const std::weak_ptr<Subclass> &wTrack)
1229 {
1230 auto pTrack = wTrack.lock();
1231 if (pTrack) {
1232 auto pList = pTrack->mList.lock();
1233 if (pTrack && this == pList.get())
1234 return pTrack;
1235 }
1236 return {};
1237 }
1238
1239 bool empty() const;
1240 size_t NChannels() const;
1241 size_t Size() const { return Any().size(); }
1242
1244 double GetStartTime() const;
1246 double GetEndTime() const;
1247
1251
1255 static TrackListHolder Temporary(AudacityProject *pProject,
1256 const Track::Holder &left = {}, const Track::Holder &right = {});
1257
1261 static TrackListHolder Temporary(
1262 AudacityProject *pProject, const std::vector<Track::Holder> &channels);
1263
1268 template<typename T>
1270 AudacityProject *pProject,
1271 const std::vector<std::shared_ptr<T>> &channels)
1272 {
1273 std::vector<Track::Holder> temp;
1274 static const auto convert = [](auto &pChannel){
1275 return std::static_pointer_cast<Track>(pChannel);
1276 };
1277 transform(channels.begin(), channels.end(), back_inserter(temp), convert);
1278 return Temporary(pProject, temp);
1279 }
1280
1282 void Append(TrackList &&list);
1283
1284 // Like RegisterPendingChangedTrack, but for a list of new tracks,
1285 // not a replacement track. Caller
1286 // supplies the list, and there are no updates.
1287 // Pending tracks will have an unassigned TrackId.
1288 // Pending new tracks WILL occur in iterations, always after actual
1289 // tracks, and in the sequence that they were added. They can be
1290 // distinguished from actual tracks by TrackId.
1291 void RegisterPendingNewTracks(TrackList &&list);
1292
1295 void AppendOne(TrackList &&list);
1296
1297private:
1298 using ListOfTracks::size;
1299
1300 // Visit all tracks satisfying a predicate, mutative access
1301 template <
1302 typename TrackType = Track,
1303 typename Pred =
1305 >
1306 auto Tracks( const Pred &pred = {} )
1308 {
1309 auto b = getBegin(), e = getEnd();
1310 return { { b, b, e, pred }, { b, e, e, pred } };
1311 }
1312
1313 // Visit all tracks satisfying a predicate, const access
1314 template <
1315 typename TrackType = const Track,
1316 typename Pred =
1318 >
1319 auto Tracks( const Pred &pred = {} ) const
1320 -> std::enable_if_t< std::is_const_v<TrackType>,
1322 >
1323 {
1324 auto b = const_cast<TrackList*>(this)->getBegin();
1325 auto e = const_cast<TrackList*>(this)->getEnd();
1326 return { { b, b, e, pred }, { b, e, e, pred } };
1327 }
1328
1329 Track *GetPrev(Track * t, bool linked = false) const;
1330 Track *GetNext(Track * t, bool linked = false) const;
1331
1332 template < typename TrackType >
1335 {
1336 auto b = const_cast<TrackList*>(this)->getBegin();
1337 auto e = const_cast<TrackList*>(this)->getEnd();
1338 return { b, iter, e };
1339 }
1340
1341 template < typename TrackType >
1344 {
1345 auto e = const_cast<TrackList*>(this)->getEnd();
1346 return { e, e, e };
1347 }
1348
1349 TrackIterRange< Track > EmptyRange() const;
1350
1352 { return (p.second == this && p.first == ListOfTracks::end())
1353 || (mPendingUpdates && p.second == &*mPendingUpdates &&
1354 p.first == mPendingUpdates->ListOfTracks::end()); }
1356 { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
1357 const_cast<TrackList*>(this)}; }
1359 { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
1360 const_cast<TrackList*>(this)}; }
1361
1364 {
1365 if ( isNull(p) )
1366 return p;
1367 auto q = p;
1368 ++q.first;
1369 return q;
1370 }
1371
1374 {
1375 if (p == getBegin())
1376 return getEnd();
1377 else {
1378 auto q = p;
1379 --q.first;
1380 return q;
1381 }
1382 }
1383
1384 void RecalcPositions(TrackNodePointer node);
1385 void QueueEvent(TrackListEvent event);
1386 void SelectionEvent(Track &track);
1387 void PermutationEvent(TrackNodePointer node);
1388 void DataEvent(
1389 const std::shared_ptr<Track> &pTrack, bool allChannels, int code );
1390 void DeletionEvent(std::weak_ptr<Track> node, bool duringReplace);
1391 void AdditionEvent(TrackNodePointer node);
1392 void ResizingEvent(TrackNodePointer node);
1393
1394 void SwapNodes(TrackNodePointer s1, TrackNodePointer s2);
1395
1396 // Nondecreasing during the session.
1397 // Nonpersistent.
1398 // Used to assign ids to added tracks.
1399 static long sCounter;
1400
1401public:
1404 using Updater = std::function<void(Track &dest, const Track &src)>;
1405 // Start a deferred update of the project.
1406 // The return value is a duplicate of the given track.
1407 // While ApplyPendingTracks or ClearPendingTracks is not yet called,
1408 // there may be other direct changes to the project that push undo history.
1409 // Meanwhile the returned object can accumulate other changes for a deferred
1410 // push, and temporarily shadow the actual project track for display purposes.
1411 // The Updater function, if not null, merges state (from the actual project
1412 // into the pending track) which is not meant to be overridden by the
1413 // accumulated pending changes.
1414 // To keep the display consistent, the Y and Height values, minimized state,
1415 // and Linked state must be copied, and this will be done even if the
1416 // Updater does not do it.
1417 // Pending track will have the same TrackId as the actual.
1418 // Pending changed tracks will not occur in iterations.
1424 Track* RegisterPendingChangedTrack(
1426 Track *src
1427 );
1428
1429 // Invoke the updaters of pending tracks. Pass any exceptions from the
1430 // updater functions.
1431 void UpdatePendingTracks();
1432
1433 /*
1434 Forget pending track additions and changes;
1435 if requested, give back the pending added tracks.
1436 @pre `GetOwner()`
1437 */
1438 void ClearPendingTracks(ListOfTracks *pAdded = nullptr);
1439
1440 // Change the state of the project.
1441 // Strong guarantee for project state in case of exceptions.
1442 // Will always clear the pending updates.
1443 // Return true if the state of the track list really did change.
1444 bool ApplyPendingTracks();
1445
1446 bool HasPendingTracks() const;
1447
1448private:
1450
1453
1454 std::shared_ptr<TrackList> mPendingUpdates;
1456 std::vector< Updater > mUpdaters;
1459 bool mAssignsIds{ true };
1460};
1461
1463 return static_cast<TrackList*>(mNode.second); }
1464
1465#endif
Abstract class ChannelGroup with two discrete iterable dimensions, channels and intervals; subclasses...
static const AudacityProject::AttachedObjects::RegisteredFactory key
const auto tracks
const auto project
std::vector< Track * > TrackArray
ClientData::Site< Track, TrackAttachment, ClientData::ShallowCopying, std::shared_ptr > AttachedTrackObjects
Template generated base class for Track lets it host opaque UI related objects.
Definition: Track.h:114
std::function< void(double)> ProgressReporter
Definition: Track.h:53
#define ENUMERATE_TRACK_TYPE(T)
Empty class which will have subclasses.
Definition: Track.h:67
bool operator==(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:55
bool operator!=(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:58
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Pairs a std::list iterator and a pointer to a list, for comparison purposes.
Definition: Track.h:51
std::list< std::shared_ptr< Track > > ListOfTracks
Definition: Track.h:45
std::enable_if_t< std::is_pointer_v< T >, T > track_cast(Track *track)
Encapsulate the checked down-casting of track pointers.
Definition: Track.h:605
std::shared_ptr< TrackList > TrackListHolder
Definition: Track.h:42
abstract base class for structures that user interface associates with tracks
Make a list of all distinct types so far mentioned in calls of a certain macro.
#define BEGIN_TYPE_ENUMERATION(Tag)
Dispatch to one of a set of functions by the run-time type of an object.
Append(Adapt< My >([](My &table) { return(WaveChannelSubViews::numFactories() > 1) ? std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveChannelView::Get(track);menu.Check(id, view.GetMultiView());}) :nullptr;}))
int id
static CustomUpdaterValue updater
static std::once_flag flag
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Holds multiple objects as a single attachment to Track.
Definition: Track.h:512
const Factory mFactory
Definition: Track.h:543
static TrackAttachment & Get(const AttachedTrackObjects::RegisteredFactory &key, Track &track, size_t iChannel)
Definition: Track.cpp:1286
std::vector< std::shared_ptr< TrackAttachment > > mAttachments
Definition: Track.h:544
~ChannelAttachmentsBase() override
static TrackAttachment * Find(const AttachedTrackObjects::RegisteredFactory &key, Track *pTrack, size_t iChannel)
Definition: Track.cpp:1305
std::function< std::shared_ptr< TrackAttachment >(Track &, size_t)> Factory
Definition: Track.h:515
Holds multiple objects of the parameter type as a single attachment to Track.
Definition: Track.h:550
~ChannelAttachments() override=default
static Attachment * Find(const AttachedTrackObjects::RegisteredFactory &key, Track *pTrack, size_t iChannel)
Definition: Track.h:568
ChannelAttachments(Track &track, F &&f)
Type-erasing constructor.
Definition: Track.h:590
static Attachment & Get(const AttachedTrackObjects::RegisteredFactory &key, Track &track, size_t iChannel)
Definition: Track.h:558
double GetEndTime() const
Get the maximum of End() values of intervals, or 0 when none.
Definition: Channel.cpp:135
double GetStartTime() const
Get the minimum of Start() values of intervals, or 0 when none.
Definition: Channel.cpp:124
virtual bool IsLeader() const =0
IteratorRange< ChannelIterator< ChannelType > > Channels()
Get range of channels with mutative access.
Definition: Channel.h:408
virtual size_t NChannels() const =0
Report the number of channels.
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:274
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:228
Site & operator=(const Site &other)
Definition: ClientData.h:250
Subclass * DoFind(Locked< DataContainer > &data, const RegisteredFactory &key)
Definition: ClientData.h:502
An object that sends messages to an open-ended list of subscribed callbacks.
Definition: Observer.h:108
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
virtual TrackListHolder Clone() const =0
Track()
Definition: Track.cpp:39
virtual Holder PasteInto(AudacityProject &project, TrackList &list) const =0
bool SameKindAs(const Track &track) const
Definition: Track.h:410
virtual const TypeInfo & GetTypeInfo() const =0
virtual void InsertSilence(double t, double len)=0
bool IsSelectedLeader() const
Definition: Track.cpp:296
TrackList * GetHolder() const
Definition: Track.h:1462
virtual void DoOnProjectTempoChange(const std::optional< double > &oldTempo, double newTempo)=0
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:254
R TypeSwitch(const Functions &...functions)
Definition: Track.h:418
static std::shared_ptr< Subclass > SharedPointer(Track *pTrack)
Definition: Track.h:180
bool HasOwner() const
Definition: Track.h:252
virtual const TypeNames & GetTypeNames() const
Definition: Track.h:219
auto SharedPointer() const -> std::enable_if_t< std::is_const_v< Subclass >, std::shared_ptr< Subclass > >
Definition: Track.h:168
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:160
TrackId GetId() const
Definition: Track.h:150
virtual void Clear(double t0, double t1)=0
bool IsLeader() const override
Definition: Track.cpp:291
std::shared_ptr< Track > Holder
Definition: Track.h:225
void SetId(TrackId id)
Definition: Track.h:152
virtual void WriteXML(XMLWriter &xmlFile) const =0
R TypeSwitch(const Functions &...functions) const
Definition: Track.h:429
std::weak_ptr< TrackList > mList
Definition: Track.h:139
TrackNodePointer mNode
Holds iterator to self, so that TrackList::Find can be constant-time.
Definition: Track.h:142
int mIndex
0-based position of this track in its TrackList
Definition: Track.h:143
static std::shared_ptr< Subclass > SharedPointer(const Track *pTrack)
Definition: Track.h:184
bool LinkConsistencyCheck()
Do the non-mutating part of consistency fix only and return status.
Definition: Track.h:249
bool Any() const
Definition: Track.cpp:285
TrackId mId
Identifies the track only in-session, not persistently.
Definition: Track.h:136
An in-session identifier of track objects across undo states. It does not persist between sessions.
Definition: Track.h:91
bool operator!=(const TrackId &other) const
Definition: Track.h:99
TrackId()
Definition: Track.h:93
bool operator<(const TrackId &other) const
Definition: Track.h:104
TrackId(long value)
Definition: Track.h:94
long mValue
Definition: Track.h:108
bool operator==(const TrackId &other) const
Definition: Track.h:96
Iterator over only members of a TrackList of the specified subtype, optionally filtered by a predicat...
Definition: Track.h:646
const FunctionType & GetPredicate() const
Definition: Track.h:692
TrackNodePointer mIter
Current position.
Definition: Track.h:797
TrackType * operator*() const
Safe to call even when at the end.
Definition: Track.h:739
TrackIter & operator--()
Safe to call even when at the beginning.
Definition: Track.h:716
friend bool operator!=(TrackIter a, TrackIter b)
Compares only current positions, assuming same beginnings and ends.
Definition: Track.h:772
auto Filter() const -> std::enable_if_t< std::is_base_of_v< TrackType, TrackType2 > &&(!std::is_const_v< TrackType >||std::is_const_v< TrackType2 >), TrackIter< TrackType2 > >
Return an iterator for a subclass of TrackType (and not removing const) with same predicate.
Definition: Track.h:681
TrackNodePointer mBegin
Allows end of reverse iteration to be detected without comparison to other TrackIter.
Definition: Track.h:796
friend bool operator==(TrackIter a, TrackIter b)
Compares only current positions, assuming same beginnings and ends.
Definition: Track.h:761
TrackIter Filter(const Predicate2 &pred2) const
Return an iterator that replaces the predicate.
Definition: Track.h:672
TrackIter & operator++()
Safe to call even when at the end.
Definition: Track.h:697
std::function< bool(std::add_pointer_t< std::add_const_t< std::remove_pointer_t< TrackType > > >) > FunctionType
Type of predicate taking pointer to const TrackType.
Definition: Track.h:651
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:751
FunctionType mPred
Optional filter
Definition: Track.h:799
TrackIter(TrackNodePointer begin, TrackNodePointer iter, TrackNodePointer end, FunctionType pred={})
Constructor, usually not called directly except by methods of TrackList.
Definition: Track.h:654
bool valid() const
Test satisfaction of the invariant, while initializing, incrementing, or decrementing.
Definition: Track.h:783
TrackNodePointer mEnd
Allows end of iteration to be detected without comparison to other TrackIter.
Definition: Track.h:798
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:975
const_reverse_iterator crbegin() const
Definition: Track.h:1046
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1228
static auto SingletonRange(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1110
auto Selected() const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
Definition: Track.h:1102
std::function< void(Track &dest, const Track &src)> Updater
Definition: Track.h:1404
const_reverse_iterator rend() const
Definition: Track.h:1045
AudacityProject * mOwner
Definition: Track.h:1449
static TrackListHolder Temporary(AudacityProject *pProject, const std::vector< std::shared_ptr< T > > &channels)
Definition: Track.h:1269
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: Track.h:1041
std::shared_ptr< TrackList > mPendingUpdates
Definition: Track.h:1454
static long sCounter
Definition: Track.h:1399
const_iterator End() const
This private function still iterates channels not tracks.
Definition: Track.h:1075
bool Move(Track *t, bool up)
Definition: Track.h:1223
const_iterator begin() const
Definition: Track.h:1034
reverse_iterator rend()
Definition: Track.h:1043
std::vector< Updater > mUpdaters
This is in correspondence with leader tracks in mPendingUpdates.
Definition: Track.h:1456
TrackNodePointer getBegin() const
Definition: Track.h:1358
iterator end()
Definition: Track.h:1033
auto Tracks(const Pred &pred={}) const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
Definition: Track.h:1319
TrackIter< const Track > Find(const Track *pTrack) const
Definition: Track.h:1059
static size_t NChannels(const Track &track)
Count channels of a track.
Definition: Track.h:1153
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1183
auto Tracks(const Pred &pred={}) -> TrackIterRange< TrackType >
Definition: Track.h:1306
size_t Size() const
Definition: Track.h:1241
bool isNull(TrackNodePointer p) const
Definition: Track.h:1351
const_reverse_iterator crend() const
Definition: Track.h:1047
TrackNodePointer getNext(TrackNodePointer p) const
Move an iterator to the next node, if any; else stay at end.
Definition: Track.h:1363
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1079
TrackNodePointer getEnd() const
Definition: Track.h:1355
TrackIter< TrackType > EndIterator() const
Definition: Track.h:1343
auto Any() const -> std::enable_if_t< std::is_const_v< TrackType >, TrackIterRange< TrackType > >
Definition: Track.h:1086
reverse_iterator rbegin()
Definition: Track.h:1042
static TrackIterRange< TrackType > Channels_(TrackIter< InTrackType > iter1)
Definition: Track.h:1124
void clear()=delete
const AudacityProject * GetOwner() const
Definition: Track.h:1015
iterator begin()
Definition: Track.h:1032
std::reverse_iterator< iterator > reverse_iterator
Definition: Track.h:1040
const_iterator cend() const
Definition: Track.h:1037
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1096
iterator Begin()
This private function still iterates channels not tracks.
Definition: Track.h:1068
const_iterator cbegin() const
Definition: Track.h:1036
const_iterator Begin() const
This private function still iterates channels not tracks.
Definition: Track.h:1073
iterator End()
This private function still iterates channels not tracks.
Definition: Track.h:1070
AudacityProject * GetOwner()
Definition: Track.h:1014
TrackIter< TrackType > MakeTrackIterator(TrackNodePointer iter) const
Definition: Track.h:1334
TrackList(const TrackList &that)=delete
TrackList(TrackList &&that)=delete
TrackNodePointer getPrev(TrackNodePointer p) const
Move an iterator to the previous node, if any; else wrap to end.
Definition: Track.h:1373
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1146
const_reverse_iterator rbegin() const
Definition: Track.h:1044
TrackKind * AddToHead(const std::shared_ptr< TrackKind > &t)
Add a Track, giving it a fresh id.
Definition: Track.h:1179
const_iterator end() const
Definition: Track.h:1035
Holds a msgid for the translation catalog; may also bind format arguments.
typename Accumulate< 0 >::type type
Generates overrides of channel-related functions.
Definition: Track.h:490
std::shared_ptr< Channel > DoGetChannel(size_t iChannel) override
Retrieve a channel.
Definition: Track.h:494
size_t NChannels() const override
Report the number of channels.
Definition: Track.h:493
ChannelGroup & DoGetChannelGroup() const override
Subclass must override.
Definition: Track.h:504
A view into an attribute value. The class does not take the ownership of the data.
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
PROJECT_FILE_IO_API void Remove(const FilePath &path)
PROJECT_FILE_IO_API wxString Find(const FilePath &path)
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196
@ ShallowCopying
copy pointers only; won't compile for std::unique_ptr
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
Utilities for compile-time type manipulation. Some terminology as in Lisp.
Definition: TypeList.h:22
typename Map< Metafunction, TypeList >::type Map_t
Definition: TypeList.h:262
std::vector< std::vector< float > > Duplicate(const std::vector< float > &audio, size_t numChannels)
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:645
static RegisteredToolbarFactory factory
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40
STL namespace.
A convenient default parameter for class template Site.
Definition: ClientData.h:28
A convenience for use with range-for.
Definition: MemoryX.h:277
iterator find(const T &t) const
Definition: MemoryX.h:300
IteratorRange< reverse_iterator > reversal() const
Definition: MemoryX.h:287
TrackIter< TrackType > end() const
Definition: MemoryX.h:291
TrackIter< TrackType > begin() const
Definition: MemoryX.h:290
Empty argument passed to some public constructors.
Definition: Track.h:129
TypeNames names
Definition: Track.h:204
bool IsBaseOf(const TypeInfo &other) const
Definition: Track.h:208
const TypeInfo * pBaseInfo
Definition: Track.h:206
Names of a track type for various purposes.
Definition: Track.h:198
wxString info
short, like "wave", in macro output, not internationalized
Definition: Track.h:199
TranslatableString name
long, like "Wave Track"
Definition: Track.h:201
wxString property
short, like "wave", as a Lisp symbol property, not internationalized
Definition: Track.h:200
Range between two TrackIters, usable in range-for statements, and with Visit member functions.
Definition: Track.h:807
TrackIterRange EndingAfter(const Track *pTrack) const
Definition: Track.h:883
void VisitWhile(Flag &flag, const Functions &...functions)
See Track::TypeSwitch.
Definition: Track.h:915
TrackIterRange operator+(const Predicate2 &pred2) const
Definition: Track.h:818
TrackIterRange(const TrackIter< TrackType > &begin, const TrackIter< TrackType > &end)
Definition: Track.h:809
void Visit(const Functions &...functions)
See Track::TypeSwitch.
Definition: Track.h:906
TrackIterRange< TrackType2 > Filter() const
Definition: Track.h:861
TrackIterRange Excluding(const TrackType *pExcluded) const
Definition: Track.h:898
TrackIterRange operator-(const Predicate2 &pred2) const
Definition: Track.h:844
TrackIterRange StartingWith(const Track *pTrack) const
Definition: Track.h:869
Notification of changes in individual tracks of TrackList, or of TrackList's composition.
Definition: Track.h:928
TrackListEvent(const TrackListEvent &)=default
const int mExtra
Definition: Track.h:964
const std::weak_ptr< Track > mpTrack
Definition: Track.h:963
const Type mType
Definition: Track.h:962
@ RESIZING
Posted when some track changed its height.
Definition: Track.h:941
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.
Definition: Track.h:931
@ DELETION
Posted when a track has been deleted from a tracklist. Also posted when one track replaces another.
Definition: Track.h:950
@ ADDITION
Posted when a track has been added to a tracklist. Also posted when one track replaces another.
Definition: Track.h:944
@ PERMUTED
Posted when tracks are reordered but otherwise unchanged.
Definition: Track.h:938
@ TRACK_DATA_CHANGE
Posted when certain fields of a track change.
Definition: Track.h:934
TrackListEvent(Type type, const std::weak_ptr< Track > &pTrack={}, int extra=-1)
Definition: Track.h:953
Select only the subsequence of the type list satisfying the predicate.
Definition: TypeList.h:500
Holds one item with description and time range for the UndoManager.
Definition: UndoManager.h:117
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
Definition: MemoryX.h:263