18#include "../../EnvelopeEditor.h"
19#include "../../HitTestResult.h"
23#include "../../RefreshCode.h"
25#include "../../TrackArt.h"
26#include "../../TrackPanelMouseEvent.h"
31#include "../../../images/Cursors.h"
36 std::weak_ptr<const Channel> wChannel
37) : mEnvelope{ pEnvelope }
38 , mwChannel{ move(wChannel) }
44#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
58 Envelope *envelope, std::weak_ptr<const Channel> wChannel,
bool timeTrack)
61 std::make_shared<EnvelopeHandle>(envelope, move(wChannel)));
62 result->mTimeTrack = timeTrack;
69 double &dBRange,
bool &dB,
float &zoomMin,
float &zoomMax)
77 zoomMin =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMin))) / dBRange + 1.0;
78 zoomMax =
LINEAR_TO_DB(std::max(1.0e-7,
double(zoomMax))) / dBRange + 1.0;
84 std::weak_ptr<EnvelopeHandle> &holder,
85 const wxMouseState &state,
const wxRect &rect,
88 auto envelope = tt->GetEnvelope();
93 float zoomMin, zoomMax;
96 std::dynamic_pointer_cast<const Channel>(tt),
97 zoomMin, zoomMax, dB, dBRange,
true);
101(std::weak_ptr<EnvelopeHandle> &holder,
102 const wxMouseState &state,
const wxRect &rect,
103 const AudacityProject *pProject,
const std::shared_ptr<WaveChannel> &wc)
108 auto time = viewInfo.PositionToTime(state.m_x, rect.GetX());
116 float zoomMin, zoomMax;
118 cache.GetDisplayBounds(zoomMin, zoomMax);
123 wc, zoomMin, zoomMax, dB, dBRange,
false);
127 const wxMouseState &state,
const wxRect &rect,
129 Envelope *envelope, std::weak_ptr<const Channel> wChannel,
130 float zoomMin,
float zoomMax,
131 bool dB,
float dBRange,
bool timeTrack)
135 const double envValue =
136 envelope->
GetValue(viewInfo.PositionToTime(state.m_x, rect.x));
141 rect.height, dB,
true, dBRange,
false) + rect.y;
146 rect.height, dB,
true, dBRange,
false) + rect.y;
149 int yMouse = abs(ctr - state.m_y);
151 yValue = abs(ctr - yValue);
157 const int yMisalign = 2;
159 const int yTolerance = 5;
166 int ContourSpacing = std::max(1,
167 static_cast<int>(rect.height / (2 * (zoomMax - zoomMin))));
168 const int MaxContours = 2;
171 int yDisplace = yValue - yMisalign - yMouse + ContourSpacing / 2;
172 if (yDisplace > (MaxContours * ContourSpacing))
175 distance = abs((yDisplace % ContourSpacing) - ContourSpacing / 2);
176 if (distance >= yTolerance)
179 return HitAnywhere(holder, envelope, move(wChannel), timeTrack);
190 const wxMouseEvent &
event = evt.
event;
192 const auto pView = std::static_pointer_cast<ChannelView>(evt.
pCell);
193 const auto pChannel = pView ? pView->FindChannel().get() :
nullptr;
198 if (
const auto pWt =
dynamic_cast<WaveChannel*
>(pChannel)) {
211 else if (
const auto pTt =
dynamic_cast<TimeTrack*
>(pChannel)) {
236 const wxMouseEvent &
event = evt.
event;
252 static auto disabledCursor =
253 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
254 static auto envelopeCursor =
258 ?
XO(
"Click and drag to warp playback time")
259 :
XO(
"Click and drag to edit the amplitude envelope");
273 const wxMouseEvent &
event = evt.
event;
277 return this->
Cancel(pProject);
283 XO(
"Adjusted envelope."),
302 (
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