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 "PendingTracks.h"
22#include "../../../../TrackPanelMouseEvent.h"
23#include "../../../../TrackArt.h"
24#include "../../../../TrackArtist.h"
25#include "../../../../TrackPanelDrawingContext.h"
26#include "ViewInfo.h"
27#include "WaveTrack.h"
28#include "WaveClip.h"
29#include "TimeStretching.h"
30#include "UndoManager.h"
31#include "ShuttleGui.h"
32#include "../../../../ProjectWindows.h"
33#include "../../../../commands/AudacityCommand.h"
34
35#include "../../../ui/SelectHandle.h"
36#include "../../../ui/TextEditHelper.h"
37#include "ClipParameters.h"
38#include "WaveChannelView.h"
40
41#include "ProjectHistory.h"
42#include "../../../../ProjectSettings.h"
43#include "SelectionState.h"
44#include "../../../../RefreshCode.h"
45#include "Theme.h"
46#include "../../../../../images/Cursors.h"
47#include "../../../../HitTestResult.h"
48#include "../../../../TrackPanel.h"
49#include "TrackFocus.h"
50
53#include "LowlitClipButton.h"
54#include "PitchAndSpeedDialog.h"
56#include "WaveClipUIUtilities.h"
57
58#include "BasicUI.h"
59#include "UserException.h"
60
61
63{
64public:
66
68 {
69 return Symbol;
70 }
72 {
73 S.AddSpace(0, 5);
74
75 S.StartMultiColumn(2, wxALIGN_CENTER);
76 {
77 S.TieTextBox(XXO("Name:"), mName, 60);
78 }
79 S.EndMultiColumn();
80 }
81public:
82 wxString mName;
83};
84
86{ XO("Set Wave Clip Name") };
87
88//Handle which is used to send mouse events to TextEditHelper
90{
91 std::shared_ptr<TextEditHelper> mHelper;
92 std::shared_ptr<WaveTrack> mpTrack;
93public:
94
95 WaveClipTitleEditHandle(const std::shared_ptr<TextEditHelper>& helper,
96 const std::shared_ptr<WaveTrack> pTrack)
97 : mHelper(helper)
98 , mpTrack{ move(pTrack) }
99 { }
100
102 {
103 }
104
105 std::shared_ptr<const Track> FindTrack() const override
106 {
107 return mpTrack;
108 }
109
111 {
112 if (mHelper->OnClick(event.event, project))
115 }
116
118 {
119 if (mHelper->OnDrag(event.event, project))
122 }
123
125 {
126 static auto ibeamCursor =
127 ::MakeCursor(wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
128 return {
129 XO("Click and drag to select text"),
130 ibeamCursor.get()
131 };
132 }
133
134 Result Release(const TrackPanelMouseEvent& event, AudacityProject* project, wxWindow*) override
135 {
136 if (mHelper->OnRelease(event.event, project))
139 }
140
142 {
143 if (mHelper)
144 {
145 mHelper->Cancel(project);
146 mHelper.reset();
147 }
149 }
150};
151
153 : CommonTrackCell{ pTrack }
154 , mClipNameFont{ wxFontInfo{} }
155{
156 if (auto trackList = pTrack->GetOwner()) {
157 if (auto pProject = trackList->GetOwner()) {
160 if(auto project = trackList->GetOwner())
161 {
162 auto& viewInfo = ViewInfo::Get(*project);
164 viewInfo.selectedRegion.Subscribe(
165 *this,
167 }
168 }
169 }
170}
171
172std::vector<UIHandlePtr> WaveTrackAffordanceControls::HitTest(const TrackPanelMouseState& state, const AudacityProject* pProject)
173{
174 std::vector<UIHandlePtr> results;
175
176 const auto px = state.state.m_x;
177 const auto py = state.state.m_y;
178 const wxPoint mousePoint { px, py };
179
180 const auto rect = state.rect;
181
182 auto track = std::static_pointer_cast<WaveTrack>(FindTrack());
183 if (!track)
184 return {};
185
186 {
189 track,
190 pProject,
191 state);
192
193 if (handle)
194 results.push_back(handle);
195 }
196
197 if (mTextEditHelper && mTextEditHelper->GetBBox().Contains(px, py))
198 {
199 results.push_back(
202 std::make_shared<WaveClipTitleEditHandle>(
203 mTextEditHelper, track)
204 )
205 );
206 }
207
208 auto &waveTrack = static_cast<WaveTrack&>(
210 auto& zoomInfo = ViewInfo::Get(*pProject);
211 const auto &intervals = waveTrack.Intervals();
212 for(auto it = intervals.begin(); it != intervals.end(); ++it)
213 {
214 if (it == mEditedInterval)
215 continue;
216
217 const auto clip = (*it);
218 if (LowlitClipButton::HitTest<ClipButtonId::Overflow>(
219 { *clip, zoomInfo, rect }, mousePoint))
220 {
221 results.push_back(AssignUIHandlePtr(
222 mOverflowButtonHandle, std::make_shared<ClipOverflowButtonHandle>(
223 track, *it, weak_from_this())));
224 mFocusInterval = it;
225 break;
226 }
227 else if (LowlitClipButton::HitTest<ClipButtonId::Pitch>(
228 { *clip, zoomInfo, rect }, mousePoint))
229 {
230 results.push_back(AssignUIHandlePtr(
232 std::make_shared<ClipPitchAndSpeedButtonHandle>(
234 mFocusInterval = it;
235 break;
236 }
237 else if (LowlitClipButton::HitTest<ClipButtonId::Speed>(
238 { *clip, zoomInfo, rect }, mousePoint))
239 {
240 results.push_back(AssignUIHandlePtr(
242 std::make_shared<ClipPitchAndSpeedButtonHandle>(
244 mFocusInterval = it;
245 break;
246 }
248 *clip, zoomInfo, state.rect, mousePoint))
249 {
250 results.push_back(AssignUIHandlePtr(
252 std::make_shared<WaveTrackAffordanceHandle>(track, clip)));
253 mFocusInterval = it;
254 break;
255 }
256 }
257
258 const auto& settings = ProjectSettings::Get(*pProject);
259 const auto currentTool = settings.GetTool();
260 if (currentTool == ToolCodes::multiTool || currentTool == ToolCodes::selectTool)
261 {
262 results.push_back(
264 mSelectHandle, state, pProject,
265 WaveChannelView::GetFirst(*track).shared_from_this()
266 )
267 );
268 }
269
270 return results;
271}
272
273void WaveTrackAffordanceControls::Draw(TrackPanelDrawingContext& context, const wxRect& rect, unsigned iPass)
274{
275 if (iPass == TrackArtist::PassBackground) {
276 const auto track = FindTrack().get();
277 if (!track)
278 return;
279 const auto artist = TrackArtist::Get(context);
280 const auto &pendingTracks = *artist->pPendingTracks;
281
282 // Color the background of the affordance rectangle (only one per track)
283 // as for the topmost channel
285 rect, **track->Channels().begin(),
286 artist->blankSelectedBrush, artist->blankBrush);
287
288 mVisibleIntervals.clear();
289
290 auto &waveTrack = static_cast<WaveTrack&>(
291 pendingTracks.SubstitutePendingChangedTrack(*track));
292 const auto& zoomInfo = *artist->pZoomInfo;
293 {
294 wxDCClipper dcClipper(context.dc, rect);
295
296 context.dc.SetTextBackground(wxTransparentColor);
297 context.dc.SetTextForeground(theTheme.Colour(clrClipNameText));
298 context.dc.SetFont(mClipNameFont);
299
300 auto px = context.lastState.m_x;
301 auto py = context.lastState.m_y;
302
303 const auto overflowHandle = mOverflowButtonHandle.lock();
304 const auto &intervals = waveTrack.Intervals();
305 for(auto it = intervals.begin(); it != intervals.end(); ++it)
306 {
307 auto interval = *it;
308 const auto& clip = *interval;
309 const auto clipRect = ClipParameters::GetClipRect(
310 clip, zoomInfo, rect);
311
312 if(!WaveChannelView::ClipDetailsVisible(clip, zoomInfo, rect))
313 {
314 TrackArt::DrawClipFolded(context.dc, clipRect);
315 continue;
316 }
317
318 const auto selected = GetSelectedInterval() == it;
319 const auto highlightAffordance =
320 !overflowHandle && (selected || clipRect.Contains(px, py));
321 auto affordanceRect = TrackArt::DrawClipAffordance(
322 context.dc, clipRect, highlightAffordance, selected);
323
324 if (
325 const auto overflowButtonRect =
326 LowlitClipButton::DrawOnClip<ClipButtonId::Overflow>(
327 { clip, zoomInfo, rect }, context.dc))
328 affordanceRect.width -= overflowButtonRect->width;
329 if (
330 const auto speedButtonRect =
331 LowlitClipButton::DrawOnClip<ClipButtonId::Speed>(
332 { clip, zoomInfo, rect }, context.dc))
333 affordanceRect.width -= speedButtonRect->width;
334 if (
335 const auto pitchButtonRect =
336 LowlitClipButton::DrawOnClip<ClipButtonId::Pitch>(
337 { clip, zoomInfo, rect }, context.dc))
338 affordanceRect.width -= pitchButtonRect->width;
339
340 if (mTextEditHelper && mEditedInterval == it)
341 {
342 if (!mTextEditHelper->Draw(context.dc, affordanceRect))
343 {
344 mTextEditHelper->Cancel(nullptr);
346 context.dc, affordanceRect, interval->GetName());
347 }
348 }
350 context.dc, affordanceRect, interval->GetName()))
351 mVisibleIntervals.push_back(it);
352 }
353 }
354 }
355}
356
358{
359 return std::find(mVisibleIntervals.begin(),
360 mVisibleIntervals.end(),
361 it) != mVisibleIntervals.end();
362}
363
365{
366 bool useDialog{ false };
367 gPrefs->Read(wxT("/GUI/DialogForNameNewLabel"), &useDialog, false);
368
369 auto interval = *it;
370 if(!interval)
371 return false;
372
373 if (useDialog)
374 {
376 auto oldName = interval->GetName();
377 Command.mName = oldName;
378 auto result = Command.PromptUser(&GetProjectFrame(project));
379 if (result && Command.mName != oldName)
380 {
381 interval->SetName(Command.mName);
382 ProjectHistory::Get(project).PushState(XO("Modified Clip Name"),
383 XO("Clip Name Edit"));
384 }
385 }
386 else if(it != mEditedInterval)
387 {
388 if(!IsIntervalVisible(it))
389 return false;
390
391 if (mTextEditHelper)
392 mTextEditHelper->Finish(&project);
393
394 mEditedInterval = it;
395 mTextEditHelper = MakeTextEditHelper(interval->GetName());
396 }
397
398 return true;
399}
400
402{
403 if (auto handle = mAffordanceHandle.lock())
404 {
405 return handle->Clicked() ? mFocusInterval : IntervalIterator{};
406 }
407 return {};
408}
409
410namespace {
411
413{
414 auto &view = WaveChannelView::GetFirst(track);
415 auto pAffordance = view.GetAffordanceControls();
416 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
417 pAffordance );
418}
419
420std::pair<std::shared_ptr<WaveTrack>, ChannelGroup::IntervalIterator<WaveTrack::Interval>>
422{
423 // Note that TrackFocus may change its state as a side effect, defining
424 // a track focus if there was none
425 auto track = TrackFocus::Get(project).Get();
426 if (!track)
427 return {};
428 if (
429 auto pWaveTrack =
430 std::dynamic_pointer_cast<WaveTrack>(track->shared_from_this()))
431 {
432 if (FindAffordance(*pWaveTrack)) {
433 auto &viewInfo = ViewInfo::Get(project);
434 const auto &intervals = pWaveTrack->Intervals();
435
436 auto it = std::find_if(
437 intervals.begin(), intervals.end(), [&](const auto& interval) {
438 if (wholeInterval)
439 return interval->Start() == viewInfo.selectedRegion.t0() &&
440 interval->End() == viewInfo.selectedRegion.t1();
441 else
442 return interval->Start() <= viewInfo.selectedRegion.t0() &&
443 interval->End() > viewInfo.selectedRegion.t0();
444 });
445
446 if(it != intervals.end())
447 return { pWaveTrack, it };
448 }
449 }
450 return {};
451}
452
453// condition for enabling the command
455{
457 [](const AudacityProject &project){
458 // const_cast isn't pretty but not harmful in this case
459 return SelectedIntervalOfFocusedTrack(const_cast<AudacityProject&>(project)).first != nullptr;
460 }
461 };
462 return flag;
463}
464
466{
468 [](const AudacityProject &project){
469 // const_cast isn't pretty but not harmful in this case
470 auto result = SelectedIntervalOfFocusedTrack(
471 const_cast<AudacityProject&>(project));
472
473 auto interval = *result.second;
474 return interval != nullptr && interval->HasPitchOrSpeed();
475 }
476 };
477 return flag;
478}
479
480}
481
482unsigned WaveTrackAffordanceControls::CaptureKey(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
483{
484 if (!mTextEditHelper
485 || !mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
486 // Handle the event if it can be processed by the text editor (if any)
487 event.Skip();
489}
490
491
492unsigned WaveTrackAffordanceControls::KeyDown(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow*, AudacityProject* project)
493{
494 auto keyCode = event.GetKeyCode();
495
496 if (mTextEditHelper)
497 {
498 if (!mTextEditHelper->OnKeyDown(keyCode, event.GetModifiers(), project)
500 event.Skip();
501
503 }
505}
506
507unsigned WaveTrackAffordanceControls::Char(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
508{
509 if (mTextEditHelper && mTextEditHelper->OnChar(event.GetUnicodeKey(), project))
512}
513
515{
516 return ExitTextEditing();
517}
518
520{
521 if (auto interval = *mEditedInterval)
522 {
523 if (text != interval->GetName()) {
524 interval->SetName(text);
525
526 ProjectHistory::Get(*project).PushState(XO("Modified Clip Name"),
527 XO("Clip Name Edit"));
528 }
529 }
531}
532
534{
536}
537
539{
540 //Nothing to do
541}
542
544{
545}
546
548{
549 mTextEditHelper.reset();
550 mEditedInterval = {};
551}
552
554{
557}
558
560{
562}
563
565{
566 using namespace RefreshCode;
567 if (mTextEditHelper)
568 {
569 if (auto trackList = FindTrack()->GetOwner())
570 {
571 mTextEditHelper->Finish(trackList->GetOwner());
572 }
574 return RefreshCell;
575 }
576 return RefreshNone;
577}
578
580{
581 if (mTextEditHelper)
582 {
583 mTextEditHelper->CopySelectedText(project);
584 return true;
585 }
586 return false;
587}
588
590{
591 if (mTextEditHelper)
592 {
593 mTextEditHelper->CutSelectedText(project);
594 return true;
595 }
596 return false;
597}
598
600{
601 if (mTextEditHelper)
602 {
603 mTextEditHelper->PasteSelectedText(project);
604 return true;
605 }
606 return false;
607}
608
610{
611 if (mTextEditHelper)
612 {
613 mTextEditHelper->SelectAll();
614 return true;
615 }
616 return false;
617}
618
620{
621 auto& viewInfo = ViewInfo::Get(*project);
622 if (mTextEditHelper)
623 {
624 if (auto interval = *mEditedInterval)
625 {
626 auto affordanceRect = ClipParameters::GetClipRect(*interval, viewInfo, event.rect);
627 if (!affordanceRect.Contains(event.event.GetPosition()))
628 return ExitTextEditing();
629 }
630 }
631 else if (auto interval = *mFocusInterval)
632 {
633 if (event.event.LeftDClick())
634 {
635 auto affordanceRect = ClipParameters::GetClipRect(*interval, viewInfo, event.rect);
636 if (affordanceRect.Contains(event.event.GetPosition()) &&
638 {
639 event.event.Skip(false);
641 }
642 }
643 }
645}
646
648{
649 auto [track, it] = SelectedIntervalOfFocusedTrack(project);
650 if(track != FindTrack())
651 return;
653}
654
657{
658 constexpr auto wholeInterval = false;
659 auto [track, it] = SelectedIntervalOfFocusedTrack(project, wholeInterval);
660
661 if (track != FindTrack())
662 return;
663
664 auto interval = *it;
665
666 if (!interval)
667 return;
668
670}
671
674{
675 const auto [track, it] = SelectedIntervalOfFocusedTrack(project);
676
677 if (track != FindTrack())
678 return;
679
680 auto interval = *it;
681
682 if (!interval || !interval->HasPitchOrSpeed())
683 return;
684
686 [track = track, interval = interval](const ProgressReporter& progress) {
687 track->ApplyPitchAndSpeed(
688 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
689 progress);
690 },
691 XO("Applying..."));
692
694 XO("Rendered time-stretched audio"), XO("Render"));
695
697}
698
699std::shared_ptr<TextEditHelper> WaveTrackAffordanceControls::MakeTextEditHelper(const wxString& text)
700{
701 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text, mClipNameFont);
702 helper->SetTextColor(theTheme.Colour(clrClipNameText));
703 helper->SetTextSelectionColor(theTheme.Colour(clrClipNameTextSelection));
704 return helper;
705}
706
708 const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject)
709 -> std::vector<MenuItem>
710{
712}
713
714// Register a menu item
715
716namespace {
717
718// Menu handler functions
719
720void OnEditClipName(const CommandContext &context)
721{
722 auto &project = context.project;
723
724 if(auto pWaveTrack = dynamic_cast<WaveTrack *>(TrackFocus::Get(project).Get()))
725 {
726 if(auto pAffordance = FindAffordance(*pWaveTrack))
727 {
728 pAffordance->StartEditSelectedClipName(project);
729 // Refresh so the cursor appears
731 }
732 }
733}
734
736{
737 auto& project = context.project;
738
739 if (
740 auto pWaveTrack =
741 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
742 {
743 if (auto pAffordance = FindAffordance(*pWaveTrack))
744 pAffordance->StartEditSelectedClipSpeed(project);
745 }
746}
747
749{
750 auto& project = context.project;
751
752 if (
753 auto pWaveTrack =
754 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
755 {
756 if (auto pAffordance = FindAffordance(*pWaveTrack))
757 pAffordance->OnRenderClipStretching(project);
758 }
759}
760
762 const CommandContext& context, bool up)
763{
764 auto [track, it] = SelectedIntervalOfFocusedTrack(context.project);
765 if (!track)
766 return;
767 const auto interval = *it;
768 if (interval->SetCentShift(interval->GetCentShift() + (up ? 100 : -100)))
770 .PushState(
771 XO("Pitch Shift"), XO("Changed Pitch Shift"),
773}
774
775void OnPitchUp(const CommandContext& context)
776{
777 OnPitchShift(context, true);
778}
779
780void OnPitchDown(const CommandContext& context)
781{
782 OnPitchShift(context, false);
783}
784
785using namespace MenuRegistry;
786
787// Register menu items
788
790 Command( L"RenameClip", XXO("&Rename Clip..."),
792 wxT("Edit/Other/Clip")
793};
794
796 Command(
797 L"ChangePitchAndSpeed", XXO("&Pitch and Speed..."), OnChangePitchAndSpeed,
798 AlwaysEnabledFlag, Options { wxT("Ctrl+Shift+P") }),
799 wxT("Edit/Other/Clip")
800};
801
803 Command( L"RenderPitchAndSpeed", XXO("Render Pitch and &Speed"),
805 wxT("Edit/Other/Clip")
806};
807
809 Command( L"PitchUp", XXO("Pitch &Up"),
811 wxT("Edit/Other/Clip")
812};
813
815 Command( L"PitchDown", XXO("Pitch &Down"),
816 OnPitchDown, SomeClipIsSelectedFlag(), Options{ wxT("Alt+Down") }),
817 wxT("Edit/Other/Clip")
818};
819}
wxT("CloseDown"))
Toolkit-neutral facade for basic user interface services.
AttachedItem sAttachment3
AttachedItem sAttachment2
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
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:48
static Settings & settings()
Definition: TrackInfo.cpp:47
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:189
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:164
An AudacityException with no visible message.
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
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:318
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,...
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
Track & SubstitutePendingChangedTrack(Track &track) const
static PendingTracks & Get(AudacityProject &project)
static PitchAndSpeedDialog & Get(AudacityProject &project)
PitchAndSpeedDialog & SetFocus(const std::optional< PitchAndSpeedDialogGroup > &group)
PitchAndSpeedDialog & Retarget(const std::shared_ptr< WaveTrack > &track, const WaveTrack::IntervalHolder &wideClip)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
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:640
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:234
void RefreshTrack(Track *trk, bool refreshbacking=true)
Definition: TrackPanel.cpp:768
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:37
unsigned Result
Definition: UIHandle.h:40
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 ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &rect, const wxPoint &pos)
static WaveChannelView & GetFirst(WaveTrack &wt)
Get the view of the first channel.
static UIHandlePtr HitAnywhere(std::weak_ptr< WaveClipAdjustBorderHandle > &holder, const std::shared_ptr< WaveTrack > &waveTrack, const AudacityProject *pProject, const TrackPanelMouseState &state)
std::shared_ptr< const Track > FindTrack() const override
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
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *project) override
bool OnTextCopy(AudacityProject &project)
void OnTextEditCancelled(AudacityProject *project) override
void OnTrackListEvent(const TrackListEvent &evt)
std::weak_ptr< ClipPitchAndSpeedButtonHandle > mPitchButtonHandle
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
std::weak_ptr< ClipOverflowButtonHandle > mOverflowButtonHandle
Observer::Subscription mSelectionChangeSubscription
std::shared_ptr< TextEditHelper > mTextEditHelper
std::weak_ptr< ClipPitchAndSpeedButtonHandle > mSpeedButtonHandle
void StartEditSelectedClipName(AudacityProject &project)
std::shared_ptr< TextEditHelper > MakeTextEditHelper(const wxString &text)
void OnRenderClipStretching(AudacityProject &project) const
bool StartEditClipName(AudacityProject &project, IntervalIterator it)
Starts in-place clip name editing or shows a Clip Name Edit dialog, depending on prefs.
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:203
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:201
constexpr auto Command
Definition: MenuRegistry.h:456
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
WAVE_TRACK_API void WithClipRenderingProgress(std::function< void(const ProgressReporter &)> action, TranslatableString title=defaultStretchRenderingTitle)
AUDACITY_DLL_API bool DrawClipTitle(wxDC &dc, const wxRect &affordanceRect, const wxString &title)
Definition: TrackArt.cpp:289
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
Definition: TrackArt.cpp:346
AUDACITY_DLL_API wxRect DrawClipAffordance(wxDC &dc, const wxRect &clipRect, bool highlight=false, bool selected=false)
Definition: TrackArt.cpp:223
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
Definition: TrackArt.cpp:651
void SelectClip(AudacityProject &project, const WaveTrack::Interval &clip)
std::vector< CommonTrackPanelCell::MenuItem > GetWaveClipMenuItems()
void OnPitchShift(const CommandContext &context, bool up)
std::pair< std::shared_ptr< WaveTrack >, ChannelGroup::IntervalIterator< WaveTrack::Interval > > SelectedIntervalOfFocusedTrack(AudacityProject &project, bool wholeInterval=true)
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:803
const Type mType
Definition: Track.h:837
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.
Definition: Track.h:806