From 32c0d462b746005b3103fc2a46b36542b3fcc40e Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 18 Sep 2020 09:42:15 -0400 Subject: [PATCH] Another method of TrackShifter to test before attachment of intervals --- src/WaveTrack.cpp | 3 +- src/WaveTrack.h | 2 +- .../wavetrack/ui/WaveTrackView.cpp | 18 +++++++++ src/tracks/ui/TimeShiftHandle.cpp | 39 ++++++++++++------- src/tracks/ui/TimeShiftHandle.h | 10 +++++ 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index c972e8965..c8755cd6e 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -2259,7 +2259,8 @@ bool WaveTrack::CanOffsetClip(WaveClip* clip, double amount, return true; } -bool WaveTrack::CanInsertClip(WaveClip* clip, double &slideBy, double &tolerance) +bool WaveTrack::CanInsertClip( + WaveClip* clip, double &slideBy, double &tolerance) const { for (const auto &c : mClips) { diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 861727da0..627fcaa69 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -474,7 +474,7 @@ private: // Before moving a clip into a track (or inserting a clip), use this // function to see if the times are valid (i.e. don't overlap with // existing clips). - bool CanInsertClip(WaveClip* clip, double &slideBy, double &tolerance); + bool CanInsertClip(WaveClip* clip, double &slideBy, double &tolerance) const; // Remove the clip from the track and return a SMART pointer to it. // You assume responsibility for its memory! diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index 1d362a680..6878fddeb 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -1377,6 +1377,24 @@ public: return std::move( mMoving ); } + bool AdjustFit( + const Track &otherTrack, const Intervals &intervals, + double &desiredOffset, double tolerance) override + { + bool ok = true; + auto pOtherWaveTrack = static_cast(&otherTrack); + for ( auto &interval: intervals ) { + auto pData = + static_cast( interval.Extra() ); + auto pClip = pData->GetClip().get(); + ok = pOtherWaveTrack->CanInsertClip( + pClip, desiredOffset, tolerance ); + if( !ok ) + break; + } + return ok; + } + bool Attach( Intervals intervals ) override { for (auto &interval : intervals) { diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 5dbe2e6ab..dd0356ee8 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -280,6 +280,12 @@ auto TrackShifter::Detach() -> Intervals return {}; } +bool TrackShifter::AdjustFit( + const Track &, const Intervals&, double &, double) +{ + return false; +} + bool TrackShifter::Attach( Intervals ) { return true; @@ -794,26 +800,30 @@ namespace { return true; } + using DetachedIntervals = + std::unordered_map; + bool CheckFit( - const ViewInfo &viewInfo, wxCoord xx, ClipMoveState &state, + ClipMoveState &state, const Correspondence &correspondence, + const DetachedIntervals &intervals, double tolerance, double &desiredSlideAmount ) { - (void)xx;// Compiler food - (void)viewInfo;// Compiler food bool ok = true; double firstTolerance = tolerance; - + // The desiredSlideAmount may change and the tolerance may get used up. for ( unsigned iPass = 0; iPass < 2 && ok; ++iPass ) { - for ( auto &trackClip : state.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) { - ok = trackClip.dstTrack->CanInsertClip( - pSrcClip, desiredSlideAmount, tolerance ); - if( !ok ) - break; - } + for ( auto &pair : state.shifters ) { + auto *pSrcTrack = pair.first; + auto iter = correspondence.find( pSrcTrack ); + if ( iter != correspondence.end() ) + if( auto *pOtherTrack = iter->second ) + if ( !(ok = pair.second->AdjustFit( + *pOtherTrack, intervals.at(pSrcTrack), + desiredSlideAmount /*in,out*/, tolerance)) ) + break; } + // If it fits ok, desiredSlideAmount could have been updated to get // the clip to fit. // Check again, in the new position, this time with zero tolerance. @@ -875,7 +885,7 @@ namespace { } ClipMoveState &state; - std::unordered_map detached; + DetachedIntervals detached; bool failed = false; }; } @@ -901,7 +911,8 @@ bool TimeShiftHandle::DoSlideVertical // i.e. one pixel tolerance at current zoom. double tolerance = viewInfo.PositionToTime(xx + 1) - viewInfo.PositionToTime(xx); - bool ok = CheckFit( viewInfo, xx, state, tolerance, desiredSlideAmount ); + bool ok = CheckFit( state, correspondence, remover.detached, + tolerance, desiredSlideAmount /*in,out*/ ); if (!ok) { // Failure, even with using tolerance. diff --git a/src/tracks/ui/TimeShiftHandle.h b/src/tracks/ui/TimeShiftHandle.h index c5bfa830b..e70e7a65c 100644 --- a/src/tracks/ui/TimeShiftHandle.h +++ b/src/tracks/ui/TimeShiftHandle.h @@ -83,6 +83,16 @@ public: /*! Default implementation does nothing */ virtual Intervals Detach(); + //! Test whether intervals can fit into another track, maybe adjusting the offset slightly + /*! Default implementation does nothing and returns false */ + virtual bool AdjustFit( + const Track &otherTrack, + const Intervals &intervals, /*!< + Assume these came from Detach() and only after MayMigrateTo returned true for otherTrack */ + double &desiredOffset, //!< [in,out] + double tolerance //! Nonnegative ceiling for allowed changes in fabs(desiredOffset) + ); + //! Put moving intervals into the track, which may have migrated from another /*! @return success