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
62 wxMenu* mMenuPtr {
nullptr };
63 int mMenuItemIdCounter { wxID_HIGHEST };
65 int mMenuLevelCounter { 0 };
70 if (mMenuLevelCounter != 0)
72 auto submenu = std::make_unique<wxMenu>();
73 mMenuPtr->AppendSubMenu(submenu.get(), menuItem.
GetTitle().Translation());
74 mMenuPtr = submenu.release();
81 mIndexedPluginList.push_back(commandItem.
name);
87 if (mMenuLevelCounter != 0)
89 assert(mMenuPtr->GetParent() !=
nullptr);
90 mMenuPtr = mMenuPtr->GetParent();
95 mMenuPtr->AppendSeparator();
97 , mMenu(menu), mMenuPtr(&mMenu)
102 assert(menuIndex >= wxID_HIGHEST && menuIndex < (wxID_HIGHEST + mIndexedPluginList.size()));
103 return mIndexedPluginList[menuIndex - wxID_HIGHEST];
117 if(!selectedEffectID.empty())
120 menu.Append(wxID_REMOVE,
_(
"No Effect"));
121 menu.AppendSeparator();
128 int commandId = wxID_NONE;
130#if defined(__WXMSW__) || defined(__WXMAC__)
131 menu.AppendSeparator();
132 menu.Append(wxID_MORE,
_(
"Get more effects..."));
134 menu.Bind(wxEVT_MENU, [&](wxCommandEvent evt) { commandId = evt.GetId(); });
136 if(parent->PopupMenu(&menu, parent->GetClientRect().GetLeftBottom()) && commandId != wxID_NONE)
138 if(commandId == wxID_REMOVE)
140 if(commandId == wxID_MORE)
143 return visitor.GetPluginID(commandId).GET();
159 auto cachedMenuItem = GetMenuItem();
179 UpdateEffectMenuItems();
199 return desc.IsEffectRealtime();
206 static_cast<MenuItem*
>(analyzeSection->begin()->get());
210 {}, groupby,
nullptr,
211 realtimeEffectPredicate
214 if(!submenu->empty())
216 root->push_back(move(analyzeSection));
222 {}, groupby,
nullptr,
223 realtimeEffectPredicate
226 mCachedMenu.swap(root);
237 const auto &ID = state.
GetID();
240 ?
desc->GetSymbol().Msgid()
245 template <
typename Visitor>
249 [visitor](
auto& effectState,
bool)
256 template <
typename Visitor>
291 class RealtimeEffectControl;
298 const wxPoint& pos = wxDefaultPosition,
299 const wxSize&
size = wxDefaultSize)
300 : wxWindow(parent,
id, pos,
size, wxNO_BORDER, wxEmptyString)
302 wxWindow::SetBackgroundStyle(wxBG_STYLE_PAINT);
303 Bind(wxEVT_PAINT, &DropHintLine::OnPaint,
this);
311 wxBufferedPaintDC dc(
this);
312 const auto rect = wxRect(GetSize());
314 dc.SetPen(*wxTRANSPARENT_PEN);
315 dc.SetBrush(GetBackgroundColour());
316 dc.DrawRectangle(rect);
325 const wxString&
label,
327 const wxPoint& pos = wxDefaultPosition,
328 const wxSize&
size = wxDefaultSize,
329 long style = wxHL_DEFAULT_STYLE,
330 const wxString&
name = wxHyperlinkCtrlNameStr)
337 const wxString&
label,
339 const wxPoint& pos = wxDefaultPosition,
340 const wxSize&
size = wxDefaultSize,
341 long style = wxHL_DEFAULT_STYLE,
342 const wxString&
name = wxHyperlinkCtrlNameStr)
345 Bind(wxEVT_PAINT, &HyperLinkCtrlWrapper::OnPaint,
this);
351 dc.SetFont(GetFont());
352 dc.SetTextForeground(GetForegroundColour());
353 dc.SetTextBackground(GetBackgroundColour());
355 auto labelRect = GetLabelRect();
357 dc.DrawText(GetLabel(), labelRect.GetTopLeft());
363#if wxUSE_ACCESSIBILITY
364 class RealtimeEffectControlAx :
public wxAccessible
367 RealtimeEffectControlAx(wxWindow* win =
nullptr) : wxAccessible(win) { }
369 wxAccStatus GetName(
int childId, wxString*
name)
override
371 if(childId != wxACC_SELF)
372 return wxACC_NOT_IMPLEMENTED;
376 *
name = wxString::Format(
_(
"Effect %d"), movable->FindIndexInParent() + 1);
380 wxAccStatus GetChildCount(
int* childCount)
override
382 const auto window = GetWindow();
383 *childCount = window->GetChildren().size();
387 wxAccStatus GetChild(
int childId, wxAccessible** child)
override
389 if(childId == wxACC_SELF)
393 const auto window = GetWindow();
394 const auto& children = window->GetChildren();
395 const auto childIndex = childId - 1;
396 if(childIndex < children.size())
397 *child = children[childIndex]->GetAccessible();
404 wxAccStatus GetRole(
int childId, wxAccRole* role)
override
406 if(childId != wxACC_SELF)
407 return wxACC_NOT_IMPLEMENTED;
409 *role = wxROLE_SYSTEM_PANE;
413 wxAccStatus GetState(
int childId,
long* state)
override
415 if(childId != wxACC_SELF)
416 return wxACC_NOT_IMPLEMENTED;
418 const auto window = GetWindow();
419 if(!window->IsEnabled())
420 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
423 *state = wxACC_STATE_SYSTEM_FOCUSABLE;
424 if(window->HasFocus())
425 *state |= wxACC_STATE_SYSTEM_FOCUSED;
462 const wxPoint& pos = wxDefaultPosition,
463 const wxSize&
size = wxDefaultSize)
465 Create(parent, winid, pos,
size);
470 const wxPoint& pos = wxDefaultPosition,
471 const wxSize&
size = wxDefaultSize)
475 MovableControl::SetBackgroundStyle(wxBG_STYLE_PAINT);
478 Bind(wxEVT_PAINT, &RealtimeEffectControl::OnPaint,
this);
479 Bind(wxEVT_SET_FOCUS, &RealtimeEffectControl::OnFocusChange,
this);
480 Bind(wxEVT_KILL_FOCUS, &RealtimeEffectControl::OnFocusChange,
this);
482 auto sizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
486 enableButton->SetTranslatableLabel(
XO(
"Power"));
487 enableButton->SetImageIndices(0, bmpEffectOff, bmpEffectOff, bmpEffectOn, bmpEffectOn, bmpEffectOff);
488 enableButton->SetButtonToggles(
true);
489 enableButton->SetBackgroundColorIndex(clrEffectListItemBackground);
490 mEnableButton = enableButton;
492 enableButton->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
493 if(mDelegate && mEffectState)
495 mEffectState->SetActive(mEnableButton->IsDown());
506 optionsButton->SetImageIndices(0,
512 optionsButton->SetBackgroundColorIndex(clrEffectListItemBackground);
513 optionsButton->SetForegroundColorIndex(clrTrackPanelText);
515 optionsButton->Bind(wxEVT_BUTTON, &RealtimeEffectControl::OnOptionsClicked,
this);
519 changeButton->SetImageIndices(0, bmpMoreNormal, bmpMoreHover, bmpMoreDown, bmpMoreHover, bmpMoreDisabled);
520 changeButton->SetBackgroundColorIndex(clrEffectListItemBackground);
521 changeButton->SetTranslatableLabel(
XO(
"Replace effect"));
522 changeButton->Bind(wxEVT_BUTTON, &RealtimeEffectControl::OnChangeButtonClicked,
this);
526 sizer->Add(dragArea, 0, wxLEFT | wxCENTER, 5);
527 sizer->Add(enableButton, 0, wxLEFT | wxCENTER, 5);
528 sizer->Add(optionsButton, 1, wxLEFT | wxCENTER, 5);
529 sizer->Add(changeButton, 0, wxLEFT | wxRIGHT | wxCENTER, 5);
530 mChangeButton = changeButton;
531 mOptionsButton = optionsButton;
533 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
534 vSizer->Add(sizer.release(), 0, wxUP | wxDOWN | wxEXPAND, 10);
536 SetSizer(vSizer.release());
538 SetInTabOrder(
false);
540#if wxUSE_ACCESSIBILITY
541 SetAccessible(
safenew RealtimeEffectControlAx(
this));
546 const std::shared_ptr<EffectListUIDelegate>& delegate,
547 const std::shared_ptr<RealtimeEffectState> &pState)
550 mDelegate = delegate;
551 mEffectState = pState;
555 ? mEnableButton->PushDown()
556 : mEnableButton->PopUp();
562 mSettingsAccess = pState->GetAccess();
565 mSettingsAccess.reset();
567 mSettingsAccess && mSettingsAccess->Get().extra.GetActive()
568 ? mEnableButton->PushDown()
569 : mEnableButton->PopUp();
572 mOptionsButton->SetTranslatableLabel(
label);
573 mOptionsButton->SetEnabled(pState &&
GetPlugin(pState->GetID()));
579 if(!mDelegate || !mProject || mEffectState ==
nullptr)
595 XO(
"Removed %s from %s").
Format(effectName, mDelegate->GetSourceName()),
604 if(!mDelegate || !mEffectState)
607 const auto ID = mEffectState->GetID();
610 if(effectPlugin ==
nullptr)
620 effectStateUI.SetTargetName(mDelegate->GetSourceName());
621 effectStateUI.Toggle(*mProject);
626 if(!mDelegate || mProject ==
nullptr)
629 if(mEffectState ==
nullptr)
632 const auto effectID = EffectsMenuHelper::PickEffect(
635 mEffectState->GetID()
640 if(effectID->empty())
646 auto oIndex = em.FindState(mDelegate->GetChannelGroup(), mEffectState);
653 ->ReplaceState(
project, mDelegate->GetChannelGroup(), *oIndex, *effectID)
657 auto effect = state->GetEffect();
663 XO(
"Replaced %s with %s")
664 .
Format(oldName, effect->GetName()),
674 wxBufferedPaintDC dc(
this);
675 const auto rect = wxRect(GetSize());
677 dc.SetPen(*wxTRANSPARENT_PEN);
678 dc.SetBrush(GetBackgroundColour());
679 dc.DrawRectangle(rect);
683 dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight());
699 return XO(
"Unknown").Translation();
706 :
public EffectListUIDelegate
734 :
public EffectListUIDelegate
762 :
public wxScrolledWindow
775 wxWindowID winid = wxID_ANY,
776 const wxPoint& pos = wxDefaultPosition,
777 const wxSize&
size = wxDefaultSize,
778 long style = wxScrolledWindowStyle,
779 const wxString&
name = wxPanelNameStr)
784 wxScrolledWindow::SetDoubleBuffered(
true);
786 auto rootSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
789 effectListContainer->SetBackgroundColorIndex(clrMedium);
790 effectListContainer->SetSizer(
safenew wxBoxSizer(wxVERTICAL));
791 effectListContainer->SetDoubleBuffered(
true);
792 effectListContainer->Hide();
796 addEffect->SetImageIndices(0,
802 addEffect->SetTranslatableLabel(
XO(
"Add effect"));
804 addEffect->SetBackgroundColorIndex(clrMedium);
805 addEffect->SetForegroundColorIndex(clrTrackPanelText);
811 dropHintLine->SetBackgroundColorIndex(clrDropHintHighlight);
812 dropHintLine->Hide();
815 rootSizer->Add(addEffect, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 20);
817 SetSizer(rootSizer.release());
822 if(
auto window =
dynamic_cast<wxWindow*
>(event.GetEventObject()))
825 Bind(EVT_MOVABLE_CONTROL_DRAG_POSITION, [
this, dropHintLine](
const MovableControlEvent& event)
827 constexpr auto DropHintLineHeight { 3 };
830 assert(sizer !=
nullptr);
835 dropHintLine->Hide();
839 if(!dropHintLine->IsShown())
841 dropHintLine->Show();
842 dropHintLine->Raise();
843 if(
auto window =
dynamic_cast<wxWindow*
>(event.GetEventObject()))
848 dropHintLine->SetSize(item->GetSize().x, DropHintLineHeight);
851 dropHintLine->SetPosition(item->GetRect().GetBottomLeft() - wxPoint(0, DropHintLineHeight));
853 dropHintLine->SetPosition(item->GetRect().GetTopLeft());
856 Bind(EVT_MOVABLE_CONTROL_DRAG_FINISHED, [
this, dropHintLine](
const MovableControlEvent& event)
858 dropHintLine->Hide();
863 const auto from =
event.GetSourceIndex();
864 const auto to =
event.GetTargetIndex();
867 auto& effectList =
mDelegate->GetEffectList();
869 effectList.GetStateAt(from)->GetEffect()->GetName();
870 bool up = (to < from);
871 effectList.MoveEffect(from, to);
878 ?
XO(
"Moved %s up in %s")
883 :
XO(
"Moved %s down in %s"))
889 wxWindowUpdateLocker freeze(
this);
894 SetScrollRate(0, 20);
895#if defined(__WXMSW__) || defined(__WXMAC__)
911 GetSizer()->Add(
mFooter, 0, wxEXPAND);
919 const auto insertItem = [
this, &msg](){
920 auto& effects =
mDelegate->GetEffectList();
925 const auto removeItem = [&](){
931 auto window = sizer->GetItem(msg.
srcIndex)->GetWindow();
933 wxTheApp->CallAfter([ref = wxWeakRef { window }] {
934 if(ref) ref->Destroy();
948 wxWindowUpdateLocker freeze(
this);
953 const auto movedItem = sizer->GetItem(msg.
srcIndex);
955 const auto proportion = movedItem->GetProportion();
956 const auto flag = movedItem->GetFlag();
957 const auto border = movedItem->GetBorder();
958 const auto window = movedItem->GetWindow();
961 window->MoveAfterInTabOrder(sizer->GetItem(msg.
dstIndex)->GetWindow());
963 window->MoveBeforeInTabOrder(sizer->GetItem(msg.
dstIndex)->GetWindow());
966 sizer->Insert(msg.
dstIndex, window, proportion,
flag, border);
984 SendSizeEventToParent();
1014 mDelegate->GetEffectList().SetActive(enable);
1019 wxWindowUpdateLocker freeze(
this);
1032 auto& effects =
mDelegate->GetEffectList();
1033 isEmpty = effects.GetStatesCount() == 0;
1034 for(
size_t i = 0, count = effects.GetStatesCount(); i < count; ++i)
1044 SendSizeEventToParent();
1052 const auto effectId = EffectsMenuHelper::PickEffect(
1054 dynamic_cast<wxWindow*
>(event.GetEventObject()),
1058 if(!effectId || effectId->empty())
1067 XO(
"This plugin could not be loaded.\nIt may have been deleted."),
1069 .Caption(
XO(
"Plugin Error")));
1076 auto effect = state->GetEffect();
1078 const auto effectName = effect->GetName();
1091 const std::shared_ptr<RealtimeEffectState> &pState)
1101 row->SetBackgroundColorIndex(clrEffectListItemBackground);
1119 for (
auto waveTrack : trackList.Any<
WaveTrack>())
1125AttachedWindows::RegisteredFactory
sKey{
1127 constexpr auto EffectsPanelMinWidth { 255 };
1132 pProjectWindow->GetContainerWindow(),
1136 wxNO_BORDER | wxSP_LIVE_UPDATE | wxSP_THIN_SASH
1138 effectsPanel->SetMinSize({EffectsPanelMinWidth, -1});
1139 effectsPanel->SetName(
_(
"Realtime effects"));
1140 effectsPanel->SetBackgroundColorIndex(clrMedium);
1141 effectsPanel->Hide();
1142 return effectsPanel;
1168 SetSashGravity(1.0);
1176 std::make_shared<ProjectEffectListDelegate>(
mProject)
1185 auto track = evt.
mpTrack.lock();
1186 auto waveTrack = std::dynamic_pointer_cast<WaveTrack>(track);
1188 if (waveTrack ==
nullptr)
1217 message.
type == UndoRedoMessage::Type::Purge ||
1218 message.
type == UndoRedoMessage::Type::BeginPurge ||
1219 message.
type == UndoRedoMessage::Type::EndPurge)
1228 message.
type == UndoRedoMessage::Type::UndoOrRedo ||
1229 message.
type == UndoRedoMessage::Type::Reset)
1231 for (auto waveTrack : waveTracks)
1232 UpdateRealtimeEffectUIData(*waveTrack);
1243 std::vector<RealtimeEffectStateUI*> shownUIs;
1248 assert(track !=
nullptr);
1252 [&shownUIs](
auto& ui)
1255 shownUIs.push_back(&ui);
1261 for (
auto effectUI : shownUIs)
1263 bool reachable =
false;
1265 for (
auto track : waveTracks)
1269 [effectUI, &reachable](
auto& ui)
1271 if (effectUI == &ui)
1296 Bind(wxEVT_CLOSE_WINDOW, [
this](wxCloseEvent&) {
1306 if(track ==
nullptr)
1312 wxWindowUpdateLocker freeze(
this);
1317 const auto pContainerWindow = projectWindow.GetContainerWindow();
1318 if (pContainerWindow->GetWindow1() !=
this)
1321 pContainerWindow->SplitVertically(
1323 projectWindow.GetTrackListWindow(),
1324 this->GetSize().GetWidth());
1328 projectWindow.Layout();
1333 wxWindowUpdateLocker freeze(
this);
1336 const auto pContainerWindow = projectWindow.GetContainerWindow();
1337 const auto pTrackListWindow = projectWindow.GetTrackListWindow();
1338 if (pContainerWindow->GetWindow2() ==
nullptr)
1341 pContainerWindow->SplitVertically(
this, pTrackListWindow);
1343 pContainerWindow->Unsplit(
this);
1344 pTrackListWindow->SetFocus();
1345 projectWindow.Layout();
1351 if(track &&
dynamic_cast<WaveTrack*
>(&*track) !=
nullptr)
1360 std::make_shared<TrackEffectListUIDelegate>(track)
1365 mTrackEffectsHeader->SetName(wxString::Format(
_(
"Realtime effects for %s"), track->GetName()));
1389 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1392#if wxUSE_ACCESSIBILITY
1395 header->SetBackgroundColorIndex(clrMedium);
1397 auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
1399 toggleEffects->SetImageIndices(0, bmpEffectOff, bmpEffectOff, bmpEffectOn, bmpEffectOn, bmpEffectOff);
1400 toggleEffects->SetButtonToggles(
true);
1401 toggleEffects->SetTranslatableLabel(
XO(
"Power"));
1402 toggleEffects->SetBackgroundColorIndex(clrMedium);
1405 toggleEffects->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
1415 hSizer->Add(toggleEffects, 0, wxSTRETCH_NOT | wxALIGN_CENTER | wxLEFT, 5);
1417 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1420 headerText->SetFont(wxFont(wxFontInfo().Bold()));
1421 headerText->SetTranslatableLabel(
XO(
"Realtime Effects"));
1422 headerText->SetForegroundColorIndex(clrTrackPanelText);
1425 trackTitle->SetForegroundColorIndex(clrTrackPanelText);
1428 vSizer->Add(headerText);
1429 vSizer->Add(trackTitle);
1431 hSizer->Add(vSizer.release(), 1, wxEXPAND | wxALL, 10);
1434 close->SetTranslatableLabel(
XO(
"Close"));
1435 close->SetImageIndices(0, bmpCloseNormal, bmpCloseHover, bmpCloseDown, bmpCloseHover, bmpCloseDisabled);
1436 close->SetBackgroundColorIndex(clrMedium);
1438 close->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) { Close(); });
1440 hSizer->Add(close, 0, wxSTRETCH_NOT | wxALIGN_CENTER | wxRIGHT, 5);
1442 header->SetSizer(hSizer.release());
1444 vSizer->Add(header, 0, wxEXPAND);
1447 effectList->SetBackgroundColorIndex(clrMedium);
1450 footer->SetBackgroundColorIndex(clrMedium);
1454 addEffectHint->SetForegroundColorIndex(clrTrackPanelText);
1457 footer, wxID_ANY,
_(
"Watch video"),
1458 "https://www.audacityteam.org/realtime-video", wxDefaultPosition,
1459 wxDefaultSize, wxHL_ALIGN_LEFT | wxHL_CONTEXTMENU);
1461 addEffectTutorialLink->Bind(
1462 wxEVT_HYPERLINK, [](wxHyperlinkEvent& event)
1465 auto footerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1466 footerSizer->Add(addEffectHint, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 20);
1467 footerSizer->Add(addEffectTutorialLink, 0, wxLEFT | wxRIGHT | wxEXPAND, 20);
1468 footer->SetSizer(footerSizer.release());
1470 footer->Bind(wxEVT_SIZE, [=](wxSizeEvent& event)
1472 if(
auto sizerItem = footer->GetSizer()->GetItem(addEffectHint))
1479 addEffectHint->SetLabel(_(
"Realtime effects are non-destructive and can be changed at any time."));
1480 addEffectHint->Wrap(mTrackEffectsPanel->GetClientSize().x - sizerItem->GetBorder() * 2);
1481 addEffectHint->InvalidateBestSize();
1486 effectList->SetFooter(footer);
1488 vSizer->Add(effectList, 1, wxEXPAND);
1503 const wxPoint& pos = wxDefaultPosition,
1504 const wxSize&
size = wxDefaultSize)
1505 : wxWindow(parent,
id, pos,
size, wxNO_BORDER, wxEmptyString)
1507 wxWindow::SetBackgroundStyle(wxBG_STYLE_PAINT);
1508 SetCursor(wxCursor(wxCURSOR_SIZENS));
1552 const auto pos =
mSplitter->ScreenToClient(ClientToScreen(evt.GetPosition()));
1563 wxBufferedPaintDC dc(
this);
1564 const auto rect = wxRect(GetSize());
1566 dc.SetPen(*wxTRANSPARENT_PEN);
1567 dc.SetBrush(GetBackgroundColour());
1568 dc.DrawRectangle(rect);
1570 dc.SetPen(GetForegroundColour());
1571 dc.SetBrush(*wxTRANSPARENT_BRUSH);
1572 const auto yy = rect.GetTop() + rect.GetHeight() / 2;
1573 dc.DrawLine(rect.GetLeft(), yy, rect.GetRight(), yy);
1581 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1584 sash->SetMinSize(wxSize{-1, 3});
1585 sash->SetSplitterWindow(
this);
1586 sash->SetBackgroundColorIndex(clrMedium);
1587 sash->SetForegroundColorIndex(clrDark);
1588 vSizer->Add(sash, 0, wxEXPAND);
1591#if wxUSE_ACCESSIBILITY
1594 header->SetBackgroundColorIndex(clrMedium);
1596 auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
1598 toggleEffects->SetImageIndices(0, bmpEffectOff, bmpEffectOff, bmpEffectOn, bmpEffectOn, bmpEffectOff);
1599 toggleEffects->SetButtonToggles(
true);
1600 toggleEffects->SetTranslatableLabel(
XO(
"Power"));
1601 toggleEffects->SetBackgroundColorIndex(clrMedium);
1604 toggleEffects->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
1614 hSizer->Add(toggleEffects, 0, wxSTRETCH_NOT | wxALIGN_CENTER | wxLEFT, 5);
1616 auto vSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1619 headerText->SetFont(wxFont(wxFontInfo().Bold()));
1620 headerText->SetTranslatableLabel(
XO(
"Master Effects"));
1621 headerText->SetForegroundColorIndex(clrTrackPanelText);
1622 header->SetName(headerText->GetLabel());
1625 desc->SetForegroundColorIndex(clrTrackPanelText);
1626 desc->SetTranslatableLabel(
XO(
"Applies to all tracks"));
1628 vSizer->Add(headerText);
1631 hSizer->Add(vSizer.release(), 1, wxEXPAND | wxALL, 10);
1634 header->SetSizer(hSizer.release());
1636 vSizer->Add(header, 0, wxEXPAND | wxTOP, 5);
1639 effectList->SetBackgroundColorIndex(clrMedium);
1640 vSizer->Add(effectList, 1, wxEXPAND);
1649 if(evt.GetKeyCode() == WXK_ESCAPE && IsShown() && IsDescendant(
FindFocus()))
Toolkit-neutral facade for basic user interface services.
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...
int GetSourceIndex() const noexcept
int GetTargetIndex() const noexcept
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)
static PendingTracks & Get(AudacityProject &project)
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.
RealtimeEffectList & GetEffectList() override
wxString GetSourceName() override
ProjectEffectListDelegate(AudacityProject &project)
std::shared_ptr< RealtimeEffectList > mEffectList
ChannelGroup * GetChannelGroup() override
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
void Visit(const StateVisitor &func)
Apply the function to all states sequentially.
static RealtimeEffectList & Get(AudacityProject &project)
bool IsActive() const
Non-blocking atomic boolean load.
void OnEffectListItemChange(const RealtimeEffectListMessage &msg)
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)
void EnableEffects(bool enable)
wxWindow * mEffectListContainer
void SetDelegate(AudacityProject &project, const std::shared_ptr< EffectListUIDelegate > &delegate)
std::shared_ptr< EffectListUIDelegate > mDelegate
Observer::Subscription mEffectListItemMovedSubscription
void InsertEffectRow(size_t index, const std::shared_ptr< RealtimeEffectState > &pState)
void SetFooter(wxWindow *footer)
wxWeakRef< AudacityProject > mProject
static RealtimeEffectManager & Get(AudacityProject &project)
UI Panel that displays realtime effects from the effect stack of an individual track,...
RealtimeEffectListWindow * mTrackEffectList
Observer::Subscription mUndoSubscription
AButton * mToggleMasterEffects
AButton * mToggleTrackEffects
wxStaticText * mTrackTitle
void ShowPanel(SampleTrack *track, bool focus)
void OnCharHook(wxKeyEvent &evt)
void MakeTrackEffectPane()
void MakeMasterEffectPane()
std::weak_ptr< SampleTrack > mCurrentTrack
wxWindow * mProjectEffectsPanel
static RealtimeEffectPanel & Get(AudacityProject &project)
wxWindow * mTrackEffectsHeader
RealtimeEffectListWindow * mMasterEffectList
~RealtimeEffectPanel() override
std::vector< std::shared_ptr< SampleTrack > > mPotentiallyRemovedTracks
wxWindow * mTrackEffectsPanel
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.
const PluginID & GetID() const noexcept
static RealtimeEffectStateUI & Get(RealtimeEffectState &state)
void OnPaint(wxPaintEvent &)
wxWeakRef< wxSplitterWindow > mSplitter
void SetSplitterWindow(wxSplitterWindow *window)
bool AcceptsFocus() const override
void OnMouseCaptureLost(wxMouseCaptureLostEvent &event)
void OnMove(wxMouseEvent &evt)
SashLine(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
void OnMouseUp(wxMouseEvent &evt)
void OnMouseDown(wxMouseEvent &evt)
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
wxString GetSourceName() override
TrackEffectListUIDelegate(std::shared_ptr< SampleTrack > track)
std::shared_ptr< SampleTrack > mTrack
RealtimeEffectList & GetEffectList() override
ChannelGroup * GetChannelGroup() override
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< Subclass > SharedPointer()
const wxString & GetName() const
Name is always the same for all channels of a group.
auto Any() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
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 &)
virtual RealtimeEffectList & GetEffectList()=0
virtual ChannelGroup * GetChannelGroup()=0
virtual ~EffectListUIDelegate()=default
virtual wxString GetSourceName()=0
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)
RealtimeEffectControl(wxWindow *parent, wxWindowID winid, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
Observer::Subscription mSubscription
void SetEffect(AudacityProject &project, const std::shared_ptr< EffectListUIDelegate > &delegate, const std::shared_ptr< RealtimeEffectState > &pState)
std::shared_ptr< RealtimeEffectState > mEffectState
void OnFocusChange(wxFocusEvent &evt)
void Create(wxWindow *parent, wxWindowID winid, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
void OnPaint(wxPaintEvent &)
std::shared_ptr< EffectListUIDelegate > mDelegate
void OnChangeButtonClicked(wxCommandEvent &event)
wxWeakRef< AudacityProject > mProject
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
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 VisitWithFunctions(const VisitorFunctions< RegistryTraits > &visitors, const GroupItem< RegistryTraits > *pTopItem, const GroupItem< RegistryTraits > *pRegistry={}, typename RegistryTraits::ComputedItemContextType &computedItemContext=RegistryTraits::ComputedItemContextType::Instance)
const TranslatableString desc
AttachedWindows::RegisteredFactory sKey
void UpdateRealtimeEffectUIData(const AudacityProject &project)
static wxString GetSafeVendor(const PluginDescriptor &descriptor)
void VisitRealtimeEffectStateUIs(const Track &track, Visitor &&visitor)
TranslatableString GetEffectName(RealtimeEffectState &state)
const PluginDescriptor * GetPlugin(const PluginID &ID)
void ReopenRealtimeEffectUIData(AudacityProject &project, SampleTrack &track)
const TranslatableString label_in
@ 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
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