14#include "../../../../HitTestResult.h"
17#include "../../../../RefreshCode.h"
18#include "../../../../Snap.h"
19#include "../../../../TrackPanelMouseEvent.h"
22#include "../../../../WaveTrack.h"
23#include "../../../../../images/Cursors.h"
28 , mLocation{ location }
34#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
41 static auto disabledCursor =
42 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
43 static wxCursor arrowCursor{ wxCURSOR_ARROW };
46 ?
XO(
"Left-Click to expand, Right-Click to remove")
47 :
XO(
"Left-Click to merge clips")),
57 const double tolerance = 0.5 / track->
GetRate();
61 fabs(time - loc.pos) < tolerance)
70 const wxRect &rect,
const wxMouseState &state,
76 if (x >= 0 && x < rect.width)
80 locRect.x = (int)(rect.x + x) - locRect.width / 2;
82 locRect.height = rect.height;
83 if (locRect.Contains(state.m_x, state.m_y))
97(std::weak_ptr<CutlineHandle> &holder,
98 const wxMouseState &state,
const wxRect &rect,
100 const std::shared_ptr<WaveTrack> &pTrack)
107 if (!
IsOverCutline(viewInfo, pTrack.get(), rect, state, &location))
110 auto result = std::make_shared<CutlineHandle>( pTrack, location );
132 const wxMouseEvent &
event = evt.
event;
147 if (event.LeftDown())
153 mEndTime = viewInfo.selectedRegion.t1();
156 double cutlineStart = 0, cutlineEnd = 0;
157 double *pCutlineStart = &cutlineStart, *pCutlineEnd = &cutlineEnd;
161 channel->ExpandCutLine(
163 if ( channel ==
mpTrack.get() )
164 pCutlineStart = pCutlineEnd =
nullptr;
167 viewInfo.selectedRegion.setTimes(cutlineStart, cutlineEnd);
177 channel->GetCachedLocations()[idx];
186 else if (event.RightDown())
188 bool removed =
false;
191 removed = channel->RemoveCutLine(
mLocation.
pos) || removed;
std::shared_ptr< UIHandle > UIHandlePtr
const int kPixelTolerance
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...
CutlineHandle(const CutlineHandle &)=delete
static HitTestPreview HitPreview(bool cutline, bool unsafe)
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
WaveTrackLocation mLocation
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
std::shared_ptr< WaveTrack > mpTrack
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
void Enter(bool forward, AudacityProject *) override
static UIHandlePtr HitTest(std::weak_ptr< CutlineHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveTrack > &pTrack)
bool HandlesRightClick() override
Whether the handle has any special right-button handling.
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Result Cancel(AudacityProject *pProject) override
bool setTimes(double t0, double t1)
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
const std::vector< Location > & GetCachedLocations() const
double GetRate() const override
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Namespace containing an enum 'what to do on a refresh?'.
int FindMergeLine(WaveTrack *track, double time)
bool IsOverCutline(const ViewInfo &viewInfo, WaveTrack *track, const wxRect &rect, const wxMouseState &state, WaveTrackLocation *pmLocation)