19#include "../../SpectrumAnalyst.h"
20#include "../../LabelTrack.h"
21#include "../playabletrack/wavetrack/ui/PitchAndSpeedDialog.h"
26#include "../../ProjectSettings.h"
27#include "../../ProjectWindow.h"
28#include "../../RefreshCode.h"
29#include "../../SelectUtilities.h"
32#include "../../TrackArt.h"
33#include "../../TrackArtist.h"
35#include "../../TrackPanel.h"
36#include "../../TrackPanelDrawingContext.h"
37#include "../../TrackPanelMouseEvent.h"
41#include "../../prefs/SpectrogramSettings.h"
42#include "../../../images/Cursors.h"
74 float minFreq, maxFreq;
78 return trackTopEdge + wxInt64((1.0 - p) * trackHeight);
85 wxInt64 mouseYCoordinate,
89 const double rate = wt->
GetRate();
100 float minFreq, maxFreq;
104 const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight;
122 pChannelView->
FindTrack()->TypeSwitch<
bool>(
125 return settings.SpectralSelectionEnabled();
132#ifdef EXPERIMENTAL_SPECTRAL_EDITING
133 SBBottom, SBTop, SBCenter, SBWidth,
139 const double t0,
const double t1,
141 double selend,
bool onlyWithinSnapDistance,
142 wxInt64 *pPixelDist,
double *pPinValue)
146 wxInt64 pixelDist = std::abs(posS - pos0);
147 bool chooseLeft =
true;
152 chooseLeft = (selend < t0);
155 const wxInt64 rightDist = std::abs(posS - pos1);
156 if (rightDist < pixelDist)
157 chooseLeft =
false, pixelDist = rightDist;
162 if (onlyWithinSnapDistance &&
167 else if (chooseLeft) {
179 wxCoord xx, wxCoord yy,
const ChannelView *pChannelView,
181 bool mayDragWidth,
bool onlyWithinSnapDistance,
182 double *pPinValue = NULL)
190 wxInt64 pixelDist = 0;
196 &pixelDist, pPinValue);
198#ifdef EXPERIMENTAL_SPECTRAL_EDITING
206 bool chooseTime =
true;
207 bool chooseBottom =
true;
208 bool chooseCenter =
false;
212 t0 <= selend && selend < t1 &&
217 static_cast<const WaveTrack*
>(pTrack.get());
218 const wxInt64 bottomSel = (f0 >= 0)
220 : rect.y + rect.height;
221 const wxInt64 topSel = (f1 >= 0)
224 wxInt64 signedBottomDist = (int)(yy - bottomSel);
225 wxInt64 verticalDist = std::abs(signedBottomDist);
226 if (bottomSel == topSel)
228 chooseBottom = (signedBottomDist >= 0);
230 const wxInt64 topDist = std::abs((
int)(yy - topSel));
231 if (topDist < verticalDist)
232 chooseBottom =
false, verticalDist = topDist;
235#ifdef SPECTRAL_EDITING_ESC_KEY
239 const wxInt64 centerSel =
241 const wxInt64 centerDist = abs((
int)(yy - centerSel));
242 if (centerDist < verticalDist)
243 chooseCenter =
true, verticalDist = centerDist,
246 if (verticalDist >= 0 &&
247 verticalDist < pixelDist) {
248 pixelDist = verticalDist;
256 if (onlyWithinSnapDistance &&
261 else if (chooseCenter) {
265 else if (mayDragWidth && fc > 0) {
269 else if (chooseBottom) {
287 static auto selectCursor =
289 return &*selectCursor;
295 static auto envelopeCursor =
297 return &*envelopeCursor;
305 static auto adjustLeftSelectionCursor =
306 ::MakeCursor(wxCURSOR_POINT_LEFT, SelectionLeftXpm, 16, 16);
307 static auto adjustRightSelectionCursor =
308 ::MakeCursor(wxCURSOR_POINT_RIGHT, SelectionRightXpm, 16, 16);
309 static auto bottomFrequencyCursor =
310 ::MakeCursor(wxCURSOR_ARROW, BottomFrequencyCursorXpm, 16, 16);
311 static auto topFrequencyCursor =
312 ::MakeCursor(wxCURSOR_ARROW, TopFrequencyCursorXpm, 16, 16);
313 static auto bandWidthCursor =
314 ::MakeCursor(wxCURSOR_ARROW, BandWidthCursorXpm, 16, 16);
321 tip =
XO(
"Click and drag to move left selection boundary.");
322 pCursor = &*adjustLeftSelectionCursor;
325 tip =
XO(
"Click and drag to move right selection boundary.");
326 pCursor = &*adjustRightSelectionCursor;
328#ifdef EXPERIMENTAL_SPECTRAL_EDITING
330 tip =
XO(
"Click and drag to move bottom selection frequency.");
331 pCursor = &*bottomFrequencyCursor;
334 tip =
XO(
"Click and drag to move top selection frequency.");
335 pCursor = &*topFrequencyCursor;
339#ifndef SPECTRAL_EDITING_ESC_KEY
342 XO(
"Click and drag to move center selection frequency to a spectral peak.") :
343 XO(
"Click and drag to move center selection frequency.");
349 XO(
"Click and drag to move center selection frequency.");
357 tip =
XO(
"Click and drag to adjust frequency bandwidth.");
358 pCursor = &*bandWidthCursor;
369(std::weak_ptr<SelectHandle> &holder,
371 const std::shared_ptr<ChannelView> &pChannelView)
375 auto old = holder.lock();
376 bool oldUseSnap =
true;
379 if( old->mTimerHandler ) {
383 old->mTimerHandler.reset();
385 oldUseSnap = old->mUseSnap;
389 auto result = std::make_shared<SelectHandle>(
390 pChannelView, oldUseSnap,
TrackList::Get(*pProject), st, viewInfo);
395 auto pTrack = pChannelView->FindTrack();
396 if (!pTrack->GetSelected())
402 const wxRect &rect = st.
rect;
403 wxInt64 leftSel = viewInfo.TimeToPosition(viewInfo.selectedRegion.t0(), rect.x);
404 wxInt64 rightSel = viewInfo.TimeToPosition(viewInfo.selectedRegion.t1(), rect.x);
406 wxASSERT(!(rightSel < leftSel));
407 static_cast<void>(leftSel);
408 static_cast<void>(rightSel);
419 wxASSERT( useSnap == newState.
mUseSnap );
425 if ( oldSnapState.Snapped() == newSnapState.Snapped() &&
426 (!oldSnapState.Snapped() ||
427 oldSnapState.outCoord == newSnapState.outCoord) )
434 const std::shared_ptr<ChannelView> &pChannelView,
bool useSnap,
437) : mpView{ pChannelView }
441 SnapPoint{ viewInfo.playRegion.GetLastActiveStart() },
442 SnapPoint{ viewInfo.playRegion.GetLastActiveEnd() },
445 const wxMouseState &state = st.
state;
449 auto pTrack = pChannelView->FindTrack();
465 if (
auto pView =
mpView.lock())
466 return pView->FindChannel();
472 template <
class A,
class B,
class DIST >
bool within(
A a, B b, DIST d)
474 return (a > b - d) && (a < b + d);
479 const double minFrequency = 1.0;
480 const double maxFrequency = (rate / 2.0);
481 const double frequency =
483 std::max(minFrequency, center));
485 std::min(frequency / minFrequency, maxFrequency / frequency);
540 const auto pView =
mpView.lock();
544 wxMouseEvent &
event = evt.
event;
546 const auto sTrack = trackList.Lock(
FindTrack());
547 const auto pTrack = sTrack.get();
548 const auto pLeader = *trackList.Find(pTrack);
555 bool selectChange = (
557 event.ControlDown() &&
561 bool bShift =
event.ShiftDown();
564 *pProject, *pTrack, bShift,
true, !unsafe);
573 if (event.LeftDClick() && !event.ShiftDown()) {
575 selectionState.SelectNone(trackList);
578 selectionState.SelectTrack(*pLeader,
true,
true);
586 pTrack->TypeSwitch( [&] (
WaveTrack &wt ) {
587 auto time = viewInfo.PositionToTime(event.m_x,
mRect.x);
590 viewInfo.selectedRegion.setTimes(
591 selectedClip->GetPlayStartTime(), selectedClip->GetPlayEndTime());
600 else if (!event.LeftDown())
606 std::make_shared<SelectionStateChanger>(selectionState, trackList);
610 bool bShiftDown =
event.ShiftDown();
611 bool bCtrlDown =
event.ControlDown();
617 if (bShiftDown || bCtrlDown) {
619 selectionState.ChangeSelectionOnShiftClick(trackList, *pTrack);
624 bool bIsSelected =
false;
626 if (!bIsSelected || trackPanel.GetSelectedTrackCount() > 1)
628 selectionState.SelectTrack(*pLeader, !bIsSelected,
true);
635 pView.get(),
mRect,
false,
false, &value);
641#ifdef EXPERIMENTAL_SPECTRAL_EDITING
652#ifdef EXPERIMENTAL_SPECTRAL_EDITING
659 (boundary == SBBottom)
671 const auto wt =
static_cast<const WaveTrack*
>(pTrack);
694 bool startNewSelection =
true;
695 if (pTrack && pTrack->GetSelected()) {
696#ifdef EXPERIMENTAL_SPECTRAL_EDITING
727 pView.get(),
mRect,
true,
true, &value);
735 startNewSelection =
false;
736#ifdef EXPERIMENTAL_SPECTRAL_EDITING
744#ifdef EXPERIMENTAL_SPECTRAL_EDITING
748 startNewSelection =
false;
760 const auto wt =
static_cast<const WaveTrack*
>(pTrack);
762 startNewSelection =
false;
774 if (startNewSelection) {
776 selectionState.SelectNone(trackList);
777#ifdef EXPERIMENTAL_SPECTRAL_EDITING
783 selectionState.SelectTrack(*pLeader,
true,
true);
800 const auto pView =
mpView.lock();
805 const wxMouseEvent &
event = evt.
event;
820 if (event.CmdDown()) {
836 enum { minimumSizedSelection = 5 };
842 if (wxLongLong(SelStart - x).Abs() < minimumSizedSelection)
847 if (
auto clickedTrack =
850 Track *sTrack = pTrack.get();
851 Track *eTrack = clickedTrack.get();
853 if ( sTrack && eTrack && !event.ControlDown() ) {
855 selectionState.SelectRangeOfTracks( trackList, *sTrack, *eTrack );
858 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
859 #ifndef SPECTRAL_EDITING_ESC_KEY
861 !viewInfo.selectedRegion.isPoint())
863 (pProject, viewInfo, y,
mRect.y,
mRect.height, pView.get());
896 const auto pView =
mpView.lock();
917 auto &state = st.
state;
919 auto xx = viewInfo.TimeToPosition(time,
mRect.x);
921 const bool bMultiToolMode =
925 if (bMultiToolMode) {
934 keyStr =
_(
"Edit, Preferences...");
937 tip =
XO(
"Multi-Tool Mode: %s for Mouse and Keyboard Preferences.")
940 if (!pTrack->GetSelected())
943 const wxRect &rect = st.
rect;
944 const bool bShiftDown = state.ShiftDown();
945 const bool bCtrlDown = state.ControlDown();
946 const bool bModifierDown = bShiftDown || bCtrlDown;
953 pView.get(), rect, !bModifierDown, !bModifierDown);
963#ifdef EXPERIMENTAL_SPECTRAL_EDITING
967 tip =
XO(
"Click and drag to set frequency bandwidth.");
968 pCursor = &*envelopeCursor;
974 if (!pTrack->GetSelected())
977 const wxRect &rect = st.
rect;
978 const bool bShiftDown = state.ShiftDown();
979 const bool bCtrlDown = state.ControlDown();
980 const bool bModifierDown = bShiftDown || bCtrlDown;
982 viewInfo, xx, state.m_y,
983 pView.get(), rect, !bModifierDown, !bModifierDown);
988 tip =
XO(
"Click and drag to select audio");
993 XO(
"(snapping)"),
wxT(
" ")
996 return { tip, pCursor };
1028 const wxRect &rect,
unsigned iPass )
1031 auto &dc = context.
dc;
1043 const wxRect &rect,
const wxRect &panelRect,
unsigned iPass )
1053 auto pView =
mpView.lock();
1057 return pView->FindTrack();
1062 mTimerHandler = std::make_shared<TimerHandler>(
this, pProject );
1110 viewport.OnScrollRight();
1114 viewport.OnScrollLeft();
1122 trackPanel.ClientToScreen(&xx, &yy);
1125 viewport.OnScrollLeft();
1129 ::wxDisplaySize(&width, &height);
1130 if (xx == width - 1) {
1132 viewport.OnScrollRight();
1144 wxMouseEvent evt(wxEVT_MOTION);
1145 const auto size = trackPanel.GetSize();
1175 ViewInfo &viewInfo,
int mouseXCoordinate,
int trackLeftEdge,
1183 std::max(0.0, viewInfo.
PositionToTime(mouseXCoordinate, trackLeftEdge));
1184 double origSelend = selend;
1208 selend = origSelend;
1232 int mouseYCoordinate,
int trackTopEdge,
1246 trackTopEdge, trackHeight);
1253 int mouseYCoordinate,
int trackTopEdge,
1263 const double rate = wt->
GetRate();
1264 const double frequency =
1266 trackTopEdge, trackHeight);
1270 if (frequency == rate || frequency < 1.0)
1280 frequency / ratio, frequency * ratio);
1286 if (frequency == rate || frequency < 1.0)
1298 ratio = 1.0 / ratio;
1307 const bool bottomDefined =
1309 const bool topDefined =
1311 if (!bottomDefined || (topDefined &&
mFreqSelPin < frequency)) {
1313 if (frequency == rate)
1323 if (frequency < 1.0)
1335(
const ViewInfo &viewInfo,
bool shiftDown,
const WaveTrack *pTrack,
double value)
1345#ifndef SPECTRAL_EDITING_ESC_KEY
1361 static const size_t minLength = 8;
1363 const double rate = pTrack->
GetRate();
1366 std::vector<float> frequencySnappingData;
1372 std::min(frequencySnappingData.max_size(),
1375 const auto effectiveLength = std::max(minLength, length);
1376 frequencySnappingData.resize(effectiveLength, 0.0f);
1378 &frequencySnappingData[0],
1387 auto windowSize =
settings.GetFFTLength();
1389 while(windowSize > effectiveLength)
1391 const int windowType =
settings.windowType;
1395 &frequencySnappingData[0], length);
1405 auto pTrack = pChannelView->
FindTrack().get();
1407 pTrack->GetSelected() &&
1418 const double rate = wt->
GetRate();
1419 const double frequency =
1421 trackTopEdge, trackHeight);
1422 const double snappedFrequency =
1424 const double maxRatio =
findMaxRatio(snappedFrequency, rate);
1429 if (f1 >= f0 && f0 >= 0)
1431 ratio =
sqrt(f1 / f0);
1437 snappedFrequency / ratio, snappedFrequency * ratio);
1455 const auto windowSize =
settings.GetFFTLength();
1456 const double rate = pTrack->
GetRate();
1457 const double nyq = rate / 2.0;
1458 const double binFrequency = rate / windowSize;
1462 if (centerFrequency <= 0) {
1463 centerFrequency = up ? binFrequency : nyq;
1464 f1 = centerFrequency *
sqrt(2.0);
1467 double ratio = f1 / centerFrequency;
1468 const int originalBin = floor(0.5 + centerFrequency / binFrequency);
1469 const int limitingBin = up ? floor(0.5 + nyq / binFrequency) : 1;
1475 double snappedFrequency = centerFrequency;
1476 int bin = originalBin;
1478 while (snappedFrequency <= centerFrequency &&
1480 snappedFrequency = analyst.
FindPeak(++bin * binFrequency, NULL);
1483 while (snappedFrequency >= centerFrequency &&
1485 snappedFrequency = analyst.
FindPeak(--bin * binFrequency, NULL);
1489 const double maxRatio =
findMaxRatio(snappedFrequency, rate);
1493 (snappedFrequency / ratio, snappedFrequency * ratio);
1498void SelectHandle::ResetFreqSelectionPin
1499 (
const ViewInfo &viewInfo,
double hintFrequency,
bool logF)
1501 switch (mFreqSelMode) {
1516 if (f0 >= 0 && f1 >= 0)
1536 const double logf1 = log(std::max(1.0, f1));
1537 const double logf0 = log(std::max(1.0, f0));
1538 const double logHint = log(std::max(1.0, hintFrequency));
1539 if (std::abs(logHint - logf1) < std::abs(logHint - logf0))
1547 std::abs(hintFrequency - f1) < std::abs(hintFrequency - f0))
std::shared_ptr< UIHandle > UIHandlePtr
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
@ SELECTION_RESIZE_REGION
std::vector< SnapPoint > SnapPointArray
static Settings & settings()
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
bool within(A a, B b, DIST d)
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static ChannelView & Get(Channel &channel)
virtual bool IsSpectral() const
static CommandManager & Get(AudacityProject &project)
NormalizedKeyString GetKeyFromName(const CommandID &name) const
std::shared_ptr< Track > FindTrack()
A LabelTrack is a Track that holds labels (LabelStruct).
bool setTimes(double t0, double t1)
bool setF0(double f, bool maySwap=true)
bool setFrequencies(double f0, double f1)
bool setF1(double f, bool maySwap=true)
float PositionToValue(float pp) const
float ValueToPosition(float val) const
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
A move-only handle representing a connection to a Publisher.
static PitchAndSpeedDialog & Get(AudacityProject &project)
void TryRetarget(const TrackPanelMouseEvent &event)
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
PlaybackScroller & GetPlaybackScroller()
static ProjectWindow & Get(AudacityProject &project)
void OnTimer(Observer::Message)
TimerHandler(SelectHandle *pParent, AudacityProject *pProject)
AudacityProject * mConnectedProject
Observer::Subscription mSubscription
SelectHandle(const SelectHandle &)
Result Cancel(AudacityProject *) override
wxRect DrawingArea(TrackPanelDrawingContext &, const wxRect &rect, const wxRect &panelRect, unsigned iPass) override
void HandleCenterFrequencyClick(const ViewInfo &viewInfo, bool shiftDown, const WaveTrack *pTrack, double value)
std::weak_ptr< Track > FindTrack()
std::weak_ptr< const WaveTrack > mFreqSelTrack
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
void Enter(bool forward, AudacityProject *pProject) override
void SetUseSnap(bool use, AudacityProject *pProject)
void AssignSelection(ViewInfo &viewInfo, double selend, Track *pTrack)
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
static void SnapCenterOnce(SpectrumAnalyst &analyst, ViewInfo &viewInfo, const WaveTrack *pTrack, bool up)
bool IsDragging() const override
bool HasEscape(AudacityProject *pProject) const override
void StartFreqSelection(ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, ChannelView *pChannelView)
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::shared_ptr< TimerHandler > mTimerHandler
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::weak_ptr< ChannelView > mpView
static UIHandlePtr HitTest(std::weak_ptr< SelectHandle > &holder, const TrackPanelMouseState &state, const AudacityProject *pProject, const std::shared_ptr< ChannelView > &pChannelView)
std::shared_ptr< SpectrumAnalyst > mFrequencySnapper
static void StartSnappingFreqSelection(SpectrumAnalyst &analyst, const ViewInfo &viewInfo, const WaveTrack *pTrack)
void AdjustSelection(AudacityProject *pProject, ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *pTrack)
Extend or contract the existing selection.
bool Escape(AudacityProject *pProject) override
std::shared_ptr< SnapManager > mSnapManager
enum SelectHandle::eFreqSelMode FREQ_SEL_INVALID
@ FREQ_SEL_SNAPPING_CENTER
std::shared_ptr< const Channel > FindChannel() const override
static UIHandle::Result NeedChangeHighlight(const SelectHandle &oldState, const SelectHandle &newState)
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
void AdjustFreqSelection(const WaveTrack *wt, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight)
SelectedRegion mInitialSelection
void MoveSnappingFreqSelection(AudacityProject *pProject, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, ChannelView *pChannelView)
void Connect(AudacityProject *pProject)
void StartSelection(AudacityProject *pProject)
Reset our selection markers.
static const int UndefinedFrequency
static void SelectTrackLength(ViewInfo &viewInfo, Track &track, bool syncLocked)
static SelectionState & Get(AudacityProject &project)
void GetBounds(const WaveTrack &wt, 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)
Mutative access to attachment even if the track argument is const.
Used for finding the peaks, for snapping to peaks.
float FindPeak(float xPos, float *pY) const
bool Calculate(Algorithm alg, int windowFunc, size_t windowSize, double rate, const float *data, size_t dataLen, float *pYMin=NULL, float *pYMax=NULL, FreqGauge *progress=NULL)
bool IsSyncLocked() const
static SyncLockState & Get(AudacityProject &project)
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< Subclass > SharedPointer()
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
static TrackList & Get(AudacityProject &project)
static wxRect MaximizeHeight(const wxRect &rect, const wxRect &panelRect)
void Refresh(bool eraseBackground=true, const wxRect *rect=(const wxRect *) NULL) override
static TrackPanel & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
static Viewport & Get(AudacityProject &project)
This allows multiple clips to be a part of one WaveTrack.
A Track that contains audio waveform data.
const WaveClip * GetClipAtTime(double time) const
double GetRate() const override
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches first channel only
sampleCount TimeToLongSamples(double t0) const
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Namespace containing an enum 'what to do on a refresh?'.
void DoListSelection(AudacityProject &project, Track &t, bool shift, bool ctrl, bool modifyState)
AUDACITY_DLL_API void DrawSnapLines(wxDC *dc, wxInt64 snap0, wxInt64 snap1)
wxCursor * EnvelopeCursor()
double findMaxRatio(double center, double rate)
void SetTipAndCursorForBoundary(SelectionBoundary boundary, bool frequencySnapping, TranslatableString &tip, wxCursor *&pCursor)
wxInt64 FrequencyToPosition(const WaveTrack *wt, double frequency, wxInt64 trackTopEdge, int trackHeight)
Converts a frequency to screen y position.
double PositionToFrequency(const WaveTrack *wt, bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, int trackHeight)
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 *pChannelView)
SelectionBoundary ChooseBoundary(const ViewInfo &viewInfo, wxCoord xx, wxCoord yy, const ChannelView *pChannelView, const wxRect &rect, bool mayDragWidth, bool onlyWithinSnapDistance, double *pPinValue=NULL)
wxCursor * SelectCursor()
__finl float_x4 __vecc sqrt(const float_x4 &a)
wxString Display(bool usesSpecialChars=false) const
Default message type for Publisher.
std::shared_ptr< TrackPanelCell > pCell