From bd08c7c7786a733bf73dac9eb8fc6226ba0bfd0c Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Mon, 20 Apr 2015 00:35:06 -0400 Subject: [PATCH] Envelope event handlers do not directly use zoom (pps) values --- src/Envelope.cpp | 70 +++++++++++++++++------------------- src/Envelope.h | 16 ++++----- src/TrackPanel.cpp | 10 +++--- src/effects/Equalization.cpp | 2 +- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 91f6edda5..b570f1cba 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -27,6 +27,7 @@ a draggable point type. *//*******************************************************************/ #include "Envelope.h" +#include "ViewInfo.h" #include @@ -319,9 +320,10 @@ void Envelope::WriteXML(XMLWriter &xmlFile) xmlFile.EndTag(wxT("envelope")); } -#ifndef SQR -#define SQR(X) ((X)*(X)) -#endif +namespace +{ +inline int SQR(int x) { return x * x; } +} /// ValueOfPixel() converts a y position on screen to an envelope value. /// @param y - y position, usually of the mouse.relative to the clip. @@ -355,7 +357,7 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, bool dB, /// We have an upper and lower envelope line. /// Also we may be showing an inner envelope (at 0.5 the range). bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax) { int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); @@ -365,10 +367,8 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, if(clip_y < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't if(clip_y > r.GetBottom()) clip_y = r.GetBottom(); - double tleft = h - mOffset; - double tright = tleft + (r.width / pps); int bestNum = -1; - int bestDist = 10; // Must be within 10 pixel radius. + int bestDistSqr = 100; // Must be within 10 pixel radius. // TODO: Cache the gPrefs value. Reading it every time is inefficient. double dBr = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); @@ -384,22 +384,25 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, // TODO: extract this into a function FindNearestControlPoint() // TODO: also fix it so that we can drag the last point on an envelope. for (int i = 0; i < len; i++) { //search for control point nearest click - if (mEnv[i]->GetT() >= tleft && mEnv[i]->GetT() <= tright) { + const double time = mEnv[i]->GetT() + mOffset; + const wxInt64 position = zoomInfo.TimeToPosition(time); + if (position >= 0 && position < r.width) { - int x = int ((mEnv[i]->GetT() + mOffset - h) * pps) + r.x; + int x = int (position); int y[4]; int numControlPoints; // Outer control points - y[0] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + double value = mEnv[i]->GetVal(); + y[0] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, true, dBr, false); - y[1] = GetWaveYPos( -mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + y[1] = GetWaveYPos(-value, zoomMin, zoomMax, r.height, dB, true, dBr, false); // Inner control points(contour) - y[2] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + y[2] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, false, dBr, false); - y[3] = GetWaveYPos( -mEnv[i]->GetVal()-.00000001, zoomMin, zoomMax, + y[3] = GetWaveYPos(-value -.00000001, zoomMin, zoomMax, r.height, dB, false, dBr, false); numControlPoints = 4; @@ -410,12 +413,13 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, if (!mMirror) numControlPoints = 1; + const int deltaXSquared = SQR(x - (event.m_x - r.x)); for(int j=0; j 1); } } @@ -427,12 +431,12 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, } else { // TODO: Extract this into a function CreateNewPoint - double when = h + (event.m_x - r.x) / pps - mOffset; + const double when = zoomInfo.PositionToTime(event.m_x, r.x); // if (when <= 0 || when >= mTrackLen) // return false; - double v = GetValueAtX( event.m_x, r, h, pps ); + const double v = GetValue( when ); int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; @@ -458,16 +462,14 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, double newVal = ValueOfPixel(clip_y, r.height, upper, dB, zoomMin, zoomMax); - mDragPoint = Insert(when, newVal); + mDragPoint = Insert(when - mOffset, newVal); mDirty = true; } mUpper = upper; - mInitialWhen = mEnv[mDragPoint]->GetT(); mInitialVal = mEnv[mDragPoint]->GetVal(); - mInitialX = event.m_x; mInitialY = event.m_y+mContourOffset; return true; @@ -502,8 +504,8 @@ void Envelope::MarkDragPointForDeletion() } void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, - double WXUNUSED(h), double pps, bool dB, - float zoomMin, float zoomMax) + const ZoomInfo &zoomInfo, bool dB, + float zoomMin, float zoomMax) { int clip_y = event.m_y - r.y; if(clip_y < 0) clip_y = 0; @@ -511,13 +513,12 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, double newVal = ValueOfPixel(clip_y, r.height, mUpper, dB, zoomMin, zoomMax); - wxASSERT( pps > 0 ); // We no longer tolerate multiple envelope points at the same t. // epsilon is less than the time offset of a single sample // TODO: However because mTrackEpsilon assumes 200KHz this use // of epsilon is a tad bogus. What we need to do instead is delete // a duplicated point on a mouse up. - double newWhen = mInitialWhen + (event.m_x - mInitialX) / pps; + double newWhen = zoomInfo.PositionToTime(event.m_x, r.x) - mOffset; // We'll limit the drag point time to be between those of the preceding // and next envelope point. @@ -538,7 +539,7 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, } bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax, float WXUNUSED(eMin), float WXUNUSED(eMax)) { @@ -552,7 +553,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, // IF we're in the rect THEN we're not deleting this point (anymore). mIsDeleting = false; // ...we're dragging it. - MoveDraggedPoint( event, r,h,pps,dB, zoomMin, zoomMax); + MoveDraggedPoint( event, r, zoomInfo, dB, zoomMin, zoomMax); return true; } @@ -565,11 +566,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, } // Exit dragging mode and deletes dragged point if neccessary. -bool Envelope::HandleMouseButtonUp( wxMouseEvent & WXUNUSED(event), wxRect & WXUNUSED(r), - double WXUNUSED(h), - double WXUNUSED(pps), bool WXUNUSED(dB), - float WXUNUSED(zoomMin), - float WXUNUSED(zoomMax) ) +bool Envelope::HandleMouseButtonUp() { if (mIsDeleting) { delete mEnv[mDragPoint]; @@ -588,18 +585,17 @@ void Envelope::Delete( int point ) // Returns true if parent needs to be redrawn bool Envelope::MouseEvent(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax) { if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE) - return HandleMouseButtonDown( event, r, h, pps,dB, + return HandleMouseButtonDown( event, r, zoomInfo,dB, zoomMin, zoomMax); if (event.Dragging() && mDragPoint >= 0) - return HandleDragging( event, r, h, pps,dB, + return HandleDragging( event, r, zoomInfo,dB, zoomMin, zoomMax); if (event.ButtonUp() && event.GetButton() == mButton) - return HandleMouseButtonUp( event, r, h, pps, dB, - zoomMin, zoomMax); + return HandleMouseButtonUp(); return false; } diff --git a/src/Envelope.h b/src/Envelope.h index 6d33ec9cf..f1fdb102f 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -29,6 +29,8 @@ class wxTextFile; class DirManager; class Envelope; +class ZoomInfo; + #define ENV_DB_RANGE 60 class EnvPoint : public XMLTagHandler { @@ -122,17 +124,15 @@ class Envelope : public XMLTagHandler { // Event Handlers // Each ofthese returns true if parents needs to be redrawn bool MouseEvent(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0); bool HandleMouseButtonDown( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0); bool HandleDragging( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0, float eMin=0., float eMax=2.); - bool HandleMouseButtonUp( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, - float zoomMin=-1.0, float zoomMax=1.0); + bool HandleMouseButtonUp(); void GetEventParams( int &height, bool &upper, bool dB, wxMouseEvent & event, wxRect & r, float &zoomMin, float &zoomMax); @@ -202,7 +202,7 @@ private: void BinarySearchForTime( int &Lo, int &Hi, double t ) const; double GetInterpolationStartValueAtPoint( int iPoint ) const; void MoveDraggedPoint( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax); // Possibly inline functions: @@ -228,12 +228,10 @@ private: /** \brief Number of pixels contour is from the true envelope. */ int mContourOffset; - double mInitialWhen; double mInitialVal; // These are used in dragging. int mDragPoint; - int mInitialX; int mInitialY; bool mUpper; bool mIsDeleting; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 12ea5948a..937383c2c 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -3815,7 +3815,7 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event) bool needUpdate = pspeedenvelope->MouseEvent( event, envRect, - mViewInfo->h, mViewInfo->zoom, + *mViewInfo, ptimetrack->GetDisplayLog(), lower, upper); if (needUpdate) { RefreshTrack(mCapturedTrack); @@ -3853,7 +3853,7 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); needUpdate = penvelope->MouseEvent( event, envRect, - mViewInfo->h, mViewInfo->zoom, + *mViewInfo, dB, zoomMin, zoomMax); // If this track is linked to another track, make the identical @@ -3871,8 +3871,8 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); updateNeeded = e2->MouseEvent(event, envRect, - mViewInfo->h, mViewInfo->zoom, dB, - zoomMin, zoomMax); + *mViewInfo, dB, + zoomMin, zoomMax); needUpdate |= updateNeeded; } if(!e2 || !updateNeeded) // no envelope found at this x point, or found but not updated @@ -3885,7 +3885,7 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); needUpdate |= e2->MouseEvent(event, envRect, - mViewInfo->h, mViewInfo->zoom, dB, + *mViewInfo, dB, zoomMin, zoomMax); } } diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 97ac092e1..8d45a2078 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -2822,7 +2822,7 @@ void EqualizationPanel::OnMouseEvent(wxMouseEvent & event) CaptureMouse(); } - if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, 0.0, mEnvRect.width, false, + if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, ZoomInfo(0.0, 1.0, mEnvRect.width), false, mEffect->mdBMin, mEffect->mdBMax)) { mEffect->EnvelopeUpdated();