mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-15 15:49:36 +02:00
TrackShifters decide what parts move or stay fixed...
... for now redundantly with the older logic. Also shorten a function name to Init
This commit is contained in:
parent
c279fb6588
commit
eb22892064
@ -654,7 +654,7 @@ double DoClipMove
|
||||
track->GetSelected() && !selectedRegion.isPoint();
|
||||
state.trackExclusions.clear();
|
||||
|
||||
TimeShiftHandle::CreateListOfCapturedClips(
|
||||
TimeShiftHandle::Init(
|
||||
state, viewInfo, *track, trackList, syncLocked, t0 );
|
||||
|
||||
auto desiredT0 = viewInfo.OffsetTimeByPixels( t0, ( right ? 1 : -1 ) );
|
||||
|
@ -741,12 +741,19 @@ public:
|
||||
}
|
||||
~NoteTrackShifter() override {}
|
||||
Track &GetTrack() const override { return *mpTrack; }
|
||||
|
||||
|
||||
HitTestResult HitTest( double ) override
|
||||
{
|
||||
return HitTestResult::Intervals;
|
||||
}
|
||||
|
||||
void SelectInterval( const TrackInterval &interval ) override
|
||||
{
|
||||
CommonSelectInterval( interval );
|
||||
}
|
||||
|
||||
bool SyncLocks() override { return true; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<NoteTrack> mpTrack;
|
||||
};
|
||||
|
@ -1329,6 +1329,21 @@ public:
|
||||
return HitTestResult::Intervals;
|
||||
}
|
||||
|
||||
void SelectInterval( const TrackInterval &interval ) override
|
||||
{
|
||||
UnfixIntervals( [&](auto &myInterval){
|
||||
// Use a slightly different test from CommonSelectInterval, rounding times
|
||||
// to exact samples according to the clip's rate
|
||||
auto data =
|
||||
static_cast<WaveTrack::IntervalData*>( myInterval.Extra() );
|
||||
auto clip = data->GetClip().get();
|
||||
return !(clip->IsClipStartAfterClip(interval.Start()) ||
|
||||
clip->BeforeClip(interval.End()));
|
||||
});
|
||||
}
|
||||
|
||||
bool SyncLocks() override { return true; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<WaveTrack> mpTrack;
|
||||
};
|
||||
|
@ -265,6 +265,19 @@ void TrackShifter::UnfixAll()
|
||||
mFixed = Intervals{};
|
||||
}
|
||||
|
||||
void TrackShifter::SelectInterval( const TrackInterval & )
|
||||
{
|
||||
UnfixAll();
|
||||
}
|
||||
|
||||
void TrackShifter::CommonSelectInterval(const TrackInterval &interval)
|
||||
{
|
||||
UnfixIntervals( [&](auto &myInterval){
|
||||
return !(interval.End() < myInterval.Start() ||
|
||||
myInterval.End() < interval.Start());
|
||||
});
|
||||
}
|
||||
|
||||
void TrackShifter::InitIntervals()
|
||||
{
|
||||
mMoving.clear();
|
||||
@ -284,15 +297,21 @@ auto CoarseTrackShifter::HitTest( double ) -> HitTestResult
|
||||
return HitTestResult::Track;
|
||||
}
|
||||
|
||||
bool CoarseTrackShifter::SyncLocks()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> auto MakeTrackShifter::Implementation() -> Function {
|
||||
return [](Track &track) {
|
||||
return std::make_unique<CoarseTrackShifter>(track);
|
||||
};
|
||||
}
|
||||
|
||||
void TimeShiftHandle::CreateListOfCapturedClips
|
||||
void TimeShiftHandle::Init
|
||||
( ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack,
|
||||
TrackList &trackList, bool syncLocked, double clickTime )
|
||||
TrackList &trackList, bool syncLocked, double clickTime,
|
||||
bool capturedAClip )
|
||||
{
|
||||
// The captured clip is the focus, but we need to create a list
|
||||
// of all clips that have to move, also...
|
||||
@ -302,9 +321,11 @@ void TimeShiftHandle::CreateListOfCapturedClips
|
||||
// First, if click was in selection, capture selected clips; otherwise
|
||||
// just the clicked-on clip
|
||||
if ( state.capturedClipIsSelection )
|
||||
// All selected tracks may move some intervals
|
||||
for (auto t : trackList.Selected())
|
||||
AddClipsToCaptured( state, viewInfo, t );
|
||||
else {
|
||||
// Move intervals only of the chosen channel group
|
||||
state.capturedClipArray.push_back
|
||||
(TrackClip( &capturedTrack, state.capturedClip ));
|
||||
|
||||
@ -320,6 +341,7 @@ void TimeShiftHandle::CreateListOfCapturedClips
|
||||
// Now, if sync-lock is enabled, capture any clip that's linked to a
|
||||
// captured clip.
|
||||
if ( syncLocked ) {
|
||||
// Sync lock propagation of unfixing of intervals
|
||||
// AWD: capturedClipArray expands as the loop runs, so newly-added
|
||||
// clips are considered (the effect is like recursion and terminates
|
||||
// because AddClipsToCaptured doesn't add duplicate clips); to remove
|
||||
@ -351,6 +373,70 @@ void TimeShiftHandle::CreateListOfCapturedClips
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Analogy of the steps above, but with TrackShifters, follows below
|
||||
|
||||
if ( state.capturedClipIsSelection ) {
|
||||
// All selected tracks may move some intervals
|
||||
const TrackInterval interval{
|
||||
viewInfo.selectedRegion.t0(),
|
||||
viewInfo.selectedRegion.t1()
|
||||
};
|
||||
for ( const auto &pair : state.shifters ) {
|
||||
auto &shifter = *pair.second;
|
||||
auto &track = shifter.GetTrack();
|
||||
if ( track.IsSelected() )
|
||||
shifter.SelectInterval( interval );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Move intervals only of the chosen channel group
|
||||
for ( auto channel : TrackList::Channels( &capturedTrack ) ) {
|
||||
auto &shifter = *state.shifters[channel];
|
||||
if ( capturedAClip ) {
|
||||
if ( channel != &capturedTrack )
|
||||
shifter.SelectInterval(TrackInterval{clickTime, clickTime});
|
||||
}
|
||||
else
|
||||
shifter.UnfixAll();
|
||||
}
|
||||
}
|
||||
|
||||
// Sync lock propagation of unfixing of intervals
|
||||
if ( syncLocked ) {
|
||||
bool change = true;
|
||||
while( change ) {
|
||||
change = false;
|
||||
|
||||
// Iterate over all unfixed intervals in all shifters
|
||||
// that do propagation...
|
||||
for ( auto &pair : state.shifters ) {
|
||||
auto &shifter = *pair.second.get();
|
||||
if (!shifter.SyncLocks())
|
||||
continue;
|
||||
auto &track = shifter.GetTrack();
|
||||
auto &intervals = shifter.MovingIntervals();
|
||||
for (auto &interval : intervals) {
|
||||
|
||||
// ...and tell all other tracks to select that interval...
|
||||
for ( auto &pair2 : state.shifters ) {
|
||||
auto &shifter2 = *pair2.second.get();
|
||||
if (&shifter2.GetTrack() == &track)
|
||||
continue;
|
||||
auto size = shifter2.MovingIntervals().size();
|
||||
shifter2.SelectInterval( interval );
|
||||
change = change ||
|
||||
(shifter2.SyncLocks() &&
|
||||
size != shifter2.MovingIntervals().size());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ... and repeat if any other interval became unfixed in a
|
||||
// shifter that propagates
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeShiftHandle::DoSlideHorizontal
|
||||
@ -542,9 +628,9 @@ UIHandle::Result TimeShiftHandle::Click
|
||||
pShifter = MakeTrackShifter::Call( *track );
|
||||
}
|
||||
|
||||
CreateListOfCapturedClips(
|
||||
Init(
|
||||
mClipMoveState, viewInfo, *pTrack, trackList,
|
||||
ProjectSettings::Get( *pProject ).IsSyncLocked(), clickTime );
|
||||
ProjectSettings::Get( *pProject ).IsSyncLocked(), clickTime, capturedAClip );
|
||||
}
|
||||
|
||||
mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive;
|
||||
|
@ -58,7 +58,17 @@ public:
|
||||
//! Change all intervals from fixed to moving
|
||||
void UnfixAll();
|
||||
|
||||
//! Notifies the shifter that a region is selected, so it may update its fixed and moving intervals
|
||||
/*! Default behavior: if any part of the track is selected, unfix all parts of it. */
|
||||
virtual void SelectInterval( const TrackInterval &interval );
|
||||
|
||||
//! Whether unfixing of an interval should propagate to all overlapping intervals in the sync lock group
|
||||
virtual bool SyncLocks() = 0;
|
||||
|
||||
protected:
|
||||
/*! Unfix any of the intervals that intersect the given one; may be useful to override `SelectInterval()` */
|
||||
void CommonSelectInterval( const TrackInterval &interval );
|
||||
|
||||
//! 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();
|
||||
@ -76,6 +86,9 @@ public:
|
||||
|
||||
HitTestResult HitTest( double ) override;
|
||||
|
||||
//! Returns false
|
||||
bool SyncLocks() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Track> mpTrack;
|
||||
};
|
||||
@ -150,9 +163,10 @@ public:
|
||||
std::shared_ptr<Track> GetTrack() const { return mCapturedTrack; }
|
||||
|
||||
// A utility function also used by menu commands
|
||||
static void CreateListOfCapturedClips
|
||||
static void Init
|
||||
( ClipMoveState &state, const ViewInfo &viewInfo, Track &capturedTrack,
|
||||
TrackList &trackList, bool syncLocked, double clickTime );
|
||||
TrackList &trackList, bool syncLocked, double clickTime,
|
||||
bool capturedAClip = true );
|
||||
|
||||
// A utility function also used by menu commands
|
||||
static void DoSlideHorizontal
|
||||
|
Loading…
x
Reference in New Issue
Block a user