Implement member functions of classes in corresponding .cpp files...

... in four cases; not in some other .cpp file.

This is another move that causes the generated graph to reflect dependencies
correctly.

This fixes other large, hidden cycles that involved PrefsDialog.cpp: there was
link dependency on that when PrefsPanel.h was used for the base class.  No
longer.

Also cycles involving TrackPanel.cpp, which contained the default
implementations for TrackPanelCell and related abstract base classes.
This commit is contained in:
Paul Licameli 2020-05-27 11:07:49 -04:00
parent 0c97138840
commit ae9aca8177
16 changed files with 323 additions and 278 deletions

View File

@ -1512,7 +1512,7 @@ bool AudacityApp::OnInit()
CommandManager::SetMenuHook( [](const CommandID &id){
if (::wxGetMouseState().ShiftDown()) {
// Only want one page of the preferences
PrefsDialog::Factories factories;
PrefsPanel::Factories factories;
factories.push_back(KeyConfigPrefsFactory( id ));
const auto pProject = GetActiveProject();
auto pWindow = FindProjectFrame( pProject );
@ -1651,7 +1651,7 @@ bool AudacityApp::InitTempDir()
}
// Only want one page of the preferences
PrefsDialog::Factories factories;
PrefsPanel::Factories factories;
factories.push_back(DirectoriesPrefsFactory());
GlobalPrefsDialog dialog(nullptr, nullptr, factories);
dialog.ShowModal();

View File

@ -293,7 +293,9 @@ list( APPEND SOURCES
TrackPanel.h
TrackPanelAx.cpp
TrackPanelAx.h
TrackPanelCell.cpp
TrackPanelCell.h
TrackPanelDrawable.cpp
TrackPanelDrawable.h
TrackPanelDrawingContext.h
TrackPanelListener.h
@ -645,6 +647,7 @@ list( APPEND SOURCES
import/ImportLOF.cpp
import/ImportPCM.cpp
import/ImportPlugin.h
import/ImportPlugin.cpp
import/ImportRaw.cpp
import/ImportRaw.h
@ -742,6 +745,7 @@ list( APPEND SOURCES
prefs/PlaybackPrefs.h
prefs/PrefsDialog.cpp
prefs/PrefsDialog.h
prefs/PrefsPanel.cpp
prefs/PrefsPanel.h
prefs/ProjectsPrefs.cpp
prefs/ProjectsPrefs.h

View File

@ -85,7 +85,7 @@ enum {
const int kSlowTimerInterval = 1000; // ms
// This timer interval is used in some busy-wait loops and is much shorter.
// const int kTimerInterval = 50; // ms
const int kTimerInterval = 50; // ms
static double wxDateTime_to_AudacityTime(wxDateTime& dateTime)
{

View File

@ -1549,88 +1549,6 @@ void TrackPanel::OnTrackFocusChange( wxCommandEvent &event )
}
}
TrackPanelDrawable::~TrackPanelDrawable()
{
}
void TrackPanelDrawable::Draw(
TrackPanelDrawingContext &, const wxRect &, unsigned )
{
}
wxRect TrackPanelDrawable::DrawingArea(
TrackPanelDrawingContext &,
const wxRect &rect, const wxRect &, unsigned )
{
return rect;
}
TrackPanelNode::TrackPanelNode()
{
}
TrackPanelNode::~TrackPanelNode()
{
}
TrackPanelGroup::TrackPanelGroup()
{
}
TrackPanelGroup::~TrackPanelGroup()
{
}
TrackPanelCell::~TrackPanelCell()
{
}
HitTestPreview TrackPanelCell::DefaultPreview
(const TrackPanelMouseState &, const AudacityProject *)
{
return {};
}
unsigned TrackPanelCell::HandleWheelRotation
(const TrackPanelMouseEvent &, AudacityProject *)
{
return RefreshCode::Cancelled;
}
unsigned TrackPanelCell::DoContextMenu
(const wxRect &, wxWindow*, wxPoint *, AudacityProject*)
{
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::CaptureKey(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::KeyDown(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::KeyUp(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::Char(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
IsVisibleTrack::IsVisibleTrack(AudacityProject *project)
: mPanelRect {
wxPoint{ 0, ViewInfo::Get( *project ).vpos },

81
src/TrackPanelCell.cpp Normal file
View File

@ -0,0 +1,81 @@
/**********************************************************************
Audacity: A Digital Audio Editor
TrackPanelCell.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "TrackPanelCell.h"
#include <wx/event.h>
#include "HitTestResult.h"
#include "RefreshCode.h"
TrackPanelNode::TrackPanelNode()
{
}
TrackPanelNode::~TrackPanelNode()
{
}
TrackPanelGroup::TrackPanelGroup()
{
}
TrackPanelGroup::~TrackPanelGroup()
{
}
TrackPanelCell::~TrackPanelCell()
{
}
HitTestPreview TrackPanelCell::DefaultPreview
(const TrackPanelMouseState &, const AudacityProject *)
{
return {};
}
unsigned TrackPanelCell::HandleWheelRotation
(const TrackPanelMouseEvent &, AudacityProject *)
{
return RefreshCode::Cancelled;
}
unsigned TrackPanelCell::DoContextMenu
(const wxRect &, wxWindow*, wxPoint *, AudacityProject*)
{
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::CaptureKey(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::KeyDown(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::KeyUp(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}
unsigned TrackPanelCell::Char(
wxKeyEvent &event, ViewInfo &, wxWindow *, AudacityProject *)
{
event.Skip();
return RefreshCode::RefreshNone;
}

View File

@ -136,7 +136,4 @@ public:
AudacityProject *project);
};
// Unnecessary #include to indicate otherwise hidden link dependencies
#include "TrackPanel.h"
#endif

View File

@ -0,0 +1,27 @@
/**********************************************************************
Audacity: A Digital Audio Editor
TrackPanelDrawable.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "TrackPanelDrawable.h"
TrackPanelDrawable::~TrackPanelDrawable()
{
}
void TrackPanelDrawable::Draw(
TrackPanelDrawingContext &, const wxRect &, unsigned )
{
}
wxRect TrackPanelDrawable::DrawingArea(
TrackPanelDrawingContext &,
const wxRect &rect, const wxRect &, unsigned )
{
return rect;
}

View File

@ -11,6 +11,10 @@ Paul Licameli
#ifndef __AUDACITY_TRACK_PANEL_DRAWABLE__
#define __AUDACITY_TRACK_PANEL_DRAWABLE__
#include "Audacity.h"
#include <wx/gdicmn.h> // for wxRect
struct TrackPanelDrawingContext;
class wxRect;
@ -51,7 +55,4 @@ public:
}
};
// Unnecessary #include to indicate otherwise hidden link dependencies
#include "TrackPanel.h"
#endif

View File

@ -886,22 +886,3 @@ void ImportStreamDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
{
EndModal( wxID_CANCEL );
}
ImportFileHandle::ImportFileHandle(const FilePath & filename)
: mFilename(filename)
{
}
ImportFileHandle::~ImportFileHandle()
{
}
void ImportFileHandle::CreateProgress()
{
wxFileName ff( mFilename );
auto title = XO("Importing %s").Format( GetFileDescription() );
mProgress = std::make_unique< ProgressDialog >(
title, Verbatim( ff.GetFullName() ) );
}

View File

@ -0,0 +1,33 @@
/**********************************************************************
Audacity: A Digital Audio Editor
ImportPlugin.cpp
Paul Licameli split from Import.cpp
**********************************************************************/
#include "ImportPlugin.h"
#include <wx/filename.h>
#include "../widgets/ProgressDialog.h"
ImportFileHandle::ImportFileHandle(const FilePath & filename)
: mFilename(filename)
{
}
ImportFileHandle::~ImportFileHandle()
{
}
void ImportFileHandle::CreateProgress()
{
wxFileName ff( mFilename );
auto title = XO("Importing %s").Format( GetFileDescription() );
mProgress = std::make_unique< ProgressDialog >(
title, Verbatim( ff.GetFullName() ) );
}

View File

@ -182,7 +182,4 @@ private:
const FileExtensions mExtensions;
};
// Unnecessary #include to indicate otherwise hidden link dependencies
#include "Import.h"
#endif

View File

@ -17,8 +17,6 @@
#include "../Audacity.h" // for USE_* macros
#include "PrefsDialog.h"
#include <mutex> // for std::call_once
#include <wx/app.h>
#include <wx/setup.h> // for wxUSE_* macros
#include <wx/defs.h>
@ -370,14 +368,6 @@ wxAccStatus TreeCtrlAx::Select(int childId, wxAccSelectionFlags selectFlags)
#endif
// PrefsPanel might move out into its own file in due course.
PluginPath PrefsPanel::GetPath(){ return BUILTIN_PREFS_PANEL_PREFIX + GetSymbol().Internal(); }
VendorSymbol PrefsPanel::GetVendor(){ return XO("Audacity");}
wxString PrefsPanel::GetVersion(){ return AUDACITY_VERSION_STRING;}
BEGIN_EVENT_TABLE(PrefsDialog, wxDialogWrapper)
EVT_BUTTON(wxID_OK, PrefsDialog::OnOK)
EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
@ -452,110 +442,10 @@ int wxTreebookExt::SetSelection(size_t n)
return i;
}
namespace {
struct PrefsItem final : Registry::ConcreteGroupItem<false> {
PrefsPanel::Factory factory;
bool expanded{ false };
PrefsItem( const wxString &name,
const PrefsPanel::Factory &factory_, bool expanded_ )
: ConcreteGroupItem<false>{ name }
, factory{ factory_ }, expanded{ expanded_ }
{}
};
// Collects registry tree nodes into a vector, in preorder.
struct PrefsItemVisitor final : Registry::Visitor {
PrefsItemVisitor( PrefsDialog::Factories &factories_ )
: factories{ factories_ }
{
childCounts.push_back( 0 );
}
void BeginGroup( Registry::GroupItem &item, const Path & ) override
{
auto pItem = dynamic_cast<PrefsItem*>( &item );
if (!pItem)
return;
indices.push_back( factories.size() );
factories.emplace_back( pItem->factory, 0, pItem->expanded );
++childCounts.back();
childCounts.push_back( 0 );
}
void EndGroup( Registry::GroupItem &item, const Path & ) override
{
auto pItem = dynamic_cast<PrefsItem*>( &item );
if (!pItem)
return;
auto &factory = factories[ indices.back() ];
factory.nChildren = childCounts.back();
childCounts.pop_back();
indices.pop_back();
}
PrefsDialog::Factories &factories;
std::vector<size_t> childCounts;
std::vector<size_t> indices;
};
const auto PathStart = wxT("Preferences");
}
namespace {
static Registry::GroupItem &sRegistry()
{
static Registry::TransparentGroupItem<> registry{ PathStart };
return registry;
}
}
PrefsPanel::Registration::Registration( const wxString &name,
const Factory &factory, bool expanded,
const Registry::Placement &placement )
{
Registry::RegisterItem( sRegistry(), placement,
std::make_unique< PrefsItem >( name, factory, expanded ) );
}
PrefsDialog::Factories
&PrefsDialog::DefaultFactories()
{
// Once only, cause initial population of preferences for the ordering
// of some preference pages that used to be given in a table but are now
// separately registered in several .cpp files; the sequence of registration
// depends on unspecified accidents of static initialization order across
// compilation units, so we need something specific here to preserve old
// default appearance of the preference dialog.
// But this needs only to mention some strings -- there is no compilation or
// link dependency of this source file on those other implementation files.
static Registry::OrderingPreferenceInitializer init{
PathStart,
{
{wxT(""),
wxT("Device,Playback,Recording,Quality,GUI,Tracks,ImportExport,Directories,Warnings,Effects,KeyConfig,Mouse")
},
{wxT("/Tracks"), wxT("TracksBehaviors,Spectrum")},
}
};
static Factories factories;
static std::once_flag flag;
std::call_once( flag, []{
PrefsItemVisitor visitor{ factories };
Registry::TransparentGroupItem<> top{ PathStart };
Registry::Visit( visitor, &top, &sRegistry() );
} );
return factories;
}
PrefsDialog::PrefsDialog(
wxWindow * parent, AudacityProject *pProject,
const TranslatableString &titlePrefix, Factories &factories)
const TranslatableString &titlePrefix,
PrefsPanel::Factories &factories)
: wxDialogWrapper(parent, wxID_ANY, XO("Audacity Preferences"),
wxDefaultPosition,
wxDefaultSize,
@ -591,11 +481,11 @@ PrefsDialog::PrefsDialog(
typedef std::pair<int, int> IntPair;
std::vector<IntPair> stack;
int iPage = 0;
for (Factories::const_iterator it = factories.begin(), end = factories.end();
for (auto it = factories.begin(), end = factories.end();
it != end; ++it, ++iPage)
{
const PrefsNode &node = *it;
const PrefsPanel::Factory &factory = node.factory;
const auto &node = *it;
const auto &factory = node.factory;
wxWindow *const w = factory(mCategories, wxID_ANY, pProject);
if (stack.empty())
// Parameters are: AddPage(page, name, IsSelected, imageId).
@ -622,8 +512,8 @@ PrefsDialog::PrefsDialog(
// And then hiding the treebook.
// Unique page, don't show the factory
const PrefsNode &node = factories[0];
const PrefsPanel::Factory &factory = node.factory;
const auto &node = factories[0];
const auto &factory = node.factory;
mUniquePage = factory(S.GetParent(), wxID_ANY, pProject);
wxWindow * uniquePageWindow = S.Prop(1)
.Position(wxEXPAND)
@ -663,7 +553,7 @@ PrefsDialog::PrefsDialog(
if (mCategories)
{
int iPage = 0;
for (Factories::const_iterator it = factories.begin(), end = factories.end();
for (auto it = factories.begin(), end = factories.end();
it != end; ++it, ++iPage)
mCategories->ExpandNode(iPage, it->expanded);
}
@ -907,7 +797,8 @@ int PrefsDialog::GetSelectedPage() const
}
GlobalPrefsDialog::GlobalPrefsDialog(
wxWindow * parent, AudacityProject *pProject, Factories &factories)
wxWindow * parent, AudacityProject *pProject,
PrefsPanel::Factories &factories)
: PrefsDialog(parent, pProject, XO("Preferences:"), factories)
{
}
@ -934,7 +825,7 @@ void PrefsDialog::RecordExpansionState()
if (mCategories)
{
int iPage = 0;
for (Factories::iterator it = mFactories.begin(), end = mFactories.end();
for (auto it = mFactories.begin(), end = mFactories.end();
it != end; ++it, ++iPage)
it->expanded = mCategories->IsNodeExpanded(iPage);
}
@ -942,24 +833,6 @@ void PrefsDialog::RecordExpansionState()
mFactories[0].expanded = true;
}
PrefsPanel::~PrefsPanel()
{
}
void PrefsPanel::Cancel()
{
}
bool PrefsPanel::ShowsPreviewButton()
{
return false;
}
wxString PrefsPanel::HelpPageName()
{
return wxEmptyString;
}
#include <wx/frame.h>
#include "../Menus.h"
#include "../Project.h"

View File

@ -15,11 +15,11 @@
#include <functional>
#include <vector>
#include "../widgets/wxPanelWrapper.h" // to inherit
#include "PrefsPanel.h"
class AudacityProject;
class wxTreebook;
class wxTreeEvent;
class PrefsPanel;
class ShuttleGui;
#ifdef __GNUC__
@ -33,28 +33,11 @@ class AudacityProject;
class PrefsDialog /* not final */ : public wxDialogWrapper
{
public:
// An array of PrefsNode specifies the tree of pages in pre-order traversal.
struct PrefsNode {
using Factory =
std::function< PrefsPanel * (
wxWindow *parent, wxWindowID winid, AudacityProject *) >;
Factory factory;
size_t nChildren{ 0 };
bool expanded{ false };
PrefsNode(const Factory &factory_,
unsigned nChildren_ = 0,
bool expanded_ = true)
: factory(factory_), nChildren(nChildren_), expanded(expanded_)
{}
};
typedef std::vector<PrefsNode> Factories;
static Factories &DefaultFactories();
PrefsDialog(wxWindow * parent,
AudacityProject *pProject, // may be null
const TranslatableString &titlePrefix = XO("Preferences:"),
Factories &factories = DefaultFactories());
PrefsPanel::Factories &factories =
PrefsPanel::DefaultFactories());
virtual ~PrefsDialog();
// Defined this so a protected virtual can be invoked after the constructor
@ -86,7 +69,7 @@ private:
PrefsPanel * GetCurrentPanel();
wxTreebook *mCategories{};
PrefsPanel *mUniquePage{};
Factories &mFactories;
PrefsPanel::Factories &mFactories;
const TranslatableString mTitlePrefix;
DECLARE_EVENT_TABLE()
@ -99,7 +82,8 @@ class GlobalPrefsDialog final : public PrefsDialog
public:
GlobalPrefsDialog(
wxWindow * parent, AudacityProject *pProject,
Factories &factories = DefaultFactories());
PrefsPanel::Factories &factories =
PrefsPanel::DefaultFactories());
virtual ~GlobalPrefsDialog();
long GetPreferredPage() override;
void SavePreferredPage() override;

133
src/prefs/PrefsPanel.cpp Normal file
View File

@ -0,0 +1,133 @@
/**********************************************************************
Audacity: A Digital Audio Editor
PrefsPanel.cpp
Paul Licameli split from PrefsDialog.cpp
**********************************************************************/
#include "PrefsPanel.h"
#include <mutex>
namespace {
const auto PathStart = wxT("Preferences");
static Registry::GroupItem &sRegistry()
{
static Registry::TransparentGroupItem<> registry{ PathStart };
return registry;
}
struct PrefsItem final : Registry::ConcreteGroupItem<false> {
PrefsPanel::Factory factory;
bool expanded{ false };
PrefsItem( const wxString &name,
const PrefsPanel::Factory &factory_, bool expanded_ )
: ConcreteGroupItem<false>{ name }
, factory{ factory_ }, expanded{ expanded_ }
{}
};
// Collects registry tree nodes into a vector, in preorder.
struct PrefsItemVisitor final : Registry::Visitor {
PrefsItemVisitor( PrefsPanel::Factories &factories_ )
: factories{ factories_ }
{
childCounts.push_back( 0 );
}
void BeginGroup( Registry::GroupItem &item, const Path & ) override
{
auto pItem = dynamic_cast<PrefsItem*>( &item );
if (!pItem)
return;
indices.push_back( factories.size() );
factories.emplace_back( pItem->factory, 0, pItem->expanded );
++childCounts.back();
childCounts.push_back( 0 );
}
void EndGroup( Registry::GroupItem &item, const Path & ) override
{
auto pItem = dynamic_cast<PrefsItem*>( &item );
if (!pItem)
return;
auto &factory = factories[ indices.back() ];
factory.nChildren = childCounts.back();
childCounts.pop_back();
indices.pop_back();
}
PrefsPanel::Factories &factories;
std::vector<size_t> childCounts;
std::vector<size_t> indices;
};
}
PluginPath PrefsPanel::GetPath()
{ return BUILTIN_PREFS_PANEL_PREFIX + GetSymbol().Internal(); }
VendorSymbol PrefsPanel::GetVendor()
{ return XO("Audacity");}
wxString PrefsPanel::GetVersion()
{ return AUDACITY_VERSION_STRING;}
PrefsPanel::Registration::Registration( const wxString &name,
const Factory &factory, bool expanded,
const Registry::Placement &placement )
{
Registry::RegisterItem( sRegistry(), placement,
std::make_unique< PrefsItem >( name, factory, expanded ) );
}
PrefsPanel::~PrefsPanel()
{
}
void PrefsPanel::Cancel()
{
}
bool PrefsPanel::ShowsPreviewButton()
{
return false;
}
wxString PrefsPanel::HelpPageName()
{
return wxEmptyString;
}
PrefsPanel::Factories
&PrefsPanel::DefaultFactories()
{
// Once only, cause initial population of preferences for the ordering
// of some preference pages that used to be given in a table but are now
// separately registered in several .cpp files; the sequence of registration
// depends on unspecified accidents of static initialization order across
// compilation units, so we need something specific here to preserve old
// default appearance of the preference dialog.
// But this needs only to mention some strings -- there is no compilation or
// link dependency of this source file on those other implementation files.
static Registry::OrderingPreferenceInitializer init{
PathStart,
{
{wxT(""),
wxT("Device,Playback,Recording,Quality,GUI,Tracks,ImportExport,Directories,Warnings,Effects,KeyConfig,Mouse")
},
{wxT("/Tracks"), wxT("TracksBehaviors,Spectrum")},
}
};
static Factories factories;
static std::once_flag flag;
std::call_once( flag, []{
PrefsItemVisitor visitor{ factories };
Registry::TransparentGroupItem<> top{ PathStart };
Registry::Visit( visitor, &top, &sRegistry() );
} );
return factories;
}

View File

@ -49,6 +49,25 @@ class ShuttleGui;
class PrefsPanel /* not final */ : public wxPanelWrapper, ComponentInterface
{
public:
// An array of PrefsNode specifies the tree of pages in pre-order traversal.
struct PrefsNode {
using Factory =
std::function< PrefsPanel * (
wxWindow *parent, wxWindowID winid, AudacityProject *) >;
Factory factory;
size_t nChildren{ 0 };
bool expanded{ false };
PrefsNode(const Factory &factory_,
unsigned nChildren_ = 0,
bool expanded_ = true)
: factory(factory_), nChildren(nChildren_), expanded(expanded_)
{}
};
using Factories = std::vector<PrefsPanel::PrefsNode>;
static Factories &DefaultFactories();
// \brief Type alias for factories such as GUIPrefsFactory that produce a
// PrefsPanel, used by the Preferences dialog in a treebook.
// The project pointer may be null. Usually it's not needed because
@ -102,7 +121,4 @@ class PrefsPanel /* not final */ : public wxPanelWrapper, ComponentInterface
virtual void Cancel();
};
// Unnecessary #include to indicate otherwise hidden link dependencies
#include "PrefsDialog.h"
#endif

View File

@ -712,7 +712,7 @@ void SpectrogramSettingsHandler::OnSpectrogramSettings(wxCommandEvent &)
{
public:
ViewSettingsDialog(wxWindow *parent, AudacityProject &project,
const TranslatableString &title, PrefsDialog::Factories &factories,
const TranslatableString &title, PrefsPanel::Factories &factories,
int page)
: PrefsDialog(parent, &project, title, factories)
, mPage(page)
@ -744,7 +744,7 @@ void SpectrogramSettingsHandler::OnSpectrogramSettings(wxCommandEvent &)
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
PrefsDialog::Factories factories;
PrefsPanel::Factories factories;
// factories.push_back(WaveformPrefsFactory( pTrack ));
factories.push_back(SpectrumPrefsFactory( pTrack ));
const int page =