29#include "../ProjectWindowBase.h"
30#include "../ProjectWindows.h"
100#include "../../images/Effect.h"
102#include "../CommonCommandFlags.h"
103#include "../prefs/GUISettings.h"
105#include "../ProjectAudioManager.h"
111#include "../widgets/AButton.h"
113#include <wx/button.h>
114#include <wx/checkbox.h>
115#include <wx/dcclient.h>
116#include <wx/dcmemory.h>
118#include <wx/settings.h>
120#include <wx/textctrl.h>
169 const std::shared_ptr<EffectSettingsAccess> &pSide = {});
172 std::unique_ptr<Message> pMessage)
override;
173 void Set(std::unique_ptr<Message> pMessage)
override;
174 void Flush()
override;
178 const std::shared_ptr<EffectSettingsAccess>
mpMain;
179 const std::weak_ptr<EffectSettingsAccess>
mwSide;
183EffectSettingsAccessTee::EffectSettingsAccessTee(
185 const std::shared_ptr<EffectSettingsAccess> &pSide
186) : mpMain{
main.shared_from_this() }
196 std::unique_ptr<Message> pMessage)
199 if (
auto pSide =
mwSide.lock())
201 pMessage ? pMessage->Clone() :
nullptr);
209 if (
auto pSide =
mwSide.lock())
210 pSide->Set(pMessage ? pMessage->Clone() :
nullptr);
212 mpMain->Set(std::move(pMessage));
218 if (
auto pSide =
mwSide.lock())
225 return mpMain->IsSameAs(other);
232 const std::shared_ptr<RealtimeEffectState> &pPriorState)
234 wxDefaultPosition, wxDefaultSize,
235 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX)
236, mEffectUIHost{ effect }
240, mpGivenAccess{ access.shared_from_this() }
241, mpAccess{ mpGivenAccess }
242, mwState{ pPriorState }
245, mSupportsRealtime{ mEffectUIHost.GetDefinition().SupportsRealtime() }
246, mHadPriorState{ (pPriorState != nullptr) }
247, mpInstance{ InitializeInstance() }
248, mpOutputs{ pPriorState ? pPriorState->GetOutputs() : nullptr }
252#if defined(__WXMAC__)
260 SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
278 const auto pServices =
280 return (!pServices || pServices->TransferDataToWindow(
mpAccess->Get())) &&
284 wxDialogWrapper::TransferDataToWindow();
290 if (!wxDialogWrapper::Validate())
294 if (!wxDialogWrapper::TransferDataFromWindow())
304 const auto pServices =
307 result = (!pServices || pServices->TransferDataFromWindow(
settings));
311 const auto seconds =
settings.extra.GetDuration();
337 return wxDialogWrapper::ShowModal();
349 wxDefaultPosition, wxDefaultSize,
true);
350 pBtn->SetImages(ImageOff, ImageOff, ImageOn, ImageOn, ImageOff);
362 S.StartHorizontalLay(wxEXPAND, 0);
368 mEnableBtn->SetBackgroundColour(GetBackgroundColour());
370 .Position(wxALIGN_CENTER | wxTOP | wxBOTTOM)
376 .ToolTip(
XO(
"Manage presets and options"))
377 .AddButton(
XO(
"Presets && settings"), wxALIGN_CENTER | wxTOP | wxBOTTOM );
386 .AddButton(
XXO(
"Debu&g"),
387 wxALIGN_CENTER | wxTOP | wxBOTTOM );
390 S.EndHorizontalLay();
411 uw->SetMinSize(wxSize(wxMax(600,
mParent->GetSize().GetWidth() * 2 / 3),
412 mParent->GetSize().GetHeight() / 2));
424 S.StartHorizontalLay( wxEXPAND );
428 .AddWindow((w = uw.release()));
430 S.EndHorizontalLay();
437 S.StartHorizontalLay(wxEXPAND, 0);
445 .ToolTip(
XO(
"Preview effect"))
446 .AddButton(
XXO(
"&Preview"),
447 wxALIGN_CENTER | wxTOP | wxBOTTOM );
453 .AddButton(
XXO(
"&Cancel"));
456 .AddButton(
XXO(
"&Apply"));
459 S.EndHorizontalLay();
484 SetMinSize(GetSize());
497 wxDialogWrapper::OnInitDialog(evt);
499#if wxCHECK_VERSION(3, 0, 0)
510 wxTextCtrl *focused = wxDynamicCast(
FindFocus(), wxTextCtrl);
513 focused->SelectAll();
587 EndModal(evt.GetId());
597 auto cleanup =
finally( [&] {
mApplyBtn->Enable(); } );
642 static const auto specialVersion =
XO(
"n/a");
644 if (result == specialVersion.MSGID())
645 result = specialVersion.Translation();
663 auto sub = std::make_unique<wxMenu>();
664 for (
size_t i = 0, cnt =
mUserPresets.size(); i < cnt; i++)
668 menu.Append(0,
_(
"User Presets"), sub.release());
679 auto sub = std::make_unique<wxMenu>();
680 for (
size_t i = 0, cnt =
mUserPresets.size(); i < cnt; i++)
684 menu.Append(0,
_(
"Delete Preset"), sub.release());
687 menu.AppendSeparator();
692 auto sub = std::make_unique<wxMenu>();
696 sub->AppendSeparator();
697 for (
size_t i = 0, cnt =
factory.size(); i < cnt; i++)
708 menu.Append(0,
_(
"Factory Presets"), sub.release());
711 menu.AppendSeparator();
716 menu.AppendSeparator();
719 menu.AppendSeparator();
722 auto sub = std::make_unique<wxMenu>();
725 sub->Append(
kDummyID, wxString::Format(
_(
"Type: %s"),
726 ::wxGetTranslation( definition.GetFamily().Translation() )));
727 sub->Append(
kDummyID, wxString::Format(
_(
"Name: %s"), definition.GetName().Translation()));
728 sub->Append(
kDummyID, wxString::Format(
_(
"Version: %s"),
730 sub->Append(
kDummyID, wxString::Format(
_(
"Vendor: %s"), definition.GetVendor().Translation()));
731 sub->Append(
kDummyID, wxString::Format(
_(
"Description: %s"), definition.GetDescription().Translation()));
732 sub->Bind(wxEVT_MENU, [](
auto&){},
kDummyID);
734 menu.Append(0,
_(
"About"), sub.release());
737 wxWindow *btn = FindWindow(
kMenuID);
738 wxRect r = btn->GetRect();
741 { r.GetLeft(), r.GetBottom() }
815 wxICON_QUESTION | wxYES_NO);
837 S.StartVerticalLay(1);
839 S.StartHorizontalLay(wxALIGN_LEFT, 0);
841 text =
S.AddTextBox(
XXO(
"Preset name:"),
name, 30);
843 S.EndHorizontalLay();
845 S.AddStandardButtons();
851 dlg.SetSize(dlg.GetSizer()->GetMinSize());
857 int rc = dlg.ShowModal();
864 name = text->GetValue();
869 XO(
"You must specify a name"),
880 XO(
"Preset already exists.\n\nReplace?"),
882 wxYES_NO | wxCANCEL | wxICON_EXCLAMATION );
884 int choice = md.ShowModal();
885 if (choice == wxID_CANCEL)
890 if (choice == wxID_NO)
956 if (!IsEscapeKey(evt))
982 wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6, 24);
983 dc.SelectObject(mod);
985#if defined(__WXGTK__)
986 wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BACKGROUND);
988 wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
991 dc.SetBackground(wxBrush(newColour));
1003 dc.DrawBitmap(pic, offset, offset,
true);
1005 dc.SelectObject(wxNullBitmap);
1041 std::shared_ptr<EffectInstance> result;
1043 auto mpState =
mwState.lock();
1045 bool priorState = (mpState !=
nullptr);
1048 mCapturing = gAudioIO->IsStreamActive() && gAudioIO->GetNumCaptureChannels() > 0 && !gAudioIO->IsMonitoring();
1058 result = mpState->GetInstance();
1063 mpAccess = std::make_shared<EffectSettingsAccessTee>(
1074 switch (event.
type) {
1075 case AudioIOEvent::CAPTURE:
1076 OnCapture(event); break;
1122 std::shared_ptr<EffectInstance> pInstance;
1124 *
project, host, client, pInstance, access } };
1129 if (dlg->Initialize()) {
1130 auto pEditor = dlg->GetEditor();
1132 return { dlg.release(), pInstance, pEditor };
1139#include "../SelectUtilities.h"
1152 int additionalButtons)
1156 mAdditionalButtons = additionalButtons;
1174 S.StartVerticalLay(
true);
1183 SetMinSize(GetSize());
EVT_MENU(OnSetPlayRegionToSelectionID, AdornedRulerPanel::OnSetPlayRegionToSelection) EVT_COMMAND(OnTogglePinnedStateID
wxEVT_COMMAND_BUTTON_CLICKED
int main(int argc, char *argv[])
EVT_MENU_RANGE(FileHistory::ID_RECENT_FIRST, FileHistory::ID_RECENT_LAST, AudacityApp::OnMRUFile) bool AudacityApp
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Toolkit-neutral facade for basic user interface services.
constexpr CommandFlag AlwaysEnabledFlag
const ReservedCommandFlag & TimeSelectedFlag()
const ReservedCommandFlag & WaveTracksSelectedFlag()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
RegistryPath UserPresetsGroup(const RegistryPath &name)
Compute part of a registry path, given a name which may be empty.
const RegistryPath & CurrentSettingsGroup()
Component of a configuration key path, for last-used destructive settings.
void EffectPreview(EffectBase &effect, EffectSettingsAccess &access, std::function< void()> updateUI, bool dryOnly)
Calculate temporary tracks of limited length with effect applied and play.
static PluginID GetID(EffectPlugin &effect)
static const int kImportID
static const int kExportID
static const int kOptionsID
static const int kCaptureID
static RealtimeEffectState::EffectFactory::Scope scope
Inject a factory for realtime effects.
static const int kDefaultsID
static const int kDummyID
static const int kPlaybackID
static const int kSaveAsID
static const int kUserPresetsDummyID
static const int kFactoryPresetsID
static const int kEnableID
static const int kDeletePresetDummyID
static const int kUserPresetsID
static const int kDeletePresetID
void MacMakeWindowFloating(NSView *handle)
XXO("&Cut/Copy/Paste Toolbar")
#define RTL_WORKAROUND(pWnd)
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
an object holding per-project preferred sample rate
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
RealtimeEffectStateChange
static Settings & settings()
Wrap wxMessageDialog so that caption IS translatable.
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.
std::shared_ptr< RealtimeEffectState > AddState(AudacityProject &project, ChannelGroup *pGroup, const PluginID &id)
Forwards to RealtimeEffectManager::AddState with proper init scope.
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
static CommandManager & Get(AudacityProject &project)
bool ReportIfActionNotAllowed(const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
virtual wxString GetVersion() const =0
TranslatableString GetName() const
Base class for many of the effects in Audacity.
static std::optional< InstancePointer > FindInstance(EffectPlugin &plugin)
EffectDefinitionInterface is a ComponentInterface that adds some basic read-only information about ef...
virtual EffectType GetType() const =0
Type determines how it behaves.
virtual bool EnablesDebug() const
Whether the effect dialog should have a Debug button; default, always false.
bool TransferDataToWindow() override
bool TransferDataFromWindow() override
virtual void OnPreview(wxCommandEvent &evt)
virtual void OnOk(wxCommandEvent &evt)
virtual void PopulateOrExchange(ShuttleGui &S)
static constexpr int kPlayID
static const EffectInstanceFactory * GetInstanceFactory(const PluginID &ID)
void SetAccept(bool accept)
bool AcceptsFocus() const override
bool AcceptsFocusFromKeyboard() const override
EffectPanel(wxWindow *parent)
Factory of instances of an effect.
virtual bool HasOptions() const =0
virtual bool CanExportPresets() const =0
Whether the effect supports export of presets to files, and importing too.
virtual const EffectSettingsManager & GetDefinition() const =0
virtual bool IsBatchProcessing() const =0
virtual RegistryPaths GetFactoryPresets() const =0
Report names of factory presets.
virtual bool SaveUserPreset(const RegistryPath &name, const EffectSettings &settings) const =0
Save settings in the configuration file as a user-named preset.
void OnEnable(wxCommandEvent &evt)
void OnFactoryPreset(wxCommandEvent &evt)
RegistryPaths mUserPresets
void OnDefaults(wxCommandEvent &evt)
Observer::Subscription mAudioIOSubscription
bool HandleCommandKeystrokes() override
void OnErase(wxEraseEvent &evt)
AudacityProject & mProject
std::shared_ptr< RealtimeEffectState > mpTempProjectState
EffectBase & mEffectUIHost
bool TransferDataToWindow() override
EffectPlugin::EffectSettingsAccessPtr mpAccess
const EffectOutputs *const mpOutputs
void OnUserPreset(wxCommandEvent &evt)
void OnDeletePreset(wxCommandEvent &evt)
void OnIdle(wxIdleEvent &evt)
Observer::Subscription mEffectStateSubscription
void OnCapture(AudioIOEvent)
EffectUIHost(wxWindow *parent, AudacityProject &project, EffectBase &effect, EffectUIServices &client, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, const std::shared_ptr< RealtimeEffectState > &pPriorState={})
EffectUIServices & mClient
void OnClose(wxCloseEvent &evt)
void OnExport(wxCommandEvent &evt)
void BuildTopBar(ShuttleGui &S)
void OnSaveAs(wxCommandEvent &evt)
const bool mHadPriorState
void OnOptions(wxCommandEvent &evt)
void OnInitDialog(wxInitDialogEvent &evt)
void OnMenu(wxCommandEvent &evt)
void OnDebug(wxCommandEvent &evt)
void OnCharHook(wxKeyEvent &evt)
EffectPlugin::EffectSettingsAccessPtr mpAccess2
void OnImport(wxCommandEvent &evt)
std::unique_ptr< EffectEditor > mpEditor
std::shared_ptr< EffectInstance > InitializeInstance()
void OnApply(wxCommandEvent &evt)
const bool mSupportsRealtime
void OnPlay(wxCommandEvent &evt)
const std::shared_ptr< EffectInstance > mpInstance
void OnCancel(wxCommandEvent &evt)
std::weak_ptr< RealtimeEffectState > mwState
wxBitmap CreateBitmap(const char *const xpm[], bool up, bool pusher)
bool IsOpenedFromEffectPanel() const
bool TransferDataFromWindow() override
void OnPaint(wxPaintEvent &evt)
virtual void ShowOptions(const EffectPlugin &plugin) const =0
virtual std::unique_ptr< EffectEditor > PopulateUI(const EffectPlugin &plugin, ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) const =0
Adds controls to a panel that is given as the parent window of S
virtual OptionalMessage ImportPresets(const EffectPlugin &plugin, EffectSettings &settings) const =0
virtual void ExportPresets(const EffectPlugin &plugin, const EffectSettings &settings) const =0
typename GlobalVariable< EffectFactory, const std::function< const EffectInstanceFactory * >, nullptr, Options... >::Scope Scope
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
void Reset() noexcept
Breaks the connection (constant time)
static PluginID GetID(const PluginProvider *provider)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
wxImage & Image(int iIndex)
Holds a msgid for the translation catalog; may also bind format arguments.
static const TranslatableString Inaudible
A special string value that will have no screen reader pronunciation.
static UndoManager & Get(AudacityProject &project)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
void Set(EffectSettings &&settings, std::unique_ptr< Message > pMessage) override
const std::weak_ptr< EffectSettingsAccess > mwSide
void Set(std::unique_ptr< Message > pMessage) override
Message-only overload of Set(). In future, this should be the only one.
const std::shared_ptr< EffectSettingsAccess > mpMain
void Flush() override
Make the last Set changes "persistent" in underlying storage.
bool IsSameAs(const EffectSettingsAccess &other) const override
const EffectSettings & Get() override
void SetLabel(const TranslatableString &label)
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
bool DoEffect(const PluginID &ID, AudacityProject &project, unsigned flags)
AUDACITY_DLL_API DialogFactoryResults DialogFactory(wxWindow &parent, EffectBase &host, EffectUIServices &client, EffectSettingsAccess &access)
bool RemoveConfigSubgroup(const EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group)
bool GetConfigSubgroups(const EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group, RegistryPaths &subgroups)
bool SetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, const Value &value)
AButton * MakeBitmapToggleButton(wxWindow *parent, const wxImage &ImageOn, const wxImage &ImageOff)
wxString GetVersionForDisplay(const EffectDefinitionInterface &definition)
constexpr int InnerMargin
enum AudioIOEvent::Type type
AudacityProject * pProject
Externalized state of a plug-in.