diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp index 09f4dc42f..b9be10278 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp @@ -736,7 +736,9 @@ class NoteTrackShifter final : public TrackShifter { public: NoteTrackShifter( NoteTrack &track ) : mpTrack{ track.SharedPointer() } - {} + { + InitIntervals(); + } ~NoteTrackShifter() override {} Track &GetTrack() const override { return *mpTrack; } diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index 8739a62dd..ebf9c8899 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -1307,6 +1307,7 @@ public: WaveTrackShifter( WaveTrack &track ) : mpTrack{ track.SharedPointer() } { + InitIntervals(); } ~WaveTrackShifter() override {} Track &GetTrack() const override { return *mpTrack; } diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index acc58dbd9..d7d34ebc0 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -246,9 +246,36 @@ namespace TrackShifter::~TrackShifter() = default; +void TrackShifter::UnfixIntervals( + std::function< bool( const TrackInterval& ) > pred ) +{ + for ( auto iter = mFixed.begin(); iter != mFixed.end(); ) { + if ( pred( *iter) ) { + mMoving.push_back( std::move( *iter ) ); + iter = mFixed.erase( iter ); + } + else + ++iter; + } +} + +void TrackShifter::UnfixAll() +{ + std::move( mFixed.begin(), mFixed.end(), std::back_inserter(mMoving) ); + mFixed = Intervals{}; +} + +void TrackShifter::InitIntervals() +{ + mMoving.clear(); + mFixed = GetTrack().GetIntervals(); +} + CoarseTrackShifter::CoarseTrackShifter( Track &track ) : mpTrack{ track.SharedPointer() } -{} +{ + InitIntervals(); +} CoarseTrackShifter::~CoarseTrackShifter() = default; diff --git a/src/tracks/ui/TimeShiftHandle.h b/src/tracks/ui/TimeShiftHandle.h index 8e68354ba..4e4ff0acf 100644 --- a/src/tracks/ui/TimeShiftHandle.h +++ b/src/tracks/ui/TimeShiftHandle.h @@ -11,6 +11,7 @@ Paul Licameli #ifndef __AUDACITY_TIMESHIFT_HANDLE__ #define __AUDACITY_TIMESHIFT_HANDLE__ +#include #include #include "../../AttachedVirtualFunction.h" @@ -22,6 +23,7 @@ using TrackArray = std::vector; class TrackList; class Track; +class TrackInterval; //! Abstract base class for policies to manipulate a track type with the Time Shift tool class TrackShifter { @@ -29,6 +31,29 @@ public: virtual ~TrackShifter() = 0; //! There is always an associated track virtual Track &GetTrack() const = 0; + + using Intervals = std::vector; + + //! Return special intervals of the track that will not move + const Intervals &FixedIntervals() const { return mFixed; } + + //! Return special intervals of the track that may move + const Intervals &MovingIntervals() const { return mMoving; } + + //! Change intervals satisfying a predicate from fixed to moving + void UnfixIntervals( + std::function< bool( const TrackInterval& ) > pred ); + + //! Change all intervals from fixed to moving + void UnfixAll(); + +protected: + //! Derived class constructor can initialize all intervals reported by the track as fixed, none moving + /*! This can't be called by the base class constructor, when GetTrack() isn't yet callable */ + void InitIntervals(); + + Intervals mFixed; + Intervals mMoving; }; //! Used in default of other reimplementations to shift any track as a whole, invoking Track::Offset()