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 "EffectEditor.h"
16#include "EffectUI.h"
17#include "EffectUIServices.h"
18#include "RealtimeEffectState.h"
19
20#include "EffectBase.h"
21#include "EffectManager.h"
22#include "UndoManager.h"
23#include "ProjectHistory.h"
24#include "ProjectWindow.h"
25#include "Track.h"
26
27namespace
28{
29const RealtimeEffectState::RegisteredFactory realtimeEffectStateUIFactory { [](auto& state)
30 { return std::make_unique<RealtimeEffectStateUI>(state); }
31};
32} // namespace
33
34
35BEGIN_EVENT_TABLE(RealtimeEffectStateUI, wxEvtHandler)
38
40 : mRealtimeEffectState(state)
41{
42}
43
45{
46 Hide();
47}
48
49bool RealtimeEffectStateUI::IsShown() const noexcept
50{
51 return mEffectUIHost != nullptr;
52}
53
55{
56 if (mEffectUIHost != nullptr && mEffectUIHost->IsShown())
57 {
58 // Bring the host to front
59 mEffectUIHost->Raise();
60 return;
61 }
62
63 const auto ID = mRealtimeEffectState.GetID();
64 const auto effectPlugin =
65 dynamic_cast<EffectBase*>(EffectManager::Get().GetEffect(ID));
66
67 if (effectPlugin == nullptr)
68 return;
69
70 const auto client = dynamic_cast<EffectUIServices *>(effectPlugin);
71
72 // Effect has no client interface
73 if (client == nullptr)
74 return;
75
76 auto& projectWindow = ProjectWindow::Get(project);
77
78 std::shared_ptr<EffectInstance> pInstance;
79
80 auto access = mRealtimeEffectState.GetAccess();
81
82 // EffectUIHost invokes shared_from_this on access
84 &projectWindow, project, *effectPlugin, *client, pInstance, *access,
85 mRealtimeEffectState.shared_from_this()));
86
87 if (!dlg->Initialize())
88 return;
89
90 // Dialog is owned by its parent now!
91 mEffectUIHost = dlg.release();
92
94
95 client->ShowClientInterface(*effectPlugin,
96 projectWindow, *mEffectUIHost, mEffectUIHost->GetEditor(), false);
97
98 // The dialog was modal? That shouldn't have happened
99 if (mEffectUIHost == nullptr || !mEffectUIHost->IsShown())
100 {
101 assert(false);
102 mEffectUIHost = {};
103 }
104
105 if (mEffectUIHost) {
106 mEffectUIHost->PushEventHandler(this);
108 }
109
110 mProjectWindowDestroyedSubscription = projectWindow.Subscribe(
112 // This achieves autosave on close of project before other important
113 // project state is destroyed
114 Hide(&project);
115 });
116
117 mParameterChangedSubscription = mEffectUIHost->GetEditor()->Subscribe(
118 [this](auto) { if (mpProject) { // This can be null if closing an effect without making changes.
119 UndoManager::Get(*mpProject).MarkUnsaved();
120 }
121 });
122}
123
125{
126 if (mEffectUIHost != nullptr)
127 {
128 mpProject = project; // May reassign as null to skip autosave in OnClose
129 // EffectUIHost calls Destroy in OnClose handler
130 mEffectUIHost->Close();
131 mEffectUIHost = {};
132 }
133}
134
136{
137 if(IsShown())
138 Hide(&project);
139 else
140 Show(project);
141}
142
144{
145 mTrackName = track.GetName();
146
147 UpdateTitle();
148}
149
151{
153}
154
157{
158 return Get(const_cast<RealtimeEffectState&>(state));
159}
160
162{
163 if (mEffectUIHost == nullptr)
164 return;
165
166 if (mEffectName.empty())
167 {
168 const auto ID = mRealtimeEffectState.GetID();
169 const auto effectPlugin = EffectManager::Get().GetEffect(ID);
170
171 if (effectPlugin != nullptr)
172 mEffectName = effectPlugin->GetDefinition().GetName();
173 }
174
175 const auto title =
176 mTrackName.empty() ?
178 /* i18n-hint: First %s is an effect name, second is a track name */
179 XO("%s - %s").Format(mEffectName, mTrackName);
180
181 mEffectUIHost->SetTitle(title);
182 mEffectUIHost->SetName(title);
183}
184
186{
188}
189
190void RealtimeEffectStateUI::OnClose(wxCloseEvent & evt)
191{
192 auto next = GetNextHandler();
193 mEffectUIHost->RemoveEventHandler(this);
194 auto pProject = mpProject;
195 mpProject = nullptr;
196 if (pProject)
197 AutoSave(*pProject);
198
199 // Pass the event through to the dialog
200 if (next)
201 next->ProcessEvent(evt);
202}
END_EVENT_TABLE()
XO("Cut/Copy/Paste")
#define safenew
Definition: MemoryX.h:9
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:161
static const auto title
const auto project
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:90
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:317
Base class for many of the effects in Audacity.
Definition: EffectBase.h:28
EffectPlugin * GetEffect(const PluginID &ID)
static EffectManager & Get()
static result_type Call(Arguments &&...arguments)
Null check of the installed function is done for you.
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:122
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:56
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:71
void MarkUnsaved()
const RealtimeEffectState::RegisteredFactory realtimeEffectStateUIFactory
Message sent when the project window is closed.
Definition: ProjectWindow.h:29