18#include "../../EnvelopeEditor.h"
19#include "../../HitTestResult.h"
20#include "../../prefs/WaveformSettings.h"
23#include "../../RefreshCode.h"
24#include "../../TimeTrack.h"
25#include "../../TrackArt.h"
26#include "../../TrackPanelMouseEvent.h"
28#include "../../WaveTrack.h"
29#include "../../../images/Cursors.h"
34 : mEnvelope{ pEnvelope }
40#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
49(std::weak_ptr<EnvelopeHandle> &holder,
Envelope *envelope,
bool timeTrack)
51 auto result =
AssignUIHandlePtr(holder, std::make_shared<EnvelopeHandle>(envelope));
52 result->mTimeTrack = timeTrack;
59 double &dBRange,
bool &dB,
float &zoomMin,
float &zoomMax)
67 zoomMin =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMin))) / dBRange + 1.0;
68 zoomMax =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMax))) / dBRange + 1.0;
74(std::weak_ptr<EnvelopeHandle> &holder,
75 const wxMouseState &state,
const wxRect &rect,
78 auto envelope = tt->GetEnvelope();
83 float zoomMin, zoomMax;
86 (holder, state, rect, pProject, envelope, zoomMin, zoomMax, dB, dBRange,
91(std::weak_ptr<EnvelopeHandle> &holder,
92 const wxMouseState &state,
const wxRect &rect,
98 auto time = viewInfo.PositionToTime(state.m_x, rect.GetX());
99 Envelope *
const envelope = wt->GetEnvelopeAtTime(time);
105 const bool dB = !wt->GetWaveformSettings().isLinear();
107 float zoomMin, zoomMax;
108 wt->GetDisplayBounds(&zoomMin, &zoomMax);
110 const float dBRange = wt->GetWaveformSettings().dBRange;
113 (holder, state, rect, pProject, envelope, zoomMin, zoomMax, dB, dBRange,
false);
117(std::weak_ptr<EnvelopeHandle> &holder,
118 const wxMouseState &state,
const wxRect &rect,
const AudacityProject *pProject,
119 Envelope *envelope,
float zoomMin,
float zoomMax,
120 bool dB,
float dBRange,
bool timeTrack)
124 const double envValue =
125 envelope->
GetValue(viewInfo.PositionToTime(state.m_x, rect.x));
130 rect.height, dB,
true, dBRange,
false) + rect.y;
135 rect.height, dB,
true, dBRange,
false) + rect.y;
138 int yMouse = abs(ctr - state.m_y);
140 yValue = abs(ctr - yValue);
146 const int yMisalign = 2;
148 const int yTolerance = 5;
155 int ContourSpacing = std::max(1,
156 static_cast<int>(rect.height / (2 * (zoomMax - zoomMin))));
157 const int MaxContours = 2;
160 int yDisplace = yValue - yMisalign - yMouse + ContourSpacing / 2;
161 if (yDisplace > (MaxContours * ContourSpacing))
164 distance = abs((yDisplace % ContourSpacing) - ContourSpacing / 2);
165 if (distance >= yTolerance)
179 const wxMouseEvent &
event = evt.
event;
181 const auto pView = std::static_pointer_cast<TrackView>(evt.
pCell);
182 const auto pTrack = pView ? pView->FindTrack().get() :
nullptr;
188 result = pTrack->TypeSwitch<
decltype(
RefreshNone) >(
197 for (
auto channel : channels ) {
200 std::make_unique< EnvelopeEditor >( *
mEnvelope,
true ) );
203 viewInfo.PositionToTime(event.GetX(), evt.
rect.GetX());
204 auto e2 = channel->GetEnvelopeAtTime(time);
207 std::make_unique< EnvelopeEditor >( *e2,
true ) );
222 std::make_unique< EnvelopeEditor >( *
mEnvelope,
false )
245 const wxMouseEvent &
event = evt.
event;
261 static auto disabledCursor =
262 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
263 static auto envelopeCursor =
267 ?
XO(
"Click and drag to warp playback time")
268 :
XO(
"Click and drag to edit the amplitude envelope");
282 const wxMouseEvent &
event = evt.
event;
286 return this->
Cancel(pProject);
292 XO(
"Adjusted envelope."),
311 (
const wxMouseEvent &event,
const ViewInfo &viewInfo)
319 bool needUpdate =
false;
std::shared_ptr< UIHandle > UIHandlePtr
IntSetting DecibelScaleCutoff
Negation of this value is the lowest dB level that should be shown in dB scales.
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
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...
std::vector< std::unique_ptr< EnvelopeEditor > > mEnvelopeEditors
static UIHandlePtr WaveTrackHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveTrack > &wt)
virtual ~EnvelopeHandle()
static UIHandlePtr TimeTrackHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< TimeTrack > &tt)
static UIHandlePtr HitEnvelope(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, Envelope *envelope, float zoomMin, float zoomMax, bool dB, float dBRange, bool timeTrack)
static UIHandlePtr HitAnywhere(std::weak_ptr< EnvelopeHandle > &holder, Envelope *envelope, bool timeTrack)
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
bool ForwardEventToEnvelopes(const wxMouseEvent &event, const ViewInfo &viewInfo)
Result Cancel(AudacityProject *pProject) override
EnvelopeHandle(const EnvelopeHandle &)=delete
void Enter(bool forward, AudacityProject *) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Piecewise linear or piecewise exponential function from double to double.
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
A kind of Track used to 'warp time'.
bool GetDisplayLog() const
double GetRangeLower() const
double GetRangeUpper() const
Abstract base class for an object holding data associated with points on a time axis.
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
void GetDisplayBounds(float *min, float *max) const
const WaveformSettings & GetWaveformSettings() const
Namespace containing an enum 'what to do on a refresh?'.
void GetTimeTrackData(const AudacityProject &project, const TimeTrack &tt, double &dBRange, bool &dB, float &zoomMin, float &zoomMax)
std::shared_ptr< TrackPanelCell > pCell