Audacity 3.2.0
RealtimeEffectStateUI.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 RealtimeEffectStateUI.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
12
13#include <cassert>
14
15#include "EffectUI.h"
16#include "RealtimeEffectState.h"
17
18#include "EffectManager.h"
19#include "ProjectHistory.h"
20#include "ProjectWindow.h"
21#include "Track.h"
22
23namespace
24{
25const RealtimeEffectState::RegisteredFactory realtimeEffectStateUIFactory { [](auto& state)
26 { return std::make_unique<RealtimeEffectStateUI>(state); }
27};
28} // namespace
29
30
31BEGIN_EVENT_TABLE(RealtimeEffectStateUI, wxEvtHandler)
34
36 : mRealtimeEffectState(state)
37{
38}
39
41{
42 Hide();
43}
44
45bool RealtimeEffectStateUI::IsShown() const noexcept
46{
47 return mEffectUIHost != nullptr;
48}
49
51{
52 if (mEffectUIHost != nullptr && mEffectUIHost->IsShown())
53 {
54 // Bring the host to front
55 mEffectUIHost->Raise();
56 return;
57 }
58
59 const auto ID = mRealtimeEffectState.GetID();
60 const auto effectPlugin = EffectManager::Get().GetEffect(ID);
61
62 if (effectPlugin == nullptr)
63 return;
64
65 EffectUIClientInterface* client = effectPlugin->GetEffectUIClientInterface();
66
67 // Effect has no client interface
68 if (client == nullptr)
69 return;
70
71 auto& projectWindow = ProjectWindow::Get(project);
72
73 std::shared_ptr<EffectInstance> pInstance;
74
75 auto access = mRealtimeEffectState.GetAccess();
76
77 // EffectUIHost invokes shared_from_this on access
79 &projectWindow, project, *effectPlugin, *client, pInstance, *access,
80 mRealtimeEffectState.shared_from_this()));
81
82 if (!dlg->Initialize())
83 return;
84
85 // Dialog is owned by its parent now!
86 mEffectUIHost = dlg.release();
87
89
90 client->ShowClientInterface(
91 projectWindow, *mEffectUIHost, mEffectUIHost->GetValidator(), false);
92
93 // The dialog was modal? That shouldn't have happened
94 if (mEffectUIHost == nullptr || !mEffectUIHost->IsShown())
95 {
96 assert(false);
97 mEffectUIHost = {};
98 }
99
100 if (mEffectUIHost) {
101 mEffectUIHost->PushEventHandler(this);
102 mpProject = &project;
103 }
104
105 mProjectWindowDestroyedSubscription = projectWindow.Subscribe(
106 [this, &project](ProjectWindowDestroyedMessage) {
107 // This achieves autosave on close of project before other important
108 // project state is destroyed
109 Hide(&project);
110 });
111
112 mParameterChangedSubscription = mEffectUIHost->GetValidator()->Subscribe(
113 [this](auto) { ProjectHistory::Get(*mpProject).ModifyState(false); });
114}
115
117{
118 if (mEffectUIHost != nullptr)
119 {
120 mpProject = project; // May reassign as null to skip autosave in OnClose
121 // EffectUIHost calls Destroy in OnClose handler
122 mEffectUIHost->Close();
123 mEffectUIHost = {};
124 }
125}
126
128{
129 if(IsShown())
130 Hide(&project);
131 else
132 Show(project);
133}
134
136{
137 mTrackName = track.GetName();
138
139 UpdateTitle();
140}
141
143{
145}
146
149{
150 return Get(const_cast<RealtimeEffectState&>(state));
151}
152
154{
155 if (mEffectUIHost == nullptr)
156 return;
157
158 if (mEffectName.empty())
159 {
160 const auto ID = mRealtimeEffectState.GetID();
161 const auto effectPlugin = EffectManager::Get().GetEffect(ID);
162
163 if (effectPlugin != nullptr)
164 mEffectName = effectPlugin->GetDefinition().GetName();
165 }
166
167 const auto title =
168 mTrackName.empty() ?
170 /* i18n-hint: First %s is an effect name, second is a track name */
171 XO("%s - %s").Format(mEffectName, mTrackName);
172
173 mEffectUIHost->SetTitle(title);
174 mEffectUIHost->SetName(title);
175}
176
178{
180}
181
182void RealtimeEffectStateUI::OnClose(wxCloseEvent & evt)
183{
184 auto next = GetNextHandler();
185 mEffectUIHost->RemoveEventHandler(this);
186 auto pProject = mpProject;
187 mpProject = nullptr;
188 if (pProject)
189 AutoSave(*pProject);
190
191 // Pass the event through to the dialog
192 if (next)
193 next->ProcessEvent(evt);
194}
END_EVENT_TABLE()
#define XO(s)
Definition: Internat.h:31
#define safenew
Definition: MemoryX.h:10
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:162
static const auto title
declares abstract base class Track, TrackList, and iterators over TrackList
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:309
EffectPlugin * GetEffect(const PluginID &ID)
static EffectManager & Get()
EffectUIClientInterface is an abstract base class to populate a UI and validate UI values....
virtual int ShowClientInterface(wxWindow &parent, wxDialog &dialog, EffectUIValidator *pValidator, bool forceModal=false)=0
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
std::shared_ptr< EffectSettingsAccess > GetAccess()
const PluginID & GetID() const noexcept
UI state for realtime effect.
Observer::Subscription mParameterChangedSubscription
TranslatableString mEffectName
bool IsShown() const noexcept
Observer::Subscription mProjectWindowDestroyedSubscription
void OnClose(wxCloseEvent &evt)
RealtimeEffectState & mRealtimeEffectState
void Show(AudacityProject &project)
void Toggle(AudacityProject &project)
wxWeakRef< EffectUIHost > mEffectUIHost
AudacityProject * mpProject
static RealtimeEffectStateUI & Get(RealtimeEffectState &state)
void UpdateTrackData(const Track &track)
void Hide(AudacityProject *project=nullptr)
void AutoSave(AudacityProject &project)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
wxString GetName() const
Definition: Track.h:466
const RealtimeEffectState::RegisteredFactory realtimeEffectStateUIFactory
Message sent when the project window is closed.
Definition: ProjectWindow.h:32