15#include <wx/splitter.h>
16#include <wx/statbmp.h>
17#include <wx/stattext.h>
19#include <wx/wupdlock.h>
20#include <wx/hyperlink.h>
22#include <wx/dcbuffer.h>
53#if wxUSE_ACCESSIBILITY
63 wxMenu* mMenuPtr {
nullptr };
64 int mMenuItemIdCounter { wxID_HIGHEST };
66 int mMenuLevelCounter { 0 };
70 : mMenu(menu), mMenuPtr(&mMenu) { }
77 if (mMenuLevelCounter != 0)
79 auto submenu = std::make_unique<wxMenu>();
80 mMenuPtr->AppendSubMenu(submenu.get(), menuItem->GetTitle().Translation());
81 mMenuPtr = submenu.release();
92 if (mMenuLevelCounter != 0)
94 assert(mMenuPtr->GetParent() !=
nullptr);
95 mMenuPtr = mMenuPtr->GetParent();
104 mMenuPtr->Append(mMenuItemIdCounter, commandItem->label_in.Translation());
105 mIndexedPluginList.push_back(commandItem->name);
106 ++mMenuItemIdCounter;
112 mMenuPtr->AppendSeparator();
117 assert(menuIndex >= wxID_HIGHEST && menuIndex < (wxID_HIGHEST + mIndexedPluginList.size()));
118 return mIndexedPluginList[menuIndex - wxID_HIGHEST];
123 template <
typename Visitor>
130 [visitor](
auto& effectState,
bool)
140 track, [&](
auto& ui) { ui.UpdateTrackData(track); });
157 class RealtimeEffectControl;
164 const wxPoint& pos = wxDefaultPosition,
165 const wxSize&
size = wxDefaultSize)
166 : wxWindow(parent,
id, pos,
size, wxNO_BORDER, wxEmptyString)
168 wxWindow::SetBackgroundStyle(wxBG_STYLE_PAINT);
169 Bind(wxEVT_PAINT, &DropHintLine::OnPaint,
this);
177 wxBufferedPaintDC dc(
this);
178 const auto rect = wxRect(GetSize());
180 dc.SetPen(*wxTRANSPARENT_PEN);
181 dc.SetBrush(GetBackgroundColour());
182 dc.DrawRectangle(rect);
191 const wxString&
label,
193 const wxPoint& pos = wxDefaultPosition,
194 const wxSize&
size = wxDefaultSize,
195 long style = wxHL_DEFAULT_STYLE,
196 const wxString&
name = wxHyperlinkCtrlNameStr)
203 const wxString&
label,
205 const wxPoint& pos = wxDefaultPosition,
206 const wxSize&
size = wxDefaultSize,
207 long style = wxHL_DEFAULT_STYLE,
208 const wxString&
name = wxHyperlinkCtrlNameStr)
211 Bind(wxEVT_PAINT, &HyperLinkCtrlWrapper::OnPaint,
this);
217 dc.SetFont(GetFont());
218 dc.SetTextForeground(GetForegroundColour());
219 dc.SetTextBackground(GetBackgroundColour());
221 auto labelRect = GetLabelRect();
223 dc.DrawText(GetLabel(), labelRect.GetTopLeft());
229#if wxUSE_ACCESSIBILITY
230 class RealtimeEffectControlAx :
public wxAccessible
233 RealtimeEffectControlAx(wxWindow* win =
nullptr) : wxAccessible(win) { }
235 wxAccStatus GetName(
int childId, wxString*
name)
override
237 if(childId != wxACC_SELF)
238 return wxACC_NOT_IMPLEMENTED;
242 *
name = wxString::Format(
_(
"Effect %d"), movable->FindIndexInParent() + 1);
246 wxAccStatus GetChildCount(
int* childCount)
override
248 const auto window = GetWindow();
249 *childCount = window->GetChildren().size();
253 wxAccStatus GetChild(
int childId, wxAccessible** child)
override
255 if(childId == wxACC_SELF)
259 const auto window = GetWindow();
260 const auto& children = window->GetChildren();
261 const auto childIndex = childId - 1;
262 if(childIndex < children.size())
263 *child = children[childIndex]->GetAccessible();
270 wxAccStatus GetRole(
int childId, wxAccRole* role)
override
272 if(childId != wxACC_SELF)
273 return wxACC_NOT_IMPLEMENTED;
275 *role = wxROLE_SYSTEM_PANE;
279 wxAccStatus GetState(
int childId,
long* state)
override
281 if(childId != wxACC_SELF)
282 return wxACC_NOT_IMPLEMENTED;
284 const auto window = GetWindow();
285 if(!window->IsEnabled())
286 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
289 *state = wxACC_STATE_SYSTEM_FOCUSABLE;
290 if(window->HasFocus())
291 *state |= wxACC_STATE_SYSTEM_FOCUSED;
301 virtual std::optional<wxString>
PickEffect(wxWindow* parent,
const wxString& selectedEffectID) = 0;
326 const wxPoint& pos = wxDefaultPosition,
327 const wxSize&
size = wxDefaultSize)
329 Create(parent, effectPicker, winid, pos,
size);
335 const wxPoint& pos = wxDefaultPosition,
336 const wxSize&
size = wxDefaultSize)
338 mEffectPicker = effectPicker;
341 MovableControl::SetBackgroundStyle(wxBG_STYLE_PAINT);
344 Bind(wxEVT_PAINT, &RealtimeEffectControl::OnPaint,
this);
345 Bind(wxEVT_SET_FOCUS, &RealtimeEffectControl::OnFocusChange,
this);
346 Bind(wxEVT_KILL_FOCUS, &RealtimeEffectControl::OnFocusChange,
this);
348 auto sizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
352 enableButton->SetTranslatableLabel(
XO(
"Power"));
353 enableButton->SetImageIndices(0, bmpEffectOff, bmpEffectOff, bmpEffectOn, bmpEffectOn, bmpEffectOff);
354 enableButton->SetButtonToggles(
true);
355 enableButton->SetBackgroundColorIndex(clrEffectListItemBackground);
356 mEnableButton = enableButton;
358 enableButton->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
360 mEffectState->SetActive(mEnableButton->IsDown());
365 optionsButton->SetImageIndices(0,
371 optionsButton->SetBackgroundColorIndex(clrEffectListItemBackground);
372 optionsButton->SetForegroundColorIndex(clrTrackPanelText);
374 optionsButton->Bind(wxEVT_BUTTON, &RealtimeEffectControl::OnOptionsClicked,
this);
378 changeButton->SetImageIndices(0, bmpMoreNormal, bmpMoreHover, bmpMoreDown, bmpMoreHover, bmpMoreDisabled);
379 changeButton->SetBackgroundColorIndex(clrEffectListItemBackground);
380 changeButton->SetTranslatableLabel(
XO(
"Replace effect"));
381 changeButton->Bind(wxEVT_BUTTON, &RealtimeEffectControl::OnChangeButtonClicked,
this);
385 sizer->Add(dragArea, 0, wxLEFT | wxCENTER, 5);
386 sizer->Add(enableButton, 0, wxLEFT | wxCENTER, 5);
387 sizer->Add(optionsButton, 1, wxLEFT | wxCENTER, 5);
388 sizer->Add(changeButton, 0, wxLEFT | wxRIGHT | wxCENTER, 5);
389 mChangeButton = changeButton;
390 mOptionsButton = optionsButton;
392 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
393 vSizer->Add(sizer.release(), 0, wxUP | wxDOWN | wxEXPAND, 10);
395 SetSizer(vSizer.release());
397#if wxUSE_ACCESSIBILITY
398 SetAccessible(
safenew RealtimeEffectControlAx(
this));
410 const auto &ID = mEffectState->GetID();
411 const auto desc = GetPlugin(ID);
413 ?
desc->GetSymbol().Msgid()
419 const std::shared_ptr<SampleTrack>& track,
420 const std::shared_ptr<RealtimeEffectState> &pState)
424 mEffectState = pState;
428 ? mEnableButton->PushDown()
429 : mEnableButton->PopUp();
437 label = GetEffectName();
438 mSettingsAccess = pState->GetAccess();
441 mSettingsAccess.reset();
443 mSettingsAccess && mSettingsAccess->Get().extra.GetActive()
444 ? mEnableButton->PushDown()
445 : mEnableButton->PopUp();
448 mOptionsButton->SetTranslatableLabel(
label);
449 mOptionsButton->SetEnabled(pState && GetPlugin(pState->GetID()));
455 if(mProject ==
nullptr || mEffectState ==
nullptr)
462 auto effectName = GetEffectName();
465 auto trackName = mTrack->GetName();
473 XO(
"Removed %s from %s").
Format(effectName, trackName),
482 if(mProject ==
nullptr || mEffectState ==
nullptr)
485 const auto ID = mEffectState->GetID();
488 if(effectPlugin ==
nullptr)
496 effectStateUI.UpdateTrackData(*mTrack);
497 effectStateUI.Toggle( *mProject );
502 if(!mTrack || mProject ==
nullptr)
504 if(mEffectState ==
nullptr)
507 const auto effectID = mEffectPicker->PickEffect(mChangeButton, mEffectState->GetID());
511 if(effectID->empty())
518 auto oIndex = em.FindState(&*mTrack, mEffectState);
522 auto oldName = GetEffectName();
524 auto trackName = mTrack->GetName();
526 ->ReplaceState(
project, &*mTrack, *oIndex, *effectID)
530 auto effect = state->GetEffect();
536 XO(
"Replaced %s with %s")
537 .
Format(oldName, effect->GetName()),
546 wxBufferedPaintDC dc(
this);
547 const auto rect = wxRect(GetSize());
549 dc.SetPen(*wxTRANSPARENT_PEN);
550 dc.SetBrush(GetBackgroundColour());
551 dc.DrawRectangle(rect);
555 dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight());
571 return XO(
"Unknown").Translation();
578 :
public wxScrolledWindow
579 ,
public RealtimeEffectPicker
596 wxWindowID winid = wxID_ANY,
597 const wxPoint& pos = wxDefaultPosition,
598 const wxSize&
size = wxDefaultSize,
599 long style = wxScrolledWindowStyle,
600 const wxString&
name = wxPanelNameStr)
601 : wxScrolledWindow(parent, winid, pos,
size, style,
name)
606 wxScrolledWindow::SetDoubleBuffered(
true);
608 auto rootSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
611 effectListContainer->SetBackgroundColorIndex(clrMedium);
612 effectListContainer->SetSizer(
safenew wxBoxSizer(wxVERTICAL));
613 effectListContainer->SetDoubleBuffered(
true);
614 effectListContainer->Hide();
618 addEffect->SetImageIndices(0,
624 addEffect->SetTranslatableLabel(
XO(
"Add effect"));
626 addEffect->SetBackgroundColorIndex(clrMedium);
627 addEffect->SetForegroundColorIndex(clrTrackPanelText);
633 addEffectHint->SetForegroundColorIndex(clrTrackPanelText);
637 this, wxID_ANY,
_(
"Watch video"),
638 "https://www.audacityteam.org/realtime-video", wxDefaultPosition,
639 wxDefaultSize, wxHL_ALIGN_LEFT | wxHL_CONTEXTMENU);
642 addEffectTutorialLink->SetTranslatableLabel(
XO(
"Watch video"));
643#if wxUSE_ACCESSIBILITY
647 addEffectTutorialLink->Bind(
648 wxEVT_HYPERLINK, [](wxHyperlinkEvent& event)
655 dropHintLine->SetBackgroundColorIndex(clrDropHintHighlight);
656 dropHintLine->Hide();
659 rootSizer->Add(addEffect, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 20);
660 rootSizer->Add(addEffectHint, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 20);
661 rootSizer->Add(addEffectTutorialLink, 0, wxLEFT | wxRIGHT | wxEXPAND, 20);
663 SetSizer(rootSizer.release());
668 if(
auto window =
dynamic_cast<wxWindow*
>(event.GetEventObject()))
671 Bind(EVT_MOVABLE_CONTROL_DRAG_POSITION, [
this, dropHintLine](
const MovableControlEvent& event)
673 constexpr auto DropHintLineHeight { 3 };
676 assert(sizer !=
nullptr);
678 if(event.GetSourceIndex() == event.GetTargetIndex())
681 dropHintLine->Hide();
685 if(!dropHintLine->IsShown())
687 dropHintLine->Show();
688 dropHintLine->Raise();
689 if(
auto window =
dynamic_cast<wxWindow*
>(event.GetEventObject()))
693 auto item = sizer->GetItem(event.GetTargetIndex());
694 dropHintLine->SetSize(item->GetSize().x, DropHintLineHeight);
696 if(event.GetTargetIndex() > event.GetSourceIndex())
697 dropHintLine->SetPosition(item->GetRect().GetBottomLeft() - wxPoint(0, DropHintLineHeight));
699 dropHintLine->SetPosition(item->GetRect().GetTopLeft());
701 Bind(EVT_MOVABLE_CONTROL_DRAG_FINISHED, [
this, dropHintLine](
const MovableControlEvent& event)
703 dropHintLine->Hide();
709 const auto from =
event.GetSourceIndex();
710 const auto to =
event.GetTargetIndex();
714 effectList.GetStateAt(from)->GetEffect()->GetName();
715 bool up = (to < from);
716 effectList.MoveEffect(from, to);
723 ?
XO(
"Moved %s up in %s")
728 :
XO(
"Moved %s down in %s"))
734 wxWindowUpdateLocker freeze(
this);
738 SetScrollRate(0, 20);
753 std::optional<wxString>
PickEffect(wxWindow* parent,
const wxString& selectedEffectID)
override
756 if(!selectedEffectID.empty())
759 menu.Append(wxID_REMOVE,
_(
"No Effect"));
760 menu.AppendSeparator();
763 RealtimeEffectsMenuVisitor visitor { menu };
767 int commandId = wxID_NONE;
769 menu.AppendSeparator();
770 menu.Append(wxID_MORE,
_(
"Get more effects..."));
772 menu.Bind(wxEVT_MENU, [&](wxCommandEvent evt) { commandId = evt.GetId(); });
774 if(parent->PopupMenu(&menu, parent->GetClientRect().GetLeftBottom()) && commandId != wxID_NONE)
776 if(commandId == wxID_REMOVE)
778 else if(commandId == wxID_MORE)
781 return visitor.GetPluginID(commandId).GET();
794 return desc.IsEffectRealtime();
801 static_cast<MenuItem*
>(analyzeSection->begin()->get());
805 {}, groupby,
nullptr,
806 realtimeEffectPredicate
809 if(!submenu->empty())
811 root->push_back(move(analyzeSection));
817 {}, groupby,
nullptr,
818 realtimeEffectPredicate
833 mAddEffectHint->SetLabel(
_(
"Realtime effects are non-destructive and can be changed at any time."));
834 mAddEffectHint->Wrap(GetClientSize().x - sizerItem->GetBorder() * 2);
843 const auto insertItem = [
this, &msg](){
849 const auto removeItem = [&](){
855 auto window = sizer->GetItem(msg.
srcIndex)->GetWindow();
857 wxTheApp->CallAfter([ref = wxWeakRef { window }] {
858 if(ref) ref->Destroy();
872 wxWindowUpdateLocker freeze(
this);
877 const auto movedItem = sizer->GetItem(msg.
srcIndex);
879 const auto proportion = movedItem->GetProportion();
880 const auto flag = movedItem->GetFlag();
881 const auto border = movedItem->GetBorder();
882 const auto window = movedItem->GetWindow();
885 window->MoveAfterInTabOrder(sizer->GetItem(msg.
dstIndex)->GetWindow());
887 window->MoveBeforeInTabOrder(sizer->GetItem(msg.
dstIndex)->GetWindow());
890 sizer->Insert(msg.
dstIndex, window, proportion,
flag, border);
908 SendSizeEventToParent();
921 const std::shared_ptr<SampleTrack>& track)
950 wxWindowUpdateLocker freeze(
this);
965 isEmpty = effects.GetStatesCount() == 0;
966 for(
size_t i = 0, count = effects.GetStatesCount(); i < count; ++i)
976 SendSizeEventToParent();
984 const auto effectID =
PickEffect(
dynamic_cast<wxWindow*
>(event.GetEventObject()), {});
986 if(!effectID || effectID->empty())
995 XO(
"This plugin could not be loaded.\nIt may have been deleted."),
997 .Caption(
XO(
"Plugin Error")));
1004 auto effect = state->GetEffect();
1006 const auto effectName = effect->GetName();
1019 const std::shared_ptr<RealtimeEffectState> &pState)
1029 row->SetBackgroundColorIndex(clrEffectListItemBackground);
1047 for (
auto waveTrack : trackList.Any<
WaveTrack>())
1053AttachedWindows::RegisteredFactory
sKey{
1055 constexpr auto EffectsPanelMinWidth { 255 };
1059 project, pProjectWindow->GetContainerWindow(), wxID_ANY);
1060 effectsPanel->SetMinSize({EffectsPanelMinWidth, -1});
1061 effectsPanel->SetName(
_(
"Realtime effects"));
1062 effectsPanel->SetBackgroundColorIndex(clrMedium);
1063 effectsPanel->Hide();
1064 return effectsPanel;
1083 long style,
const wxString&
name)
1084 : wxPanel(parent,
id, pos,
size, style,
name)
1088 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1091#if wxUSE_ACCESSIBILITY
1094 header->SetBackgroundColorIndex(clrMedium);
1096 auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
1098 toggleEffects->SetImageIndices(0, bmpEffectOff, bmpEffectOff, bmpEffectOn, bmpEffectOn, bmpEffectOff);
1099 toggleEffects->SetButtonToggles(
true);
1100 toggleEffects->SetTranslatableLabel(
XO(
"Power"));
1101 toggleEffects->SetBackgroundColorIndex(clrMedium);
1104 toggleEffects->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
1113 hSizer->Add(toggleEffects, 0, wxSTRETCH_NOT | wxALIGN_CENTER | wxLEFT, 5);
1115 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1118 headerText->SetFont(wxFont(wxFontInfo().Bold()));
1119 headerText->SetTranslatableLabel(
XO(
"Realtime Effects"));
1120 headerText->SetForegroundColorIndex(clrTrackPanelText);
1123 trackTitle->SetForegroundColorIndex(clrTrackPanelText);
1126 vSizer->Add(headerText);
1127 vSizer->Add(trackTitle);
1129 hSizer->Add(vSizer.release(), 1, wxEXPAND | wxALL, 10);
1132 close->SetTranslatableLabel(
XO(
"Close"));
1133 close->SetImageIndices(0, bmpCloseNormal, bmpCloseHover, bmpCloseDown, bmpCloseHover, bmpCloseDisabled);
1134 close->SetBackgroundColorIndex(clrMedium);
1136 close->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) { Close(); });
1138 hSizer->Add(close, 0, wxSTRETCH_NOT | wxALIGN_CENTER | wxRIGHT, 5);
1140 header->SetSizer(hSizer.release());
1142 vSizer->Add(header, 0, wxEXPAND);
1145 effectList->SetBackgroundColorIndex(clrMedium);
1146 vSizer->Add(effectList, 1, wxEXPAND);
1151 SetSizerAndFit(vSizer.release());
1155 auto track = evt.
mpTrack.lock();
1156 auto waveTrack = std::dynamic_pointer_cast<WaveTrack>(track);
1158 if (waveTrack ==
nullptr)
1187 message.
type == UndoRedoMessage::Type::Purge ||
1188 message.
type == UndoRedoMessage::Type::BeginPurge ||
1189 message.
type == UndoRedoMessage::Type::EndPurge)
1198 message.
type == UndoRedoMessage::Type::UndoOrRedo ||
1199 message.
type == UndoRedoMessage::Type::Reset)
1201 for (auto waveTrack : waveTracks)
1202 UpdateRealtimeEffectUIData(*waveTrack);
1213 std::vector<RealtimeEffectStateUI*> shownUIs;
1218 assert(track !=
nullptr);
1222 [&shownUIs](
auto& ui)
1225 shownUIs.push_back(&ui);
1231 for (
auto effectUI : shownUIs)
1233 bool reachable =
false;
1235 for (
auto track : waveTracks)
1239 [effectUI, &reachable](
auto& ui)
1241 if (effectUI == &ui)
1266 Bind(wxEVT_CLOSE_WINDOW, [
this](wxCloseEvent&) {
1276 if(track ==
nullptr)
1282 wxWindowUpdateLocker freeze(
this);
1287 const auto pContainerWindow = projectWindow.GetContainerWindow();
1288 if (pContainerWindow->GetWindow1() !=
this)
1291 pContainerWindow->SplitVertically(
1293 projectWindow.GetTrackListWindow(),
1294 this->GetSize().GetWidth());
1298 projectWindow.Layout();
1303 wxWindowUpdateLocker freeze(
this);
1306 const auto pContainerWindow = projectWindow.GetContainerWindow();
1307 const auto pTrackListWindow = projectWindow.GetTrackListWindow();
1308 if (pContainerWindow->GetWindow2() ==
nullptr)
1311 pContainerWindow->SplitVertically(
this, pTrackListWindow);
1313 pContainerWindow->Unsplit(
this);
1314 pTrackListWindow->SetFocus();
1315 projectWindow.Layout();
1321 if(track &&
dynamic_cast<WaveTrack*
>(&*track) !=
nullptr)
1332 mHeader->SetName(wxString::Format(
_(
"Realtime effects for %s"), track->GetName()));
1344 mHeader->SetName(wxEmptyString);
1354 if(evt.GetKeyCode() == WXK_ESCAPE && IsShown() && IsDescendant(
FindFocus()))
Toolkit-neutral facade for basic user interface services.
const TranslatableString name
ChoiceSetting RealtimeEffectsGroupBy
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
RealtimeEffectStateChange
for(int ii=0, nn=names.size();ii< nn;++ii)
static void DrawFocus(wxDC &dc, wxRect &r)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
void RemoveState(AudacityProject &project, ChannelGroup *pGroup, std::shared_ptr< RealtimeEffectState > pState)
Forwards to RealtimeEffectManager::RemoveState with proper init scope.
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
EffectPlugin * GetEffect(const PluginID &ID)
static EffectManager & Get()
An explicitly nonlocalized string, not meant for the user to see.
Changes default arrow navigation to behave more list- or table-like. Instead of searching focusable i...
void Create(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxString &name=wxPanelNameStr)
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
A move-only handle representing a connection to a Publisher.
void Reset() noexcept
Breaks the connection (constant time)
const wxString & GetVendor() const
static Identifier GetEffectNameFromID(const PluginID &ID)
static bool IsPluginAvailable(const PluginDescriptor &plug)
const PluginDescriptor * GetPlugin(const PluginID &ID) const
static PluginManager & Get()
A listener notified of changes in preferences.
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
static RealtimeEffectList & Get(AudacityProject &project)
size_t GetStatesCount() const noexcept
bool IsActive() const
Non-blocking atomic boolean load.
void SetActive(bool value)
Done by main thread only, under a lock guard.
void OnEffectListItemChange(const RealtimeEffectListMessage &msg)
void UpdatePrefs() override
RealtimeEffectListWindow(wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxScrolledWindowStyle, const wxString &name=wxPanelNameStr)
void OnAddEffectClicked(const wxCommandEvent &event)
wxStaticText * mAddEffectHint
void EnableEffects(bool enable)
void OnSizeChanged(wxSizeEvent &event)
wxWindow * mEffectListContainer
std::unique_ptr< MenuTable::MenuItem > mEffectMenuRoot
void UpdateEffectMenuItems()
std::shared_ptr< SampleTrack > mTrack
std::optional< wxString > PickEffect(wxWindow *parent, const wxString &selectedEffectID) override
void SetTrack(AudacityProject &project, const std::shared_ptr< SampleTrack > &track)
Observer::Subscription mEffectListItemMovedSubscription
void InsertEffectRow(size_t index, const std::shared_ptr< RealtimeEffectState > &pState)
Observer::Subscription mPluginsChangedSubscription
wxWindow * mAddEffectTutorialLink
wxWeakRef< AudacityProject > mProject
static RealtimeEffectManager & Get(AudacityProject &project)
UI Panel that displays realtime effects from the effect stack of an individual track,...
Observer::Subscription mUndoSubscription
wxStaticText * mTrackTitle
void ShowPanel(SampleTrack *track, bool focus)
RealtimeEffectListWindow * mEffectList
void OnCharHook(wxKeyEvent &evt)
std::weak_ptr< SampleTrack > mCurrentTrack
static RealtimeEffectPanel & Get(AudacityProject &project)
~RealtimeEffectPanel() override
std::vector< std::shared_ptr< SampleTrack > > mPotentiallyRemovedTracks
RealtimeEffectPanel(AudacityProject &project, wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxString &name=wxPanelNameStr)
Observer::Subscription mFocusChangeSubscription
AudacityProject & mProject
Observer::Subscription mTrackListChanged
void SetTrack(const std::shared_ptr< SampleTrack > &track)
Shows effects from the effect stack of the track.
static RealtimeEffectStateUI & Get(RealtimeEffectState &state)
std::vector< Identifier > Path
bool IsLeader() const override
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
std::shared_ptr< Subclass > SharedPointer()
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
static UndoManager & Get(AudacityProject &project)
A Track that contains audio waveform data.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
DropHintLine(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
bool AcceptsFocus() const override
void OnPaint(wxPaintEvent &)
void Create(wxWindow *parent, wxWindowID id, const wxString &label, const wxString &url, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxHL_DEFAULT_STYLE, const wxString &name=wxHyperlinkCtrlNameStr)
void OnPaint(wxPaintEvent &evt)
HyperLinkCtrlWrapper(wxWindow *parent, wxWindowID id, const wxString &label, const wxString &url, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxHL_DEFAULT_STYLE, const wxString &name=wxHyperlinkCtrlNameStr)
RealtimeEffectControl()=default
std::shared_ptr< EffectSettingsAccess > mSettingsAccess
void OnOptionsClicked(wxCommandEvent &event)
Observer::Subscription mSubscription
std::shared_ptr< RealtimeEffectState > mEffectState
void OnFocusChange(wxFocusEvent &evt)
static const PluginDescriptor * GetPlugin(const PluginID &ID)
void Create(wxWindow *parent, RealtimeEffectPicker *effectPicker, wxWindowID winid, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
void OnPaint(wxPaintEvent &)
void SetEffect(AudacityProject &project, const std::shared_ptr< SampleTrack > &track, const std::shared_ptr< RealtimeEffectState > &pState)
void OnChangeButtonClicked(wxCommandEvent &event)
wxWeakRef< AudacityProject > mProject
TranslatableString GetEffectName() const
RealtimeEffectControl(wxWindow *parent, RealtimeEffectPicker *effectPicker, wxWindowID winid, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
std::shared_ptr< SampleTrack > mTrack
virtual std::optional< wxString > PickEffect(wxWindow *parent, const wxString &selectedEffectID)=0
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
void Visit(Visitor &visitor, BaseItem *pTopItem, const GroupItemBase *pRegistry)
const TranslatableString desc
AttachedWindows::RegisteredFactory sKey
void VisitRealtimeEffectStateUIs(SampleTrack &track, Visitor &&visitor)
static wxString GetSafeVendor(const PluginDescriptor &descriptor)
void UpdateRealtimeEffectUIData(SampleTrack &track)
void ReopenRealtimeEffectUIData(AudacityProject &project, SampleTrack &track)
@ Remove
Effect item was removed from the list at srcIndex position. affectedState is removed state.
@ DidReplace
Effect item was replaced with a new item at srcIndex position. affectedState is an old state.
@ Move
Item position has changed, from srcIndex to dstIndex. affectedState is the moved state.
@ Insert
New effect item was added to the list at srcIndex position. affectedState is a new state.
@ WillReplace
Effect item will be replaced with a new item at srcIndex position. affectedState is the state to be r...
std::shared_ptr< RealtimeEffectState > affectedState
void UpdatePrefs() override
PrefsListenerHelper(AudacityProject &project)
AudacityProject & mProject
Common abstract base class for items that group other items.
Common abstract base class for items that are not groups.
Notification of changes in individual tracks of TrackList, or of TrackList's composition.
const std::weak_ptr< Track > mpTrack
@ DELETION
Posted when a track has been deleted from a tracklist. Also posted when one track replaces another.
@ ADDITION
Posted when a track has been added to a tracklist. Also posted when one track replaces another.
@ TRACK_DATA_CHANGE
Posted when certain fields of a track change.
Type of message published by UndoManager.
enum UndoRedoMessage::Type type