diff --git a/src/Snap.cpp b/src/Snap.cpp index c28f27d50..951c81197 100644 --- a/src/Snap.cpp +++ b/src/Snap.cpp @@ -8,14 +8,14 @@ **********************************************************************/ +#include "Snap.h" + +#include #include #include "LabelTrack.h" -#include "Prefs.h" #include "Project.h" -#include "Snap.h" #include "TrackPanel.h" -#include "WaveTrack.h" #include "widgets/NumericTextCtrl.h" // Change this to "true" to snap to nearest and "false" to snap to previous @@ -29,8 +29,10 @@ static int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2) } SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, - double zoom, int pixelTolerance, bool noTimeSnap) + const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap) : mConverter(NumericConverter::TIME) + , mPixelTolerance(std::max(0, pixelTolerance)) + , mZoomInfo(zoomInfo) { int i; @@ -50,13 +52,7 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, } mSnapPoints = new SnapPointArray(CompareSnapPoints); - if (zoom > 0 && pixelTolerance > 0) - mTolerance = pixelTolerance / zoom; - else { - // This shouldn't happen, but we don't want to crash if we get - // illegal values. The net effect of this is to never snap. - mTolerance = 0.0; - } + // Two time points closer than this are considered the same mEpsilon = 1 / 44100.0; @@ -135,9 +131,12 @@ double SnapManager::Get(int index) } // Returns the difference in time between t and the point at a given index -double SnapManager::Diff(double t, int index) +wxInt64 SnapManager::PixelDiff(double t, int index) { - return fabs(t - Get(index)); + return abs( + mZoomInfo.TimeToPosition(t, 0) - + mZoomInfo.TimeToPosition(Get(index), 0) + ); } // Find the index where this SnapPoint should go in @@ -168,7 +167,7 @@ int SnapManager::Find(double t) next++; // Now return whichever one is closer to time t - if (next < len && Diff(t, next) < Diff(t, index)) + if (next < len && PixelDiff(t, next) < PixelDiff(t, index)) return next; else return index; @@ -189,7 +188,7 @@ bool SnapManager::SnapToPoints(Track *currentTrack, int index = Find(t); // If it's too far away, just give up now - if (Diff(t, index) >= mTolerance) + if (PixelDiff(t, index) >= mPixelTolerance) return false; // Otherwise, search left and right for all of the points @@ -198,10 +197,10 @@ bool SnapManager::SnapToPoints(Track *currentTrack, int right = index; int i; - while(left > 0 && Diff(t, left-1) < mTolerance) + while(left > 0 && PixelDiff(t, left-1) < mPixelTolerance) left--; - while(right < len-1 && Diff(t, right+1) < mTolerance) + while(right < len-1 && PixelDiff(t, right+1) < mPixelTolerance) right++; if (left == index && right == index) { diff --git a/src/Snap.h b/src/Snap.h index a4d32ca7c..a3e9fe82c 100644 --- a/src/Snap.h +++ b/src/Snap.h @@ -22,6 +22,7 @@ #include "widgets/NumericTextCtrl.h" class TrackClipArray; +class ZoomInfo; enum { @@ -43,9 +44,9 @@ class SnapPoint { WX_DEFINE_SORTED_ARRAY(SnapPoint *, SnapPointArray); class SnapManager { - public: +public: SnapManager(TrackList *tracks, TrackClipArray *exclusions, - double zoom, int pixelTolerance, bool noTimeSnap = false); + const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap = false); ~SnapManager(); @@ -54,34 +55,35 @@ class SnapManager { // Pass rightEdge=true if this is the right edge of a selection, // and false if it's the left edge. bool Snap(Track *currentTrack, - double t, - bool rightEdge, - double *out_t, - bool *snappedPoint, - bool *snappedTime); + double t, + bool rightEdge, + double *out_t, + bool *snappedPoint, + bool *snappedTime); static wxArrayString GetSnapLabels(); static wxArrayString GetSnapValues(); static const wxString & GetSnapValue(int index); static int GetSnapIndex(const wxString & value); - private: +private: void CondListAdd(double t, Track *tr); double Get(int index); - double Diff(double t, int index); + wxInt64 PixelDiff(double t, int index); int Find(double t, int i0, int i1); int Find(double t); bool SnapToPoints(Track *currentTrack, double t, bool rightEdge, - double *out_t); + double *out_t); double mEpsilon; - double mTolerance; - double mZoom; SnapPointArray *mSnapPoints; // Info for snap-to-time NumericConverter mConverter; bool mSnapToTime; + + const wxInt64 mPixelTolerance; + const ZoomInfo &mZoomInfo; }; #endif diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 5c891984a..d73ba2f57 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -2570,7 +2570,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, delete mSnapManager; mSnapManager = new SnapManager(mTracks, NULL, - mViewInfo->zoom, + *mViewInfo, 4); // pixel tolerance mSnapLeft = -1; @@ -4120,7 +4120,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) delete mSnapManager; mSnapManager = new SnapManager(mTracks, &mCapturedClipArray, - mViewInfo->zoom, + *mViewInfo, 4, // pixel tolerance true); // don't snap to time mSnapLeft = -1; diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 0c4455f0e..5b737c2a9 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -2204,7 +2204,7 @@ void AdornedRulerPanel::HandleSnapping() delete mSnapManager; } mSnapManager = new SnapManager(mProject->GetTracks(), NULL, - mViewInfo->zoom, + *mViewInfo, QUICK_PLAY_SNAP_PIXEL); bool snappedPoint, snappedTime; mIsSnapped = (mSnapManager->Snap(NULL, mQuickPlayPos, false,