Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
SampleHandle Class Referencefinal

#include <SampleHandle.h>

Inheritance diagram for SampleHandle:
[legend]
Collaboration diagram for SampleHandle:
[legend]

Public Member Functions

 SampleHandle (const std::shared_ptr< WaveChannel > &pTrack)
 
SampleHandleoperator= (const SampleHandle &)=default
 
virtual ~SampleHandle ()
 
std::shared_ptr< const TrackFindTrack () const override
 
void Enter (bool forward, AudacityProject *) override
 
Result Click (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
Result Drag (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
HitTestPreview Preview (const TrackPanelMouseState &state, AudacityProject *pProject) override
 
Result Release (const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
 
Result Cancel (AudacityProject *pProject) override
 
bool StopsOnKeystroke () override
 
- Public Member Functions inherited from UIHandle
virtual ~UIHandle ()=0
 
virtual void Enter (bool forward, AudacityProject *pProject)
 
virtual bool HasRotation () const
 
virtual bool Rotate (bool forward)
 
virtual bool HasEscape (AudacityProject *pProject) const
 
virtual bool Escape (AudacityProject *pProject)
 
virtual bool HandlesRightClick ()
 Whether the handle has any special right-button handling. More...
 
virtual Result Click (const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
 
virtual Result Drag (const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
 
virtual HitTestPreview Preview (const TrackPanelMouseState &state, AudacityProject *pProject)=0
 
virtual Result Release (const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent)=0
 
virtual Result Cancel (AudacityProject *pProject)=0
 
virtual bool StopsOnKeystroke ()
 
virtual void OnProjectChange (AudacityProject *pProject)
 
virtual std::shared_ptr< const TrackFindTrack () const =0
 
virtual bool IsDragging () const
 
Result GetChangeHighlight () const
 
void SetChangeHighlight (Result val)
 
- Public Member Functions inherited from TrackPanelDrawable
virtual ~TrackPanelDrawable ()=0
 
virtual void Draw (TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
 
virtual wxRect DrawingArea (TrackPanelDrawingContext &context, const wxRect &rect, const wxRect &panelRect, unsigned iPass)
 

Static Public Member Functions

static UIHandlePtr HitAnywhere (std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const std::shared_ptr< WaveChannel > &pChannel)
 
static UIHandlePtr HitTest (std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveChannel > &pChannel)
 
- Static Public Member Functions inherited from UIHandle
static UIHandle::Result NeedChangeHighlight (const UIHandle &, const UIHandle &)
 
static std::shared_ptr< const TrackTrackFromChannel (const std::shared_ptr< const Channel > &pChannel)
 A frequent convenience in the definition of UIHandles. More...
 
- Static Public Member Functions inherited from TrackPanelDrawable
static wxRect MaximizeWidth (const wxRect &rect, const wxRect &panelRect)
 
static wxRect MaximizeHeight (const wxRect &rect, const wxRect &panelRect)
 

Private Member Functions

 SampleHandle (const SampleHandle &)=delete
 
float FindSampleEditingLevel (const wxMouseEvent &event, const ViewInfo &viewInfo, double t0)
 

Static Private Member Functions

static HitTestPreview HitPreview (const wxMouseState &state, const AudacityProject *pProject, bool unsafe)
 

Private Attributes

std::shared_ptr< WaveChannelmClickedTrack
 
std::shared_ptr< WaveClipChannelmClickedClip {}
 
wxRect mRect {}
 
int mClickedStartPixel {}
 
int mLastDragPixel {}
 
float mLastDragSampleValue {}
 
bool mAltKey {}
 

Additional Inherited Members

- Public Types inherited from UIHandle
using Result = unsigned
 
using Cell = TrackPanelCell
 
- Protected Attributes inherited from UIHandle
Result mChangeHighlight { 0 }
 

Detailed Description

Definition at line 25 of file SampleHandle.h.

Constructor & Destructor Documentation

◆ SampleHandle() [1/2]

SampleHandle::SampleHandle ( const SampleHandle )
privatedelete

◆ SampleHandle() [2/2]

SampleHandle::SampleHandle ( const std::shared_ptr< WaveChannel > &  pTrack)
explicit

Definition at line 41 of file SampleHandle.cpp.

42 : mClickedTrack{ pTrack }
43{
44}
std::shared_ptr< WaveChannel > mClickedTrack
Definition: SampleHandle.h:73

◆ ~SampleHandle()

SampleHandle::~SampleHandle ( )
virtual

Definition at line 177 of file SampleHandle.cpp.

178{
179}

Member Function Documentation

◆ Cancel()

UIHandle::Result SampleHandle::Cancel ( AudacityProject pProject)
overridevirtual

Implements UIHandle.

Definition at line 460 of file SampleHandle.cpp.

461{
462 mClickedTrack.reset();
463 ProjectHistory::Get( *pProject ).RollbackState();
465}
static ProjectHistory & Get(AudacityProject &project)

References ProjectHistory::Get(), mClickedTrack, RefreshCode::RefreshCell, and ProjectHistory::RollbackState().

Referenced by Drag(), and Release().

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

◆ Click()

UIHandle::Result SampleHandle::Click ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

Someone has just clicked the mouse. What do we do?

We're in a track view and zoomed enough to see the samples.

Implements UIHandle.

Definition at line 186 of file SampleHandle.cpp.

188{
189 using namespace RefreshCode;
190 using namespace WaveChannelUtilities;
191 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
192 if ( unsafe )
193 return Cancelled;
194
195 const wxMouseEvent &event = evt.event;
196 const wxRect &rect = evt.rect;
197 const auto &viewInfo = ViewInfo::Get( *pProject );
198
199 const double t0 = viewInfo.PositionToTime(event.m_x, rect.x);
200 const auto pTrack = mClickedTrack.get();
202 if (!mClickedClip)
203 return Cancelled;
204
205 const auto intervals = viewInfo.FindIntervals(rect.width);
207 if (!SampleResolutionTest(viewInfo, *mClickedClip, intervals))
208 {
210 XO("To use Draw, zoom in further until you can see the individual samples."),
211 XO("Draw Tool"));
212 return Cancelled;
213 }
214
216 mRect = rect;
217
218 //convert t0 to samples
219 mClickedStartPixel = viewInfo.TimeToPosition(t0);
220
221 //Determine how drawing should occur. If alt is down,
222 //do a smoothing, instead of redrawing.
223 if (event.m_altDown)
224 {
225 mAltKey = true;
226 //*************************************************
227 //*** ALT-DOWN-CLICK (SAMPLE SMOOTHING) ***
228 //*************************************************
229 //
230 // Smoothing works like this: There is a smoothing kernel radius constant that
231 // determines how wide the averaging window is. Plus, there is a smoothing brush radius,
232 // which determines how many pixels wide around the selected pixel this smoothing is applied.
233 //
234 // Samples will be replaced by a mixture of the original points and the smoothed points,
235 // with a triangular mixing probability whose value at the center point is
236 // SMOOTHING_PROPORTION_MAX and at the far bounds is SMOOTHING_PROPORTION_MIN
237
238 //Get the region of samples around the selected point
239 size_t sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
240 Floats sampleRegion{ sampleRegionSize };
241 Floats newSampleRegion{ 1 + 2 * (size_t)SMOOTHING_BRUSH_RADIUS };
242
243 //Get a sample from the clip to do some tricks on.
244 constexpr auto mayThrow = false;
245 const auto sampleRegionRange = GetFloatsCenteredAroundTime(*mClickedTrack,
246 t0, sampleRegion.get(),
248
249 //Go through each point of the smoothing brush and apply a smoothing operation.
250 for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
251 float sumOfSamples = 0;
252 for (auto ii = -SMOOTHING_KERNEL_RADIUS; ii <= SMOOTHING_KERNEL_RADIUS; ++ii) {
253 //Go through each point of the smoothing kernel and find the average
254 const auto sampleRegionIndex =
256 const auto inRange = sampleRegionRange.first <= sampleRegionIndex &&
257 sampleRegionIndex < sampleRegionRange.second;
258 if (!inRange)
259 continue;
260 //The average is a weighted average, scaled by a weighting kernel that is simply triangular
261 // A triangular kernel across N items, with a radius of R ( 2 R + 1 points), if the farthest:
262 // points have a probability of a, the entire triangle has total probability of (R + 1)^2.
263 // For sample number ii and middle brush sample M, (R + 1 - abs(M-ii))/ ((R+1)^2) gives a
264 // legal distribution whose total probability is 1.
265 //
266 //
267 // weighting factor value
268 sumOfSamples += (SMOOTHING_KERNEL_RADIUS + 1 - abs(ii)) *
269 sampleRegion[sampleRegionIndex];
270 }
271 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
272 sumOfSamples /
274 }
275
276
277 // Now that the NEW sample levels are determined, go through each and mix it appropriately
278 // with the original point, according to a 2-part linear function whose center has probability
279 // SMOOTHING_PROPORTION_MAX and extends out SMOOTHING_BRUSH_RADIUS, at which the probability is
280 // SMOOTHING_PROPORTION_MIN. _MIN and _MAX specify how much of the smoothed curve make it through.
281
282 float prob;
283
284 for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
285
286 prob =
288 (float)abs(jj) / SMOOTHING_BRUSH_RADIUS *
290
291 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
292 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] * prob +
294 (1 - prob);
295 }
296 // Set a range of samples around the mouse event
297 // Don't require dithering later
299 t0, newSampleRegion.get(), SMOOTHING_BRUSH_RADIUS,
301
302 // mLastDragSampleValue will not be used
303 }
304 else
305 {
306 mAltKey = false;
307 //*************************************************
308 //*** PLAIN DOWN-CLICK (NORMAL DRAWING) ***
309 //*************************************************
310
311 //Otherwise (e.g., the alt button is not down) do normal redrawing, based on the mouse position.
312 const float newLevel = FindSampleEditingLevel(event, viewInfo, t0);
313
314 //Set the sample to the point of the mouse event
315 // Don't require dithering later
316
318
319 mLastDragSampleValue = newLevel;
320 }
321
322 //Set the member data structures for drawing
324
325 // Sample data changed on either branch, so refresh the track display.
326 return RefreshCell;
327}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
XO("Cut/Copy/Paste")
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.
static const int SMOOTHING_BRUSH_RADIUS
static const double SMOOTHING_PROPORTION_MAX
static const int SMOOTHING_KERNEL_RADIUS
static const double SMOOTHING_PROPORTION_MIN
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
std::shared_ptr< WaveClipChannel > mClickedClip
Definition: SampleHandle.h:74
float FindSampleEditingLevel(const wxMouseEvent &event, const ViewInfo &viewInfo, double t0)
float mLastDragSampleValue
Definition: SampleHandle.h:79
int mClickedStartPixel
Definition: SampleHandle.h:77
wxRect mRect
Definition: SampleHandle.h:75
int mLastDragPixel
Definition: SampleHandle.h:78
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
WAVE_TRACK_API void SetFloatsCenteredAroundTime(WaveChannel &channel, double t, const float *buffer, size_t numSideSamples, sampleFormat effectiveFormat)
Similar to GetFloatsCenteredAroundTime, but for writing. Sets as many samples as it can according to ...
WAVE_TRACK_API std::pair< size_t, size_t > GetFloatsCenteredAroundTime(const WaveChannel &channel, double t, float *buffer, size_t numSideSamples, bool mayThrow)
Gets as many samples as it can, but no more than 2 * numSideSamples + 1, centered around t....
WAVE_TRACK_API ClipPointer GetClipAtTime(WaveChannel &channel, double time)
WAVE_TRACK_API void SetFloatAtTime(WaveChannel &channel, double t, float value, sampleFormat effectiveFormat)
Sets sample nearest to t to value. Silently fails if GetClipAtTime(t) == nullptr.
bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveChannelInterval &clip, const ZoomInfo::Intervals &intervals)

References AudacityMessageBox(), Cancelled, TrackPanelMouseEvent::event, FindSampleEditingLevel(), ProjectAudioIO::Get(), ViewInfo::Get(), WaveChannelUtilities::GetClipAtTime(), WaveChannelUtilities::GetFloatsCenteredAroundTime(), ProjectAudioIO::IsAudioActive(), mAltKey, mClickedClip, mClickedStartPixel, mClickedTrack, mLastDragPixel, mLastDragSampleValue, mRect, narrowestSampleFormat, TrackPanelMouseEvent::rect, RefreshCode::RefreshCell, anonymous_namespace{SampleHandle.cpp}::SampleResolutionTest(), WaveChannelUtilities::SetFloatAtTime(), WaveChannelUtilities::SetFloatsCenteredAroundTime(), SMOOTHING_BRUSH_RADIUS, SMOOTHING_KERNEL_RADIUS, SMOOTHING_PROPORTION_MAX, SMOOTHING_PROPORTION_MIN, and XO().

Here is the call graph for this function:

◆ Drag()

UIHandle::Result SampleHandle::Drag ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 351 of file SampleHandle.cpp.

353{
354 using namespace RefreshCode;
355 using namespace WaveChannelUtilities;
356 const wxMouseEvent &event = evt.event;
357 const auto &viewInfo = ViewInfo::Get( *pProject );
358
359 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
360 if (unsafe)
361 {
362 this->Cancel(pProject);
363 return RefreshCell | Cancelled;
364 }
365
366 // There must have been some clicking before dragging ...
367 assert(mClickedTrack && mClickedClip);
368 if (!(mClickedTrack && mClickedClip))
369 return Cancelled;
370
371 //*************************************************
372 //*** DRAG-DRAWING ***
373 //*************************************************
374
375 //No dragging effects if the alt key is down--
376 //Don't allow left-right dragging for smoothing operation
377 if (mAltKey)
378 return RefreshNone;
379
380 const double t0 = viewInfo.PositionToTime(mLastDragPixel);
381 const double t1 = viewInfo.PositionToTime(event.m_x, mRect.x);
382
383 const int x1 =
384 event.m_controlDown ? mClickedStartPixel : viewInfo.TimeToPosition(t1);
385 const float newLevel = FindSampleEditingLevel(event, viewInfo, t0);
386 const auto start = std::min(t0, t1);
387 const auto end = std::max(t0, t1);
388
389 // Starting from the originally clicked clip, restrict the editing boundaries
390 // to the succession of clips with visible samples. If, of clips A, B and C,
391 // only B had invisible samples, it'd mean one could not drag-draw from A
392 // into C, but that probably isn't a behavior worthwhile much implementation
393 // complications.
395 const auto iter = std::find_if(clips.begin(), clips.end(),
396 // Compare the intervals, not the pointers to them
397 [this](const auto &pClip){ return *pClip == *mClickedClip; });
398 const auto clickedClipIndex = std::distance(clips.begin(), iter);
399 constexpr auto forward = true;
400 const auto intervals = viewInfo.FindIntervals(mRect.width);
401 const size_t leftmostEditable = GetLastEditableClipStartingFromNthClip(
402 clickedClipIndex, !forward, clips, viewInfo, intervals);
403 const size_t rightmostEditable = GetLastEditableClipStartingFromNthClip(
404 clickedClipIndex, forward, clips, viewInfo, intervals);
405
406 const auto editStart =
407 std::max(start, clips[leftmostEditable]->GetPlayStartTime());
408 const auto editEnd =
409 std::min(end, clips[rightmostEditable]->GetPlayEndTime());
410
411 // For fast pencil movements covering more than one sample between two
412 // updates, we draw a line going from v0 at t0 to v1 at t1.
413 const auto interpolator = [t0, t1, v0 = mLastDragSampleValue,
414 v1 = newLevel](double t) {
415 if (t0 == t1)
416 return v1;
417 const auto gradient = (v1 - v0) / (t1 - t0);
418 const auto value = static_cast<float>(gradient * (t - t0) + v0);
419 // t may be outside t0 and t1, and we don't want to extrapolate.
420 return std::clamp(value, std::min(v0, v1), std::max(v0, v1));
421 };
423 editStart, editEnd, interpolator, narrowestSampleFormat);
424
425 mLastDragPixel = x1;
426 mLastDragSampleValue = newLevel;
427
428 return RefreshCell;
429}
int min(int a, int b)
Result Cancel(AudacityProject *pProject) override
WAVE_TRACK_API void SetFloatsWithinTimeRange(WaveChannel &channel, double t0, double t1, const std::function< float(double sampleTime)> &producer, sampleFormat effectiveFormat)
Provides a means of setting clip values as a function of time. Included are closest sample to t0 up t...
WAVE_TRACK_API ClipPointers SortedClipArray(WaveChannel &channel)
Get clips sorted by play start time.
size_t GetLastEditableClipStartingFromNthClip(size_t n, bool forward, const WaveChannelUtilities::ClipPointers &sortedClips, const ViewInfo &viewInfo, const ZoomInfo::Intervals &intervals)
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References Cancel(), Cancelled, details::end(), TrackPanelMouseEvent::event, FindSampleEditingLevel(), forward, ProjectAudioIO::Get(), ViewInfo::Get(), anonymous_namespace{SampleHandle.cpp}::GetLastEditableClipStartingFromNthClip(), ProjectAudioIO::IsAudioActive(), mAltKey, mClickedClip, mClickedStartPixel, mClickedTrack, min(), mLastDragPixel, mLastDragSampleValue, mRect, narrowestSampleFormat, RefreshCode::RefreshCell, RefreshCode::RefreshNone, WaveChannelUtilities::SetFloatsWithinTimeRange(), and WaveChannelUtilities::SortedClipArray().

Here is the call graph for this function:

◆ Enter()

void SampleHandle::Enter ( bool  forward,
AudacityProject  
)
overridevirtual

Reimplemented from UIHandle.

Definition at line 46 of file SampleHandle.cpp.

47{
48#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
50#endif
51}
Result mChangeHighlight
Definition: UIHandle.h:152

References UIHandle::mChangeHighlight, and RefreshCode::RefreshCell.

◆ FindSampleEditingLevel()

float SampleHandle::FindSampleEditingLevel ( const wxMouseEvent &  event,
const ViewInfo viewInfo,
double  t0 
)
private

Definition at line 467 of file SampleHandle.cpp.

469{
470 using namespace WaveChannelUtilities;
471 // Calculate where the mouse is located vertically (between +/- 1)
472 float zoomMin, zoomMax;
473 auto &cache = WaveformScale::Get(*mClickedTrack);
474 cache.GetDisplayBounds(zoomMin, zoomMax);
475
476 const int yy = event.m_y - mRect.y;
477 const int height = mRect.GetHeight();
479 const bool dB = !settings.isLinear();
480 float newLevel =
481 ::ValueOfPixel(yy, height, false, dB,
482 settings.dBRange, zoomMin, zoomMax);
483
484 //Take the envelope into account
485 const auto time = viewInfo.PositionToTime(event.m_x, mRect.x);
486 if (const auto env = GetEnvelopeAtTime(*mClickedTrack, time)){
487 // Calculate sample as it would be rendered
488 double envValue = env->GetValue(t0);
489 if (envValue > 0)
490 newLevel /= envValue;
491 else
492 newLevel = 0;
493
494 //Make sure the NEW level is between +/-1
495 newLevel = std::max(-1.0f, std::min(1.0f, newLevel));
496 }
497
498 return newLevel;
499}
float ValueOfPixel(int yy, int height, bool offset, bool dB, double dBRange, float zoomMin, float zoomMax)
Definition: TrackArt.cpp:122
static Settings & settings()
Definition: TrackInfo.cpp:51
static WaveformScale & Get(const WaveTrack &track)
Mutative access to attachment even if the track argument is const.
static WaveformSettings & Get(const WaveTrack &track)
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:34
WAVE_TRACK_API Envelope * GetEnvelopeAtTime(WaveChannel &channel, double time)

References WaveformSettings::Get(), WaveformScale::Get(), WaveChannelUtilities::GetEnvelopeAtTime(), mClickedTrack, min(), mRect, ZoomInfo::PositionToTime(), settings(), and ValueOfPixel().

Referenced by Click(), and Drag().

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

◆ FindTrack()

std::shared_ptr< const Track > SampleHandle::FindTrack ( ) const
overridevirtual
Returns
pointer to associated track, if any

Implements UIHandle.

Definition at line 181 of file SampleHandle.cpp.

182{
184}
static std::shared_ptr< const Track > TrackFromChannel(const std::shared_ptr< const Channel > &pChannel)
A frequent convenience in the definition of UIHandles.
Definition: UIHandle.cpp:63

References mClickedTrack, and UIHandle::TrackFromChannel().

Here is the call graph for this function:

◆ HitAnywhere()

UIHandlePtr SampleHandle::HitAnywhere ( std::weak_ptr< SampleHandle > &  holder,
const wxMouseState &  state,
const std::shared_ptr< WaveChannel > &  pChannel 
)
static

Definition at line 76 of file SampleHandle.cpp.

78{
79 auto result = std::make_shared<SampleHandle>(pChannel);
80 result = AssignUIHandlePtr(holder, result);
81 return result;
82}
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:164

References AssignUIHandlePtr().

Referenced by WaveformView::DetailedHitTest(), and HitTest().

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

◆ HitPreview()

HitTestPreview SampleHandle::HitPreview ( const wxMouseState &  state,
const AudacityProject pProject,
bool  unsafe 
)
staticprivate

Definition at line 53 of file SampleHandle.cpp.

55{
56 static auto disabledCursor =
57 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
58 static wxCursor smoothCursor{ wxCURSOR_SPRAYCAN };
59 static auto pencilCursor =
60 ::MakeCursor(wxCURSOR_PENCIL, DrawCursorXpm, 12, 22);
61
62 // TODO: message should also mention the brush. Describing the modifier key
63 // (alt, or other) varies with operating system.
64 auto message = XO("Click and drag to edit the samples");
65
66 return {
67 message,
68 (unsafe
69 ? &*disabledCursor
70 : (state.AltDown()
71 ? &smoothCursor
72 : &*pencilCursor))
73 };
74}
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:189

References MakeCursor(), and XO().

Referenced by Preview().

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

◆ HitTest()

UIHandlePtr SampleHandle::HitTest ( std::weak_ptr< SampleHandle > &  holder,
const wxMouseState &  state,
const wxRect &  rect,
const AudacityProject pProject,
const std::shared_ptr< WaveChannel > &  pChannel 
)
static

method that tells us if the mouse event landed on an editable sample

Definition at line 118 of file SampleHandle.cpp.

121{
122 using namespace WaveChannelUtilities;
123 const auto &viewInfo = ViewInfo::Get( *pProject );
124
127 if (!pChannel)
128 return {};
129 auto &waveChannel = *pChannel;
130 const auto time = viewInfo.PositionToTime(state.m_x, rect.x);
131 const auto clickedClip =
132 WaveChannelUtilities::GetClipAtTime(waveChannel, time);
133 if (!clickedClip)
134 return {};
135
136 const double tt = adjustTime(waveChannel, time);
137 const auto intervals = viewInfo.FindIntervals(rect.width);
138 if (!SampleResolutionTest(viewInfo, *clickedClip, intervals))
139 return {};
140
141 // Just get one sample.
142 float oneSample;
143 constexpr auto mayThrow = false;
145 tt, oneSample, mayThrow))
146 return {};
147
148 // Get y distance of envelope point from center line (in pixels).
149 auto &cache = WaveformScale::Get(waveChannel);
150 float zoomMin, zoomMax;
151 cache.GetDisplayBounds(zoomMin, zoomMax);
152
153 double envValue = 1.0;
154 if (const auto env =
156 // Calculate sample as it would be rendered
157 envValue = env->GetValue(tt);
158
159 auto &settings = WaveformSettings::Get(waveChannel);
160 const bool dB = !settings.isLinear();
161 int yValue = GetWaveYPos(oneSample * envValue,
162 zoomMin, zoomMax,
163 rect.height, dB, true,
164 settings.dBRange, false) + rect.y;
165
166 // Get y position of mouse (in pixels)
167 int yMouse = state.m_y;
168
169 // Perhaps yTolerance should be put into preferences?
170 const int yTolerance = 10; // More tolerance on samples than on envelope.
171 if (abs(yValue - yMouse) >= yTolerance)
172 return {};
173
174 return HitAnywhere(holder, state, pChannel);
175}
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
Definition: TrackArt.cpp:66
static UIHandlePtr HitAnywhere(std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const std::shared_ptr< WaveChannel > &pChannel)
WAVE_TRACK_API bool GetFloatAtTime(const WaveChannel &channel, double t, float &value, bool mayThrow)
double adjustTime(const WaveChannel &wt, double time)

References anonymous_namespace{SampleHandle.cpp}::adjustTime(), ViewInfo::Get(), WaveformSettings::Get(), WaveformScale::Get(), WaveChannelUtilities::GetClipAtTime(), WaveChannelUtilities::GetEnvelopeAtTime(), WaveChannelUtilities::GetFloatAtTime(), GetWaveYPos(), HitAnywhere(), anonymous_namespace{SampleHandle.cpp}::SampleResolutionTest(), and settings().

Referenced by WaveformView::DetailedHitTest().

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

◆ operator=()

SampleHandle & SampleHandle::operator= ( const SampleHandle )
default

◆ Preview()

HitTestPreview SampleHandle::Preview ( const TrackPanelMouseState state,
AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 431 of file SampleHandle.cpp.

433{
434 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
435 return HitPreview(st.state, pProject, unsafe);
436}
static HitTestPreview HitPreview(const wxMouseState &state, const AudacityProject *pProject, bool unsafe)

References ProjectAudioIO::Get(), HitPreview(), ProjectAudioIO::IsAudioActive(), and TrackPanelMouseState::state.

Here is the call graph for this function:

◆ Release()

UIHandle::Result SampleHandle::Release ( const TrackPanelMouseEvent event,
AudacityProject pProject,
wxWindow *  pParent 
)
overridevirtual

Implements UIHandle.

Definition at line 438 of file SampleHandle.cpp.

441{
442 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
443 if (unsafe)
444 return this->Cancel(pProject);
445
446 //*************************************************
447 //*** UP-CLICK (Finish drawing) ***
448 //*************************************************
449 //On up-click, send the state to the undo stack
450 mClickedTrack.reset(); //Set this to NULL so it will catch improper drag events.
451 mClickedClip = nullptr;
452 ProjectHistory::Get( *pProject ).PushState(XO("Moved Samples"),
453 XO("Sample Edit"),
455
456 // No change to draw since last drag
458}
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)

References Cancel(), CONSOLIDATE, ProjectAudioIO::Get(), ProjectHistory::Get(), ProjectAudioIO::IsAudioActive(), mClickedClip, mClickedTrack, ProjectHistory::PushState(), RefreshCode::RefreshNone, and XO().

Here is the call graph for this function:

◆ StopsOnKeystroke()

bool SampleHandle::StopsOnKeystroke ( )
inlineoverridevirtual

Reimplemented from UIHandle.

Definition at line 67 of file SampleHandle.h.

67{ return true; }

Member Data Documentation

◆ mAltKey

bool SampleHandle::mAltKey {}
private

Definition at line 80 of file SampleHandle.h.

Referenced by Click(), and Drag().

◆ mClickedClip

std::shared_ptr<WaveClipChannel> SampleHandle::mClickedClip {}
private

Definition at line 74 of file SampleHandle.h.

Referenced by Click(), Drag(), and Release().

◆ mClickedStartPixel

int SampleHandle::mClickedStartPixel {}
private

Definition at line 77 of file SampleHandle.h.

Referenced by Click(), and Drag().

◆ mClickedTrack

std::shared_ptr<WaveChannel> SampleHandle::mClickedTrack
private

Definition at line 73 of file SampleHandle.h.

Referenced by Cancel(), Click(), Drag(), FindSampleEditingLevel(), FindTrack(), and Release().

◆ mLastDragPixel

int SampleHandle::mLastDragPixel {}
private

Definition at line 78 of file SampleHandle.h.

Referenced by Click(), and Drag().

◆ mLastDragSampleValue

float SampleHandle::mLastDragSampleValue {}
private

Definition at line 79 of file SampleHandle.h.

Referenced by Click(), and Drag().

◆ mRect

wxRect SampleHandle::mRect {}
private

Definition at line 75 of file SampleHandle.h.

Referenced by Click(), Drag(), and FindSampleEditingLevel().


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