diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp index b9be10278..74ad9d3d3 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackView.cpp @@ -742,6 +742,11 @@ public: ~NoteTrackShifter() override {} Track &GetTrack() const override { return *mpTrack; } + HitTestResult HitTest( double ) override + { + return HitTestResult::Intervals; + } + private: std::shared_ptr mpTrack; }; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index ebf9c8899..b00cb9c5b 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -1312,6 +1312,23 @@ public: ~WaveTrackShifter() override {} Track &GetTrack() const override { return *mpTrack; } + HitTestResult HitTest( double time ) override + { + auto pClip = mpTrack->GetClipAtTime( time ); + + if (!pClip) + return HitTestResult::Miss; + + // Make a side-effect on our intervals + UnfixIntervals( [&](const auto &interval){ + return + static_cast(interval.Extra()) + ->GetClip().get() == pClip; + } ); + + return HitTestResult::Intervals; + } + private: std::shared_ptr mpTrack; }; diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index d7d34ebc0..a53324a5c 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -279,6 +279,11 @@ CoarseTrackShifter::CoarseTrackShifter( Track &track ) CoarseTrackShifter::~CoarseTrackShifter() = default; +auto CoarseTrackShifter::HitTest( double ) -> HitTestResult +{ + return HitTestResult::Track; +} + template<> auto MakeTrackShifter::Implementation() -> Function { return [](Track &track) { return std::make_unique(track); @@ -494,29 +499,38 @@ UIHandle::Result TimeShiftHandle::Click mClipMoveState.capturedClip = NULL; mClipMoveState.capturedClipArray.clear(); - bool ok = true; bool captureClips = false; + bool capturedAClip = false; auto pShifter = MakeTrackShifter::Call( *pTrack ); - if (!event.ShiftDown()) - pTrack->TypeSwitch( - [&](WaveTrack *wt) { - if (nullptr == - (mClipMoveState.capturedClip = wt->GetClipAtX(event.m_x))) - ok = false; - else - captureClips = true; -#ifdef USE_MIDI - }, - [&](NoteTrack *) { - captureClips = true; -#endif - } - ); + if (!event.ShiftDown()) { + switch( pShifter->HitTest( clickTime ) ) { + case TrackShifter::HitTestResult::Miss: + return Cancelled; + case TrackShifter::HitTestResult::Intervals: { + captureClips = true; + if ( !pShifter->MovingIntervals().empty() ) { + capturedAClip = true; - if ( ! ok ) - return Cancelled; + // There is still some code special to WaveTracks here that + // needs to go elsewhere + auto &interval = pShifter->MovingIntervals()[0]; + auto pInfo = + dynamic_cast(interval.Extra()); + if ( pInfo ) + mClipMoveState.capturedClip = pInfo->GetClip().get(); + } + break; + } + case TrackShifter::HitTestResult::Track: + default: + break; + } + } + else { + // As in the default above: just do shifting of one whole track + } if ( captureClips ) { mClipMoveState.shifters[pTrack] = std::move( pShifter ); diff --git a/src/tracks/ui/TimeShiftHandle.h b/src/tracks/ui/TimeShiftHandle.h index 4e4ff0acf..7aa942996 100644 --- a/src/tracks/ui/TimeShiftHandle.h +++ b/src/tracks/ui/TimeShiftHandle.h @@ -32,6 +32,17 @@ public: //! There is always an associated track virtual Track &GetTrack() const = 0; + //! Possibilities for HitTest on the clicked track + enum class HitTestResult { + Miss, //!< Don't shift anything + Intervals, //; //! Return special intervals of the track that will not move @@ -63,6 +74,8 @@ public: ~CoarseTrackShifter() override; Track &GetTrack() const override { return *mpTrack; } + HitTestResult HitTest( double ) override; + private: std::shared_ptr mpTrack; };