18#include "../../EnvelopeEditor.h"
19#include "../../HitTestResult.h"
20#include "../../prefs/WaveformSettings.h"
23#include "../../RefreshCode.h"
25#include "../../TrackArt.h"
26#include "../../TrackPanelMouseEvent.h"
30#include "../../../images/Cursors.h"
35 std::weak_ptr<const Channel> wChannel
36) : mEnvelope{ pEnvelope }
37 , mwChannel{ move(wChannel) }
43#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
57 Envelope *envelope, std::weak_ptr<const Channel> wChannel,
bool timeTrack)
60 std::make_shared<EnvelopeHandle>(envelope, move(wChannel)));
61 result->mTimeTrack = timeTrack;
68 double &dBRange,
bool &dB,
float &zoomMin,
float &zoomMax)
76 zoomMin =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMin))) / dBRange + 1.0;
77 zoomMax =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMax))) / dBRange + 1.0;
83 std::weak_ptr<EnvelopeHandle> &holder,
84 const wxMouseState &state,
const wxRect &rect,
87 auto envelope = tt->GetEnvelope();
92 float zoomMin, zoomMax;
95 std::dynamic_pointer_cast<const Channel>(tt),
96 zoomMin, zoomMax, dB, dBRange,
true);
100(std::weak_ptr<EnvelopeHandle> &holder,
101 const wxMouseState &state,
const wxRect &rect,
102 const AudacityProject *pProject,
const std::shared_ptr<WaveChannel> &wc)
107 auto time = viewInfo.PositionToTime(state.m_x, rect.GetX());
115 float zoomMin, zoomMax;
117 cache.GetDisplayBounds(zoomMin, zoomMax);
122 wc, zoomMin, zoomMax, dB, dBRange,
false);
126 const wxMouseState &state,
const wxRect &rect,
128 Envelope *envelope, std::weak_ptr<const Channel> wChannel,
129 float zoomMin,
float zoomMax,
130 bool dB,
float dBRange,
bool timeTrack)
134 const double envValue =
135 envelope->
GetValue(viewInfo.PositionToTime(state.m_x, rect.x));
140 rect.height, dB,
true, dBRange,
false) + rect.y;
145 rect.height, dB,
true, dBRange,
false) + rect.y;
148 int yMouse = abs(ctr - state.m_y);
150 yValue = abs(ctr - yValue);
156 const int yMisalign = 2;
158 const int yTolerance = 5;
165 int ContourSpacing = std::max(1,
166 static_cast<int>(rect.height / (2 * (zoomMax - zoomMin))));
167 const int MaxContours = 2;
170 int yDisplace = yValue - yMisalign - yMouse + ContourSpacing / 2;
171 if (yDisplace > (MaxContours * ContourSpacing))
174 distance = abs((yDisplace % ContourSpacing) - ContourSpacing / 2);
175 if (distance >= yTolerance)
178 return HitAnywhere(holder, envelope, move(wChannel), timeTrack);
189 const wxMouseEvent &
event = evt.
event;
191 const auto pView = std::static_pointer_cast<ChannelView>(evt.
pCell);
192 const auto pChannel = pView ? pView->FindChannel().get() :
nullptr;
197 if (
const auto pWt =
dynamic_cast<WaveChannel*
>(pChannel)) {
210 else if (
const auto pTt =
dynamic_cast<TimeTrack*
>(pChannel)) {
235 const wxMouseEvent &
event = evt.
event;
251 static auto disabledCursor =
252 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
253 static auto envelopeCursor =
257 ?
XO(
"Click and drag to warp playback time")
258 :
XO(
"Click and drag to edit the amplitude envelope");
272 const wxMouseEvent &
event = evt.
event;
276 return this->
Cancel(pProject);
282 XO(
"Adjusted envelope."),
301 (
const wxMouseEvent &event,
const ViewInfo &viewInfo)
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...
virtual ~EnvelopeHandle()
static UIHandlePtr WaveChannelHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveChannel > &wt)
static UIHandlePtr TimeTrackHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< TimeTrack > &tt)
std::unique_ptr< EnvelopeEditor > mpEnvelopeEditor
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::weak_ptr< const Channel > mwChannel
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
std::shared_ptr< const Track > FindTrack() const override
bool ForwardEventToEnvelopes(const wxMouseEvent &event, const ViewInfo &viewInfo)
Result Cancel(AudacityProject *pProject) override
EnvelopeHandle(const EnvelopeHandle &)=delete
void Enter(bool forward, AudacityProject *) override
static UIHandlePtr HitEnvelope(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, Envelope *envelope, std::weak_ptr< const Channel > wChannel, float zoomMin, float zoomMax, bool dB, float dBRange, bool timeTrack)
static UIHandlePtr HitAnywhere(std::weak_ptr< EnvelopeHandle > &holder, Envelope *envelope, std::weak_ptr< const Channel > wChannel, bool timeTrack)
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
static std::shared_ptr< const Track > TrackFromChannel(const std::shared_ptr< const Channel > &pChannel)
A frequent convenience in the definition of UIHandles.
static ViewInfo & Get(AudacityProject &project)
Namespace containing an enum 'what to do on a refresh?'.
WAVE_TRACK_API Envelope * GetEnvelopeAtTime(WaveChannel &channel, double time)
void GetTimeTrackData(const AudacityProject &project, const TimeTrack &tt, double &dBRange, bool &dB, float &zoomMin, float &zoomMax)
std::shared_ptr< TrackPanelCell > pCell