diff --git a/src/tracks/ui/SelectHandle.cpp b/src/tracks/ui/SelectHandle.cpp index 798ca0b0f..ebc8c2cd8 100644 --- a/src/tracks/ui/SelectHandle.cpp +++ b/src/tracks/ui/SelectHandle.cpp @@ -429,13 +429,10 @@ UIHandlePtr SelectHandle::HitTest // preserve during movement before the click. auto old = holder.lock(); std::shared_ptr oldSnapManager; - wxInt64 oldSnapLeft = -1, oldSnapRight = -1; if (old) { // It should not have started listening to timer events wxASSERT( !old->mTimerHandler ); oldSnapManager = std::move(old->mSnapManager); - oldSnapLeft = old->mSnapLeft; - oldSnapRight = old->mSnapRight; } auto result = std::make_shared( pTrack ); @@ -443,8 +440,6 @@ UIHandlePtr SelectHandle::HitTest // Copy the pre-dragging state result->mSnapManager = std::move( oldSnapManager ); - result->mSnapLeft = oldSnapLeft; - result->mSnapRight = oldSnapRight; const wxMouseState &state = st.state; const wxRect &rect = st.rect; @@ -571,8 +566,6 @@ UIHandle::Result SelectHandle::Click if (!mSnapManager) { // We create a NEW snap manager in case any snap-points have changed mSnapManager = std::make_shared(trackList, &viewInfo); - mSnapLeft = -1; - mSnapRight = -1; } bool bShiftDown = event.ShiftDown(); @@ -964,7 +957,7 @@ UIHandle::Result SelectHandle::Release mSelectionStateChanger.reset(); } - if (mSnapLeft != -1 || mSnapRight != -1) + if (mSnapStart.outCoord != -1 || mSnapEnd.outCoord != -1) return RefreshAll; else return RefreshNone; @@ -988,7 +981,7 @@ void SelectHandle::DrawExtras if (pass == Panel) { // Draw snap guidelines if we have any if ( mSnapManager ) - mSnapManager->Draw( dc, mSnapLeft, mSnapRight ); + mSnapManager->Draw( dc, mSnapStart.outCoord, mSnapEnd.outCoord ); } } @@ -1103,21 +1096,20 @@ void SelectHandle::StartSelection mSelStartValid = true; mSelStart = std::max(0.0, viewInfo.PositionToTime(mouseXCoordinate, trackLeftEdge)); - double s = mSelStart; - if (mSnapManager.get()) { - mSnapLeft = -1; - mSnapRight = -1; auto pTrack = pProject->GetTracks()->Lock(mpTrack); - auto results = mSnapManager->Snap(pTrack.get(), mSelStart, false); - if (results.Snapped()) { - s = results.outTime; - if (results.snappedPoint) - mSnapLeft = trackLeftEdge + results.outCoord; + mSnapStart = mSnapManager->Snap(pTrack.get(), mSelStart, false); + if (mSnapStart.Snapped()) { + // Reassign mSelStart! + mSelStart = mSnapStart.outTime; + if (mSnapStart.snappedPoint) + mSnapStart.outCoord += trackLeftEdge; } + if (!mSnapStart.snappedPoint) + mSnapStart.outCoord = -1; } - viewInfo.selectedRegion.setTimes(s, s); + viewInfo.selectedRegion.setTimes(mSelStart, mSelStart); // PRL: commented out the Sonify stuff with the TrackPanel refactor. // It was no-op anyway. @@ -1136,15 +1128,37 @@ void SelectHandle::AdjustSelection // Must be dragging frequency bounds only. return; - const double selend = + double selend = std::max(0.0, viewInfo.PositionToTime(mouseXCoordinate, trackLeftEdge)); - double origSel0, origSel1; - double sel0, sel1; + double origSelend = selend; auto pTrack = Track::Pointer( track ); if (!pTrack) pTrack = pProject->GetTracks()->Lock(mpTrack); + if (pTrack && mSnapManager.get()) { + bool rightEdge = (selend > mSelStart); + mSnapEnd = mSnapManager->Snap(pTrack.get(), selend, rightEdge); + if (mSnapEnd.Snapped()) { + selend = mSnapEnd.outTime; + if (mSnapEnd.snappedPoint) + mSnapEnd.outCoord += trackLeftEdge; + } + if (!mSnapEnd.snappedPoint) + mSnapEnd.outCoord = -1; + + // Check if selection endpoints are too close together to snap (unless + // using snap-to-time -- then we always accept the snap results) + if (mSnapStart.outCoord >= 0 && + mSnapEnd.outCoord >= 0 && + std::abs(mSnapStart.outCoord - mSnapEnd.outCoord) < 3 && + !mSnapEnd.snappedTime) { + selend = origSelend; + mSnapEnd.outCoord = -1; + } + } + + double sel0, sel1; if (mSelStart < selend) { sel0 = mSelStart; sel1 = selend; @@ -1154,36 +1168,6 @@ void SelectHandle::AdjustSelection sel0 = selend; } - origSel0 = sel0; - origSel1 = sel1; - - if (pTrack && mSnapManager.get()) { - mSnapLeft = -1; - mSnapRight = -1; - auto results = mSnapManager->Snap(pTrack.get(), sel0, false); - if (results.Snapped()) { - sel0 = results.outTime; - if (results.snappedPoint) - mSnapLeft = trackLeftEdge + results.outCoord; - } - results = mSnapManager->Snap(pTrack.get(), sel1, true); - if (results.Snapped()) { - sel1 = results.outTime; - if (results.snappedPoint) - mSnapRight = trackLeftEdge + results.outCoord; - } - - // Check if selection endpoints are too close together to snap (unless - // using snap-to-time -- then we always accept the snap results) - if (mSnapLeft >= 0 && mSnapRight >= 0 && mSnapRight - mSnapLeft < 3 && - !results.snappedTime) { - sel0 = origSel0; - sel1 = origSel1; - mSnapLeft = -1; - mSnapRight = -1; - } - } - viewInfo.selectedRegion.setTimes(sel0, sel1); //On-Demand: check to see if there is an OD thing associated with this track. If so we want to update the focal point for the task. diff --git a/src/tracks/ui/SelectHandle.h b/src/tracks/ui/SelectHandle.h index 5f78f4567..ce9e4498f 100644 --- a/src/tracks/ui/SelectHandle.h +++ b/src/tracks/ui/SelectHandle.h @@ -13,6 +13,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../UIHandle.h" #include "../../SelectedRegion.h" +#include "../../Snap.h" #include "../../MemoryX.h" #include @@ -109,13 +110,8 @@ private: wxRect mRect{}; SelectedRegion mInitialSelection{}; - // 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 - // guidelines so the user knows when such snapping is taking place. std::shared_ptr mSnapManager; - wxInt64 mSnapLeft{ -1 }; - wxInt64 mSnapRight{ -1 }; + SnapResults mSnapStart, mSnapEnd; bool mSelStartValid{}; double mSelStart{ 0.0 };