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->clipAffordanceBackgroundSelBrush,
287 artist->clipAffordanceBackgroundBrush,
288 true, true);
289
290 mVisibleIntervals.clear();
291
292 auto &waveTrack = static_cast<WaveTrack&>(
293 pendingTracks.SubstitutePendingChangedTrack(*track));
294 const auto& zoomInfo = *artist->pZoomInfo;
295 {
296 wxDCClipper dcClipper(context.dc, rect);
297
298 context.dc.SetTextBackground(wxTransparentColor);
299 context.dc.SetTextForeground(theTheme.Colour(clrClipNameText));
300 context.dc.SetFont(mClipNameFont);
301
302 auto px = context.lastState.m_x;
303 auto py = context.lastState.m_y;
304
305 const auto overflowHandle = mOverflowButtonHandle.lock();
306 const auto &intervals = waveTrack.Intervals();
307 for(auto it = intervals.begin(); it != intervals.end(); ++it)
308 {
309 auto interval = *it;
310 const auto& clip = *interval;
311 const auto clipRect = ClipParameters::GetClipRect(
312 clip, zoomInfo, rect);
313
314 if(!WaveChannelView::ClipDetailsVisible(clip, zoomInfo, rect))
315 {
316 TrackArt::DrawClipFolded(context.dc, clipRect);
317 continue;
318 }
319
320 const auto selected = GetSelectedInterval() == it;
321 const auto highlightAffordance =
322 !overflowHandle && (selected || clipRect.Contains(px, py));
323 auto affordanceRect = TrackArt::DrawClipAffordance(
324 context.dc, clipRect, highlightAffordance, selected);
325
326 if (
327 const auto overflowButtonRect =
328 LowlitClipButton::DrawOnClip<ClipButtonId::Overflow>(
329 { clip, zoomInfo, rect }, context.dc))
330 affordanceRect.width -= overflowButtonRect->width;
331 if (
332 const auto speedButtonRect =
333 LowlitClipButton::DrawOnClip<ClipButtonId::Speed>(
334 { clip, zoomInfo, rect }, context.dc))
335 affordanceRect.width -= speedButtonRect->width;
336 if (
337 const auto pitchButtonRect =
338 LowlitClipButton::DrawOnClip<ClipButtonId::Pitch>(
339 { clip, zoomInfo, rect }, context.dc))
340 affordanceRect.width -= pitchButtonRect->width;
341
342 if (mTextEditHelper && mEditedInterval == it)
343 {
344 if (!mTextEditHelper->Draw(context.dc, affordanceRect))
345 {
346 mTextEditHelper->Cancel(nullptr);
348 context.dc, affordanceRect, interval->GetName());
349 }
350 }
352 context.dc, affordanceRect, interval->GetName()))
353 mVisibleIntervals.push_back(it);
354 }
355 }
356 }
357}
358
360{
361 return std::find(mVisibleIntervals.begin(),
362 mVisibleIntervals.end(),
363 it) != mVisibleIntervals.end();
364}
365
367{
368 bool useDialog{ false };
369 gPrefs->Read(wxT("/GUI/DialogForNameNewLabel"), &useDialog, false);
370
371 auto interval = *it;
372 if(!interval)
373 return false;
374
375 if (useDialog)
376 {
378 auto oldName = interval->GetName();
379 Command.mName = oldName;
380 auto result = Command.PromptUser(&GetProjectFrame(project));
381 if (result && Command.mName != oldName)
382 {
383 interval->SetName(Command.mName);
384 ProjectHistory::Get(project).PushState(XO("Modified Clip Name"),
385 XO("Clip Name Edit"));
386 }
387 }
388 else if(it != mEditedInterval)
389 {
390 if(!IsIntervalVisible(it))
391 return false;
392
393 if (mTextEditHelper)
394 mTextEditHelper->Finish(&project);
395
396 mEditedInterval = it;
397 mTextEditHelper = MakeTextEditHelper(interval->GetName());
398 }
399
400 return true;
401}
402
404{
405 if (auto handle = mAffordanceHandle.lock())
406 {
407 return handle->Clicked() ? mFocusInterval : IntervalIterator{};
408 }
409 return {};
410}
411
412namespace {
413
415{
416 auto &view = WaveChannelView::GetFirst(track);
417 auto pAffordance = view.GetAffordanceControls();
418 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
419 pAffordance );
420}
421
422std::pair<std::shared_ptr<WaveTrack>, ChannelGroup::IntervalIterator<WaveTrack::Interval>>
424{
425 // Note that TrackFocus may change its state as a side effect, defining
426 // a track focus if there was none
427 auto track = TrackFocus::Get(project).Get();
428 if (!track)
429 return {};
430 if (
431 auto pWaveTrack =
432 std::dynamic_pointer_cast<WaveTrack>(track->shared_from_this()))
433 {
434 if (FindAffordance(*pWaveTrack)) {
435 auto &viewInfo = ViewInfo::Get(project);
436 const auto &intervals = pWaveTrack->Intervals();
437
438 auto it = std::find_if(
439 intervals.begin(), intervals.end(), [&](const auto& interval) {
440 if (wholeInterval)
441 return interval->Start() == viewInfo.selectedRegion.t0() &&
442 interval->End() == viewInfo.selectedRegion.t1();
443 else
444 return interval->Start() <= viewInfo.selectedRegion.t0() &&
445 interval->End() > viewInfo.selectedRegion.t0();
446 });
447
448 if(it != intervals.end())
449 return { pWaveTrack, it };
450 }
451 }
452 return {};
453}
454
455// condition for enabling the command
457{
459 [](const AudacityProject &project){
460 // const_cast isn't pretty but not harmful in this case
461 return SelectedIntervalOfFocusedTrack(const_cast<AudacityProject&>(project)).first != nullptr;
462 }
463 };
464 return flag;
465}
466
468{
470 [](const AudacityProject &project){
471 // const_cast isn't pretty but not harmful in this case
472 auto result = SelectedIntervalOfFocusedTrack(
473 const_cast<AudacityProject&>(project));
474
475 auto interval = *result.second;
476 return interval != nullptr && interval->HasPitchOrSpeed();
477 }
478 };
479 return flag;
480}
481
482}
483
484unsigned WaveTrackAffordanceControls::CaptureKey(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
485{
486 if (!mTextEditHelper
487 || !mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
488 // Handle the event if it can be processed by the text editor (if any)
489 event.Skip();
491}
492
493
494unsigned WaveTrackAffordanceControls::KeyDown(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow*, AudacityProject* project)
495{
496 auto keyCode = event.GetKeyCode();
497
498 if (mTextEditHelper)
499 {
500 if (!mTextEditHelper->OnKeyDown(keyCode, event.GetModifiers(), project)
502 event.Skip();
503
505 }
507}
508
509unsigned WaveTrackAffordanceControls::Char(wxKeyEvent& event, ViewInfo& viewInfo, wxWindow* pParent, AudacityProject* project)
510{
511 if (mTextEditHelper && mTextEditHelper->OnChar(event.GetUnicodeKey(), project))
514}
515
517{
518 return ExitTextEditing();
519}
520
522{
523 if (auto interval = *mEditedInterval)
524 {
525 if (text != interval->GetName()) {
526 interval->SetName(text);
527
528 ProjectHistory::Get(*project).PushState(XO("Modified Clip Name"),
529 XO("Clip Name Edit"));
530 }
531 }
533}
534
536{
538}
539
541{
542 //Nothing to do
543}
544
546{
547}
548
550{
551 mTextEditHelper.reset();
552 mEditedInterval = {};
553}
554
556{
559}
560
562{
564}
565
567{
568 using namespace RefreshCode;
569 if (mTextEditHelper)
570 {
571 if (auto trackList = FindTrack()->GetOwner())
572 {
573 mTextEditHelper->Finish(trackList->GetOwner());
574 }
576 return RefreshCell;
577 }
578 return RefreshNone;
579}
580
582{
583 if (mTextEditHelper)
584 {
585 mTextEditHelper->CopySelectedText(project);
586 return true;
587 }
588 return false;
589}
590
592{
593 if (mTextEditHelper)
594 {
595 mTextEditHelper->CutSelectedText(project);
596 return true;
597 }
598 return false;
599}
600
602{
603 if (mTextEditHelper)
604 {
605 mTextEditHelper->PasteSelectedText(project);
606 return true;
607 }
608 return false;
609}
610
612{
613 if (mTextEditHelper)
614 {
615 mTextEditHelper->SelectAll();
616 return true;
617 }
618 return false;
619}
620
622{
623 auto& viewInfo = ViewInfo::Get(*project);
624 if (mTextEditHelper)
625 {
626 if (auto interval = *mEditedInterval)
627 {
628 auto affordanceRect = ClipParameters::GetClipRect(*interval, viewInfo, event.rect);
629 if (!affordanceRect.Contains(event.event.GetPosition()))
630 return ExitTextEditing();
631 }
632 }
633 else if (auto interval = *mFocusInterval)
634 {
635 if (event.event.LeftDClick())
636 {
637 auto affordanceRect = ClipParameters::GetClipRect(*interval, viewInfo, event.rect);
638 if (affordanceRect.Contains(event.event.GetPosition()) &&
640 {
641 event.event.Skip(false);
643 }
644 }
645 }
647}
648
650{
651 auto [track, it] = SelectedIntervalOfFocusedTrack(project);
652 if(track != FindTrack())
653 return;
655}
656
659{
660 constexpr auto wholeInterval = false;
661 auto [track, it] = SelectedIntervalOfFocusedTrack(project, wholeInterval);
662
663 if (track != FindTrack())
664 return;
665
666 auto interval = *it;
667
668 if (!interval)
669 return;
670
672}
673
676{
677 const auto [track, it] = SelectedIntervalOfFocusedTrack(project);
678
679 if (track != FindTrack())
680 return;
681
682 auto interval = *it;
683
684 if (!interval || !interval->HasPitchOrSpeed())
685 return;
686
688 [track = track, interval = interval](const ProgressReporter& progress) {
689 track->ApplyPitchAndSpeed(
690 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
691 progress);
692 },
693 XO("Applying..."));
694
696 XO("Rendered time-stretched audio"), XO("Render"));
697
699}
700
701std::shared_ptr<TextEditHelper> WaveTrackAffordanceControls::MakeTextEditHelper(const wxString& text)
702{
703 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text, mClipNameFont);
704 helper->SetTextColor(theTheme.Colour(clrClipNameText));
705 helper->SetTextSelectionColor(theTheme.Colour(clrClipNameTextSelection));
706 return helper;
707}
708
710 const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject)
711 -> std::vector<MenuItem>
712{
714}
715
716// Register a menu item
717
718namespace {
719
720// Menu handler functions
721
722void OnEditClipName(const CommandContext &context)
723{
724 auto &project = context.project;
725
726 if(auto pWaveTrack = dynamic_cast<WaveTrack *>(TrackFocus::Get(project).Get()))
727 {
728 if(auto pAffordance = FindAffordance(*pWaveTrack))
729 {
730 pAffordance->StartEditSelectedClipName(project);
731 // Refresh so the cursor appears
733 }
734 }
735}
736
738{
739 auto& project = context.project;
740
741 if (
742 auto pWaveTrack =
743 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
744 {
745 if (auto pAffordance = FindAffordance(*pWaveTrack))
746 pAffordance->StartEditSelectedClipSpeed(project);
747 }
748}
749
751{
752 auto& project = context.project;
753
754 if (
755 auto pWaveTrack =
756 dynamic_cast<WaveTrack*>(TrackFocus::Get(project).Get()))
757 {
758 if (auto pAffordance = FindAffordance(*pWaveTrack))
759 pAffordance->OnRenderClipStretching(project);
760 }
761}
762
764 const CommandContext& context, bool up)
765{
766 auto [track, it] = SelectedIntervalOfFocusedTrack(context.project);
767 if (!track)
768 return;
769 const auto interval = *it;
770 if (interval->SetCentShift(interval->GetCentShift() + (up ? 100 : -100)))
772 .PushState(
773 XO("Pitch Shift"), XO("Changed Pitch Shift"),
775}
776
777void OnPitchUp(const CommandContext& context)
778{
779 OnPitchShift(context, true);
780}
781
782void OnPitchDown(const CommandContext& context)
783{
784 OnPitchShift(context, false);
785}
786
787using namespace MenuRegistry;
788
789// Register menu items
790
792 Command( L"RenameClip", XXO("&Rename Clip..."),
794 wxT("Edit/Other/Clip")
795};
796
798 Command(
799 L"ChangePitchAndSpeed", XXO("&Pitch and Speed..."), OnChangePitchAndSpeed,
800 AlwaysEnabledFlag, Options { wxT("Ctrl+Shift+P") }),
801 wxT("Edit/Other/Clip")
802};
803
805 Command( L"RenderPitchAndSpeed", XXO("Render Pitch and &Speed"),
807 wxT("Edit/Other/Clip")
808};
809
811 Command( L"PitchUp", XXO("Pitch &Up"),
813 wxT("Edit/Other/Clip")
814};
815
817 Command( L"PitchDown", XXO("Pitch &Down"),
818 OnPitchDown, SomeClipIsSelectedFlag(), Options{ wxT("Alt+Down") }),
819 wxT("Edit/Other/Clip")
820};
821}
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:51
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:82
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:202
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 void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true, bool useBeatsAlternateColor=false)
Helper: draws background with selection rect.
Definition: TrackArt.cpp:648
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
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