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 110 of file EnvelopeEditor.cpp.

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

◆ ~EnvelopeEditor()

EnvelopeEditor::~EnvelopeEditor ( )

Definition at line 122 of file EnvelopeEditor.cpp.

123{
124}

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 37 of file EnvelopeEditor.cpp.

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

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

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 158 of file EnvelopeEditor.cpp.

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

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 321 of file EnvelopeEditor.cpp.

322{
324 mButton = wxMOUSE_BTN_NONE;
325 return true;
326}
void ClearDragPoint()
Definition: Envelope.cpp:213

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 329 of file EnvelopeEditor.cpp.

332{
333 if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE)
334 return HandleMouseButtonDown( event, r, zoomInfo, dB, dBRange,
335 zoomMin, zoomMax);
336 if (event.Dragging() && mEnvelope.GetDragPoint() >= 0)
337 return HandleDragging( event, r, zoomInfo, dB, dBRange,
338 zoomMin, zoomMax);
339 if (event.ButtonUp() && event.GetButton() == mButton)
340 return HandleMouseButtonUp();
341 return false;
342}
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 274 of file EnvelopeEditor.cpp.

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

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 138 of file EnvelopeEditor.cpp.

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

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: