21#include "../../../../TrackPanelMouseEvent.h"
22#include "../../../../TrackArt.h"
23#include "../../../../TrackArtist.h"
24#include "../../../../TrackPanelDrawingContext.h"
31#include "../../../../ProjectWindows.h"
32#include "../../../../commands/AudacityCommand.h"
34#include "../../../ui/SelectHandle.h"
35#include "../../../ui/TextEditHelper.h"
41#include "../../../../ProjectSettings.h"
43#include "../../../../RefreshCode.h"
45#include "../../../../../images/Cursors.h"
46#include "../../../../HitTestResult.h"
47#include "../../../../TrackPanel.h"
50#include "../WaveTrackUtils.h"
76 S.StartMultiColumn(2, wxALIGN_CENTER);
87{
XO(
"Set Wave Clip Name") };
97 const std::shared_ptr<WaveTrack> pTrack)
127 static auto ibeamCursor =
130 XO(
"Click and drag to select text"),
155 , mClipNameFont{ wxFontInfo{} }
157 if (
auto trackList = pTrack->GetOwner())
161 if(
auto project = trackList->GetOwner())
165 viewInfo.selectedRegion.Subscribe(
174 std::vector<UIHandlePtr> results;
176 const auto px = state.
state.m_x;
177 const auto py = state.
state.m_y;
178 const wxPoint mousePoint { px, py };
180 const auto rect = state.
rect;
182 auto track = std::static_pointer_cast<WaveTrack>(
FindTrack());
184 assert(track->IsLeader());
194 results.push_back(handle);
202 std::make_shared<WaveClipTitleEditHandle>(
208 const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
210 const auto intervals = waveTrack->Intervals();
211 for(
auto it = intervals.begin(); it != intervals.end(); ++it)
216 const auto clip = (*it)->GetClip(0);
217 if (LowlitClipButton::HitTest<ClipButtonId::Overflow>(
218 { *clip, zoomInfo, rect }, mousePoint))
222 track, *it, weak_from_this())));
226 else if (LowlitClipButton::HitTest<ClipButtonId::Pitch>(
227 { *clip, zoomInfo, rect }, mousePoint))
231 std::make_shared<ClipPitchAndSpeedButtonHandle>(
236 else if (LowlitClipButton::HitTest<ClipButtonId::Speed>(
237 { *clip, zoomInfo, rect }, mousePoint))
241 std::make_shared<ClipPitchAndSpeedButtonHandle>(
247 *clip, zoomInfo, state.
rect, mousePoint))
251 std::make_shared<WaveTrackAffordanceHandle>(track, clip)));
258 const auto currentTool =
settings.GetTool();
282 const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
283 const auto& zoomInfo = *artist->pZoomInfo;
285 wxDCClipper dcClipper(context.
dc, rect);
287 context.
dc.SetTextBackground(wxTransparentColor);
295 const auto intervals = waveTrack->Intervals();
296 for(
auto it = intervals.begin(); it != intervals.end(); ++it)
299 const auto& clip = *interval->GetClip(0);
301 clip, zoomInfo, rect);
310 const auto highlightAffordance =
311 !overflowHandle && (selected || clipRect.Contains(px, py));
313 context.
dc, clipRect, highlightAffordance, selected);
316 const auto overflowButtonRect =
317 LowlitClipButton::DrawOnClip<ClipButtonId::Overflow>(
318 { clip, zoomInfo, rect }, context.
dc))
319 affordanceRect.width -= overflowButtonRect->width;
321 const auto speedButtonRect =
322 LowlitClipButton::DrawOnClip<ClipButtonId::Speed>(
323 { clip, zoomInfo, rect }, context.
dc))
324 affordanceRect.width -= speedButtonRect->width;
326 const auto pitchButtonRect =
327 LowlitClipButton::DrawOnClip<ClipButtonId::Pitch>(
328 { clip, zoomInfo, rect }, context.
dc))
329 affordanceRect.width -= pitchButtonRect->width;
337 context.
dc, affordanceRect, interval->GetName());
341 context.
dc, affordanceRect, interval->GetName()))
351 return std::find(mVisibleIntervals.begin(),
352 mVisibleIntervals.end(),
353 it) != mVisibleIntervals.end();
358 bool useDialog{
false };
359 gPrefs->
Read(
wxT(
"/GUI/DialogForNameNewLabel"), &useDialog,
false);
368 auto oldName = interval->GetName();
371 if (result &&
Command.mName != oldName)
373 interval->SetName(
Command.mName);
375 XO(
"Clip Name Edit"));
407 auto pAffordance = view.GetAffordanceControls();
408 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
422 std::dynamic_pointer_cast<WaveTrack>(track->shared_from_this()))
426 auto intervals = pWaveTrack->Intervals();
428 auto it = std::find_if(
429 intervals.begin(), intervals.end(), [&](
const auto& interval) {
431 return interval->Start() == viewInfo.selectedRegion.t0() &&
432 interval->End() == viewInfo.selectedRegion.t1();
434 return interval->Start() <= viewInfo.selectedRegion.t0() &&
435 interval->End() > viewInfo.selectedRegion.t0();
438 if(it != intervals.end())
439 return { pWaveTrack, it };
465 auto interval = *result.second;
466 return interval !=
nullptr && interval->HasPitchOrSpeed();
477 || !
mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
486 auto keyCode =
event.GetKeyCode();
515 if (text != interval->GetName()) {
516 interval->SetName(text);
519 XO(
"Clip Name Edit"));
561 if (
auto trackList =
FindTrack()->GetOwner())
619 if (!affordanceRect.Contains(event.
event.GetPosition()))
625 if (event.
event.LeftDClick())
628 if (affordanceRect.Contains(event.
event.GetPosition()) &&
631 event.event.Skip(
false);
650 constexpr auto wholeInterval =
false;
674 if (!interval || !interval->HasPitchOrSpeed())
679 track->ApplyPitchAndSpeed(
680 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
686 XO(
"Rendered time-stretched audio"),
XO(
"Render"));
693 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text,
mClipNameFont);
695 helper->SetTextSelectionColor(
theTheme.
Colour(clrClipNameTextSelection));
700 const wxRect &rect,
const wxPoint *pPosition,
AudacityProject *pProject)
701 -> std::vector<MenuItem>
720 pAffordance->StartEditSelectedClipName(
project);
736 pAffordance->StartEditSelectedClipSpeed(
project);
749 pAffordance->OnRenderClipStretching(
project);
759 const auto interval = *it;
760 if (interval->SetCentShift(interval->GetCentShift() + (up ? 100 : -100)))
763 XO(
"Pitch Shift"),
XO(
"Changed Pitch Shift"),
782 Command( L
"RenameClip",
XXO(
"&Rename Clip..."),
784 wxT(
"Edit/Other/Clip")
791 wxT(
"Edit/Other/Clip")
795 Command( L
"RenderPitchAndSpeed",
XXO(
"Render Pitch and &Speed"),
797 wxT(
"Edit/Other/Clip")
803 wxT(
"Edit/Other/Clip")
809 wxT(
"Edit/Other/Clip")
Toolkit-neutral facade for basic user interface services.
AttachedItem sAttachment3
AttachedItem sAttachment2
constexpr CommandFlag AlwaysEnabledFlag
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
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 ...
std::function< void(double)> ProgressReporter
static Settings & settings()
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)
An AudacityException with no visible message.
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...
static ChannelView & Get(Channel &channel)
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
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,...
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.
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.
static bool IsGoodEditKeyCode(int keyCode)
wxColour & Colour(int iIndex)
static TrackArtist * Get(TrackPanelDrawingContext &)
static TrackPanel & Get(AudacityProject &project)
void RefreshTrack(Track *trk, bool refreshbacking=true)
Short-lived drawing and event-handling object associated with a TrackPanelCell.
static ViewInfo & Get(AudacityProject &project)
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
~WaveClipTitleEditHandle()
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
unsigned ExitTextEditing()
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
IntervalIterator mFocusInterval
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
IntervalIterator mEditedInterval
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.
virtual bool Read(const wxString &key, bool *value) const =0
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Namespace containing an enum 'what to do on a refresh?'.
AUDACITY_DLL_API bool DrawClipTitle(wxDC &dc, const wxRect &affordanceRect, const wxString &title)
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
AUDACITY_DLL_API wxRect DrawClipAffordance(wxDC &dc, const wxRect &clipRect, bool highlight=false, bool selected=false)
void SelectClip(AudacityProject &project, const WaveTrack::Interval &clip)
std::vector< CommonTrackPanelCell::MenuItem > GetWaveClipMenuItems()
WAVE_TRACK_API void WithClipRenderingProgress(std::function< void(const ProgressReporter &)> action, TranslatableString title=defaultStretchRenderingTitle, TranslatableString message=XO("Rendering Clip"))
void OnRenderClipStretching(const CommandContext &context)
void OnPitchDown(const CommandContext &context)
const ReservedCommandFlag & StretchedClipIsSelectedFlag()
void OnPitchUp(const CommandContext &context)
void OnPitchShift(const CommandContext &context, bool up)
const ReservedCommandFlag & SomeClipIsSelectedFlag()
void OnEditClipName(const CommandContext &context)
auto FindAffordance(WaveTrack &track)
AttachedItem sAttachment4
std::pair< std::shared_ptr< WaveTrack >, ChannelGroup::IntervalIterator< WaveTrack::Interval > > SelectedIntervalOfFocusedTrack(AudacityProject &project, bool wholeInterval=true)
AttachedItem sAttachment5
void OnChangePitchAndSpeed(const CommandContext &context)
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.
@ SELECTION_CHANGE
Posted when the set of selected tracks changes.