Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
EnvelopeEditor Class Reference

#include <EnvelopeEditor.h>

Collaboration diagram for EnvelopeEditor:
[legend]

Public Member Functions

 EnvelopeEditor (Envelope &envelope, bool mirrored)
 
 ~EnvelopeEditor ()
 
bool MouseEvent (const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin=-1.0, float zoomMax=1.0)
 

Static Public Member Functions

static void DrawPoints (const Envelope &env, TrackPanelDrawingContext &context, const wxRect &r, bool dB, double dBRange, float zoomMin, float zoomMax, bool mirrored, int origin=0)
 

Private Member Functions

bool HandleMouseButtonDown (const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin=-1.0, float zoomMax=1.0)
 
bool HandleDragging (const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin=-1.0, float zoomMax=1.0, float eMin=0., float eMax=2.)
 
bool HandleMouseButtonUp ()
 
float ValueOfPixel (int y, int height, bool upper, bool dB, double dBRange, float zoomMin, float zoomMax)
 
void MoveDragPoint (const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin, float zoomMax)
 

Private Attributes

EnvelopemEnvelope
 
const bool mMirrored
 
int mContourOffset
 Number of pixels contour is from the true envelope. More...
 
bool mUpper
 
int mButton
 
bool mDirty
 

Detailed Description

Definition at line 22 of file EnvelopeEditor.h.

Constructor & Destructor Documentation

◆ EnvelopeEditor()

EnvelopeEditor::EnvelopeEditor ( Envelope envelope,
bool  mirrored 
)

Definition at line 109 of file EnvelopeEditor.cpp.

110 : mEnvelope(envelope)
111 , mMirrored(mirrored)
112 , mContourOffset(-1)
113 // , mInitialVal(-1.0)
114 // , mInitialY(-1)
115 , mUpper(false)
116 , mButton(wxMOUSE_BTN_NONE)
117 , mDirty(false)
118{
119}
Envelope & mEnvelope
const bool mMirrored
int mContourOffset
Number of pixels contour is from the true envelope.

◆ ~EnvelopeEditor()

EnvelopeEditor::~EnvelopeEditor ( )

Definition at line 121 of file EnvelopeEditor.cpp.

122{
123}

Member Function Documentation

◆ DrawPoints()

void EnvelopeEditor::DrawPoints ( const Envelope env,
TrackPanelDrawingContext context,
const wxRect &  r,
bool  dB,
double  dBRange,
float  zoomMin,
float  zoomMax,
bool  mirrored,
int  origin = 0 
)
static

Definition at line 36 of file EnvelopeEditor.cpp.

40{
41 auto &dc = context.dc;
42 const auto artist = TrackArtist::Get( context );
43 const auto &zoomInfo = *artist->pZoomInfo;
44
45 bool highlight = false;
46#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
47 auto target = dynamic_cast<EnvelopeHandle*>(context.target.get());
48 highlight = target && target->GetEnvelope() == this;
49#endif
50 wxPen &pen = highlight ? AColor::uglyPen : AColor::envelopePen;
51 dc.SetPen( pen );
52 dc.SetBrush(*wxWHITE_BRUSH);
53
54 for (int i = 0; i < (int)env.GetNumberOfPoints(); i++) {
55 const double time = env[i].GetT() + env.GetOffset();
56 const wxInt64 position = zoomInfo.TimeToPosition(time, origin);
57 if (position >= 0 && position < r.width) {
58 // Change colour if this is the draggable point...
59 if (i == env.GetDragPoint()) {
60 dc.SetPen( pen );
61 dc.SetBrush(AColor::envelopeBrush);
62 }
63
64 double v = env[i].GetVal();
65 int x = (int)(position);
66 int y, y2;
67
68 y = GetWaveYPos(v, zoomMin, zoomMax, r.height, dB,
69 true, dBRange, false);
70 if (!mirrored) {
71 DrawPoint(dc, r, x, y, true);
72 }
73 else {
74 y2 = GetWaveYPos(-v-.000000001, zoomMin, zoomMax, r.height, dB,
75 true, dBRange, false);
76
77 // This follows the same logic as the envelop drawing in
78 // TrackArt::DrawEnvelope().
79 // TODO: make this calculation into a reusable function.
80 if (y2 - y < 9) {
81 int value = (int)((zoomMax / (zoomMax - zoomMin)) * r.height);
82 y = value - 4;
83 y2 = value + 4;
84 }
85
86 DrawPoint(dc, r, x, y, true);
87 DrawPoint(dc, r, x, y2, false);
88
89 // Contour
90 y = GetWaveYPos(v, zoomMin, zoomMax, r.height, dB,
91 false, dBRange, false);
92 y2 = GetWaveYPos(-v-.000000001, zoomMin, zoomMax, r.height, dB,
93 false, dBRange, false);
94 if (y <= y2) {
95 DrawPoint(dc, r, x, y, true);
96 DrawPoint(dc, r, x, y2, false);
97 }
98 }
99
100 // Change colour back again if was the draggable point.
101 if (i == env.GetDragPoint()) {
102 dc.SetPen( pen );
103 dc.SetBrush(*wxWHITE_BRUSH);
104 }
105 }
106 }
107}
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
Definition: TrackArt.cpp:49
static wxBrush envelopeBrush
Definition: AColor.h:117
static wxPen uglyPen
Definition: AColor.h:141
static wxPen envelopePen
Definition: AColor.h:115
Envelope * GetEnvelope() const
double GetOffset() const
Definition: Envelope.h:90
size_t GetNumberOfPoints() const
Return number of points.
Definition: Envelope.cpp:689
int GetDragPoint() const
Definition: Envelope.h:213
static TrackArtist * Get(TrackPanelDrawingContext &)
Definition: TrackArtist.cpp:69
void DrawPoint(wxDC &dc, const wxRect &r, int x, int y, bool top)

References TrackPanelDrawingContext::dc, anonymous_namespace{EnvelopeEditor.cpp}::DrawPoint(), AColor::envelopeBrush, AColor::envelopePen, TrackArtist::Get(), Envelope::GetDragPoint(), EnvelopeHandle::GetEnvelope(), Envelope::GetNumberOfPoints(), Envelope::GetOffset(), GetWaveYPos(), TrackPanelDrawingContext::target, and AColor::uglyPen.

Referenced by anonymous_namespace{WaveformView.cpp}::DrawClipWaveform(), anonymous_namespace{TimeTrackView.cpp}::DrawTimeTrack(), and EqualizationPanel::OnPaint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleDragging()

bool EnvelopeEditor::HandleDragging ( const wxMouseEvent &  event,
wxRect &  r,
const ZoomInfo zoomInfo,
bool  dB,
double  dBRange,
float  zoomMin = -1.0,
float  zoomMax = 1.0,
float  eMin = 0.,
float  eMax = 2. 
)
private

Definition at line 292 of file EnvelopeEditor.cpp.

296{
297 mDirty = true;
298
299 wxRect larger = r;
300 larger.Inflate(10, 10);
301
302 if (larger.Contains(event.m_x, event.m_y))
303 {
304 // IF we're in the rect THEN we're not deleting this point (anymore).
305 // ...we're dragging it.
306 MoveDragPoint( event, r, zoomInfo, dB, dBRange, zoomMin, zoomMax);
307 return true;
308 }
309
311 // IF we already know we're deleting THEN no envelope point to update.
312 return false;
313
314 // Invalidate the point
316 return true;
317}
void MoveDragPoint(const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin, float zoomMax)
bool GetDragPointValid() const
Definition: Envelope.h:218
void SetDragPointValid(bool valid)
Definition: Envelope.cpp:144

References Envelope::GetDragPointValid(), mDirty, mEnvelope, MoveDragPoint(), and Envelope::SetDragPointValid().

Referenced by MouseEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleMouseButtonDown()

bool EnvelopeEditor::HandleMouseButtonDown ( const wxMouseEvent &  event,
wxRect &  r,
const ZoomInfo zoomInfo,
bool  dB,
double  dBRange,
float  zoomMin = -1.0,
float  zoomMax = 1.0 
)
private

HandleMouseButtonDown either finds an existing control point or adds a NEW one which is then recorded as the point to drag. This is slightly complicated by there possibly being four control points for a given time value: We have an upper and lower envelope line. Also we may be showing an inner envelope (at 0.5 the range).

Definition at line 157 of file EnvelopeEditor.cpp.

161{
162 int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin));
163 bool upper = !mMirrored || (zoomMin >= 0.0) || (event.m_y - r.y < ctr);
164
165 int clip_y = event.m_y - r.y;
166 if(clip_y < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't
167 if(clip_y > r.GetBottom()) clip_y = r.GetBottom();
168
169 int bestNum = -1;
170 int bestDistSqr = 100; // Must be within 10 pixel radius.
171
172 // Member variables hold state that will be needed in dragging.
173 mButton = event.GetButton();
174 mContourOffset = false;
175
176 // wxLogDebug(wxT("Y:%i Height:%i Offset:%i"), y, height, mContourOffset );
177 int len = mEnvelope.GetNumberOfPoints();
178
179 // TODO: extract this into a function FindNearestControlPoint()
180 // TODO: also fix it so that we can drag the last point on an envelope.
181 for (int i = 0; i < len; i++) { //search for control point nearest click
182 const double time = mEnvelope[i].GetT() + mEnvelope.GetOffset();
183 const wxInt64 position = zoomInfo.TimeToPosition(time);
184 if (position >= 0 && position < r.width) {
185
186 int x = (int)(position);
187 int y[4];
188 int numControlPoints;
189
190 // Outer control points
191 double value = mEnvelope[i].GetVal();
192 y[0] = GetWaveYPos(value, zoomMin, zoomMax, r.height,
193 dB, true, dBRange, false);
194 y[1] = GetWaveYPos(-value, zoomMin, zoomMax, r.height,
195 dB, true, dBRange, false);
196
197 // Inner control points(contour)
198 y[2] = GetWaveYPos(value, zoomMin, zoomMax, r.height,
199 dB, false, dBRange, false);
200 y[3] = GetWaveYPos(-value -.00000001, zoomMin, zoomMax,
201 r.height, dB, false, dBRange, false);
202
203 numControlPoints = 4;
204
205 if (y[2] > y[3])
206 numControlPoints = 2;
207
208 if (!mMirrored)
209 numControlPoints = 1;
210
211 const int deltaXSquared = SQR(x - (event.m_x - r.x));
212 for(int j=0; j<numControlPoints; j++){
213
214 const int dSqr = deltaXSquared + SQR(y[j] - (event.m_y - r.y));
215 if (dSqr < bestDistSqr) {
216 bestNum = i;
217 bestDistSqr = dSqr;
218 mContourOffset = (bool)(j > 1);
219 }
220 }
221 }
222 }
223
224 if (bestNum >= 0) {
225 mEnvelope.SetDragPoint(bestNum);
226 }
227 else {
228 // TODO: Extract this into a function CreateNewPoint
229 const double when = zoomInfo.PositionToTime(event.m_x, r.x);
230
231 // if (when <= 0 || when >= mTrackLen)
232 // return false;
233
234 const double v = mEnvelope.GetValue( when );
235
236 int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB,
237 false, dBRange, false) ;
238 int cb = GetWaveYPos( -v-.000000001, zoomMin, zoomMax, r.height, dB,
239 false, dBRange, false) ;
240 if (ct <= cb || !mMirrored) {
241 int t = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB,
242 true, dBRange, false) ;
243 int b = GetWaveYPos( -v, zoomMin, zoomMax, r.height, dB,
244 true, dBRange, false) ;
245
246 ct = (t + ct) / 2;
247 cb = (b + cb) / 2;
248
249 if (mMirrored &&
250 (event.m_y - r.y) > ct &&
251 ((event.m_y - r.y) < cb))
252 mContourOffset = true;
253 else
254 mContourOffset = false;
255 }
256
257 double newVal = ValueOfPixel(clip_y, r.height, upper, dB, dBRange,
258 zoomMin, zoomMax);
259
261 mDirty = true;
262 }
263
264 mUpper = upper;
265
266 // const int dragPoint = mEnvelope.GetDragPoint();
267 // mInitialVal = mEnvelope[dragPoint].GetVal();
268 // mInitialY = event.m_y+mContourOffset;
269
270 return true;
271}
float ValueOfPixel(int y, int height, bool upper, bool dB, double dBRange, float zoomMin, float zoomMax)
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
Definition: Envelope.cpp:823
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:173
void SetDragPoint(int dragPoint)
Definition: Envelope.cpp:138
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:41
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ZoomInfo.cpp:51

References Envelope::GetNumberOfPoints(), Envelope::GetOffset(), Envelope::GetValue(), GetWaveYPos(), Envelope::InsertOrReplace(), mButton, mContourOffset, mDirty, mEnvelope, mMirrored, mUpper, ZoomInfo::PositionToTime(), Envelope::SetDragPoint(), anonymous_namespace{EnvelopeEditor.cpp}::SQR(), ZoomInfo::TimeToPosition(), and ValueOfPixel().

Referenced by MouseEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleMouseButtonUp()

bool EnvelopeEditor::HandleMouseButtonUp ( )
private

Definition at line 320 of file EnvelopeEditor.cpp.

321{
323 mButton = wxMOUSE_BTN_NONE;
324 return true;
325}
void ClearDragPoint()
Definition: Envelope.cpp:207

References Envelope::ClearDragPoint(), mButton, and mEnvelope.

Referenced by MouseEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MouseEvent()

bool EnvelopeEditor::MouseEvent ( const wxMouseEvent &  event,
wxRect &  r,
const ZoomInfo zoomInfo,
bool  dB,
double  dBRange,
float  zoomMin = -1.0,
float  zoomMax = 1.0 
)

Definition at line 328 of file EnvelopeEditor.cpp.

331{
332 if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE)
333 return HandleMouseButtonDown( event, r, zoomInfo, dB, dBRange,
334 zoomMin, zoomMax);
335 if (event.Dragging() && mEnvelope.GetDragPoint() >= 0)
336 return HandleDragging( event, r, zoomInfo, dB, dBRange,
337 zoomMin, zoomMax);
338 if (event.ButtonUp() && event.GetButton() == mButton)
339 return HandleMouseButtonUp();
340 return false;
341}
bool HandleDragging(const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin=-1.0, float zoomMax=1.0, float eMin=0., float eMax=2.)
bool HandleMouseButtonDown(const wxMouseEvent &event, wxRect &r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin=-1.0, float zoomMax=1.0)
bool HandleMouseButtonUp()

References Envelope::GetDragPoint(), HandleDragging(), HandleMouseButtonDown(), HandleMouseButtonUp(), mButton, and mEnvelope.

Here is the call graph for this function:

◆ MoveDragPoint()

void EnvelopeEditor::MoveDragPoint ( const wxMouseEvent &  event,
wxRect &  r,
const ZoomInfo zoomInfo,
bool  dB,
double  dBRange,
float  zoomMin,
float  zoomMax 
)
private

Definition at line 273 of file EnvelopeEditor.cpp.

276{
277 int clip_y = event.m_y - r.y;
278 if(clip_y < 0) clip_y = 0;
279 if(clip_y > r.height) clip_y = r.height;
280 double newVal = ValueOfPixel(clip_y, r.height, mUpper, dB, dBRange,
281 zoomMin, zoomMax);
282
283 // We no longer tolerate multiple envelope points at the same t.
284 // epsilon is less than the time offset of a single sample
285 // TODO: However because mTrackEpsilon assumes 200KHz this use
286 // of epsilon is a tad bogus. What we need to do instead is DELETE
287 // a duplicated point on a mouse up.
288 double newWhen = zoomInfo.PositionToTime(event.m_x, r.x) - mEnvelope.GetOffset();
289 mEnvelope.MoveDragPoint(newWhen, newVal);
290}
void MoveDragPoint(double newWhen, double value)
Definition: Envelope.cpp:181

References Envelope::GetOffset(), mEnvelope, Envelope::MoveDragPoint(), mUpper, ZoomInfo::PositionToTime(), and ValueOfPixel().

Referenced by HandleDragging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ValueOfPixel()

float EnvelopeEditor::ValueOfPixel ( int  y,
int  height,
bool  upper,
bool  dB,
double  dBRange,
float  zoomMin,
float  zoomMax 
)
private

ValueOfPixel() converts a y position on screen to an envelope value.

Parameters
y- y position, usually of the mouse.relative to the clip.
height- height of the rectangle we are in. @upper - true if we are on the upper line, false if on lower. @dB - display mode either linear or log. @zoomMin - vertical scale, typically -1.0 @zoomMax - vertical scale, typically +1.0

Definition at line 137 of file EnvelopeEditor.cpp.

140{
141 float v = ::ValueOfPixel(y, height, 0 != mContourOffset, dB, dBRange, zoomMin, zoomMax);
142
143 // MB: this is mostly equivalent to what the old code did, I'm not sure
144 // if anything special is needed for asymmetric ranges
145 if(upper)
146 return mEnvelope.ClampValue(v);
147 else
148 return mEnvelope.ClampValue(-v);
149}
double ClampValue(double value)
Definition: Envelope.h:102

References Envelope::ClampValue(), mContourOffset, mEnvelope, and ValueOfPixel().

Referenced by HandleMouseButtonDown(), MoveDragPoint(), and ValueOfPixel().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mButton

int EnvelopeEditor::mButton
private

Definition at line 68 of file EnvelopeEditor.h.

Referenced by HandleMouseButtonDown(), HandleMouseButtonUp(), and MouseEvent().

◆ mContourOffset

int EnvelopeEditor::mContourOffset
private

Number of pixels contour is from the true envelope.

Definition at line 62 of file EnvelopeEditor.h.

Referenced by HandleMouseButtonDown(), and ValueOfPixel().

◆ mDirty

bool EnvelopeEditor::mDirty
private

Definition at line 69 of file EnvelopeEditor.h.

Referenced by HandleDragging(), and HandleMouseButtonDown().

◆ mEnvelope

Envelope& EnvelopeEditor::mEnvelope
private

◆ mMirrored

const bool EnvelopeEditor::mMirrored
private

Definition at line 59 of file EnvelopeEditor.h.

Referenced by HandleMouseButtonDown().

◆ mUpper

bool EnvelopeEditor::mUpper
private

Definition at line 67 of file EnvelopeEditor.h.

Referenced by HandleMouseButtonDown(), and MoveDragPoint().


The documentation for this class was generated from the following files: