1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-18 17:10:05 +02:00

Table-driven construction of Prefs dialog. A factory for each kind of panel...

... and maybe a future plug-in protocol to break compilation dependency on
all of the PrefsPanel subclasses.
This commit is contained in:
Paul Licameli 2015-06-13 17:59:47 -04:00
parent 3e5d2af7cb
commit 8399effc45
43 changed files with 359 additions and 36 deletions

View File

@ -82,3 +82,8 @@ bool BatchPrefs::Apply()
BatchPrefs::~BatchPrefs()
{
}
PrefsPanel *BatchPrefsFactory::Create(wxWindow *parent)
{
return new BatchPrefs(parent);
}

View File

@ -34,4 +34,9 @@ private:
DECLARE_EVENT_TABLE();
};
class BatchPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -373,3 +373,8 @@ bool DevicePrefs::Apply()
return true;
}
PrefsPanel *DevicePrefsFactory::Create(wxWindow *parent)
{
return new DevicePrefs(parent);
}

View File

@ -54,4 +54,10 @@ class DevicePrefs :public PrefsPanel
DECLARE_EVENT_TABLE();
};
class DevicePrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -242,3 +242,8 @@ bool DirectoriesPrefs::Apply()
return true;
}
PrefsPanel *DirectoriesPrefsFactory::Create(wxWindow *parent)
{
return new DirectoriesPrefs(parent);
}

View File

@ -38,4 +38,9 @@ class DirectoriesPrefs :public PrefsPanel
DECLARE_EVENT_TABLE();
};
class DirectoriesPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -165,3 +165,8 @@ bool EffectsPrefs::Apply()
return true;
}
PrefsPanel *EffectsPrefsFactory::Create(wxWindow *parent)
{
return new EffectsPrefs(parent);
}

View File

@ -34,4 +34,9 @@ class EffectsPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class EffectsPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -780,3 +780,8 @@ void ExtImportPrefsDropTarget::SetDataObject(wxDataObject* data)
{
this->m_dataObject = data;
}
PrefsPanel *ExtImportPrefsFactory::Create(wxWindow *parent)
{
return new ExtImportPrefs(parent);
}

View File

@ -107,4 +107,10 @@ class ExtImportPrefs:public PrefsPanel
DECLARE_EVENT_TABLE()
};
class ExtImportPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -158,3 +158,8 @@ bool GUIPrefs::Apply()
return true;
}
PrefsPanel *GUIPrefsFactory::Create(wxWindow *parent)
{
return new GUIPrefs(parent);
}

View File

@ -43,4 +43,9 @@ class GUIPrefs :public PrefsPanel
wxArrayString mRangeChoices;
};
class GUIPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -109,3 +109,8 @@ bool ImportExportPrefs::Apply()
return true;
}
PrefsPanel *ImportExportPrefsFactory::Create(wxWindow *parent)
{
return new ImportExportPrefs(parent);
}

View File

@ -33,4 +33,9 @@ class ImportExportPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class ImportExportPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -1211,3 +1211,8 @@ void KeyConfigPrefs::Cancel()
}
#endif
PrefsPanel *KeyConfigPrefsFactory::Create(wxWindow *parent)
{
return new KeyConfigPrefs(parent);
}

View File

@ -141,6 +141,12 @@ class KeyConfigPrefs:public PrefsPanel
DECLARE_EVENT_TABLE();
};
#endif
#endif
class KeyConfigPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -235,3 +235,8 @@ bool LibraryPrefs::Apply()
return true;
}
PrefsPanel *LibraryPrefsFactory::Create(wxWindow *parent)
{
return new LibraryPrefs(parent);
}

View File

@ -46,4 +46,9 @@ class LibraryPrefs :public PrefsPanel
DECLARE_EVENT_TABLE();
};
class LibraryPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -284,4 +284,9 @@ bool MidiIOPrefs::Validate()
return true;
}
PrefsPanel *MidiIOPrefsFactory::Create(wxWindow *parent)
{
return new MidiIOPrefs(parent);
}
#endif

View File

@ -62,6 +62,11 @@ class MidiIOPrefs:public PrefsPanel
DECLARE_EVENT_TABLE();
};
class MidiIOPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif
#endif

View File

@ -161,5 +161,9 @@ void ModulePrefs::SetModuleStatus( wxString fname, int iStatus ){
gPrefs->Flush();
}
PrefsPanel *ModulePrefsFactory::Create(wxWindow *parent)
{
return new ModulePrefs(parent);
}

View File

@ -50,4 +50,9 @@ class ModulePrefs:public PrefsPanel
wxArrayString mPaths;
};
class ModulePrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -196,3 +196,8 @@ bool MousePrefs::Apply()
// PopulateOrExchange(S);
return true;
}
PrefsPanel *MousePrefsFactory::Create(wxWindow *parent)
{
return new MousePrefs(parent);
}

View File

@ -38,4 +38,9 @@ class MousePrefs :public PrefsPanel
wxListCtrl * mList;
};
class MousePrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -122,3 +122,8 @@ bool PlaybackPrefs::Apply()
return true;
}
PrefsPanel *PlaybackPrefsFactory::Create(wxWindow *parent)
{
return new PlaybackPrefs(parent);
}

View File

@ -32,4 +32,10 @@ class PlaybackPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class PlaybackPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -15,6 +15,7 @@
*//*******************************************************************/
#include "../Audacity.h"
#include "PrefsDialog.h"
#include <wx/defs.h>
#include <wx/button.h>
@ -41,7 +42,6 @@
#include "../Prefs.h"
#include "../ShuttleGui.h"
#include "PrefsDialog.h"
#include "PrefsPanel.h"
#include "BatchPrefs.h"
@ -108,11 +108,82 @@ int wxTreebookExt::SetSelection(size_t n)
PrefsDialog::PrefsDialog(wxWindow * parent)
PrefsDialog::Factories
&PrefsDialog::DefaultFactories()
{
// To do, perhaps: create this table by registration, without including each PrefsPanel
// class... and thus allowing a plug-in protocol
static DevicePrefsFactory devicePrefsFactory;
static PlaybackPrefsFactory playbackPrefsFactory;
static RecordingPrefsFactory recordingPrefsFactory;
#ifdef EXPERIMENTAL_MIDI_OUT
static MidiIOPrefsFactory midiIOPrefsFactory;
#endif
static QualityPrefsFactory qualityPrefsFactory;
static GUIPrefsFactory guiPrefsFactory;
static TracksPrefsFactory tracksPrefsFactory;
static ImportExportPrefsFactory importExportPrefsFactory;
static ExtImportPrefsFactory extImportPrefsFactory;
static ProjectsPrefsFactory projectsPrefsFactory;
#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
static LibraryPrefsFactory libraryPrefsFactory;
#endif
static SpectrumPrefsFactory spectrumPrefsFactory;
static DirectoriesPrefsFactory directoriesPrefsFactory;
static WarningsPrefsFactory warningsPrefsFactory;
static EffectsPrefsFactory effectsPrefsFactory;
#ifdef EXPERIMENTAL_THEME_PREFS
static ThemePrefsFactory themePrefsFactory;
#endif
// static BatchPrefsFactory batchPrefsFactory;
static KeyConfigPrefsFactory keyConfigPrefsFactory;
static MousePrefsFactory mousePrefsFactory;
#ifdef EXPERIMENTAL_MODULE_PREFS
static ModulePrefsFactory modulePrefsFactory;
#endif
static PrefsNode nodes[] = {
&devicePrefsFactory,
&playbackPrefsFactory,
&recordingPrefsFactory,
#ifdef EXPERIMENTAL_MIDI_OUT
&midiIOPrefsFactory,
#endif
&qualityPrefsFactory,
&guiPrefsFactory,
&tracksPrefsFactory,
&importExportPrefsFactory,
&extImportPrefsFactory,
&projectsPrefsFactory,
#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
&libraryPrefsFactory,
#endif
&spectrumPrefsFactory,
&directoriesPrefsFactory,
&warningsPrefsFactory,
&effectsPrefsFactory,
#ifdef EXPERIMENTAL_THEME_PREFS
&themePrefsFactory,
#endif
// &batchPrefsFactory,
&keyConfigPrefsFactory,
&mousePrefsFactory,
#ifdef EXPERIMENTAL_MODULE_PREFS
&modulePrefsFactory,
#endif
};
static Factories factories(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
return factories;
}
PrefsDialog::PrefsDialog(wxWindow * parent, Factories &factories)
: wxDialog(parent, wxID_ANY, wxString(_("Audacity Preferences")),
wxDefaultPosition,
wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, mFactories(factories)
{
ShuttleGui S(this, eIsCreating);
@ -124,38 +195,32 @@ PrefsDialog::PrefsDialog(wxWindow * parent)
S.Prop(1);
S.AddWindow(mCategories, wxEXPAND);
wxWindow *w;
// Parameters are: AddPage(page, name, IsSelected, imageId).
w = new DevicePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new PlaybackPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new RecordingPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#ifdef EXPERIMENTAL_MIDI_OUT
w = new MidiIOPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#endif
w = new QualityPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new GUIPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new TracksPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new ImportExportPrefs(mCategories);mCategories->AddPage(w, w->GetName(), false, 0);
w = new ExtImportPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new ProjectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
w = new LibraryPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#endif
w = new SpectrumPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new DirectoriesPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new WarningsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new EffectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#ifdef EXPERIMENTAL_THEME_PREFS
w = new ThemePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#endif
// w = new BatchPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new KeyConfigPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
w = new MousePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#ifdef EXPERIMENTAL_MODULE_PREFS
w = new ModulePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0);
#endif
{
typedef std::pair<int, int> IntPair;
std::vector<IntPair> stack;
int iPage = 0;
for (Factories::const_iterator it = factories.begin(), end = factories.end();
it != end; ++it, ++iPage)
{
const PrefsNode &node = *it;
PrefsPanelFactory &factory = *node.pFactory;
wxWindow *const w = factory.Create(mCategories);
if (stack.empty())
// Parameters are: AddPage(page, name, IsSelected, imageId).
mCategories->AddPage(w, w->GetName(), false, 0);
else {
IntPair &top = *stack.rbegin();
mCategories->InsertSubPage(top.first, w, w->GetName(), false, 0);
if (--top.second == 0) {
// Expand all nodes before the layout calculation
mCategories->ExpandNode(top.first, true);
stack.pop_back();
}
}
if (node.nChildren > 0)
stack.push_back(IntPair(iPage, node.nChildren));
}
}
}
S.EndHorizontalLay();
}
@ -189,6 +254,14 @@ PrefsDialog::PrefsDialog(wxWindow * parent)
Fit();
wxSize sz = GetSize();
// Collapse nodes only after layout so the tree is wide enough
{
int iPage = 0;
for (Factories::const_iterator it = factories.begin(), end = factories.end();
it != end; ++it, ++iPage)
mCategories->ExpandNode(iPage, it->expanded);
}
// This ASSERT used to limit us to 800 x 600.
// However, we think screens have got bigger now, and that was a bit too restrictive.
// The impetus for increasing the limit (before we ASSERT) was that this ASSERT
@ -221,6 +294,8 @@ PrefsDialog::~PrefsDialog()
void PrefsDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
{
RecordExpansionState();
for (size_t i = 0; i < mCategories->GetPageCount(); i++) {
((PrefsPanel *) mCategories->GetPage(i))->Cancel();
}
@ -238,6 +313,8 @@ void PrefsDialog::OnTreeKeyDown(wxTreeEvent & event)
void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
{
RecordExpansionState();
// Validate all pages first
for (size_t i = 0; i < mCategories->GetPageCount(); i++) {
PrefsPanel *panel = (PrefsPanel *) mCategories->GetPage(i);
@ -311,3 +388,14 @@ void PrefsDialog::ShowTempDirPage()
{
SelectPageByName(_("Directories"));
}
void PrefsDialog::RecordExpansionState()
{
// Remember expansion state of the tree control
{
int iPage = 0;
for (Factories::iterator it = mFactories.begin(), end = mFactories.end();
it != end; ++it, ++iPage)
it->expanded = mCategories->IsNodeExpanded(iPage);
}
}

View File

@ -12,6 +12,7 @@
#ifndef __AUDACITY_PREFS_DIALOG__
#define __AUDACITY_PREFS_DIALOG__
#include <vector>
#include <wx/button.h>
#include <wx/event.h>
#include <wx/dialog.h>
@ -19,10 +20,31 @@
#include <wx/treebook.h>
#include <wx/window.h>
class PrefsPanelFactory;
#ifdef __GNUC__
#define CONST
#else
#define CONST const
#endif
class PrefsDialog:public wxDialog
{
public:
PrefsDialog(wxWindow * parent);
// An array of PrefsNode specifies the tree of pages in pre-order traversal.
struct PrefsNode {
PrefsPanelFactory * CONST pFactory;
CONST int nChildren;
bool expanded;
PrefsNode(PrefsPanelFactory *pFactory_, int nChildren_ = 0)
: pFactory(pFactory_), nChildren(nChildren_), expanded(false)
{}
};
typedef std::vector<PrefsNode> Factories;
static Factories &DefaultFactories();
PrefsDialog(wxWindow * parent, Factories &factories = DefaultFactories());
virtual ~PrefsDialog();
void OnCategoryChange(wxCommandEvent & e);
@ -34,7 +56,10 @@ class PrefsDialog:public wxDialog
void ShowTempDirPage();
private:
void RecordExpansionState();
wxTreebook *mCategories;
Factories &mFactories;
DECLARE_EVENT_TABLE()
};

View File

@ -61,4 +61,10 @@ class PrefsPanel:public wxPanel
}
};
class PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent) = 0;
};
#endif

View File

@ -79,3 +79,8 @@ bool ProjectsPrefs::Apply()
return true;
}
PrefsPanel *ProjectsPrefsFactory::Create(wxWindow *parent)
{
return new ProjectsPrefs(parent);
}

View File

@ -33,4 +33,9 @@ class ProjectsPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class ProjectsPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -228,3 +228,8 @@ bool QualityPrefs::Apply()
return true;
}
PrefsPanel *QualityPrefsFactory::Create(wxWindow *parent)
{
return new QualityPrefs(parent);
}

View File

@ -53,4 +53,9 @@ class QualityPrefs :public PrefsPanel
DECLARE_EVENT_TABLE();
};
class QualityPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -202,3 +202,8 @@ bool RecordingPrefs::Apply()
#endif
return gPrefs->Flush();
}
PrefsPanel *RecordingPrefsFactory::Create(wxWindow *parent)
{
return new RecordingPrefs(parent);
}

View File

@ -32,4 +32,9 @@ class RecordingPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class RecordingPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -342,6 +342,11 @@ BEGIN_EVENT_TABLE(SpectrumPrefs, PrefsPanel)
EVT_CHOICE(ID_WINDOW_SIZE, SpectrumPrefs::OnWindowSize)
END_EVENT_TABLE()
PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent)
{
return new SpectrumPrefs(parent);
}
SpectrogramSettings::SpectrogramSettings()
: hFFT(0)
, window(0)

View File

@ -124,4 +124,10 @@ public:
#endif
};
class SpectrumPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -205,3 +205,8 @@ bool ThemePrefs::Apply()
return true;
}
PrefsPanel *ThemePrefsFactory::Create(wxWindow *parent)
{
return new ThemePrefs(parent);
}

View File

@ -41,4 +41,9 @@ class ThemePrefs :public PrefsPanel
DECLARE_EVENT_TABLE();
};
class ThemePrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -165,3 +165,8 @@ bool TracksPrefs::Apply()
return true;
}
PrefsPanel *TracksPrefsFactory::Create(wxWindow *parent)
{
return new TracksPrefs(parent);
}

View File

@ -39,4 +39,9 @@ class TracksPrefs :public PrefsPanel
wxArrayString mViewChoices;
};
class TracksPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif

View File

@ -83,3 +83,8 @@ bool WarningsPrefs::Apply()
return true;
}
PrefsPanel *WarningsPrefsFactory::Create(wxWindow *parent)
{
return new WarningsPrefs(parent);
}

View File

@ -33,4 +33,9 @@ class WarningsPrefs :public PrefsPanel
void PopulateOrExchange(ShuttleGui & S);
};
class WarningsPrefsFactory : public PrefsPanelFactory
{
public:
virtual PrefsPanel *Create(wxWindow *parent);
};
#endif