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->clipAffordanceBackgroundSelBrush,
287 artist->clipAffordanceBackgroundBrush,
292 auto &waveTrack =
static_cast<WaveTrack&
>(
293 pendingTracks.SubstitutePendingChangedTrack(*track));
294 const auto& zoomInfo = *artist->pZoomInfo;
296 wxDCClipper dcClipper(context.
dc, rect);
298 context.
dc.SetTextBackground(wxTransparentColor);
306 const auto &intervals = waveTrack.Intervals();
307 for(
auto it = intervals.begin(); it != intervals.end(); ++it)
310 const auto& clip = *interval;
312 clip, zoomInfo, rect);
321 const auto highlightAffordance =
322 !overflowHandle && (selected || clipRect.Contains(px, py));
324 context.
dc, clipRect, highlightAffordance, selected);
327 const auto overflowButtonRect =
328 LowlitClipButton::DrawOnClip<ClipButtonId::Overflow>(
329 { clip, zoomInfo, rect }, context.
dc))
330 affordanceRect.width -= overflowButtonRect->width;
332 const auto speedButtonRect =
333 LowlitClipButton::DrawOnClip<ClipButtonId::Speed>(
334 { clip, zoomInfo, rect }, context.
dc))
335 affordanceRect.width -= speedButtonRect->width;
337 const auto pitchButtonRect =
338 LowlitClipButton::DrawOnClip<ClipButtonId::Pitch>(
339 { clip, zoomInfo, rect }, context.
dc))
340 affordanceRect.width -= pitchButtonRect->width;
348 context.
dc, affordanceRect, interval->GetName());
352 context.
dc, affordanceRect, interval->GetName()))
361 return std::find(mVisibleIntervals.begin(),
362 mVisibleIntervals.end(),
363 it) != mVisibleIntervals.end();
368 bool useDialog{
false };
369 gPrefs->
Read(
wxT(
"/GUI/DialogForNameNewLabel"), &useDialog,
false);
378 auto oldName = interval->GetName();
381 if (result &&
Command.mName != oldName)
383 interval->SetName(
Command.mName);
385 XO(
"Clip Name Edit"));
417 auto pAffordance = view.GetAffordanceControls();
418 return std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
432 std::dynamic_pointer_cast<WaveTrack>(track->shared_from_this()))
436 const auto &intervals = pWaveTrack->Intervals();
438 auto it = std::find_if(
439 intervals.begin(), intervals.end(), [&](
const auto& interval) {
441 return interval->Start() == viewInfo.selectedRegion.t0() &&
442 interval->End() == viewInfo.selectedRegion.t1();
444 return interval->Start() <= viewInfo.selectedRegion.t0() &&
445 interval->End() > viewInfo.selectedRegion.t0();
448 if(it != intervals.end())
449 return { pWaveTrack, it };
475 auto interval = *result.second;
476 return interval !=
nullptr && interval->HasPitchOrSpeed();
487 || !
mTextEditHelper->CaptureKey(event.GetKeyCode(), event.GetModifiers()))
496 auto keyCode =
event.GetKeyCode();
525 if (text != interval->GetName()) {
526 interval->SetName(text);
529 XO(
"Clip Name Edit"));
571 if (
auto trackList =
FindTrack()->GetOwner())
629 if (!affordanceRect.Contains(event.
event.GetPosition()))
635 if (event.
event.LeftDClick())
638 if (affordanceRect.Contains(event.
event.GetPosition()) &&
641 event.event.Skip(
false);
660 constexpr auto wholeInterval =
false;
684 if (!interval || !interval->HasPitchOrSpeed())
689 track->ApplyPitchAndSpeed(
690 { { interval->GetPlayStartTime(), interval->GetPlayEndTime() } },
696 XO(
"Rendered time-stretched audio"),
XO(
"Render"));
703 auto helper = std::make_shared<TextEditHelper>(shared_from_this(), text,
mClipNameFont);
705 helper->SetTextSelectionColor(
theTheme.
Colour(clrClipNameTextSelection));
710 const wxRect &rect,
const wxPoint *pPosition,
AudacityProject *pProject)
711 -> std::vector<MenuItem>
730 pAffordance->StartEditSelectedClipName(
project);
746 pAffordance->StartEditSelectedClipSpeed(
project);
759 pAffordance->OnRenderClipStretching(
project);
769 const auto interval = *it;
770 if (interval->SetCentShift(interval->GetCentShift() + (up ? 100 : -100)))
773 XO(
"Pitch Shift"),
XO(
"Changed Pitch Shift"),
792 Command( L
"RenameClip",
XXO(
"&Rename Clip..."),
794 wxT(
"Edit/Other/Clip")
801 wxT(
"Edit/Other/Clip")
805 Command( L
"RenderPitchAndSpeed",
XXO(
"Render Pitch and &Speed"),
807 wxT(
"Edit/Other/Clip")
813 wxT(
"Edit/Other/Clip")
819 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
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 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.
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)
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.