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 40 of file SampleHandle.cpp.

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

◆ ~SampleHandle()

SampleHandle::~SampleHandle ( )
virtual

Definition at line 176 of file SampleHandle.cpp.

177{
178}

Member Function Documentation

◆ Cancel()

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

Implements UIHandle.

Definition at line 459 of file SampleHandle.cpp.

460{
461 mClickedTrack.reset();
462 ProjectHistory::Get( *pProject ).RollbackState();
464}
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 185 of file SampleHandle.cpp.

187{
188 using namespace RefreshCode;
189 using namespace WaveChannelUtilities;
190 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
191 if ( unsafe )
192 return Cancelled;
193
194 const wxMouseEvent &event = evt.event;
195 const wxRect &rect = evt.rect;
196 const auto &viewInfo = ViewInfo::Get( *pProject );
197
198 const double t0 = viewInfo.PositionToTime(event.m_x, rect.x);
199 const auto pTrack = mClickedTrack.get();
201 if (!mClickedClip)
202 return Cancelled;
203
204 const auto intervals = viewInfo.FindIntervals(rect.width);
206 if (!SampleResolutionTest(viewInfo, *mClickedClip, intervals))
207 {
209 XO("To use Draw, zoom in further until you can see the individual samples."),
210 XO("Draw Tool"));
211 return Cancelled;
212 }
213
215 mRect = rect;
216
217 //convert t0 to samples
218 mClickedStartPixel = viewInfo.TimeToPosition(t0);
219
220 //Determine how drawing should occur. If alt is down,
221 //do a smoothing, instead of redrawing.
222 if (event.m_altDown)
223 {
224 mAltKey = true;
225 //*************************************************
226 //*** ALT-DOWN-CLICK (SAMPLE SMOOTHING) ***
227 //*************************************************
228 //
229 // Smoothing works like this: There is a smoothing kernel radius constant that
230 // determines how wide the averaging window is. Plus, there is a smoothing brush radius,
231 // which determines how many pixels wide around the selected pixel this smoothing is applied.
232 //
233 // Samples will be replaced by a mixture of the original points and the smoothed points,
234 // with a triangular mixing probability whose value at the center point is
235 // SMOOTHING_PROPORTION_MAX and at the far bounds is SMOOTHING_PROPORTION_MIN
236
237 //Get the region of samples around the selected point
238 size_t sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
239 Floats sampleRegion{ sampleRegionSize };
240 Floats newSampleRegion{ 1 + 2 * (size_t)SMOOTHING_BRUSH_RADIUS };
241
242 //Get a sample from the clip to do some tricks on.
243 constexpr auto mayThrow = false;
244 const auto sampleRegionRange = GetFloatsCenteredAroundTime(*mClickedTrack,
245 t0, sampleRegion.get(),
247
248 //Go through each point of the smoothing brush and apply a smoothing operation.
249 for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
250 float sumOfSamples = 0;
251 for (auto ii = -SMOOTHING_KERNEL_RADIUS; ii <= SMOOTHING_KERNEL_RADIUS; ++ii) {
252 //Go through each point of the smoothing kernel and find the average
253 const auto sampleRegionIndex =
255 const auto inRange = sampleRegionRange.first <= sampleRegionIndex &&
256 sampleRegionIndex < sampleRegionRange.second;
257 if (!inRange)
258 continue;
259 //The average is a weighted average, scaled by a weighting kernel that is simply triangular
260 // A triangular kernel across N items, with a radius of R ( 2 R + 1 points), if the farthest:
261 // points have a probability of a, the entire triangle has total probability of (R + 1)^2.
262 // For sample number ii and middle brush sample M, (R + 1 - abs(M-ii))/ ((R+1)^2) gives a
263 // legal distribution whose total probability is 1.
264 //
265 //
266 // weighting factor value
267 sumOfSamples += (SMOOTHING_KERNEL_RADIUS + 1 - abs(ii)) *
268 sampleRegion[sampleRegionIndex];
269 }
270 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
271 sumOfSamples /
273 }
274
275
276 // Now that the NEW sample levels are determined, go through each and mix it appropriately
277 // with the original point, according to a 2-part linear function whose center has probability
278 // SMOOTHING_PROPORTION_MAX and extends out SMOOTHING_BRUSH_RADIUS, at which the probability is
279 // SMOOTHING_PROPORTION_MIN. _MIN and _MAX specify how much of the smoothed curve make it through.
280
281 float prob;
282
283 for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
284
285 prob =
287 (float)abs(jj) / SMOOTHING_BRUSH_RADIUS *
289
290 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
291 newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] * prob +
293 (1 - prob);
294 }
295 // Set a range of samples around the mouse event
296 // Don't require dithering later
298 t0, newSampleRegion.get(), SMOOTHING_BRUSH_RADIUS,
300
301 // mLastDragSampleValue will not be used
302 }
303 else
304 {
305 mAltKey = false;
306 //*************************************************
307 //*** PLAIN DOWN-CLICK (NORMAL DRAWING) ***
308 //*************************************************
309
310 //Otherwise (e.g., the alt button is not down) do normal redrawing, based on the mouse position.
311 const float newLevel = FindSampleEditingLevel(event, viewInfo, t0);
312
313 //Set the sample to the point of the mouse event
314 // Don't require dithering later
315
317
318 mLastDragSampleValue = newLevel;
319 }
320
321 //Set the member data structures for drawing
323
324 // Sample data changed on either branch, so refresh the track display.
325 return RefreshCell;
326}
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 350 of file SampleHandle.cpp.

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

46{
47#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
49#endif
50}
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 466 of file SampleHandle.cpp.

468{
469 using namespace WaveChannelUtilities;
470 // Calculate where the mouse is located vertically (between +/- 1)
471 float zoomMin, zoomMax;
472 auto &cache = WaveformScale::Get(*mClickedTrack);
473 cache.GetDisplayBounds(zoomMin, zoomMax);
474
475 const int yy = event.m_y - mRect.y;
476 const int height = mRect.GetHeight();
478 const bool dB = !settings.isLinear();
479 float newLevel =
480 ::ValueOfPixel(yy, height, false, dB,
481 settings.dBRange, zoomMin, zoomMax);
482
483 //Take the envelope into account
484 const auto time = viewInfo.PositionToTime(event.m_x, mRect.x);
485 if (const auto env = GetEnvelopeAtTime(*mClickedTrack, time)){
486 // Calculate sample as it would be rendered
487 double envValue = env->GetValue(t0);
488 if (envValue > 0)
489 newLevel /= envValue;
490 else
491 newLevel = 0;
492
493 //Make sure the NEW level is between +/-1
494 newLevel = std::max(-1.0f, std::min(1.0f, newLevel));
495 }
496
497 return newLevel;
498}
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:69
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 180 of file SampleHandle.cpp.

181{
183}
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().

Referenced by anonymous_namespace{WaveformView.cpp}::DrawClipWaveform().

Here is the call graph for this function:
Here is the caller 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 75 of file SampleHandle.cpp.

77{
78 auto result = std::make_shared<SampleHandle>(pChannel);
79 result = AssignUIHandlePtr(holder, result);
80 return result;
81}
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 52 of file SampleHandle.cpp.

54{
55 static auto disabledCursor =
56 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
57 static wxCursor smoothCursor{ wxCURSOR_SPRAYCAN };
58 static auto pencilCursor =
59 ::MakeCursor(wxCURSOR_PENCIL, DrawCursorXpm, 12, 22);
60
61 // TODO: message should also mention the brush. Describing the modifier key
62 // (alt, or other) varies with operating system.
63 auto message = XO("Click and drag to edit the samples");
64
65 return {
66 message,
67 (unsafe
68 ? &*disabledCursor
69 : (state.AltDown()
70 ? &smoothCursor
71 : &*pencilCursor))
72 };
73}
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 117 of file SampleHandle.cpp.

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

432{
433 const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive();
434 return HitPreview(st.state, pProject, unsafe);
435}
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 437 of file SampleHandle.cpp.

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