1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-29 22:58:39 +02:00

PopupMenuTable need not publicize its wxMenu subclass

This commit is contained in:
Paul Licameli 2020-02-04 20:51:29 -05:00
parent 9435e97fb8
commit 3517b900b1
11 changed files with 63 additions and 58 deletions

View File

@ -297,8 +297,7 @@ UIHandle::Result NoteTrackVZoomHandle::Release
PopupMenuTable *const pTable = PopupMenuTable *const pTable =
(PopupMenuTable *) &NoteTrackVRulerMenuTable::Instance(); (PopupMenuTable *) &NoteTrackVRulerMenuTable::Instance();
std::unique_ptr<PopupMenuTable::Menu> auto pMenu = PopupMenuTable::BuildMenu(pParent, pTable, &data);
pMenu(PopupMenuTable::BuildMenu(pParent, pTable, &data));
// Accelerators only if zooming enabled. // Accelerators only if zooming enabled.
if( !bVZoom ) if( !bVZoom )

View File

@ -265,7 +265,7 @@ PopupMenuTable &SpectrumVRulerMenuTable::Instance()
return instance; return instance;
} }
void SpectrumVRulerMenuTable::InitMenu(Menu *pMenu) void SpectrumVRulerMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrackVRulerMenuTable::InitMenu(pMenu); WaveTrackVRulerMenuTable::InitMenu(pMenu);

View File

@ -83,7 +83,7 @@ public:
static PopupMenuTable &Instance(); static PopupMenuTable &Instance();
private: private:
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void OnSpectrumScaleType(wxCommandEvent &evt); void OnSpectrumScaleType(wxCommandEvent &evt);
}; };

View File

@ -162,7 +162,7 @@ public:
private: private:
void InitUserData(void *pUserData) override; void InitUserData(void *pUserData) override;
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void DestroyMenu() override void DestroyMenu() override
{ {
@ -186,7 +186,7 @@ void WaveColorMenuTable::InitUserData(void *pUserData)
mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData); mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
} }
void WaveColorMenuTable::InitMenu(Menu *pMenu) void WaveColorMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack); WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
auto WaveColorId = IdOfWaveColor( pTrack->GetWaveColorIndex()); auto WaveColorId = IdOfWaveColor( pTrack->GetWaveColorIndex());
@ -261,7 +261,7 @@ public:
private: private:
void InitUserData(void *pUserData) override; void InitUserData(void *pUserData) override;
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void DestroyMenu() override void DestroyMenu() override
{ {
@ -286,7 +286,7 @@ void FormatMenuTable::InitUserData(void *pUserData)
mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData); mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
} }
void FormatMenuTable::InitMenu(Menu *pMenu) void FormatMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack); WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
auto formatId = IdOfFormat(pTrack->GetSampleFormat()); auto formatId = IdOfFormat(pTrack->GetSampleFormat());
@ -384,7 +384,7 @@ public:
private: private:
void InitUserData(void *pUserData) override; void InitUserData(void *pUserData) override;
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void DestroyMenu() override void DestroyMenu() override
{ {
@ -411,7 +411,7 @@ void RateMenuTable::InitUserData(void *pUserData)
mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData); mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
} }
void RateMenuTable::InitMenu(Menu *pMenu) void RateMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack); WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
const auto rateId = IdOfRate((int)pTrack->GetRate()); const auto rateId = IdOfRate((int)pTrack->GetRate());
@ -583,7 +583,7 @@ protected:
WaveTrackMenuTable() : mpData(NULL) {mpTrack=NULL;} WaveTrackMenuTable() : mpData(NULL) {mpTrack=NULL;}
void InitUserData(void *pUserData) override; void InitUserData(void *pUserData) override;
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void DestroyMenu() override void DestroyMenu() override
{ {
@ -637,7 +637,7 @@ static std::vector<WaveTrackSubViewType> AllTypes()
return result; return result;
} }
void WaveTrackMenuTable::InitMenu(Menu *pMenu) void WaveTrackMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack); WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);

View File

@ -118,8 +118,7 @@ UIHandle::Result WaveTrackVZoomHandle::DoRelease(
*pProject, *pProject,
pTrack, rect, RefreshCode::RefreshNone, event.m_y, doZoom }; pTrack, rect, RefreshCode::RefreshNone, event.m_y, doZoom };
std::unique_ptr<PopupMenuTable::Menu> auto pMenu = PopupMenuTable::BuildMenu(pParent, &table, &data);
pMenu(PopupMenuTable::BuildMenu(pParent, &table, &data));
// Accelerators only if zooming enabled. // Accelerators only if zooming enabled.
if( !bVZoom ) if( !bVZoom )

View File

@ -266,7 +266,7 @@ PopupMenuTable &WaveformVRulerMenuTable::Instance()
return instance; return instance;
} }
void WaveformVRulerMenuTable::InitMenu(Menu *pMenu) void WaveformVRulerMenuTable::InitMenu(wxMenu *pMenu)
{ {
WaveTrackVRulerMenuTable::InitMenu(pMenu); WaveTrackVRulerMenuTable::InitMenu(pMenu);

View File

@ -83,7 +83,7 @@ public:
static PopupMenuTable &Instance(); static PopupMenuTable &Instance();
private: private:
virtual void InitMenu(Menu *pMenu) override; virtual void InitMenu(wxMenu *pMenu) override;
void OnWaveformScaleType(wxCommandEvent &evt); void OnWaveformScaleType(wxCommandEvent &evt);
}; };

View File

@ -52,7 +52,7 @@ private:
mpData = static_cast<CommonTrackControls::InitMenuData*>(pUserData); mpData = static_cast<CommonTrackControls::InitMenuData*>(pUserData);
} }
void InitMenu(Menu *pMenu) override void InitMenu(wxMenu *pMenu) override
{ {
TimeTrack *const pTrack = static_cast<TimeTrack*>(mpData->pTrack); TimeTrack *const pTrack = static_cast<TimeTrack*>(mpData->pTrack);

View File

@ -91,7 +91,7 @@ private:
void OnMoveTrack(wxCommandEvent &event); void OnMoveTrack(wxCommandEvent &event);
void InitUserData(void *pUserData) override; void InitUserData(void *pUserData) override;
void InitMenu(Menu *pMenu) override; void InitMenu(wxMenu *pMenu) override;
void DestroyMenu() override void DestroyMenu() override
{ {
@ -112,7 +112,7 @@ void TrackMenuTable::InitUserData(void *pUserData)
mpData = static_cast<CommonTrackControls::InitMenuData*>(pUserData); mpData = static_cast<CommonTrackControls::InitMenuData*>(pUserData);
} }
void TrackMenuTable::InitMenu(Menu *pMenu) void TrackMenuTable::InitMenu(wxMenu *pMenu)
{ {
Track *const pTrack = mpData->pTrack; Track *const pTrack = mpData->pTrack;
@ -282,7 +282,7 @@ unsigned CommonTrackControls::DoContextMenu(
PopupMenuTable *const pExtension = GetMenuExtension(track.get()); PopupMenuTable *const pExtension = GetMenuExtension(track.get());
if (pExtension) if (pExtension)
pMenu->Extend(pExtension); PopupMenuTable::ExtendMenu( *pMenu, *pExtension );
pParent->PopupMenu pParent->PopupMenu
(pMenu.get(), buttonRect.x + 1, buttonRect.y + buttonRect.height + 1); (pMenu.get(), buttonRect.x + 1, buttonRect.y + buttonRect.height + 1);

View File

@ -11,14 +11,31 @@ Paul Licameli split from TrackPanel.cpp
#include "../Audacity.h" #include "../Audacity.h"
#include "PopupMenuTable.h" #include "PopupMenuTable.h"
PopupMenuTable::Menu::~Menu() namespace {
struct PopupMenu : public wxMenu
{
PopupMenu(wxEvtHandler *pParent_, void *pUserData_)
: pParent{ pParent_ }, tables{}, pUserData{ pUserData_ } {}
~PopupMenu() override;
void Extend(PopupMenuTable *pTable);
void DisconnectTable(PopupMenuTable *pTable);
void Disconnect();
wxEvtHandler *pParent;
std::vector<PopupMenuTable*> tables;
void *pUserData;
};
PopupMenu::~PopupMenu()
{ {
// Event connections between the parent window and the singleton table // Event connections between the parent window and the singleton table
// object must be broken when this menu is destroyed. // object must be broken when this menu is destroyed.
Disconnect(); Disconnect();
} }
void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable) void PopupMenu::Extend(PopupMenuTable *pTable)
{ {
pTable->InitUserData(pUserData); pTable->InitUserData(pUserData);
@ -55,7 +72,8 @@ void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable)
case PopupMenuTable::Entry::SubMenu: case PopupMenuTable::Entry::SubMenu:
{ {
const auto subTable = pEntry->subTable; const auto subTable = pEntry->subTable;
auto subMenu = BuildMenu( this->pParent, subTable, pUserData ); auto subMenu =
PopupMenuTable::BuildMenu( this->pParent, subTable, pUserData );
this->AppendSubMenu( this->AppendSubMenu(
subMenu.release(), subTable->Caption().Translation()); subMenu.release(), subTable->Caption().Translation());
} }
@ -68,7 +86,7 @@ void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable)
tables.push_back( pTable ); tables.push_back( pTable );
} }
void PopupMenuTable::Menu::DisconnectTable(PopupMenuTable *pTable) void PopupMenu::DisconnectTable(PopupMenuTable *pTable)
{ {
for (const PopupMenuTable::Entry *pEntry = &*pTable->Get().begin(); for (const PopupMenuTable::Entry *pEntry = &*pTable->Get().begin();
pEntry->IsValid(); ++pEntry) { pEntry->IsValid(); ++pEntry) {
@ -83,22 +101,28 @@ void PopupMenuTable::Menu::DisconnectTable(PopupMenuTable *pTable)
pTable->DestroyMenu(); pTable->DestroyMenu();
} }
void PopupMenuTable::Menu::Disconnect() void PopupMenu::Disconnect()
{ {
for ( auto pTable : tables ) for ( auto pTable : tables )
DisconnectTable(pTable); DisconnectTable(pTable);
} }
}
void PopupMenuTable::InitMenu(Menu *) void PopupMenuTable::InitMenu(wxMenu *)
{ {
} }
// static // static
std::unique_ptr<PopupMenuTable::Menu> PopupMenuTable::BuildMenu std::unique_ptr<wxMenu> PopupMenuTable::BuildMenu
( wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData ) ( wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData )
{ {
// Rebuild as needed each time. That makes it safe in case of language change. // Rebuild as needed each time. That makes it safe in case of language change.
std::unique_ptr<Menu> theMenu{ safenew Menu( pParent, pUserData ) }; auto theMenu = std::make_unique<PopupMenu>( pParent, pUserData );
theMenu->Extend(pTable); theMenu->Extend(pTable);
return theMenu; return theMenu;
} }
void PopupMenuTable::ExtendMenu( wxMenu &menu, PopupMenuTable &otherTable )
{
dynamic_cast<PopupMenu&>(menu).Extend(&otherTable);
}

View File

@ -62,27 +62,6 @@ public:
: mCaption{ caption } : mCaption{ caption }
{} {}
class Menu
: public wxMenu
{
friend class PopupMenuTable;
Menu(wxEvtHandler *pParent_, void *pUserData_)
: pParent{ pParent_ }, tables{}, pUserData{ pUserData_ } {}
public:
virtual ~Menu();
void Extend(PopupMenuTable *pTable);
void DisconnectTable(PopupMenuTable *pTable);
void Disconnect();
private:
wxEvtHandler *pParent;
std::vector<PopupMenuTable*> tables;
void *pUserData;
};
// Called before the menu items are appended. // Called before the menu items are appended.
// Store user data, if needed. // Store user data, if needed.
virtual void InitUserData(void *pUserData) = 0; virtual void InitUserData(void *pUserData) = 0;
@ -90,21 +69,21 @@ public:
// Called when the menu is about to pop up. // Called when the menu is about to pop up.
// Your chance to enable and disable items. // Your chance to enable and disable items.
// Default implementation does nothing. // Default implementation does nothing.
virtual void InitMenu(Menu *pMenu); virtual void InitMenu(wxMenu *pMenu);
// Called when menu is destroyed. // Called when menu is destroyed.
virtual void DestroyMenu() = 0; virtual void DestroyMenu() = 0;
// Optional pUserData gets passed to the InitUserData routines of tables. // Optional pUserData gets passed to the InitUserData routines of tables.
// No memory management responsibility is assumed by this function. // No memory management responsibility is assumed by this function.
static std::unique_ptr<Menu> BuildMenu static std::unique_ptr<wxMenu> BuildMenu
(wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData = NULL); (wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData = NULL);
const TranslatableString &Caption() const { return mCaption; } const TranslatableString &Caption() const { return mCaption; }
protected: // menu must have been built by BuildMenu
virtual void Populate() = 0; // More items get added to the end of it
void Clear() { mContents.clear(); } static void ExtendMenu( wxMenu &menu, PopupMenuTable &otherTable );
using Entries = std::vector<PopupMenuTableEntry>; using Entries = std::vector<PopupMenuTableEntry>;
const Entries& Get() const Entries& Get()
@ -114,6 +93,10 @@ protected:
return mContents; return mContents;
} }
protected:
virtual void Populate() = 0;
void Clear() { mContents.clear(); }
Entries mContents; Entries mContents;
TranslatableString mCaption; TranslatableString mCaption;
}; };
@ -128,7 +111,7 @@ which inherits from PopupMenuTable,
DECLARE_POPUP_MENU(MyTable); DECLARE_POPUP_MENU(MyTable);
virtual void InitUserData(void *pUserData); virtual void InitUserData(void *pUserData);
virtual void InitMenu(Menu *pMenu); virtual void InitMenu(wxMenu *pMenu);
virtual void DestroyMenu(); virtual void DestroyMenu();
Then in MyTable.cpp, Then in MyTable.cpp,
@ -139,7 +122,7 @@ void MyTable::InitUserData(void *pUserData)
auto pData = static_cast<MyData*>(pUserData); auto pData = static_cast<MyData*>(pUserData);
} }
void MyTable::InitMenu(Menu *pMenu) void MyTable::InitMenu(wxMenu *pMenu)
{ {
// enable or disable menu items // enable or disable menu items
} }
@ -168,7 +151,7 @@ auto pMenu = PopupMenuTable::BuildMenu(pParent, &myTable, &data);
// Optionally: // Optionally:
OtherTable otherTable; OtherTable otherTable;
pMenu->Extend(&otherTable); PopupMenuTable::ExtendMenu( *pMenu, otherTable );
pParent->PopupMenu(pMenu.get(), event.m_x, event.m_y); pParent->PopupMenu(pMenu.get(), event.m_x, event.m_y);