From a2f109de2e43890217c57ea14d3cb8a45463521c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 19 Jul 2021 22:08:27 -0400 Subject: [PATCH] Reimplement PrefsListener without wx/app.h or wxCommandEvent... ... so that Prefs depends only on the allowed subset of wxBase --- src/AdornedRulerPanel.cpp | 3 +-- src/Prefs.cpp | 30 ++++++++++++++++++++++++------ src/Prefs.h | 19 +++++++++++-------- src/menus/ViewMenus.cpp | 6 ++---- src/prefs/PrefsDialog.cpp | 2 +- src/toolbars/DeviceToolBar.cpp | 3 +-- src/widgets/Meter.cpp | 3 +-- 7 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index 33c91bb56..8b8c45fc7 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -1932,8 +1932,7 @@ void AdornedRulerPanel::OnAutoScroll(wxCommandEvent&) gPrefs->Flush(); - wxTheApp->AddPendingEvent(wxCommandEvent{ - EVT_PREFS_UPDATE, ViewInfo::UpdateScrollPrefsID() }); + PrefsListener::Broadcast(ViewInfo::UpdateScrollPrefsID()); } diff --git a/src/Prefs.cpp b/src/Prefs.cpp index 071698622..1c8cdb3ee 100755 --- a/src/Prefs.cpp +++ b/src/Prefs.cpp @@ -50,7 +50,6 @@ *//*******************************************************************/ - #include "Prefs.h" #include @@ -61,7 +60,7 @@ #include "Internat.h" #include "MemoryX.h" -#include +#include "BasicUI.h" BoolSetting DefaultUpdatesCheckingFlag{ L"/Update/DefaultUpdatesChecking", true }; @@ -71,20 +70,39 @@ std::unique_ptr ugPrefs {}; FileConfig *gPrefs = nullptr; int gMenusDirty = 0; -wxDEFINE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent); +struct MyEvent : wxEvent +{ +public: + explicit MyEvent(int id) : mId{id} {} + virtual wxEvent *Clone() const override { return new MyEvent{mId}; } + int mId; +}; + +wxDECLARE_EVENT(EVT_PREFS_UPDATE, MyEvent); +wxDEFINE_EVENT(EVT_PREFS_UPDATE, MyEvent); struct PrefsListener::Impl : wxEvtHandler { Impl( PrefsListener &owner ); ~Impl(); - void OnEvent(wxCommandEvent&); + void OnEvent(wxEvent&); PrefsListener &mOwner; }; +static wxEvtHandler hub; + +void PrefsListener::Broadcast(int id) +{ + BasicUI::CallAfter([id]{ + MyEvent event{ id }; + hub.ProcessEvent(event); + }); +} + PrefsListener::Impl::Impl( PrefsListener &owner ) : mOwner{ owner } { - wxTheApp->Bind(EVT_PREFS_UPDATE, &PrefsListener::Impl::OnEvent, this); + hub.Bind(EVT_PREFS_UPDATE, &PrefsListener::Impl::OnEvent, this); } PrefsListener::Impl::~Impl() @@ -104,7 +122,7 @@ void PrefsListener::UpdateSelectedPrefs( int ) { } -void PrefsListener::Impl::OnEvent( wxCommandEvent &evt ) +void PrefsListener::Impl::OnEvent( wxEvent &evt ) { evt.Skip(); auto id = evt.GetId(); diff --git a/src/Prefs.h b/src/Prefs.h index 29d33cdd4..39fceeff2 100644 --- a/src/Prefs.h +++ b/src/Prefs.h @@ -29,8 +29,6 @@ #ifndef __AUDACITY_PREFS__ #define __AUDACITY_PREFS__ - - // Increment this every time the prefs need to be reset // the first part (before the r) indicates the version the reset took place // the second part (after the r) indicates the number of times the prefs have been reset within the same version @@ -385,15 +383,20 @@ public: }; -// An event emitted by the application when the Preference dialog commits -// changes -wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, - EVT_PREFS_UPDATE, wxCommandEvent); - -// Invoke UpdatePrefs() when Preference dialog commits changes. +//! A listener notified of changes in preferences class AUDACITY_DLL_API PrefsListener { public: + //! Call this static function to notify all PrefsListener objects + /*! + @param id when positive, passed to UpdateSelectedPrefs() of all listeners, + meant to indicate that only a certain subset of preferences have changed; + else their UpdatePrefs() methods are called. (That is supposed to happen + when the user OK's changes in the Preferences dialog.) + Callbacks are delayed, in the main thread, using BasicUI::CallAfter + */ + static void Broadcast(int id = 0); + PrefsListener(); virtual ~PrefsListener(); diff --git a/src/menus/ViewMenus.cpp b/src/menus/ViewMenus.cpp index 12d8acc84..9a6d40d2b 100644 --- a/src/menus/ViewMenus.cpp +++ b/src/menus/ViewMenus.cpp @@ -331,8 +331,7 @@ void OnShowClipping(const CommandContext &context) gPrefs->Flush(); commandManager.Check(wxT("ShowClipping"), checked); - wxTheApp->AddPendingEvent(wxCommandEvent{ - EVT_PREFS_UPDATE, ShowClippingPrefsID() }); + PrefsListener::Broadcast(ShowClippingPrefsID()); trackPanel.Refresh(false); } @@ -348,8 +347,7 @@ void OnShowNameOverlay(const CommandContext &context) gPrefs->Flush(); commandManager.Check(wxT("ShowTrackNameInWaveform"), checked); - wxTheApp->AddPendingEvent(wxCommandEvent{ - EVT_PREFS_UPDATE, ShowTrackNameInWaveformPrefsID() }); + PrefsListener::Broadcast(ShowTrackNameInWaveformPrefsID()); trackPanel.Refresh(false); } diff --git a/src/prefs/PrefsDialog.cpp b/src/prefs/PrefsDialog.cpp index 42b7f4caf..50b1c6df4 100644 --- a/src/prefs/PrefsDialog.cpp +++ b/src/prefs/PrefsDialog.cpp @@ -766,7 +766,7 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event)) // so AudacityProject::UpdatePrefs() or any of the routines it calls must // not cause MenuCreator::RebuildMenuBar() to be executed. - wxTheApp->AddPendingEvent(wxCommandEvent{ EVT_PREFS_UPDATE }); + PrefsListener::Broadcast(); if( IsModal() ) EndModal(true); diff --git a/src/toolbars/DeviceToolBar.cpp b/src/toolbars/DeviceToolBar.cpp index 288d2c0a2..ab1e3b730 100644 --- a/src/toolbars/DeviceToolBar.cpp +++ b/src/toolbars/DeviceToolBar.cpp @@ -681,8 +681,7 @@ void DeviceToolBar::OnChoice(wxCommandEvent &event) gAudioIO->HandleDeviceChange(); } - wxTheApp->AddPendingEvent(wxCommandEvent{ - EVT_PREFS_UPDATE, DeviceToolbarPrefsID() }); + PrefsListener::Broadcast(DeviceToolbarPrefsID()); } void DeviceToolBar::ShowInputDialog() diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index 5fa1ef7ce..e5cfef4da 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -2103,8 +2103,7 @@ void MeterPanel::OnPreferences(wxCommandEvent & WXUNUSED(event)) // Currently, there are 2 playback meters and 2 record meters and any number of // mixerboard meters, so we have to send out an preferences updated message to // ensure they all update themselves. - wxTheApp->AddPendingEvent(wxCommandEvent{ - EVT_PREFS_UPDATE, MeterPrefsID() }); + PrefsListener::Broadcast(MeterPrefsID()); } }