Audacity 3.2.0
Enumerations | Functions
anonymous_namespace{SelectHandle.cpp} Namespace Reference

Enumerations

enum  SelectionBoundary {
  SBNone , SBLeft , SBRight , SBBottom ,
  SBTop , SBCenter , SBWidth
}
 

Functions

wxInt64 FrequencyToPosition (const WaveChannel &wc, double frequency, wxInt64 trackTopEdge, int trackHeight)
 Converts a frequency to screen y position. More...
 
double PositionToFrequency (const WaveChannel &wc, bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, int trackHeight)
 
template<typename T >
void SetIfNotNull (T *pValue, const T Value)
 
bool isSpectralSelectionView (const ChannelView &channelView)
 
SelectionBoundary ChooseTimeBoundary (const double t0, const double t1, const ViewInfo &viewInfo, double selend, bool onlyWithinSnapDistance, wxInt64 *pPixelDist, double *pPinValue)
 
SelectionBoundary ChooseBoundary (const ViewInfo &viewInfo, wxCoord xx, wxCoord yy, const ChannelView &channelView, const wxRect &rect, bool mayDragWidth, bool onlyWithinSnapDistance, double *pPinValue=NULL)
 
wxCursor * SelectCursor ()
 
wxCursor * EnvelopeCursor ()
 
void SetTipAndCursorForBoundary (SelectionBoundary boundary, bool frequencySnapping, TranslatableString &tip, wxCursor *&pCursor)
 
template<class A , class B , class DIST >
bool within (A a, B b, DIST d)
 
double findMaxRatio (double center, double rate)
 

Enumeration Type Documentation

◆ SelectionBoundary

enum anonymous_namespace{SelectHandle.cpp}::SelectionBoundary

Function Documentation

◆ ChooseBoundary()

SelectionBoundary anonymous_namespace{SelectHandle.cpp}::ChooseBoundary ( const ViewInfo viewInfo,
wxCoord  xx,
wxCoord  yy,
const ChannelView channelView,
const wxRect &  rect,
bool  mayDragWidth,
bool  onlyWithinSnapDistance,
double *  pPinValue = NULL 
)

Definition at line 171 of file SelectHandle.cpp.

177 {
178 // Choose one of four boundaries to adjust, or the center frequency.
179 // May choose frequencies only if in a spectrogram view and
180 // within the time boundaries.
181 // May choose no boundary if onlyWithinSnapDistance is true.
182 // Otherwise choose the eligible boundary nearest the mouse click.
183 const double selend = viewInfo.PositionToTime(xx, rect.x);
184 wxInt64 pixelDist = 0;
185 const double t0 = viewInfo.selectedRegion.t0();
186 const double t1 = viewInfo.selectedRegion.t1();
187
188 SelectionBoundary boundary =
189 ChooseTimeBoundary(t0,t1,viewInfo, selend, onlyWithinSnapDistance,
190 &pixelDist, pPinValue);
191
192 //const double t0 = viewInfo.selectedRegion.t0();
193 //const double t1 = viewInfo.selectedRegion.t1();
194 const double f0 = viewInfo.selectedRegion.f0();
195 const double f1 = viewInfo.selectedRegion.f1();
196 const double fc = viewInfo.selectedRegion.fc();
197 double ratio = 0;
198
199 bool chooseTime = true;
200 bool chooseBottom = true;
201 bool chooseCenter = false;
202 // Consider adjustment of frequencies only if mouse is
203 // within the time boundaries
204 if (!viewInfo.selectedRegion.isPoint() &&
205 t0 <= selend && selend < t1 &&
206 isSpectralSelectionView(channelView)) {
207 auto pWc = channelView.FindChannel<const WaveChannel>();
208 // Spectral selection track is always wave
209 assert(pWc);
210 auto &wc = *pWc;
211 const wxInt64 bottomSel = (f0 >= 0)
212 ? FrequencyToPosition(wc, f0, rect.y, rect.height)
213 : rect.y + rect.height;
214 const wxInt64 topSel = (f1 >= 0)
215 ? FrequencyToPosition(wc, f1, rect.y, rect.height)
216 : rect.y;
217 wxInt64 signedBottomDist = (int)(yy - bottomSel);
218 wxInt64 verticalDist = std::abs(signedBottomDist);
219 if (bottomSel == topSel)
220 // Top and bottom are too close to resolve on screen
221 chooseBottom = (signedBottomDist >= 0);
222 else {
223 const wxInt64 topDist = std::abs((int)(yy - topSel));
224 if (topDist < verticalDist)
225 chooseBottom = false, verticalDist = topDist;
226 }
227 if (fc > 0
228#ifdef SPECTRAL_EDITING_ESC_KEY
229 && mayDragWidth
230#endif
231 ) {
232 const wxInt64 centerSel =
233 FrequencyToPosition(wc, fc, rect.y, rect.height);
234 const wxInt64 centerDist = abs((int)(yy - centerSel));
235 if (centerDist < verticalDist)
236 chooseCenter = true, verticalDist = centerDist,
237 ratio = f1 / fc;
238 }
239 if (verticalDist >= 0 &&
240 verticalDist < pixelDist) {
241 pixelDist = verticalDist;
242 chooseTime = false;
243 }
244 }
245
246 if (!chooseTime) {
247 // PRL: Seems I need a larger tolerance to make snapping work
248 // at top of track, not sure why
249 if (onlyWithinSnapDistance &&
250 pixelDist >= FREQ_SNAP_DISTANCE) {
251 SetIfNotNull(pPinValue, -1.0);
252 return SBNone;
253 }
254 else if (chooseCenter) {
255 SetIfNotNull(pPinValue, ratio);
256 return SBCenter;
257 }
258 else if (mayDragWidth && fc > 0) {
259 SetIfNotNull(pPinValue, fc);
260 return SBWidth;
261 }
262 else if (chooseBottom) {
263 SetIfNotNull(pPinValue, f1);
264 return SBBottom;
265 }
266 else {
267 SetIfNotNull(pPinValue, f0);
268 return SBTop;
269 }
270 }
271 else
272 {
273 return boundary;
274 }
275 }
@ FREQ_SNAP_DISTANCE
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
double t1() const
Definition: ViewInfo.h:36
double f1() const
Definition: ViewInfo.h:38
double fc() const
Definition: ViewInfo.h:39
bool isPoint() const
Definition: ViewInfo.h:40
double f0() const
Definition: ViewInfo.h:37
double t0() const
Definition: ViewInfo.h:35
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:216
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:34
wxInt64 FrequencyToPosition(const WaveChannel &wc, double frequency, wxInt64 trackTopEdge, int trackHeight)
Converts a frequency to screen y position.
void SetIfNotNull(T *pValue, const T Value)
SelectionBoundary ChooseTimeBoundary(const double t0, const double t1, const ViewInfo &viewInfo, double selend, bool onlyWithinSnapDistance, wxInt64 *pPixelDist, double *pPinValue)
bool isSpectralSelectionView(const ChannelView &channelView)

References ChooseTimeBoundary(), NotifyingSelectedRegion::f0(), NotifyingSelectedRegion::f1(), NotifyingSelectedRegion::fc(), CommonChannelCell::FindChannel(), FREQ_SNAP_DISTANCE, FrequencyToPosition(), NotifyingSelectedRegion::isPoint(), isSpectralSelectionView(), ZoomInfo::PositionToTime(), SBBottom, SBCenter, SBNone, SBTop, SBWidth, ViewInfo::selectedRegion, SetIfNotNull(), NotifyingSelectedRegion::t0(), and NotifyingSelectedRegion::t1().

Referenced by SelectHandle::Click(), and SelectHandle::Preview().

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

◆ ChooseTimeBoundary()

SelectionBoundary anonymous_namespace{SelectHandle.cpp}::ChooseTimeBoundary ( const double  t0,
const double  t1,
const ViewInfo viewInfo,
double  selend,
bool  onlyWithinSnapDistance,
wxInt64 *  pPixelDist,
double *  pPinValue 
)

Definition at line 131 of file SelectHandle.cpp.

137 {
138 const wxInt64 posS = viewInfo.TimeToPosition(selend);
139 const wxInt64 pos0 = viewInfo.TimeToPosition(t0);
140 wxInt64 pixelDist = std::abs(posS - pos0);
141 bool chooseLeft = true;
142
143 if (t1<=t0)
144 // Special case when selection is a point, and thus left
145 // and right distances are the same
146 chooseLeft = (selend < t0);
147 else {
148 const wxInt64 pos1 = viewInfo.TimeToPosition(t1);
149 const wxInt64 rightDist = std::abs(posS - pos1);
150 if (rightDist < pixelDist)
151 chooseLeft = false, pixelDist = rightDist;
152 }
153
154 SetIfNotNull(pPixelDist, pixelDist);
155
156 if (onlyWithinSnapDistance &&
157 pixelDist >= SELECTION_RESIZE_REGION) {
158 SetIfNotNull(pPinValue, -1.0);
159 return SBNone;
160 }
161 else if (chooseLeft) {
162 SetIfNotNull(pPinValue, t1);
163 return SBLeft;
164 }
165 else {
166 SetIfNotNull(pPinValue, t0);
167 return SBRight;
168 }
169 }
@ SELECTION_RESIZE_REGION
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 SBLeft, SBNone, SBRight, SELECTION_RESIZE_REGION, SetIfNotNull(), and ZoomInfo::TimeToPosition().

Referenced by ChooseBoundary().

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

◆ EnvelopeCursor()

wxCursor * anonymous_namespace{SelectHandle.cpp}::EnvelopeCursor ( )

Definition at line 284 of file SelectHandle.cpp.

285 {
286 // This one doubles as the center frequency cursor for spectral selection:
287 static auto envelopeCursor =
288 ::MakeCursor(wxCURSOR_ARROW, EnvCursorXpm, 16, 16);
289 return &*envelopeCursor;
290 }
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:189

References MakeCursor().

Referenced by SetTipAndCursorForBoundary().

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

◆ findMaxRatio()

double anonymous_namespace{SelectHandle.cpp}::findMaxRatio ( double  center,
double  rate 
)
inline

Definition at line 486 of file SelectHandle.cpp.

487 {
488 const double minFrequency = 1.0;
489 const double maxFrequency = (rate / 2.0);
490 const double frequency =
491 std::min(maxFrequency,
492 std::max(minFrequency, center));
493 return
494 std::min(frequency / minFrequency, maxFrequency / frequency);
495 }
int min(int a, int b)

References min().

Referenced by SelectHandle::AdjustFreqSelection(), SelectHandle::MoveSnappingFreqSelection(), and SelectHandle::SnapCenterOnce().

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

◆ FrequencyToPosition()

wxInt64 anonymous_namespace{SelectHandle.cpp}::FrequencyToPosition ( const WaveChannel wc,
double  frequency,
wxInt64  trackTopEdge,
int  trackHeight 
)

Converts a frequency to screen y position.

Definition at line 69 of file SelectHandle.cpp.

73 {
74 const auto &settings = SpectrogramSettings::Get(wc);
75 float minFreq, maxFreq;
76 SpectrogramBounds::Get(wc).GetBounds(wc, minFreq, maxFreq);
77 const NumberScale numberScale(settings.GetScale(minFreq, maxFreq));
78 const float p = numberScale.ValueToPosition(frequency);
79 return trackTopEdge + wxInt64((1.0 - p) * trackHeight);
80 }
static Settings & settings()
Definition: TrackInfo.cpp:51
void GetBounds(const WaveChannel &wc, float &min, float &max) const
static SpectrogramBounds & Get(WaveTrack &track)
Get either the global default settings, or the track's own if previously created.
static SpectrogramSettings & Get(const WaveTrack &track)

References SpectrogramSettings::Get(), SpectrogramBounds::Get(), SpectrogramBounds::GetBounds(), settings(), and NumberScale::ValueToPosition().

Referenced by ChooseBoundary().

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

◆ isSpectralSelectionView()

bool anonymous_namespace{SelectHandle.cpp}::isSpectralSelectionView ( const ChannelView channelView)
inline

Definition at line 117 of file SelectHandle.cpp.

117 {
118 const WaveChannel *pChannel{};
119 return
120 channelView.IsSpectral() &&
121 (pChannel = channelView.FindChannel<const WaveChannel>().get()) &&
123 }
virtual bool IsSpectral() const
bool SpectralSelectionEnabled() const

References CommonChannelCell::FindChannel(), SpectrogramSettings::Get(), ChannelView::IsSpectral(), and SpectrogramSettings::SpectralSelectionEnabled().

Referenced by ChooseBoundary(), SelectHandle::Click(), SelectHandle::MoveSnappingFreqSelection(), SelectHandle::Preview(), and SelectHandle::StartFreqSelection().

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

◆ PositionToFrequency()

double anonymous_namespace{SelectHandle.cpp}::PositionToFrequency ( const WaveChannel wc,
bool  maySnap,
wxInt64  mouseYCoordinate,
wxInt64  trackTopEdge,
int  trackHeight 
)

Converts a position (mouse Y coordinate) to frequency, in Hz.

Definition at line 84 of file SelectHandle.cpp.

89 {
90 const double rate = wc.GetRate();
91
92 // Handle snapping
93 if (maySnap &&
94 mouseYCoordinate - trackTopEdge < FREQ_SNAP_DISTANCE)
95 return rate;
96 if (maySnap &&
97 trackTopEdge + trackHeight - mouseYCoordinate < FREQ_SNAP_DISTANCE)
98 return -1;
99
100 const auto &settings = SpectrogramSettings::Get(wc);
101 float minFreq, maxFreq;
102 SpectrogramBounds::Get(wc).GetBounds(wc, minFreq, maxFreq);
103 const NumberScale numberScale(settings.GetScale(minFreq, maxFreq));
104 const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight;
105 return numberScale.PositionToValue(1.0 - p);
106 }
double GetRate() const override
Definition: WaveTrack.cpp:800

References FREQ_SNAP_DISTANCE, SpectrogramSettings::Get(), SpectrogramBounds::Get(), SpectrogramBounds::GetBounds(), WaveChannel::GetRate(), NumberScale::PositionToValue(), and settings().

Referenced by SelectHandle::AdjustFreqSelection(), SelectHandle::MoveSnappingFreqSelection(), and SelectHandle::StartFreqSelection().

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

◆ SelectCursor()

wxCursor * anonymous_namespace{SelectHandle.cpp}::SelectCursor ( )

Definition at line 277 of file SelectHandle.cpp.

278 {
279 static auto selectCursor =
280 ::MakeCursor(wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
281 return &*selectCursor;
282 }

References MakeCursor().

Referenced by SelectHandle::Preview(), and SetTipAndCursorForBoundary().

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

◆ SetIfNotNull()

template<typename T >
void anonymous_namespace{SelectHandle.cpp}::SetIfNotNull ( T *  pValue,
const T  Value 
)
inline

Definition at line 109 of file SelectHandle.cpp.

110 {
111 if (pValue == NULL)
112 return;
113 *pValue = Value;
114 }

Referenced by ChooseBoundary(), and ChooseTimeBoundary().

Here is the caller graph for this function:

◆ SetTipAndCursorForBoundary()

void anonymous_namespace{SelectHandle.cpp}::SetTipAndCursorForBoundary ( SelectionBoundary  boundary,
bool  frequencySnapping,
TranslatableString tip,
wxCursor *&  pCursor 
)

Definition at line 292 of file SelectHandle.cpp.

295 {
296
297 static auto adjustLeftSelectionCursor =
298 ::MakeCursor(wxCURSOR_POINT_LEFT, SelectionLeftXpm, 16, 16);
299 static auto adjustRightSelectionCursor =
300 ::MakeCursor(wxCURSOR_POINT_RIGHT, SelectionRightXpm, 16, 16);
301 static auto bottomFrequencyCursor =
302 ::MakeCursor(wxCURSOR_ARROW, BottomFrequencyCursorXpm, 16, 16);
303 static auto topFrequencyCursor =
304 ::MakeCursor(wxCURSOR_ARROW, TopFrequencyCursorXpm, 16, 16);
305 static auto bandWidthCursor =
306 ::MakeCursor(wxCURSOR_ARROW, BandWidthCursorXpm, 16, 16);
307
308 switch (boundary) {
309 case SBNone:
310 pCursor = SelectCursor();
311 break;
312 case SBLeft:
313 tip = XO("Click and drag to move left selection boundary.");
314 pCursor = &*adjustLeftSelectionCursor;
315 break;
316 case SBRight:
317 tip = XO("Click and drag to move right selection boundary.");
318 pCursor = &*adjustRightSelectionCursor;
319 break;
320 case SBBottom:
321 tip = XO("Click and drag to move bottom selection frequency.");
322 pCursor = &*bottomFrequencyCursor;
323 break;
324 case SBTop:
325 tip = XO("Click and drag to move top selection frequency.");
326 pCursor = &*topFrequencyCursor;
327 break;
328 case SBCenter:
329 {
330#ifndef SPECTRAL_EDITING_ESC_KEY
331 tip =
332 frequencySnapping ?
333 XO("Click and drag to move center selection frequency to a spectral peak.") :
334 XO("Click and drag to move center selection frequency.");
335
336#else
337 shiftDown;
338
339 tip =
340 XO("Click and drag to move center selection frequency.");
341
342#endif
343
344 pCursor = EnvelopeCursor();
345 }
346 break;
347 case SBWidth:
348 tip = XO("Click and drag to adjust frequency bandwidth.");
349 pCursor = &*bandWidthCursor;
350 break;
351 default:
352 wxASSERT(false);
353 } // switch
354 // Falls through the switch if there was no boundary found.
355 }
XO("Cut/Copy/Paste")

References EnvelopeCursor(), MakeCursor(), SBBottom, SBCenter, SBLeft, SBNone, SBRight, SBTop, SBWidth, SelectCursor(), and XO().

Referenced by SelectHandle::Preview().

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

◆ within()

template<class A , class B , class DIST >
bool anonymous_namespace{SelectHandle.cpp}::within ( A  a,
b,
DIST  d 
)

Definition at line 481 of file SelectHandle.cpp.

482 {
483 return (a > b - d) && (a < b + d);
484 }