1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-15 15:49:36 +02:00

Choose track or clip shifting behavior without a TypeSwitch...

... Preserving existing behavior, but maybe these cases should be reconsidered
and made more uniform.  (e.g. should hit test on NoteTrack sometimes miss, as
with WaveTrack?)

Also made details of WaveTrack hit testing consistent with what ClipMenus does
This commit is contained in:
Paul Licameli 2020-09-09 23:50:17 -04:00
parent 8f8c20ac80
commit c279fb6588
4 changed files with 67 additions and 18 deletions

View File

@ -742,6 +742,11 @@ public:
~NoteTrackShifter() override {}
Track &GetTrack() const override { return *mpTrack; }
HitTestResult HitTest( double ) override
{
return HitTestResult::Intervals;
}
private:
std::shared_ptr<NoteTrack> mpTrack;
};

View File

@ -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<WaveTrack::IntervalData*>(interval.Extra())
->GetClip().get() == pClip;
} );
return HitTestResult::Intervals;
}
private:
std::shared_ptr<WaveTrack> mpTrack;
};

View File

@ -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<CoarseTrackShifter>(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 ( ! ok )
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;
// There is still some code special to WaveTracks here that
// needs to go elsewhere
auto &interval = pShifter->MovingIntervals()[0];
auto pInfo =
dynamic_cast<WaveTrack::IntervalData*>(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 );

View File

@ -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, //<! May shift other tracks' intervals, if clicked in selection
Track //<! Shift selected track only as a whole
};
//! Decide how shift behaves, based on the track that is clicked in
/*! If the return value is Intervals, then some intervals may be marked moving as a side effect */
virtual HitTestResult HitTest( double time ) = 0;
using Intervals = std::vector<TrackInterval>;
//! 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<Track> mpTrack;
};