From 4a55b0d0cc2738a909edd81d785ece51d251e7c2 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 21 Sep 2018 13:48:49 -0400 Subject: [PATCH 1/8] Remove unused functions --- src/tracks/ui/TimeShiftHandle.cpp | 55 ------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 0b2129906..46ac74f25 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -99,61 +99,6 @@ TimeShiftHandle::~TimeShiftHandle() namespace { - // Adds a track's clips to mCapturedClipArray within a specified time - void AddClipsToCaptured - (TrackClipArray &capturedClipArray, Track *pTrack, double t0, double t1) - { - if (pTrack->GetKind() == Track::Wave) - { - for(const auto &clip: static_cast(pTrack)->GetClips()) - { - if (!clip->AfterClip(t0) && !clip->BeforeClip(t1)) - { - // Avoid getting clips that were already captured - bool newClip = true; - for (unsigned int ii = 0; newClip && ii < capturedClipArray.size(); ++ii) - newClip = (capturedClipArray[ii].clip != clip.get()); - if (newClip) - capturedClipArray.push_back(TrackClip(pTrack, clip.get())); - } - } - } - else - { - // This handles label tracks rather heavy-handedly -- it would be nice to - // treat individual labels like clips - - // Avoid adding a track twice - bool newClip = true; - for (unsigned int ii = 0; newClip && ii < capturedClipArray.size(); ++ii) - newClip = (capturedClipArray[ii].track != pTrack); - if (newClip) { -#ifdef USE_MIDI - // do not add NoteTrack if the data is outside of time bounds - if (pTrack->GetKind() == Track::Note) { - if (pTrack->GetEndTime() < t0 || pTrack->GetStartTime() > t1) - return; - } -#endif - capturedClipArray.push_back(TrackClip(pTrack, NULL)); - } - } - } - - // Helper for the above, adds a track's clips to mCapturedClipArray (eliminates - // duplication of this logic) - void AddClipsToCaptured - (TrackClipArray &capturedClipArray, - const ViewInfo &viewInfo, Track *pTrack, bool withinSelection) - { - if (withinSelection) - AddClipsToCaptured(capturedClipArray, pTrack, - viewInfo.selectedRegion.t0(), viewInfo.selectedRegion.t1()); - else - AddClipsToCaptured(capturedClipArray, pTrack, - pTrack->GetStartTime(), pTrack->GetEndTime()); - } - // Adds a track's clips to state.capturedClipArray within a specified time void AddClipsToCaptured ( ClipMoveState &state, Track *t, double t0, double t1 ) From b79f5d9291a9437c1a2c41235aa76984af3d4705 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 22 Sep 2018 14:36:52 -0400 Subject: [PATCH 2/8] Simplification and better comments relating to time-shift... ... fewer switches on USE_MIDI. In fact capturedClipArray is nonempty whenever capturedClip is not null. --- src/Snap.h | 4 +- src/tracks/ui/TimeShiftHandle.cpp | 242 ++++++++++++------------------ 2 files changed, 99 insertions(+), 147 deletions(-) diff --git a/src/Snap.h b/src/Snap.h index 6aaf6f8bf..edddcccf4 100644 --- a/src/Snap.h +++ b/src/Snap.h @@ -40,8 +40,10 @@ public: Track *track; Track *origTrack; - WaveTrack *dstTrack; WaveClip *clip; + + // These fields are used only during time-shift dragging + WaveTrack *dstTrack; std::shared_ptr holder; }; diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 46ac74f25..5190d2211 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -61,8 +61,6 @@ UIHandlePtr TimeShiftHandle::HitAnywhere (std::weak_ptr &holder, const std::shared_ptr &pTrack, bool gripHit) { - // After all that, it still may be unsafe to drag. - // Even if so, make an informative cursor change from default to "banned." auto result = std::make_shared( pTrack, gripHit ); result = AssignUIHandlePtr(holder, result); return result; @@ -103,25 +101,18 @@ namespace void AddClipsToCaptured ( ClipMoveState &state, Track *t, double t0, double t1 ) { + auto &clips = state.capturedClipArray; + + bool exclude = true; if (t->GetKind() == Track::Wave) { + exclude = false; for(const auto &clip: static_cast(t)->GetClips()) - { - if ( ! clip->AfterClip(t0) && ! clip->BeforeClip(t1) ) - { + if ( ! clip->AfterClip(t0) && ! clip->BeforeClip(t1) && // Avoid getting clips that were already captured - bool newClip = true; - for (unsigned int i = 0; i < state.capturedClipArray.size(); ++i) { - if ( state.capturedClipArray[i].clip == clip.get() ) { - newClip = false; - break; - } - } - - if (newClip) - state.capturedClipArray.push_back( TrackClip(t, clip.get()) ); - } - } + ! std::any_of( clips.begin(), clips.end(), + [&](const TrackClip &c) { return c.clip == clip.get(); } ) ) + clips.emplace_back( t, clip.get() ); } else { @@ -129,15 +120,8 @@ namespace // treat individual labels like clips // Avoid adding a track twice - bool newClip = true; - for ( unsigned int i = 0; i < state.capturedClipArray.size(); ++i ) { - if ( state.capturedClipArray[i].track == t ) { - newClip = false; - break; - } - } - - if (newClip) { + if( ! std::any_of( clips.begin(), clips.end(), + [&](const TrackClip &c) { return c.track == t; } ) ) { #ifdef USE_MIDI // do not add NoteTrack if the data is outside of time bounds if (t->GetKind() == Track::Note) { @@ -145,12 +129,14 @@ namespace return; } #endif - state.capturedClipArray.push_back(TrackClip(t, NULL)); + clips.emplace_back( t, nullptr ); } } + if ( exclude ) + state.trackExclusions.push_back(t); } - // Helper for the above, adds a track's clips to mCapturedClipArray (eliminates + // Helper for the above, adds a track's clips to capturedClipArray (eliminates // duplication of this logic) void AddClipsToCaptured ( ClipMoveState &state, const ViewInfo &viewInfo, @@ -205,6 +191,31 @@ namespace return 0; } + + void DoOffset( ClipMoveState &state, Track *pTrack, double offset, + WaveClip *pExcludedClip = nullptr ) + { + auto &clips = state.capturedClipArray; + if ( !clips.empty() ) { + for (auto &clip : clips) { + if (clip.clip) { + if (clip.clip != pExcludedClip) + clip.clip->Offset( offset ); + } + else + clip.track->Offset( offset ); + } + } + else if ( pTrack ) { + // Was a shift-click + for (auto channel = + pTrack->GetLink() && !pTrack->GetLinked() + ? pTrack->GetLink() : pTrack; + channel; + channel = channel->GetLinked() ? channel->GetLink() : nullptr) + channel->Offset( offset ); + } + } } void TimeShiftHandle::CreateListOfCapturedClips @@ -221,11 +232,8 @@ void TimeShiftHandle::CreateListOfCapturedClips if ( state.capturedClipIsSelection ) { TrackListIterator iter( &trackList ); for (Track *t = iter.First(); t; t = iter.Next()) { - if (t->GetSelected()) { + if (t->GetSelected()) AddClipsToCaptured( state, viewInfo, t, true ); - if (t->GetKind() != Track::Wave) - state.trackExclusions.push_back(t); - } } } else { @@ -248,40 +256,33 @@ void TimeShiftHandle::CreateListOfCapturedClips // Now, if sync-lock is enabled, capture any clip that's linked to a // captured clip. if ( syncLocked ) { - // AWD: mCapturedClipArray expands as the loop runs, so newly-added + // 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 // this behavior just store the array size beforehand. for (unsigned int i = 0; i < state.capturedClipArray.size(); ++i) { + auto &trackClip = state.capturedClipArray[i]; // Capture based on tracks that have clips -- that means we // don't capture based on links to label tracks for now (until // we can treat individual labels as clips) - if ( state.capturedClipArray[i].clip ) { + if ( trackClip.clip ) { // Iterate over sync-lock group tracks. SyncLockedTracksIterator git( &trackList ); - for (Track *t = git.StartWith( state.capturedClipArray[i].track ); + for (Track *t = git.StartWith( trackClip.track ); t; t = git.Next() ) - { AddClipsToCaptured(state, t, - state.capturedClipArray[i].clip->GetStartTime(), - state.capturedClipArray[i].clip->GetEndTime() ); - if (t->GetKind() != Track::Wave) - state.trackExclusions.push_back(t); - } + trackClip.clip->GetStartTime(), + trackClip.clip->GetEndTime() ); } #ifdef USE_MIDI // Capture additional clips from NoteTracks - Track *nt = state.capturedClipArray[i].track; + Track *nt = trackClip.track; if (nt->GetKind() == Track::Note) { // Iterate over sync-lock group tracks. SyncLockedTracksIterator git( &trackList ); for (Track *t = git.StartWith(nt); t; t = git.Next()) - { AddClipsToCaptured ( state, t, nt->GetStartTime(), nt->GetEndTime() ); - if (t->GetKind() != Track::Wave) - state.trackExclusions.push_back(t); - } } #endif } @@ -291,11 +292,10 @@ void TimeShiftHandle::CreateListOfCapturedClips void TimeShiftHandle::DoSlideHorizontal ( ClipMoveState &state, TrackList &trackList, Track &capturedTrack ) { -#ifdef USE_MIDI + // Given a signed slide distance, move clips, but subject to constraint of + // non-overlapping with other clips, so the distance may be adjusted toward + // zero. if ( state.capturedClipArray.size() ) -#else - if ( state.capturedClip ) -#endif { double allowed; double initialAllowed; @@ -305,21 +305,18 @@ void TimeShiftHandle::DoSlideHorizontal do { // loop to compute allowed, does not actually move anything yet initialAllowed = state.hSlideAmount; - unsigned int i, j; - for ( i = 0; i < state.capturedClipArray.size(); ++i ) { - WaveTrack *track = (WaveTrack *)state.capturedClipArray[i].track; - WaveClip *clip = state. capturedClipArray[i].clip; + for ( auto &trackClip : state.capturedClipArray ) { + if (const auto clip = trackClip.clip) { + // only audio clips are used to compute allowed + const auto track = static_cast( trackClip.track ); - if (clip) { // only audio clips are used to compute allowed // Move all other selected clips totally out of the way // temporarily because they're all moving together and // we want to find out if OTHER clips are in the way, // not one of the moving ones - for ( j = 0; j < state.capturedClipArray.size(); j++ ) { - WaveClip *clip2 = state.capturedClipArray[j].clip; - if (clip2 && clip2 != clip) - clip2->Offset(-safeBigDistance); - } + DoOffset( state, nullptr, -safeBigDistance, clip ); + auto cleanup = finally( [&] + { DoOffset( state, nullptr, safeBigDistance, clip ); } ); if ( track->CanOffsetClip(clip, state.hSlideAmount, &allowed) ) { if ( state.hSlideAmount != allowed ) { @@ -331,36 +328,18 @@ void TimeShiftHandle::DoSlideHorizontal state.hSlideAmount = 0.0; state.snapLeft = state.snapRight = -1; // see bug 1067 } - - for ( j = 0; j < state.capturedClipArray.size(); ++j ) { - WaveClip *clip2 = state.capturedClipArray[j].clip; - if (clip2 && clip2 != clip) - clip2->Offset(safeBigDistance); - } } } } while ( state.hSlideAmount != initialAllowed ); - if ( state.hSlideAmount != 0.0 ) { // finally, here is where clips are moved - unsigned int i; - for ( i = 0; i < state.capturedClipArray.size(); ++i ) { - Track *track = state.capturedClipArray[i].track; - WaveClip *clip = state.capturedClipArray[i].clip; - if (clip) - clip->Offset( state.hSlideAmount ); - else - track->Offset( state.hSlideAmount ); - } - } + // finally, here is where clips are moved + if ( state.hSlideAmount != 0.0 ) + DoOffset( state, nullptr, state.hSlideAmount ); } - else { + else // For Shift key down, or // For non wavetracks, specifically label tracks ... - capturedTrack.Offset( state.hSlideAmount ); - Track* link = capturedTrack.GetLink(); - if (link) - link->Offset( state.hSlideAmount ); - } + DoOffset( state, &capturedTrack, state.hSlideAmount ); } UIHandle::Result TimeShiftHandle::Click @@ -427,7 +406,6 @@ UIHandle::Result TimeShiftHandle::Click mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive; mRect = rect; mMouseClickX = event.m_x; - const double selStart = viewInfo.PositionToTime(event.m_x, mRect.x); mSnapManager = std::make_shared(trackList, &viewInfo, &mClipMoveState.capturedClipArray, @@ -437,8 +415,8 @@ UIHandle::Result TimeShiftHandle::Click mClipMoveState.snapRight = -1; mSnapPreferRightEdge = mClipMoveState.capturedClip && - (fabs(selStart - mClipMoveState.capturedClip->GetEndTime()) < - fabs(selStart - mClipMoveState.capturedClip->GetStartTime())); + (fabs(clickTime - mClipMoveState.capturedClip->GetEndTime()) < + fabs(clickTime - mClipMoveState.capturedClip->GetStartTime())); return RefreshNone; } @@ -446,15 +424,21 @@ UIHandle::Result TimeShiftHandle::Click UIHandle::Result TimeShiftHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { + using namespace RefreshCode; + const bool unsafe = pProject->IsAudioActive(); + if (unsafe) { + this->Cancel(pProject); + return RefreshAll | Cancelled; + } + const wxMouseEvent &event = evt.event; ViewInfo &viewInfo = pProject->GetViewInfo(); - // We may switch pTrack to its stereo partner below Track *track = dynamic_cast(evt.pCell.get()); // Uncommenting this permits drag to continue to work even over the controls area /* - pTrack = static_cast(evt.pCell)->FindTrack().get(); + track = static_cast(evt.pCell)->FindTrack().get(); */ if (!track) { @@ -471,13 +455,6 @@ UIHandle::Result TimeShiftHandle::Drag return RefreshCode::RefreshNone; - using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); - if (unsafe) { - this->Cancel(pProject); - return RefreshAll | Cancelled; - } - TrackList *const trackList = pProject->GetTracks(); // GM: DoSlide now implementing snap-to @@ -486,28 +463,8 @@ UIHandle::Result TimeShiftHandle::Drag // Start by undoing the current slide amount; everything // happens relative to the original horizontal position of // each clip... -#ifdef USE_MIDI - if (mClipMoveState.capturedClipArray.size()) -#else - if (mClipMoveState.capturedClip) -#endif - { - for (unsigned ii = 0; ii < mClipMoveState.capturedClipArray.size(); ++ii) { - if (mClipMoveState.capturedClipArray[ii].clip) - mClipMoveState.capturedClipArray[ii].clip->Offset - ( -mClipMoveState.hSlideAmount ); - else - mClipMoveState.capturedClipArray[ii].track->Offset - ( -mClipMoveState.hSlideAmount ); - } - } - else { - // Was a shift-click - mCapturedTrack->Offset( -mClipMoveState.hSlideAmount ); - Track *const link = mCapturedTrack->GetLink(); - if (link) - link->Offset( -mClipMoveState.hSlideAmount ); - } + DoOffset( + mClipMoveState, mCapturedTrack.get(), -mClipMoveState.hSlideAmount ); if ( mClipMoveState.capturedClipIsSelection ) { // Slide the selection, too @@ -593,9 +550,7 @@ UIHandle::Result TimeShiftHandle::Drag const int diff = TrackPosition(*trackList, pTrack.get()) - TrackPosition(*trackList, mCapturedTrack.get()); - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ii < nn; ++ii ) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { if (trackClip.clip) { // Move all clips up or down by an equal count of audio tracks. Track *const pSrcTrack = trackClip.track; @@ -620,9 +575,7 @@ UIHandle::Result TimeShiftHandle::Drag // Having passed that test, remove clips temporarily from their // tracks, so moving clips don't interfere with each other // when we call CanInsertClip() - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ii < nn; ++ii ) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { WaveClip *const pSrcClip = trackClip.clip; if (pSrcClip) trackClip.holder = @@ -640,24 +593,28 @@ UIHandle::Result TimeShiftHandle::Drag double tolerance = viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x); // The desiredSlideAmount may change and the tolerance may get used up. - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ok && ii < nn; ++ii) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) - ok = trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance); + if (pSrcClip) { + ok = trackClip.dstTrack->CanInsertClip( + pSrcClip, desiredSlideAmount, tolerance ); + if( !ok ) + break; + } } if( ok ) { // fits ok, but desiredSlideAmount could have been updated to get the clip to fit. // Check again, in the new position, this time with zero tolerance. tolerance = 0.0; - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ok && ii < nn; ++ii) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) - ok = trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance); + if (pSrcClip) { + ok = trackClip.dstTrack->CanInsertClip( + pSrcClip, desiredSlideAmount, tolerance); + if ( !ok ) + break; + } } } @@ -668,9 +625,7 @@ UIHandle::Result TimeShiftHandle::Drag ok = true; // assume slide is OK. tolerance = 0.0; desiredSlideAmount = slide; - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ii < nn; ++ii) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { WaveClip *const pSrcClip = trackClip.clip; if (pSrcClip){ // back to the track it came from... @@ -678,9 +633,7 @@ UIHandle::Result TimeShiftHandle::Drag ok = ok && trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance); } } - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ii < nn; ++ii) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray) { WaveClip *const pSrcClip = trackClip.clip; if (pSrcClip){ @@ -707,9 +660,7 @@ UIHandle::Result TimeShiftHandle::Drag } else { // Do the vertical moves of clips - for ( unsigned ii = 0, nn = mClipMoveState.capturedClipArray.size(); - ii < nn; ++ii ) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { WaveClip *const pSrcClip = trackClip.clip; if (pSrcClip) { const auto dstTrack = trackClip.dstTrack; @@ -778,19 +729,18 @@ UIHandle::Result TimeShiftHandle::Release if ( !mDidSlideVertically && mClipMoveState.hSlideAmount == 0 ) return result; - for ( size_t ii = 0; ii < mClipMoveState.capturedClipArray.size(); ++ii ) + for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - TrackClip &trackClip = mClipMoveState.capturedClipArray[ii]; WaveClip* pWaveClip = trackClip.clip; // Note that per AddClipsToCaptured(Track *t, double t0, double t1), - // in the non-WaveTrack case, the code adds a NULL clip to mCapturedClipArray, + // in the non-WaveTrack case, the code adds a NULL clip to capturedClipArray, // so we have to check for that any time we're going to deref it. // Previous code did not check it here, and that caused bug 367 crash. if (pWaveClip && trackClip.track != trackClip.origTrack) { // Now that user has dropped the clip into a different track, - // make sure the sample rate matches the destination track (mCapturedTrack). + // make sure the sample rate matches the destination track. // Assume the clip was dropped in a wave track pWaveClip->Resample (static_cast(trackClip.track)->GetRate()); From 37b3968dd6b843f0fd268a009be5b81508701865 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 14:06:13 -0400 Subject: [PATCH 3/8] Some factoring of TimeShiftHandle::Drag --- src/tracks/ui/TimeShiftHandle.cpp | 66 +++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 5190d2211..9a855c16a 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -421,6 +421,48 @@ UIHandle::Result TimeShiftHandle::Click return RefreshNone; } +namespace { + struct TemporaryClipRemover { + TemporaryClipRemover( ClipMoveState &clipMoveState ) + : state( clipMoveState ) + { + // Pluck the moving clips out of their tracks + for ( auto &trackClip : state.capturedClipArray ) { + WaveClip *const pSrcClip = trackClip.clip; + if (pSrcClip) + trackClip.holder = + // Assume track is wave because it has a clip + static_cast(trackClip.track)-> + RemoveAndReturnClip(pSrcClip); + } + } + + void Fail() + { + // Cause destructor to put all clips back where they came from + for ( auto &trackClip : state.capturedClipArray ) + trackClip.dstTrack = static_cast(trackClip.track); + } + + ~TemporaryClipRemover() + { + // Complete (or roll back) the vertical move. + // Put moving clips into their destination tracks + // which become the source tracks when we move again + for ( auto &trackClip : state.capturedClipArray ) { + WaveClip *const pSrcClip = trackClip.clip; + if (pSrcClip) { + const auto dstTrack = trackClip.dstTrack; + dstTrack->AddClip(std::move(trackClip.holder)); + trackClip.track = dstTrack; + } + } + } + + ClipMoveState &state; + }; +} + UIHandle::Result TimeShiftHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { @@ -575,14 +617,7 @@ UIHandle::Result TimeShiftHandle::Drag // Having passed that test, remove clips temporarily from their // tracks, so moving clips don't interfere with each other // when we call CanInsertClip() - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) - trackClip.holder = - // Assume track is wave because it has a clip - static_cast(trackClip.track)-> - RemoveAndReturnClip(pSrcClip); - } + TemporaryClipRemover remover( mClipMoveState ); // Now check that the move is possible bool ok = true; @@ -620,6 +655,8 @@ UIHandle::Result TimeShiftHandle::Drag if (!ok) { // Failure, even with using tolerance. + remover.Fail(); + // Failure -- we'll put clips back where they were // ok will next indicate if a horizontal slide is OK. ok = true; // assume slide is OK. @@ -641,9 +678,6 @@ UIHandle::Result TimeShiftHandle::Drag // Put the clip back appropriately shifted! if( ok) trackClip.holder->Offset(slide); - // Assume track is wave because it has a clip - static_cast(trackClip.track)-> - AddClip(std::move(trackClip.holder)); } } // Make the offset permanent; start from a "clean slate" @@ -659,16 +693,6 @@ UIHandle::Result TimeShiftHandle::Drag return RefreshAll; } else { - // Do the vertical moves of clips - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) { - const auto dstTrack = trackClip.dstTrack; - dstTrack->AddClip(std::move(trackClip.holder)); - trackClip.track = dstTrack; - } - } - mCapturedTrack = pTrack; mDidSlideVertically = true; From aa3c3a8d5afe55ccc509e6d539287b8bfa07ba1b Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 14:50:56 -0400 Subject: [PATCH 4/8] More factoring of TimeShiftHandle::Drag --- src/tracks/ui/TimeShiftHandle.cpp | 144 ++++++++++++++++-------------- src/tracks/ui/TimeShiftHandle.h | 5 +- 2 files changed, 81 insertions(+), 68 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 9a855c16a..7de9c0f77 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -405,7 +405,7 @@ UIHandle::Result TimeShiftHandle::Click mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive; mRect = rect; - mMouseClickX = event.m_x; + mClipMoveState.mMouseClickX = event.m_x; mSnapManager = std::make_shared(trackList, &viewInfo, &mClipMoveState.capturedClipArray, @@ -422,6 +422,77 @@ UIHandle::Result TimeShiftHandle::Click } namespace { + double FindDesiredSlideAmount( + const ViewInfo &viewInfo, wxCoord xx, const wxMouseEvent &event, + SnapManager *pSnapManager, + bool slideUpDownOnly, bool snapPreferRightEdge, + ClipMoveState &state, + Track &capturedTrack, Track &track ) + { + if (slideUpDownOnly) + return 0.0; + else { + double desiredSlideAmount = + viewInfo.PositionToTime(event.m_x) - + viewInfo.PositionToTime(state.mMouseClickX); + double clipLeft = 0, clipRight = 0; + + if (track.GetKind() == Track::Wave) { + WaveTrack *const mtw = static_cast(&track); + const double rate = mtw->GetRate(); + // set it to a sample point + desiredSlideAmount = rint(desiredSlideAmount * rate) / rate; + } + + // Adjust desiredSlideAmount using SnapManager + if (pSnapManager) { + if (state.capturedClip) { + clipLeft = state.capturedClip->GetStartTime() + + desiredSlideAmount; + clipRight = state.capturedClip->GetEndTime() + + desiredSlideAmount; + } + else { + clipLeft = capturedTrack.GetStartTime() + desiredSlideAmount; + clipRight = capturedTrack.GetEndTime() + desiredSlideAmount; + } + + auto results = + pSnapManager->Snap(&capturedTrack, clipLeft, false); + auto newClipLeft = results.outTime; + results = + pSnapManager->Snap(&capturedTrack, clipRight, false); + auto newClipRight = results.outTime; + + // Only one of them is allowed to snap + if (newClipLeft != clipLeft && newClipRight != clipRight) { + // Un-snap the un-preferred edge + if (snapPreferRightEdge) + newClipLeft = clipLeft; + else + newClipRight = clipRight; + } + + // Take whichever one snapped (if any) and compute the NEW desiredSlideAmount + state.snapLeft = -1; + state.snapRight = -1; + if (newClipLeft != clipLeft) { + const double difference = (newClipLeft - clipLeft); + desiredSlideAmount += difference; + state.snapLeft = + viewInfo.TimeToPosition(newClipLeft, xx); + } + else if (newClipRight != clipRight) { + const double difference = (newClipRight - clipRight); + desiredSlideAmount += difference; + state.snapRight = + viewInfo.TimeToPosition(newClipRight, xx); + } + } + return desiredSlideAmount; + } + } + struct TemporaryClipRemover { TemporaryClipRemover( ClipMoveState &clipMoveState ) : state( clipMoveState ) @@ -514,69 +585,10 @@ UIHandle::Result TimeShiftHandle::Drag } mClipMoveState.hSlideAmount = 0.0; - double desiredSlideAmount; - if (mSlideUpDownOnly) { - desiredSlideAmount = 0.0; - } - else { - desiredSlideAmount = - viewInfo.PositionToTime(event.m_x) - - viewInfo.PositionToTime(mMouseClickX); - double clipLeft = 0, clipRight = 0; - - if (pTrack->GetKind() == Track::Wave) { - WaveTrack *const mtw = static_cast(pTrack.get()); - const double rate = mtw->GetRate(); - // set it to a sample point - desiredSlideAmount = rint(desiredSlideAmount * rate) / rate; - } - - // Adjust desiredSlideAmount using SnapManager - if (mSnapManager.get()) { - if (mClipMoveState.capturedClip) { - clipLeft = mClipMoveState.capturedClip->GetStartTime() - + desiredSlideAmount; - clipRight = mClipMoveState.capturedClip->GetEndTime() - + desiredSlideAmount; - } - else { - clipLeft = mCapturedTrack->GetStartTime() + desiredSlideAmount; - clipRight = mCapturedTrack->GetEndTime() + desiredSlideAmount; - } - - auto results = - mSnapManager->Snap(mCapturedTrack.get(), clipLeft, false); - auto newClipLeft = results.outTime; - results = - mSnapManager->Snap(mCapturedTrack.get(), clipRight, false); - auto newClipRight = results.outTime; - - // Only one of them is allowed to snap - if (newClipLeft != clipLeft && newClipRight != clipRight) { - // Un-snap the un-preferred edge - if (mSnapPreferRightEdge) - newClipLeft = clipLeft; - else - newClipRight = clipRight; - } - - // Take whichever one snapped (if any) and compute the NEW desiredSlideAmount - mClipMoveState.snapLeft = -1; - mClipMoveState.snapRight = -1; - if (newClipLeft != clipLeft) { - const double difference = (newClipLeft - clipLeft); - desiredSlideAmount += difference; - mClipMoveState.snapLeft = - viewInfo.TimeToPosition(newClipLeft, mRect.x); - } - else if (newClipRight != clipRight) { - const double difference = (newClipRight - clipRight); - desiredSlideAmount += difference; - mClipMoveState.snapRight = - viewInfo.TimeToPosition(newClipRight, mRect.x); - } - } - } + double desiredSlideAmount = + FindDesiredSlideAmount( viewInfo, mRect.x, event, mSnapManager.get(), + mSlideUpDownOnly, mSnapPreferRightEdge, mClipMoveState, + *mCapturedTrack, *pTrack ); // Scroll during vertical drag. // EnsureVisible(pTrack); //vvv Gale says this has problems on Linux, per bug 393 thread. Revert for 2.0.2. @@ -682,7 +694,7 @@ UIHandle::Result TimeShiftHandle::Drag } // Make the offset permanent; start from a "clean slate" if( ok ) { - mMouseClickX = event.m_x; + mClipMoveState.mMouseClickX = event.m_x; if (mClipMoveState.capturedClipIsSelection) { // Slide the selection, too viewInfo.selectedRegion.move( slide ); @@ -697,7 +709,7 @@ UIHandle::Result TimeShiftHandle::Drag mDidSlideVertically = true; // Make the offset permanent; start from a "clean slate" - mMouseClickX = event.m_x; + mClipMoveState.mMouseClickX = event.m_x; } // Not done yet, check for horizontal movement. diff --git a/src/tracks/ui/TimeShiftHandle.h b/src/tracks/ui/TimeShiftHandle.h index 0a81acfce..7f81ec8db 100644 --- a/src/tracks/ui/TimeShiftHandle.h +++ b/src/tracks/ui/TimeShiftHandle.h @@ -30,6 +30,8 @@ struct ClipMoveState { TrackClipArray capturedClipArray {}; wxInt64 snapLeft { -1 }, snapRight { -1 }; + int mMouseClickX{}; + void clear() { capturedClip = nullptr; @@ -38,6 +40,7 @@ struct ClipMoveState { hSlideAmount = 0; capturedClipArray.clear(); snapLeft = snapRight = -1; + mMouseClickX = 0; } }; @@ -108,8 +111,6 @@ private: bool mSnapPreferRightEdge{}; - int mMouseClickX{}; - // Handles snapping the selection boundaries or track boundaries to // line up with existing tracks or labels. mSnapLeft and mSnapRight // are the horizontal index of pixels to display user feedback From fc5f7331d1c2d8549284416037e2b924e4405d82 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 19:14:14 -0400 Subject: [PATCH 5/8] More factoring of TimeShiftHandle::Drag --- src/tracks/ui/TimeShiftHandle.cpp | 57 ++++++++++++++++++------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 7de9c0f77..368a608a9 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -493,6 +493,37 @@ namespace { } } + bool FindCorrespondence( + TrackList &trackList, Track &track, Track &capturedTrack, + ClipMoveState &state) + { + const int diff = + TrackPosition(trackList, &track) - + TrackPosition(trackList, &capturedTrack); + for ( auto &trackClip : state.capturedClipArray ) { + if (trackClip.clip) { + // Move all clips up or down by an equal count of audio tracks. + Track *const pSrcTrack = trackClip.track; + auto pDstTrack = NthAudioTrack(trackList, + diff + TrackPosition(trackList, pSrcTrack)); + // Can only move mono to mono, or left to left, or right to right + // And that must be so for each captured clip + bool stereo = (pSrcTrack->GetLink() != 0); + if (pDstTrack && stereo && !pSrcTrack->GetLinked()) + // Assume linked track is wave or null + pDstTrack = static_cast(pDstTrack->GetLink()); + bool ok = pDstTrack && + (stereo == (pDstTrack->GetLink() != 0)) && + (!stereo || (pSrcTrack->GetLinked() == pDstTrack->GetLinked())); + if (ok) + trackClip.dstTrack = pDstTrack; + else + return false; + } + } + return true; + } + struct TemporaryClipRemover { TemporaryClipRemover( ClipMoveState &clipMoveState ) : state( clipMoveState ) @@ -601,30 +632,8 @@ UIHandle::Result TimeShiftHandle::Drag pTrack->GetKind() == Track::Wave /* && !mCapturedClipIsSelection*/) { - const int diff = - TrackPosition(*trackList, pTrack.get()) - - TrackPosition(*trackList, mCapturedTrack.get()); - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - if (trackClip.clip) { - // Move all clips up or down by an equal count of audio tracks. - Track *const pSrcTrack = trackClip.track; - auto pDstTrack = NthAudioTrack(*trackList, - diff + TrackPosition(*trackList, pSrcTrack)); - // Can only move mono to mono, or left to left, or right to right - // And that must be so for each captured clip - bool stereo = (pSrcTrack->GetLink() != 0); - if (pDstTrack && stereo && !pSrcTrack->GetLinked()) - // Assume linked track is wave or null - pDstTrack = static_cast(pDstTrack->GetLink()); - bool ok = pDstTrack && - (stereo == (pDstTrack->GetLink() != 0)) && - (!stereo || (pSrcTrack->GetLinked() == pDstTrack->GetLinked())); - if (ok) - trackClip.dstTrack = pDstTrack; - else - return RefreshAll; - } - } + if (!FindCorrespondence( *trackList, *pTrack, *mCapturedTrack, mClipMoveState)) + return RefreshAll; // Having passed that test, remove clips temporarily from their // tracks, so moving clips don't interfere with each other From d812513979634d05d8c13dccb82a91f79923709f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 19:27:07 -0400 Subject: [PATCH 6/8] More factoring of TimeShiftHandle::Drag --- src/tracks/ui/TimeShiftHandle.cpp | 75 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 368a608a9..d949ec440 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -524,6 +524,36 @@ namespace { return true; } + bool CheckFit( + const ViewInfo &viewInfo, wxCoord xx, ClipMoveState &state, + double tolerance, double &desiredSlideAmount ) + { + 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; + } + } + // 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. + if (firstTolerance == 0) + break; + else + tolerance = 0.0; + } + + return ok; + } + struct TemporaryClipRemover { TemporaryClipRemover( ClipMoveState &clipMoveState ) : state( clipMoveState ) @@ -641,56 +671,23 @@ UIHandle::Result TimeShiftHandle::Drag TemporaryClipRemover remover( mClipMoveState ); // Now check that the move is possible - bool ok = true; + double slide = desiredSlideAmount; // remember amount requested. // The test for tolerance will need review with FishEye! // The tolerance is supposed to be the time for one pixel, i.e. one pixel tolerance // at current zoom. - double slide = desiredSlideAmount; // remember amount requested. - double tolerance = viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x); - - // The desiredSlideAmount may change and the tolerance may get used up. - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) { - ok = trackClip.dstTrack->CanInsertClip( - pSrcClip, desiredSlideAmount, tolerance ); - if( !ok ) - break; - } - } - - if( ok ) { - // fits ok, but desiredSlideAmount could have been updated to get the clip to fit. - // Check again, in the new position, this time with zero tolerance. - tolerance = 0.0; - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip) { - ok = trackClip.dstTrack->CanInsertClip( - pSrcClip, desiredSlideAmount, tolerance); - if ( !ok ) - break; - } - } - } - + double tolerance = + viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x); + bool ok = CheckFit( viewInfo, event.m_x, mClipMoveState, tolerance, desiredSlideAmount ); + if (!ok) { // Failure, even with using tolerance. remover.Fail(); // Failure -- we'll put clips back where they were // ok will next indicate if a horizontal slide is OK. - ok = true; // assume slide is OK. tolerance = 0.0; desiredSlideAmount = slide; - for ( auto &trackClip : mClipMoveState.capturedClipArray ) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip){ - // back to the track it came from... - trackClip.dstTrack = static_cast(trackClip.track); - ok = ok && trackClip.dstTrack->CanInsertClip(pSrcClip, desiredSlideAmount, tolerance); - } - } + ok = CheckFit( viewInfo, event.m_x, mClipMoveState, tolerance, desiredSlideAmount ); for ( auto &trackClip : mClipMoveState.capturedClipArray) { WaveClip *const pSrcClip = trackClip.clip; if (pSrcClip){ From 68eb24545bf151e131d3a254550580a2dc8e19ce Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 19:43:48 -0400 Subject: [PATCH 7/8] More factoring of TimeShiftHandle::Drag --- src/tracks/ui/TimeShiftHandle.cpp | 115 ++++++++++++++++-------------- src/tracks/ui/TimeShiftHandle.h | 8 +++ 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index d949ec440..22e1858b2 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -595,6 +595,65 @@ namespace { }; } +bool TimeShiftHandle::DoSlideVertical +( ViewInfo &viewInfo, wxCoord xx, + ClipMoveState &state, TrackList &trackList, Track &capturedTrack, + Track &dstTrack, double &desiredSlideAmount ) +{ + if (!FindCorrespondence( trackList, dstTrack, capturedTrack, state)) + return false; + + // Having passed that test, remove clips temporarily from their + // tracks, so moving clips don't interfere with each other + // when we call CanInsertClip() + TemporaryClipRemover remover{ state }; + + // Now check that the move is possible + double slide = desiredSlideAmount; // remember amount requested. + // The test for tolerance will need review with FishEye! + // The tolerance is supposed to be the time for one pixel, + // 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 ); + + if (!ok) { + // Failure, even with using tolerance. + remover.Fail(); + + // Failure -- we'll put clips back where they were + // ok will next indicate if a horizontal slide is OK. + tolerance = 0.0; + desiredSlideAmount = slide; + ok = CheckFit( viewInfo, xx, state, tolerance, desiredSlideAmount ); + for ( auto &trackClip : state.capturedClipArray) { + WaveClip *const pSrcClip = trackClip.clip; + if (pSrcClip){ + + // Attempt to move to a new track did not work. + // Put the clip back appropriately shifted! + if( ok) + trackClip.holder->Offset(slide); + } + } + // Make the offset permanent; start from a "clean slate" + if( ok ) { + state.mMouseClickX = xx; + if (state.capturedClipIsSelection) { + // Slide the selection, too + viewInfo.selectedRegion.move( slide ); + } + state.hSlideAmount = 0; + } + + return false; + } + + // Make the offset permanent; start from a "clean slate" + state.mMouseClickX = xx; + return true; +} + UIHandle::Result TimeShiftHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { @@ -662,61 +721,13 @@ UIHandle::Result TimeShiftHandle::Drag pTrack->GetKind() == Track::Wave /* && !mCapturedClipIsSelection*/) { - if (!FindCorrespondence( *trackList, *pTrack, *mCapturedTrack, mClipMoveState)) - return RefreshAll; - - // Having passed that test, remove clips temporarily from their - // tracks, so moving clips don't interfere with each other - // when we call CanInsertClip() - TemporaryClipRemover remover( mClipMoveState ); - - // Now check that the move is possible - double slide = desiredSlideAmount; // remember amount requested. - // The test for tolerance will need review with FishEye! - // The tolerance is supposed to be the time for one pixel, i.e. one pixel tolerance - // at current zoom. - double tolerance = - viewInfo.PositionToTime(event.m_x+1) - viewInfo.PositionToTime(event.m_x); - bool ok = CheckFit( viewInfo, event.m_x, mClipMoveState, tolerance, desiredSlideAmount ); - - if (!ok) { - // Failure, even with using tolerance. - remover.Fail(); - - // Failure -- we'll put clips back where they were - // ok will next indicate if a horizontal slide is OK. - tolerance = 0.0; - desiredSlideAmount = slide; - ok = CheckFit( viewInfo, event.m_x, mClipMoveState, tolerance, desiredSlideAmount ); - for ( auto &trackClip : mClipMoveState.capturedClipArray) { - WaveClip *const pSrcClip = trackClip.clip; - if (pSrcClip){ - - // Attempt to move to a new track did not work. - // Put the clip back appropriately shifted! - if( ok) - trackClip.holder->Offset(slide); - } - } - // Make the offset permanent; start from a "clean slate" - if( ok ) { - mClipMoveState.mMouseClickX = event.m_x; - if (mClipMoveState.capturedClipIsSelection) { - // Slide the selection, too - viewInfo.selectedRegion.move( slide ); - } - mClipMoveState.hSlideAmount = 0; - } - - return RefreshAll; - } - else { + if ( DoSlideVertical( viewInfo, event.m_x, mClipMoveState, + *trackList, *mCapturedTrack, *pTrack, desiredSlideAmount ) ) { mCapturedTrack = pTrack; mDidSlideVertically = true; - - // Make the offset permanent; start from a "clean slate" - mClipMoveState.mMouseClickX = event.m_x; } + else + return RefreshAll; // Not done yet, check for horizontal movement. slidVertically = true; diff --git a/src/tracks/ui/TimeShiftHandle.h b/src/tracks/ui/TimeShiftHandle.h index 7f81ec8db..782ce7a83 100644 --- a/src/tracks/ui/TimeShiftHandle.h +++ b/src/tracks/ui/TimeShiftHandle.h @@ -68,6 +68,14 @@ public: static void DoSlideHorizontal ( ClipMoveState &state, TrackList &trackList, Track &capturedTrack ); + // Try to move clips from one WaveTrack to another, before also moving + // by some horizontal amount, which may be slightly adjusted to fit the + // destination tracks. + static bool DoSlideVertical + ( ViewInfo &viewInfo, wxCoord xx, + ClipMoveState &state, TrackList &trackList, Track &capturedTrack, + Track &dstTrack, double &desiredSlideAmount ); + static UIHandlePtr HitAnywhere (std::weak_ptr &holder, const std::shared_ptr &pTrack, bool gripHit); From 4998a5cea5260165c61fc6ef79c973a15643df60 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 26 Sep 2018 19:48:30 -0400 Subject: [PATCH 8/8] Rearrange some logic in TimeShiftHandle::Click --- src/tracks/ui/TimeShiftHandle.cpp | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index 22e1858b2..06988a0e9 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -373,35 +373,37 @@ UIHandle::Result TimeShiftHandle::Click clickTime >= viewInfo.selectedRegion.t0() && clickTime < viewInfo.selectedRegion.t1()); - WaveTrack *wt = pTrack->GetKind() == Track::Wave - ? static_cast(pTrack.get()) : nullptr; + mClipMoveState.capturedClip = NULL; + mClipMoveState.capturedClipArray.clear(); - if ((wt -#ifdef USE_MIDI - || pTrack->GetKind() == Track::Note -#endif - ) && !event.ShiftDown()) - { -#ifdef USE_MIDI - if (!wt) - mClipMoveState.capturedClip = nullptr; - else -#endif + bool ok = true; + bool captureClips = false; + + if (!event.ShiftDown()) { + WaveTrack *wt = pTrack->GetKind() == Track::Wave + ? static_cast(pTrack.get()) : nullptr; + if (wt) { - mClipMoveState.capturedClip = wt->GetClipAtX(event.m_x); - if (mClipMoveState.capturedClip == NULL) - return Cancelled; + if (nullptr == + (mClipMoveState.capturedClip = wt->GetClipAtX(event.m_x))) + ok = false; + else + captureClips = true; } +#ifdef USE_MIDI + else if (pTrack->GetKind() == Track::Note) + { + captureClips = true; + } +#endif + } + if ( ! ok ) + return Cancelled; + else if ( captureClips ) CreateListOfCapturedClips ( mClipMoveState, viewInfo, *pTrack, *trackList, pProject->IsSyncLocked(), clickTime ); - } - else { - // Shift was down, or track was not Wave or Note - mClipMoveState.capturedClip = NULL; - mClipMoveState.capturedClipArray.clear(); - } mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive; mRect = rect;