Audacity 3.2.0
WaveTrackAffordanceControls.cpp
Go to the documentation of this file.
1/*!********************************************************************
2*
3 Audacity: A Digital Audio Editor
4
5 WaveTrackAffordanceControls.cpp
6
7 Vitaly Sverchinsky
8
9 **********************************************************************/
10
12
13#include <wx/dc.h>
14#include <wx/frame.h>
15
16#include "AllThemeResources.h"
17#include "CommandContext.h"
18#include "CommandFlag.h"
19#include "CommandFunctors.h"
20#include "MenuRegistry.h"
21#include "../../../../TrackPanelMouseEvent.h"
22#include "../../../../TrackArt.h"
23#include "../../../../TrackArtist.h"
24#include "../../../../TrackPanelDrawingContext.h"
25#include "ViewInfo.h"
26#include "WaveTrack.h"
27#include "WaveClip.h"
28#include "WaveTrackUtilities.h"
29#include "UndoManager.h"
30#include "ShuttleGui.h"
31#include "../../../../ProjectWindows.h"
32#include "../../../../commands/AudacityCommand.h"
33
34#include "../../../ui/TextEditHelper.h"
35#include "../../../ui/SelectHandle.h"
36#include "WaveChannelView.h"//need only ClipParameters
38
39#include "ProjectHistory.h"
40#include "../../../../ProjectSettings.h"
41#include "SelectionState.h"
42#include "../../../../RefreshCode.h"
43#include "Theme.h"
44#include "../../../../../images/Cursors.h"
45#include "../../../../HitTestResult.h"
46#include "../../../../TrackPanel.h"
47#include "TrackFocus.h"
48
49#include "../WaveTrackUtils.h"
50
52#include "WaveClipUtilities.h"
53
55
56#include "BasicUI.h"
57#include "UserException.h"
58
59
61{
62public:
64
66 {
67 return Symbol;
68 }
70 {
71 S.AddSpace(0, 5);
72
73 S.StartMultiColumn(2, wxALIGN_CENTER);
74 {
75 S.TieTextBox(XXO("Name:"), mName, 60);
76 }
77 S.EndMultiColumn();
78 }
79public:
80 wxString mName;
81};
82
84{ XO("Set Wave Clip Name") };
85
86//Handle which is used to send mouse events to TextEditHelper
88{
89 std::shared_ptr<TextEditHelper> mHelper;
90 std::shared_ptr<WaveTrack> mpTrack;
91public:
92
93 WaveClipTitleEditHandle(const std::shared_ptr<TextEditHelper>& helper,
94 const std::shared_ptr<WaveTrack> pTrack)
95 : mHelper(helper)
96 , mpTrack{ move(pTrack) }
97 { }
98
100 {
101 }
102
103 std::shared_ptr<const Channel> FindChannel() const override
104 {
105 return mpTrack;
106 }
107
109 {
110 if (mHelper->OnClick(event.event, project))
113 }
114
116 {
117 if (mHelper->OnDrag(event.event, project))
120 }
121
123 {
124 static auto ibeamCursor =
125 ::MakeCursor(wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
126 return {
127 XO("Click and drag to select text"),
128 ibeamCursor.get()
129 };
130 }
131
132 Result Release(const TrackPanelMouseEvent& event, AudacityProject* project, wxWindow*) override
133 {
134 if (mHelper->OnRelease(event.event, project))
137 }
138
140 {
141 if (mHelper)
142 {
143 mHelper->Cancel(project);
144 mHelper.reset();
145 }
147 }
148};
149
151 : CommonTrackCell{ pTrack, 0 }
152 , mClipNameFont{ wxFontInfo{} }
153{
154 if (auto trackList = pTrack->GetOwner())
155 {
156 mTrackListEventSubscription = trackList->Subscribe(
158 if(auto project = trackList->GetOwner())
159 {
160 auto& viewInfo = ViewInfo::Get(*project);
162 viewInfo.selectedRegion.Subscribe(
163 *this,
165 }
166 }
167}
168
169std::vector<UIHandlePtr> WaveTrackAffordanceControls::HitTest(const TrackPanelMouseState& state, const AudacityProject* pProject)
170{
171 std::vector<UIHandlePtr> results;
172
173 auto px = state.state.m_x;
174 auto py = state.state.m_y;
175
176 const auto rect = state.rect;
177
178 auto track = std::static_pointer_cast<WaveTrack>(FindTrack());
179 // Assume only leader channels have affordance areas
180 assert(track->IsLeader());
181
182 {
185 track,
186 pProject,
187 state);
188
189 if (handle)
190 results.push_back(handle);
191 }
192
193 if (mTextEditHelper && mTextEditHelper->GetBBox().Contains(px, py))
194 {
195 results.push_back(
198 std::make_shared<WaveClipTitleEditHandle>(
199 mTextEditHelper, track)
200 )
201 );
202 }
203
204 const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
205 auto& zoomInfo = ViewInfo::Get(*pProject);
206 const auto intervals = waveTrack->Intervals();
207 for(auto it = intervals.begin(); it != intervals.end(); ++it)
208 {
209 if (it == mEditedInterval)
210 continue;
211
212 auto interval = *it;
213 if (WaveChannelView::HitTest(*interval->GetClip(0), zoomInfo, state.rect, {px, py}))
214 {
215 results.push_back(
218 std::make_shared<WaveTrackAffordanceHandle>(track, interval->GetClip(0))
219 )
220 );
221 mFocusInterval = it;
222 break;
223 }
224 }
225
226 const auto& settings = ProjectSettings::Get(*pProject);
227 const auto currentTool = settings.GetTool();
228 if (currentTool == ToolCodes::multiTool || currentTool == ToolCodes::selectTool)
229 {
230 results.push_back(
232 mSelectHandle, state, pProject,
233 ChannelView::Get(*track).shared_from_this()
234 )
235 );
236 }
237
238 return results;
239}
240
241void WaveTrackAffordanceControls::Draw(TrackPanelDrawingContext& context, const wxRect& rect, unsigned iPass)
242{
243 if (iPass == TrackArtist::PassBackground) {
244 auto track = FindTrack();
245 const auto artist = TrackArtist::Get(context);
246
247 TrackArt::DrawBackgroundWithSelection(context, rect, track.get(), artist->blankSelectedBrush, artist->blankBrush);
248
249 mVisibleIntervals.clear();
250
251 const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
252 const auto& zoomInfo = *artist->pZoomInfo;
253 {
254 wxDCClipper dcClipper(context.dc, rect);
255
256 context.dc.SetTextBackground(wxTransparentColor);
257 context.dc.SetTextForeground(theTheme.Colour(clrClipNameText));
258 context.dc.SetFont(mClipNameFont);
259
260 auto px = context.lastState.m_x;
261 auto py = context.lastState.m_y;
262
263 const auto intervals = waveTrack->Intervals();
264 for(auto it = intervals.begin(); it != intervals.end(); ++it)
265 {
266 auto interval = *it;
267 auto affordanceRect
268 = ClipParameters::GetClipRect(*interval->GetClip(0), zoomInfo, rect);
269
270 if(!WaveChannelView::ClipDetailsVisible(*interval->GetClip(0), zoomInfo, rect))
271 {
272 TrackArt::DrawClipFolded(context.dc, affordanceRect);
273 continue;
274 }
275
276 const auto selected = GetSelectedInterval() == it;
277 const auto highlight = selected || affordanceRect.Contains(px, py);
278 const auto titleRect = TrackArt::DrawClipAffordance(context.dc, affordanceRect, highlight, selected);
279 if (mTextEditHelper && mEditedInterval == it)
280 {
281 if(!mTextEditHelper->Draw(context.dc, titleRect))
282 {
283 mTextEditHelper->Cancel(nullptr);
285 context.dc, titleRect, interval->GetName(),
286 interval->GetStretchRatio());
287 }
288 }
290 context.dc, titleRect, interval->GetName(),
291 interval->GetStretchRatio()))
292 {
293 mVisibleIntervals.push_back(it);
294 }
295 }
296 }
297
298 }
299}
300
302{
303 return std::find(mVisibleIntervals.begin(),
304 mVisibleIntervals.end(),
305 it) != mVisibleIntervals.end();
306}
307
309{
310 bool useDialog{ false };
311 gPrefs->Read(wxT("/GUI/DialogForNameNewLabel"), &useDialog, false);
312
313 auto interval = *it;
314 if(!interval)
315 return false;
316
317 if (useDialog)
318 {
320 auto oldName = interval->GetName();
321 Command.mName = oldName;
322 auto result = Command.PromptUser(&GetProjectFrame(project));
323 if (result && Command.mName != oldName)
324 {
325 interval->SetName(Command.mName);
326 ProjectHistory::Get(project).PushState(XO("Modified Clip Name"),
327 XO("Clip Name Edit"));
328 }
329 }
330 else if(it != mEditedInterval)
331 {
332 if(!IsIntervalVisible(it))
333 return false;
334
335 if (mTextEditHelper)
336 mTextEditHelper->Finish(&project);
337
338 mEditedInterval = it;
339 mTextEditHelper = MakeTextEditHelper(interval->GetName());
340 }
341
342 return true;
343}
344
346{
347 if (auto handle = mAffordanceHandle.lock())
348 {
349 return handle->Clicked() ? mFocusInterval : IntervalIterator{};
350 }
351 return {};
352}
353
354namespace {
355
357{
358 auto &view = ChannelView::Get(track);
359 auto pAffordance = view.GetAffordanceControls();
360 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
361 pAffordance );
362}
363
364std::pair<WaveTrack*, ChannelGroup::IntervalIterator<WaveTrack::Interval>>
366{
367 // Note that TrackFocus may change its state as a side effect, defining
368 // a track focus if there was none
369 if (auto pWaveTrack =
370 dynamic_cast<WaveTrack *>(TrackFocus::Get(project).Get())) {
371 if (FindAffordance(*pWaveTrack)) {
372 auto &viewInfo = ViewInfo::Get(project);
373 auto intervals = pWaveTrack->Intervals();
374
375 auto it = std::find_if(intervals.begin(), intervals.end(), [&](const auto& interval)
376 {
377 return interval->Start() == viewInfo.selectedRegion.t0() &&
378 interval->End() == viewInfo.selectedRegion.t1();
379 });
380
381 if(it != intervals.end())
382 return { pWaveTrack, it };
383 }
384 }
385 return {};
386}
387
388// condition for enabling the command
390{
392 [](const AudacityProject &project){
393 // const_cast isn't pretty but not harmful in this case
394 return SelectedIntervalOfFocusedTrack(const_cast<AudacityProject&>(project)).first != nullptr;
395 }
396 };
397 return flag;
398}
399
401{
403 [](const AudacityProject &project){
404 // const_cast isn't pretty but not harmful in this case
405 auto result = SelectedIntervalOfFocusedTrack(
406 const_cast<AudacityProject&>(project));
407
408 auto interval = *result.second;
409 return interval != nullptr && !interval->StretchRatioEquals(1.0);
410 }
411 };
412 return flag;
413}
414
415}
416
417unsigned WaveTrackAffordanceControls::CaptureKey(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
418{
419 if (!mTextEditHelper
420 || !mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
421 // Handle the event if it can be processed by the text editor (if any)
422 event.Skip();
424}
425
426
427unsigned WaveTrackAffordanceControls::KeyDown(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow*, AudacityProject* project)
428{
429 auto keyCode = event.GetKeyCode();
430
431 if (mTextEditHelper)
432 {
433 if (!mTextEditHelper->OnKeyDown(keyCode, event.GetModifiers(), project)
435 event.Skip();
436
438 }
440}
441
442unsigned WaveTrackAffordanceControls::Char(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
443{
444 if (mTextEditHelper && mTextEditHelper->OnChar(event.GetUnicodeKey(), project))
447}
448
450{
451 return ExitTextEditing();
452}
453
455{
456 if (auto interval = *mEditedInterval)
457 {
458 if (text != interval->GetName()) {
459 interval->SetName(text);
460
461 ProjectHistory::Get(*project).PushState(XO("Modified Clip Name"),
462 XO("Clip Name Edit"));
463 }
464 }
466}
467
469{
471}
472
474{
475 //Nothing to do
476}
477
479{
480}
481
483{
484 mTextEditHelper.reset();
485 mEditedInterval = {};
486}
487
489{
492}
493
495{
497}
498
500{
501 using namespace RefreshCode;
502 if (mTextEditHelper)
503 {
504 if (auto trackList = FindTrack()->GetOwner())
505 {
506 mTextEditHelper->Finish(trackList->GetOwner());
507 }
509 return RefreshCell;
510 }
511 return RefreshNone;
512}
513
515{
516 if (mTextEditHelper)
517 {
518 mTextEditHelper->CopySelectedText(project);
519 return true;
520 }
521 return false;
522}
523
525{
526 if (mTextEditHelper)
527 {
528 mTextEditHelper->CutSelectedText(project);
529 return true;
530 }
531 return false;
532}
533
535{
536 if (mTextEditHelper)
537 {
538 mTextEditHelper->PasteSelectedText(project);
539 return true;
540 }
541 return false;
542}
543
545{
546 if (mTextEditHelper)
547 {
548 mTextEditHelper->SelectAll();
549 return true;
550 }
551 return false;
552}
553
555{
556 auto& viewInfo = ViewInfo::Get(*project);
557 if (mTextEditHelper)
558 {
559 if (auto interval = *mEditedInterval)
560 {
561 auto affordanceRect = ClipParameters::GetClipRect(*interval->GetClip(0), viewInfo, event.rect);
562 if (!affordanceRect.Contains(event.event.GetPosition()))
563 return ExitTextEditing();
564 }
565 }
566 else if (auto interval = *mFocusInterval)
567 {
568 if (event.event.LeftDClick())
569 {
570 auto affordanceRect = ClipParameters::GetClipRect(*interval->GetClip(0), viewInfo, event.rect);
571 if (affordanceRect.Contains(event.event.GetPosition()) &&
573 {
574 event.event.Skip(false);
576 }
577 }
578 }
580}
581
583{
584 auto [track, it] = SelectedIntervalOfFocusedTrack(project);
585 if(track != FindTrack().get())
586 return;
588}
589
590namespace
591{
593{
594 auto& viewInfo = ViewInfo::Get(project);
595 viewInfo.selectedRegion.setTimes(interval.GetPlayStartTime(), interval.GetPlayEndTime());
597}
598}
599
602{
603 auto [track, it] = SelectedIntervalOfFocusedTrack(project);
604
605 if (track != FindTrack().get())
606 return;
607
608 auto interval = *it;
609
610 if (!interval)
611 return;
612
613 ChangeClipSpeedDialog dlg(*track, *interval, &GetProjectFrame(project));
614
615 if (wxID_OK == dlg.ShowModal())
616 {
617 PushClipSpeedChangedUndoState(project, 100.0 / interval->GetStretchRatio());
618 SelectInterval(project, *interval);
619 }
620}
621
624{
625 const auto [track, it] = SelectedIntervalOfFocusedTrack(project);
626
627 if (track != FindTrack().get())
628 return;
629
630 auto interval = *it;
631
632 if (!interval || interval->StretchRatioEquals(1.0))
633 return;
634
636 [track = track, interval = interval](const ProgressReporter& progress) {
637 track->ApplyStretchRatio(
638 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
639 progress);
640 },
641 XO("Applying..."));
642
644 XO("Rendered time-stretched audio"), XO("Render"));
645
646 SelectInterval(project, *interval);
647}
648
649std::shared_ptr<TextEditHelper> WaveTrackAffordanceControls::MakeTextEditHelper(const wxString& text)
650{
651 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text, mClipNameFont);
652 helper->SetTextColor(theTheme.Colour(clrClipNameText));
653 helper->SetTextSelectionColor(theTheme.Colour(clrClipNameTextSelection));
654 return helper;
655}
656
658 const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject)
659 -> std::vector<MenuItem>
660{
661 return GetWaveClipMenuItems();
662}
663
664// Register a menu item
665
666namespace {
667
668// Menu handler functions
669
670void OnEditClipName(const CommandContext &context)
671{
672 auto &project = context.project;
673
674 if(auto pWaveTrack = dynamic_cast<WaveTrack *>(TrackFocus::Get(project).Get()))
675 {
676 if(auto pAffordance = FindAffordance(*pWaveTrack))
677 {
678 pAffordance->StartEditSelectedClipName(project);
679 // Refresh so the cursor appears
681 }
682 }
683}
684
686{
687 auto& project = context.project;
688
689 if (
690 auto pWaveTrack =
691 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
692 {
693 if (auto pAffordance = FindAffordance(*pWaveTrack))
694 pAffordance->StartEditSelectedClipSpeed(project);
695 }
696}
697
699{
700 auto& project = context.project;
701
702 if (
703 auto pWaveTrack =
704 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
705 {
706 if (auto pAffordance = FindAffordance(*pWaveTrack))
707 pAffordance->OnRenderClipStretching(project);
708 }
709}
710
711using namespace MenuRegistry;
712
713// Register menu items
714
716 Command( L"RenameClip", XXO("&Rename Clip..."),
718 wxT("Edit/Other/Clip")
719};
720
722 Command( L"ChangeClipSpeed", XXO("Change &Speed..."),
724 wxT("Edit/Other/Clip")
725};
726
728 Command( L"RenderClipStretching", XXO("Render Clip S&tretching"),
730 wxT("Edit/Other/Clip")
731};
732}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
AttachedItem sAttachment3
AttachedItem sAttachment2
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
const auto project
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
std::function< void(double)> ProgressReporter
Definition: Track.h:53
static Settings & settings()
Definition: TrackInfo.cpp:69
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:188
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:159
An AudacityException with no visible message.
std::vector< CommonTrackPanelCell::MenuItem > GetWaveClipMenuItems()
void PushClipSpeedChangedUndoState(AudacityProject &project, double speedInPercent)
static std::once_flag flag
Base class for command in Audacity.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static ChannelView & Get(Channel &channel)
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
std::shared_ptr< Track > FindTrack()
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
Generates classes whose instances register items at construction.
Definition: Registry.h:388
static UIHandlePtr HitTest(std::weak_ptr< SelectHandle > &holder, const TrackPanelMouseState &state, const AudacityProject *pProject, const std::shared_ptr< ChannelView > &pChannelView)
ComponentInterfaceSymbol GetSymbol() const override
static const ComponentInterfaceSymbol Symbol
void PopulateOrExchange(ShuttleGui &S) override
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:630
static bool IsGoodEditKeyCode(int keyCode)
wxColour & Colour(int iIndex)
static TrackArtist * Get(TrackPanelDrawingContext &)
Definition: TrackArtist.cpp:69
Track * Get()
Definition: TrackFocus.cpp:156
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:233
void RefreshTrack(Track *trk, bool refreshbacking=true)
Definition: TrackPanel.cpp:764
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:36
unsigned Result
Definition: UIHandle.h:39
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
static bool ClipDetailsVisible(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect)
static bool HitTest(const WaveClip &clip, const ZoomInfo &zoomInfo, const wxRect &rect, const wxPoint &pos)
static UIHandlePtr HitAnywhere(std::weak_ptr< WaveClipAdjustBorderHandle > &holder, const std::shared_ptr< WaveTrack > &waveTrack, const AudacityProject *pProject, const TrackPanelMouseState &state)
WaveClipTitleEditHandle(const std::shared_ptr< TextEditHelper > &helper, const std::shared_ptr< WaveTrack > pTrack)
Result Release(const TrackPanelMouseEvent &event, AudacityProject *project, wxWindow *) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *project) override
std::shared_ptr< TextEditHelper > mHelper
Result Cancel(AudacityProject *project) override
std::shared_ptr< WaveTrack > mpTrack
std::shared_ptr< const Channel > FindChannel() const override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *project) override
double GetPlayStartTime() const
Definition: WaveTrack.cpp:393
double GetPlayEndTime() const
Definition: WaveTrack.cpp:399
bool OnTextCopy(AudacityProject &project)
void OnTextEditCancelled(AudacityProject *project) override
void OnTrackListEvent(const TrackListEvent &evt)
void OnTextContextMenu(AudacityProject *project, const wxPoint &position) override
std::weak_ptr< WaveClipAdjustBorderHandle > mClipBorderAdjustHandle
unsigned CaptureKey(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
std::vector< MenuItem > GetMenuItems(const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject) override
Return a list of items for DoContextMenu() (empties for separators)
void OnTextEditFinished(AudacityProject *project, const wxString &text) override
unsigned LoseFocus(AudacityProject *project) override
bool IsIntervalVisible(const IntervalIterator &it) const noexcept
WaveTrackAffordanceControls(const std::shared_ptr< Track > &pTrack)
void OnSelectionChange(NotifyingSelectedRegionMessage)
bool OnTextSelect(AudacityProject &project)
std::vector< IntervalIterator > mVisibleIntervals
std::weak_ptr< WaveTrackAffordanceHandle > mAffordanceHandle
Observer::Subscription mSelectionChangeSubscription
std::shared_ptr< TextEditHelper > mTextEditHelper
void StartEditSelectedClipName(AudacityProject &project)
std::shared_ptr< TextEditHelper > MakeTextEditHelper(const wxString &text)
bool StartEditClipName(AudacityProject &project, IntervalIterator it)
Starts in-place clip name editing or shows a Clip Name Edit dialog, depending on prefs.
void OnRenderClipStretching(AudacityProject &project)
std::weak_ptr< SelectHandle > mSelectHandle
unsigned KeyDown(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
unsigned OnAffordanceClick(const TrackPanelMouseEvent &event, AudacityProject *project)
Observer::Subscription mTrackListEventSubscription
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
bool OnTextCut(AudacityProject &project)
IntervalIterator GetSelectedInterval() const
void OnTextModified(AudacityProject *project, const wxString &text) override
bool OnTextPaste(AudacityProject &project)
void StartEditSelectedClipSpeed(AudacityProject &project)
std::weak_ptr< WaveClipTitleEditHandle > mTitleEditHandle
unsigned Char(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
A Track that contains audio waveform data.
Definition: WaveTrack.h:222
virtual bool Read(const wxString &key, bool *value) const =0
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196
constexpr auto Command
Definition: MenuRegistry.h:456
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
Definition: TrackArt.cpp:399
AUDACITY_DLL_API wxRect DrawClipAffordance(wxDC &dc, const wxRect &affordanceRect, bool highlight=false, bool selected=false)
Definition: TrackArt.cpp:201
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
Definition: TrackArt.cpp:704
AUDACITY_DLL_API bool DrawAudioClipTitle(wxDC &dc, const wxRect &titleRect, const wxString &title, double clipStretchRatio)
Definition: TrackArt.cpp:333
WAVE_TRACK_API void WithStretchRenderingProgress(std::function< void(const ProgressReporter &)> action, TranslatableString title=defaultStretchRenderingTitle, TranslatableString message=XO("Rendering Time-Stretched Audio"))
void SelectInterval(AudacityProject &project, const WaveTrack::Interval &interval)
std::pair< WaveTrack *, ChannelGroup::IntervalIterator< WaveTrack::Interval > > SelectedIntervalOfFocusedTrack(AudacityProject &project)
static wxRect GetClipRect(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect, bool *outShowSamples=nullptr)
Notification of changes in individual tracks of TrackList, or of TrackList's composition.
Definition: Track.h:928
const Type mType
Definition: Track.h:962
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.
Definition: Track.h:931