1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-18 09:00:07 +02:00

Envelope event handlers do not directly use zoom (pps) values

This commit is contained in:
Paul-Licameli 2015-04-20 00:35:06 -04:00 committed by Paul Licameli
parent 1f9113f5cc
commit bd08c7c778
4 changed files with 46 additions and 52 deletions

View File

@ -27,6 +27,7 @@ a draggable point type.
*//*******************************************************************/ *//*******************************************************************/
#include "Envelope.h" #include "Envelope.h"
#include "ViewInfo.h"
#include <math.h> #include <math.h>
@ -319,9 +320,10 @@ void Envelope::WriteXML(XMLWriter &xmlFile)
xmlFile.EndTag(wxT("envelope")); xmlFile.EndTag(wxT("envelope"));
} }
#ifndef SQR namespace
#define SQR(X) ((X)*(X)) {
#endif inline int SQR(int x) { return x * x; }
}
/// ValueOfPixel() converts a y position on screen to an envelope value. /// ValueOfPixel() converts a y position on screen to an envelope value.
/// @param y - y position, usually of the mouse.relative to the clip. /// @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. /// We have an upper and lower envelope line.
/// Also we may be showing an inner envelope (at 0.5 the range). /// Also we may be showing an inner envelope (at 0.5 the range).
bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
double h, double pps, bool dB, const ZoomInfo &zoomInfo, bool dB,
float zoomMin, float zoomMax) float zoomMin, float zoomMax)
{ {
int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); 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 < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't
if(clip_y > r.GetBottom()) clip_y = r.GetBottom(); if(clip_y > r.GetBottom()) clip_y = r.GetBottom();
double tleft = h - mOffset;
double tright = tleft + (r.width / pps);
int bestNum = -1; 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. // TODO: Cache the gPrefs value. Reading it every time is inefficient.
double dBr = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); 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: extract this into a function FindNearestControlPoint()
// TODO: also fix it so that we can drag the last point on an envelope. // 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 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 y[4];
int numControlPoints; int numControlPoints;
// Outer control points // 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); 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); dB, true, dBr, false);
// Inner control points(contour) // 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); 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); r.height, dB, false, dBr, false);
numControlPoints = 4; numControlPoints = 4;
@ -410,12 +413,13 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
if (!mMirror) if (!mMirror)
numControlPoints = 1; numControlPoints = 1;
const int deltaXSquared = SQR(x - (event.m_x - r.x));
for(int j=0; j<numControlPoints; j++){ for(int j=0; j<numControlPoints; j++){
int d = (int)(sqrt((double)(SQR(x-event.m_x) + SQR(y[j]-(event.m_y-r.y)))) + 0.5); const int dSqr = deltaXSquared + SQR(y[j] - (event.m_y - r.y));
if (d < bestDist) { if (dSqr < bestDistSqr) {
bestNum = i; bestNum = i;
bestDist = d; bestDistSqr = dSqr;
mContourOffset = (bool)(j > 1); mContourOffset = (bool)(j > 1);
} }
} }
@ -427,12 +431,12 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
} }
else { else {
// TODO: Extract this into a function CreateNewPoint // 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) // if (when <= 0 || when >= mTrackLen)
// return false; // 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, int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB,
false, dBr, false) ; false, dBr, false) ;
@ -458,16 +462,14 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
double newVal = ValueOfPixel(clip_y, r.height, upper, dB, double newVal = ValueOfPixel(clip_y, r.height, upper, dB,
zoomMin, zoomMax); zoomMin, zoomMax);
mDragPoint = Insert(when, newVal); mDragPoint = Insert(when - mOffset, newVal);
mDirty = true; mDirty = true;
} }
mUpper = upper; mUpper = upper;
mInitialWhen = mEnv[mDragPoint]->GetT();
mInitialVal = mEnv[mDragPoint]->GetVal(); mInitialVal = mEnv[mDragPoint]->GetVal();
mInitialX = event.m_x;
mInitialY = event.m_y+mContourOffset; mInitialY = event.m_y+mContourOffset;
return true; return true;
@ -502,8 +504,8 @@ void Envelope::MarkDragPointForDeletion()
} }
void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r,
double WXUNUSED(h), double pps, bool dB, const ZoomInfo &zoomInfo, bool dB,
float zoomMin, float zoomMax) float zoomMin, float zoomMax)
{ {
int clip_y = event.m_y - r.y; int clip_y = event.m_y - r.y;
if(clip_y < 0) clip_y = 0; 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, double newVal = ValueOfPixel(clip_y, r.height, mUpper, dB,
zoomMin, zoomMax); zoomMin, zoomMax);
wxASSERT( pps > 0 );
// We no longer tolerate multiple envelope points at the same t. // We no longer tolerate multiple envelope points at the same t.
// epsilon is less than the time offset of a single sample // epsilon is less than the time offset of a single sample
// TODO: However because mTrackEpsilon assumes 200KHz this use // TODO: However because mTrackEpsilon assumes 200KHz this use
// of epsilon is a tad bogus. What we need to do instead is delete // of epsilon is a tad bogus. What we need to do instead is delete
// a duplicated point on a mouse up. // 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 // We'll limit the drag point time to be between those of the preceding
// and next envelope point. // and next envelope point.
@ -538,7 +539,7 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r,
} }
bool Envelope::HandleDragging( 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 zoomMin, float zoomMax,
float WXUNUSED(eMin), float WXUNUSED(eMax)) 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). // IF we're in the rect THEN we're not deleting this point (anymore).
mIsDeleting = false; mIsDeleting = false;
// ...we're dragging it. // ...we're dragging it.
MoveDraggedPoint( event, r,h,pps,dB, zoomMin, zoomMax); MoveDraggedPoint( event, r, zoomInfo, dB, zoomMin, zoomMax);
return true; return true;
} }
@ -565,11 +566,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r,
} }
// Exit dragging mode and deletes dragged point if neccessary. // Exit dragging mode and deletes dragged point if neccessary.
bool Envelope::HandleMouseButtonUp( wxMouseEvent & WXUNUSED(event), wxRect & WXUNUSED(r), bool Envelope::HandleMouseButtonUp()
double WXUNUSED(h),
double WXUNUSED(pps), bool WXUNUSED(dB),
float WXUNUSED(zoomMin),
float WXUNUSED(zoomMax) )
{ {
if (mIsDeleting) { if (mIsDeleting) {
delete mEnv[mDragPoint]; delete mEnv[mDragPoint];
@ -588,18 +585,17 @@ void Envelope::Delete( int point )
// Returns true if parent needs to be redrawn // Returns true if parent needs to be redrawn
bool Envelope::MouseEvent(wxMouseEvent & event, wxRect & r, bool Envelope::MouseEvent(wxMouseEvent & event, wxRect & r,
double h, double pps, bool dB, const ZoomInfo &zoomInfo, bool dB,
float zoomMin, float zoomMax) float zoomMin, float zoomMax)
{ {
if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE) if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE)
return HandleMouseButtonDown( event, r, h, pps,dB, return HandleMouseButtonDown( event, r, zoomInfo,dB,
zoomMin, zoomMax); zoomMin, zoomMax);
if (event.Dragging() && mDragPoint >= 0) if (event.Dragging() && mDragPoint >= 0)
return HandleDragging( event, r, h, pps,dB, return HandleDragging( event, r, zoomInfo,dB,
zoomMin, zoomMax); zoomMin, zoomMax);
if (event.ButtonUp() && event.GetButton() == mButton) if (event.ButtonUp() && event.GetButton() == mButton)
return HandleMouseButtonUp( event, r, h, pps, dB, return HandleMouseButtonUp();
zoomMin, zoomMax);
return false; return false;
} }

View File

@ -29,6 +29,8 @@ class wxTextFile;
class DirManager; class DirManager;
class Envelope; class Envelope;
class ZoomInfo;
#define ENV_DB_RANGE 60 #define ENV_DB_RANGE 60
class EnvPoint : public XMLTagHandler { class EnvPoint : public XMLTagHandler {
@ -122,17 +124,15 @@ class Envelope : public XMLTagHandler {
// Event Handlers // Event Handlers
// Each ofthese returns true if parents needs to be redrawn // Each ofthese returns true if parents needs to be redrawn
bool MouseEvent(wxMouseEvent & event, wxRect & r, 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); float zoomMin=-1.0, float zoomMax=1.0);
bool HandleMouseButtonDown( wxMouseEvent & event, wxRect & r, 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); float zoomMin=-1.0, float zoomMax=1.0);
bool HandleDragging( wxMouseEvent & event, wxRect & r, 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.); float zoomMin=-1.0, float zoomMax=1.0, float eMin=0., float eMax=2.);
bool HandleMouseButtonUp( wxMouseEvent & event, wxRect & r, bool HandleMouseButtonUp();
double h, double pps, bool dB,
float zoomMin=-1.0, float zoomMax=1.0);
void GetEventParams( int &height, bool &upper, bool dB, void GetEventParams( int &height, bool &upper, bool dB,
wxMouseEvent & event, wxRect & r, wxMouseEvent & event, wxRect & r,
float &zoomMin, float &zoomMax); float &zoomMin, float &zoomMax);
@ -202,7 +202,7 @@ private:
void BinarySearchForTime( int &Lo, int &Hi, double t ) const; void BinarySearchForTime( int &Lo, int &Hi, double t ) const;
double GetInterpolationStartValueAtPoint( int iPoint ) const; double GetInterpolationStartValueAtPoint( int iPoint ) const;
void MoveDraggedPoint( wxMouseEvent & event, wxRect & r, void MoveDraggedPoint( wxMouseEvent & event, wxRect & r,
double h, double pps, bool dB, const ZoomInfo &zoomInfo, bool dB,
float zoomMin, float zoomMax); float zoomMin, float zoomMax);
// Possibly inline functions: // Possibly inline functions:
@ -228,12 +228,10 @@ private:
/** \brief Number of pixels contour is from the true envelope. */ /** \brief Number of pixels contour is from the true envelope. */
int mContourOffset; int mContourOffset;
double mInitialWhen;
double mInitialVal; double mInitialVal;
// These are used in dragging. // These are used in dragging.
int mDragPoint; int mDragPoint;
int mInitialX;
int mInitialY; int mInitialY;
bool mUpper; bool mUpper;
bool mIsDeleting; bool mIsDeleting;

View File

@ -3815,7 +3815,7 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event)
bool needUpdate = bool needUpdate =
pspeedenvelope->MouseEvent( pspeedenvelope->MouseEvent(
event, envRect, event, envRect,
mViewInfo->h, mViewInfo->zoom, *mViewInfo,
ptimetrack->GetDisplayLog(), lower, upper); ptimetrack->GetDisplayLog(), lower, upper);
if (needUpdate) { if (needUpdate) {
RefreshTrack(mCapturedTrack); RefreshTrack(mCapturedTrack);
@ -3853,7 +3853,7 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
needUpdate = penvelope->MouseEvent( needUpdate = penvelope->MouseEvent(
event, envRect, event, envRect,
mViewInfo->h, mViewInfo->zoom, *mViewInfo,
dB, zoomMin, zoomMax); dB, zoomMin, zoomMax);
// If this track is linked to another track, make the identical // If this track is linked to another track, make the identical
@ -3871,8 +3871,8 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
float zoomMin, zoomMax; float zoomMin, zoomMax;
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
updateNeeded = e2->MouseEvent(event, envRect, updateNeeded = e2->MouseEvent(event, envRect,
mViewInfo->h, mViewInfo->zoom, dB, *mViewInfo, dB,
zoomMin, zoomMax); zoomMin, zoomMax);
needUpdate |= updateNeeded; needUpdate |= updateNeeded;
} }
if(!e2 || !updateNeeded) // no envelope found at this x point, or found but not updated 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; float zoomMin, zoomMax;
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
needUpdate |= e2->MouseEvent(event, envRect, needUpdate |= e2->MouseEvent(event, envRect,
mViewInfo->h, mViewInfo->zoom, dB, *mViewInfo, dB,
zoomMin, zoomMax); zoomMin, zoomMax);
} }
} }

View File

@ -2822,7 +2822,7 @@ void EqualizationPanel::OnMouseEvent(wxMouseEvent & event)
CaptureMouse(); 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->mdBMin, mEffect->mdBMax))
{ {
mEffect->EnvelopeUpdated(); mEffect->EnvelopeUpdated();