22#include "../../../../TrackPanelMouseEvent.h"
23#include "../../../../TrackArt.h"
24#include "../../../../TrackArtist.h"
25#include "../../../../TrackPanelDrawingContext.h"
32#include "../../../../ProjectWindows.h"
33#include "../../../../commands/AudacityCommand.h"
35#include "../../../ui/SelectHandle.h"
36#include "../../../ui/TextEditHelper.h"
42#include "../../../../ProjectSettings.h"
44#include "../../../../RefreshCode.h"
46#include "../../../../../images/Cursors.h"
47#include "../../../../HitTestResult.h"
48#include "../../../../TrackPanel.h"
75 S.StartMultiColumn(2, wxALIGN_CENTER);
86{
XO(
"Set Wave Clip Name") };
96 const std::shared_ptr<WaveTrack> pTrack)
126 static auto ibeamCursor =
129 XO(
"Click and drag to select text"),
154 , mClipNameFont{ wxFontInfo{} }
156 if (
auto trackList = pTrack->GetOwner()) {
157 if (
auto pProject = trackList->GetOwner()) {
160 if(
auto project = trackList->GetOwner())
164 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());
194 results.push_back(handle);
202 std::make_shared<WaveClipTitleEditHandle>(
208 auto &waveTrack =
static_cast<WaveTrack&
>(
211 const auto &intervals = waveTrack.Intervals();
212 for(
auto it = intervals.begin(); it != intervals.end(); ++it)
217 const auto clip = (*it);
218 if (LowlitClipButton::HitTest<ClipButtonId::Overflow>(
219 { *clip, zoomInfo, rect }, mousePoint))
223 track, *it, weak_from_this())));
227 else if (LowlitClipButton::HitTest<ClipButtonId::Pitch>(
228 { *clip, zoomInfo, rect }, mousePoint))
232 std::make_shared<ClipPitchAndSpeedButtonHandle>(
237 else if (LowlitClipButton::HitTest<ClipButtonId::Speed>(
238 { *clip, zoomInfo, rect }, mousePoint))
242 std::make_shared<ClipPitchAndSpeedButtonHandle>(
248 *clip, zoomInfo, state.
rect, mousePoint))
252 std::make_shared<WaveTrackAffordanceHandle>(track, clip)));
259 const auto currentTool =
settings.GetTool();
280 const auto &pendingTracks = *artist->pPendingTracks;
285 rect, **track->Channels().begin(),
286 artist->blankSelectedBrush, artist->blankBrush);
290 auto &waveTrack =
static_cast<WaveTrack&
>(
291 pendingTracks.SubstitutePendingChangedTrack(*track));
292 const auto& zoomInfo = *artist->pZoomInfo;
294 wxDCClipper dcClipper(context.
dc, rect);
296 context.
dc.SetTextBackground(wxTransparentColor);
304 const auto &intervals = waveTrack.Intervals();
305 for(
auto it = intervals.begin(); it != intervals.end(); ++it)
308 const auto& clip = *interval;
310 clip, zoomInfo, rect);
319 const auto highlightAffordance =
320 !overflowHandle && (selected || clipRect.Contains(px, py));
322 context.
dc, clipRect, highlightAffordance, selected);
325 const auto overflowButtonRect =
326 LowlitClipButton::DrawOnClip<ClipButtonId::Overflow>(
327 { clip, zoomInfo, rect }, context.
dc))
328 affordanceRect.width -= overflowButtonRect->width;
330 const auto speedButtonRect =
331 LowlitClipButton::DrawOnClip<ClipButtonId::Speed>(
332 { clip, zoomInfo, rect }, context.
dc))
333 affordanceRect.width -= speedButtonRect->width;
335 const auto pitchButtonRect =
336 LowlitClipButton::DrawOnClip<ClipButtonId::Pitch>(
337 { clip, zoomInfo, rect }, context.
dc))
338 affordanceRect.width -= pitchButtonRect->width;
346 context.
dc, affordanceRect, interval->GetName());
350 context.
dc, affordanceRect, interval->GetName()))
359 return std::find(mVisibleIntervals.begin(),
360 mVisibleIntervals.end(),
361 it) != mVisibleIntervals.end();
366 bool useDialog{
false };
367 gPrefs->
Read(
wxT(
"/GUI/DialogForNameNewLabel"), &useDialog,
false);
376 auto oldName = interval->GetName();
379 if (result &&
Command.mName != oldName)
381 interval->SetName(
Command.mName);
383 XO(
"Clip Name Edit"));
415 auto pAffordance = view.GetAffordanceControls();
416 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
430 std::dynamic_pointer_cast<WaveTrack>(track->shared_from_this()))
434 const auto &intervals = pWaveTrack->Intervals();
436 auto it = std::find_if(
437 intervals.begin(), intervals.end(), [&](
const auto& interval) {
439 return interval->Start() == viewInfo.selectedRegion.t0() &&
440 interval->End() == viewInfo.selectedRegion.t1();
442 return interval->Start() <= viewInfo.selectedRegion.t0() &&
443 interval->End() > viewInfo.selectedRegion.t0();
446 if(it != intervals.end())
447 return { pWaveTrack, it };
473 auto interval = *result.second;
474 return interval !=
nullptr && interval->HasPitchOrSpeed();
485 || !
mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
494 auto keyCode =
event.GetKeyCode();
523 if (text != interval->GetName()) {
524 interval->SetName(text);
527 XO(
"Clip Name Edit"));
569 if (
auto trackList =
FindTrack()->GetOwner())
627 if (!affordanceRect.Contains(event.
event.GetPosition()))
633 if (event.
event.LeftDClick())
636 if (affordanceRect.Contains(event.
event.GetPosition()) &&
639 event.event.Skip(
false);
658 constexpr auto wholeInterval =
false;
682 if (!interval || !interval->HasPitchOrSpeed())
687 track->ApplyPitchAndSpeed(
688 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
694 XO(
"Rendered time-stretched audio"),
XO(
"Render"));
701 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text,
mClipNameFont);
703 helper->SetTextSelectionColor(
theTheme.
Colour(clrClipNameTextSelection));
708 const wxRect &rect,
const wxPoint *pPosition,
AudacityProject *pProject)
709 -> std::vector<MenuItem>
728 pAffordance->StartEditSelectedClipName(
project);
744 pAffordance->StartEditSelectedClipSpeed(
project);
757 pAffordance->OnRenderClipStretching(
project);
767 const auto interval = *it;
768 if (interval->SetCentShift(interval->GetCentShift() + (up ? 100 : -100)))
771 XO(
"Pitch Shift"),
XO(
"Changed Pitch Shift"),
790 Command( L
"RenameClip",
XXO(
"&Rename Clip..."),
792 wxT(
"Edit/Other/Clip")
799 wxT(
"Edit/Other/Clip")
803 Command( L
"RenderPitchAndSpeed",
XXO(
"Render Pitch and &Speed"),
805 wxT(
"Edit/Other/Clip")
811 wxT(
"Edit/Other/Clip")
817 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...
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,...
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
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.
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 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
~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?'.
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)
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
AUDACITY_DLL_API wxRect DrawClipAffordance(wxDC &dc, const wxRect &clipRect, bool highlight=false, bool selected=false)
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
void SelectClip(AudacityProject &project, const WaveTrack::Interval &clip)
std::vector< CommonTrackPanelCell::MenuItem > GetWaveClipMenuItems()
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.