1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-30 07:39:42 +02:00

Define TrackShifter, subclasses, factory method; collect them...

... in TimeShiftHandle.  They do nothing useful yet, but responsibilities
will shift into them.

TypeSwitch is avoided and the subclasses are defined in appropriate places
for dependency management, thanks to AttachedVirtualFunction.
This commit is contained in:
Paul Licameli 2020-09-09 05:10:23 -04:00
parent 1501f09bf1
commit d8a894b95b
4 changed files with 106 additions and 2 deletions

View File

@ -729,4 +729,27 @@ void NoteTrackView::Draw(
}
CommonTrackView::Draw( context, rect, iPass );
}
#include "../../../ui/TimeShiftHandle.h"
class NoteTrackShifter final : public TrackShifter {
public:
NoteTrackShifter( NoteTrack &track )
: mpTrack{ track.SharedPointer<NoteTrack>() }
{}
~NoteTrackShifter() override {}
Track &GetTrack() const override { return *mpTrack; }
private:
std::shared_ptr<NoteTrack> mpTrack;
};
using MakeNoteTrackShifter = MakeTrackShifter::Override<NoteTrack>;
template<> template<> auto MakeNoteTrackShifter::Implementation() -> Function {
return [](NoteTrack &track) {
return std::make_unique<NoteTrackShifter>(track);
};
}
static MakeNoteTrackShifter registerMakeNoteTrackShifter;
#endif

View File

@ -1301,3 +1301,24 @@ void WaveTrackView::Draw(
CommonTrackView::Draw( context, rect, iPass );
}
class WaveTrackShifter final : public TrackShifter {
public:
WaveTrackShifter( WaveTrack &track )
: mpTrack{ track.SharedPointer<WaveTrack>() }
{
}
~WaveTrackShifter() override {}
Track &GetTrack() const override { return *mpTrack; }
private:
std::shared_ptr<WaveTrack> mpTrack;
};
using MakeWaveTrackShifter = MakeTrackShifter::Override<WaveTrack>;
template<> template<> auto MakeWaveTrackShifter::Implementation() -> Function {
return [](WaveTrack &track) {
return std::make_unique<WaveTrackShifter>(track);
};
}
static MakeWaveTrackShifter registerMakeWaveTrackShifter;

View File

@ -244,6 +244,20 @@ namespace
}
}
TrackShifter::~TrackShifter() = default;
CoarseTrackShifter::CoarseTrackShifter( Track &track )
: mpTrack{ track.SharedPointer() }
{}
CoarseTrackShifter::~CoarseTrackShifter() = default;
template<> auto MakeTrackShifter::Implementation() -> Function {
return [](Track &track) {
return std::make_unique<CoarseTrackShifter>(track);
};
}
void TimeShiftHandle::CreateListOfCapturedClips
( ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack,
TrackList &trackList, bool syncLocked, double clickTime )
@ -456,6 +470,8 @@ UIHandle::Result TimeShiftHandle::Click
bool ok = true;
bool captureClips = false;
auto pShifter = MakeTrackShifter::Call( *pTrack );
if (!event.ShiftDown())
pTrack->TypeSwitch(
[&](WaveTrack *wt) {
@ -474,10 +490,21 @@ UIHandle::Result TimeShiftHandle::Click
if ( ! ok )
return Cancelled;
else if ( captureClips )
if ( captureClips ) {
mClipMoveState.shifters[pTrack] = std::move( pShifter );
// Collect TrackShifters for the rest of the tracks
for ( auto track : trackList.Any() ) {
auto &pShifter = mClipMoveState.shifters[track];
if (!pShifter)
pShifter = MakeTrackShifter::Call( *track );
}
CreateListOfCapturedClips(
mClipMoveState, viewInfo, *pTrack, trackList,
ProjectSettings::Get( *pProject ).IsSyncLocked(), clickTime );
}
mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive;
mRect = rect;

View File

@ -11,12 +11,41 @@ Paul Licameli
#ifndef __AUDACITY_TIMESHIFT_HANDLE__
#define __AUDACITY_TIMESHIFT_HANDLE__
#include <unordered_map>
#include "../../AttachedVirtualFunction.h"
#include "../../UIHandle.h"
class SnapManager;
class Track;
using TrackArray = std::vector<Track*>;
class TrackList;
class Track;
//! Abstract base class for policies to manipulate a track type with the Time Shift tool
class TrackShifter {
public:
virtual ~TrackShifter() = 0;
//! There is always an associated track
virtual Track &GetTrack() const = 0;
};
//! Used in default of other reimplementations to shift any track as a whole, invoking Track::Offset()
class CoarseTrackShifter final : public TrackShifter {
public:
CoarseTrackShifter( Track &track );
~CoarseTrackShifter() override;
Track &GetTrack() const override { return *mpTrack; }
private:
std::shared_ptr<Track> mpTrack;
};
struct MakeTrackShifterTag;
using MakeTrackShifter = AttachedVirtualFunction<
MakeTrackShifterTag, std::unique_ptr<TrackShifter>, Track>;
class ViewInfo;
class WaveClip;
class WaveTrack;
@ -40,12 +69,15 @@ public:
using TrackClipArray = std::vector <TrackClip>;
struct ClipMoveState {
using ShifterMap = std::unordered_map<Track*, std::unique_ptr<TrackShifter>>;
// non-NULL only if click was in a WaveTrack and without Shift key:
WaveClip *capturedClip {};
bool capturedClipIsSelection {};
TrackArray trackExclusions {};
double hSlideAmount {};
ShifterMap shifters;
TrackClipArray capturedClipArray {};
wxInt64 snapLeft { -1 }, snapRight { -1 };
@ -57,6 +89,7 @@ struct ClipMoveState {
capturedClipIsSelection = false;
trackExclusions.clear();
hSlideAmount = 0;
shifters.clear();
capturedClipArray.clear();
snapLeft = snapRight = -1;
mMouseClickX = 0;
@ -73,7 +106,7 @@ public:
explicit TimeShiftHandle
( const std::shared_ptr<Track> &pTrack, bool gripHit );
TimeShiftHandle &operator=(const TimeShiftHandle&) = default;
TimeShiftHandle &operator=(TimeShiftHandle&&) = default;
bool IsGripHit() const { return mGripHit; }
std::shared_ptr<Track> GetTrack() const { return mCapturedTrack; }