diff --git a/src/tracks/playabletrack/notetrack/ui/NoteTrackVZoomHandle.cpp b/src/tracks/playabletrack/notetrack/ui/NoteTrackVZoomHandle.cpp index 14d6130d8..fc5f906ed 100644 --- a/src/tracks/playabletrack/notetrack/ui/NoteTrackVZoomHandle.cpp +++ b/src/tracks/playabletrack/notetrack/ui/NoteTrackVZoomHandle.cpp @@ -297,8 +297,7 @@ UIHandle::Result NoteTrackVZoomHandle::Release PopupMenuTable *const pTable = (PopupMenuTable *) &NoteTrackVRulerMenuTable::Instance(); - std::unique_ptr - pMenu(PopupMenuTable::BuildMenu(pParent, pTable, &data)); + auto pMenu = PopupMenuTable::BuildMenu(pParent, pTable, &data); // Accelerators only if zooming enabled. if( !bVZoom ) diff --git a/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.cpp index 3fa664f57..c16010226 100644 --- a/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.cpp @@ -265,7 +265,7 @@ PopupMenuTable &SpectrumVRulerMenuTable::Instance() return instance; } -void SpectrumVRulerMenuTable::InitMenu(Menu *pMenu) +void SpectrumVRulerMenuTable::InitMenu(wxMenu *pMenu) { WaveTrackVRulerMenuTable::InitMenu(pMenu); diff --git a/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.h b/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.h index 2f9f106be..b050746a1 100644 --- a/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.h +++ b/src/tracks/playabletrack/wavetrack/ui/SpectrumVZoomHandle.h @@ -83,7 +83,7 @@ public: static PopupMenuTable &Instance(); private: - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void OnSpectrumScaleType(wxCommandEvent &evt); }; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp index fda5ca333..72d30c634 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp @@ -162,7 +162,7 @@ public: private: void InitUserData(void *pUserData) override; - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void DestroyMenu() override { @@ -186,7 +186,7 @@ void WaveColorMenuTable::InitUserData(void *pUserData) mpData = static_cast(pUserData); } -void WaveColorMenuTable::InitMenu(Menu *pMenu) +void WaveColorMenuTable::InitMenu(wxMenu *pMenu) { WaveTrack *const pTrack = static_cast(mpData->pTrack); auto WaveColorId = IdOfWaveColor( pTrack->GetWaveColorIndex()); @@ -261,7 +261,7 @@ public: private: void InitUserData(void *pUserData) override; - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void DestroyMenu() override { @@ -286,7 +286,7 @@ void FormatMenuTable::InitUserData(void *pUserData) mpData = static_cast(pUserData); } -void FormatMenuTable::InitMenu(Menu *pMenu) +void FormatMenuTable::InitMenu(wxMenu *pMenu) { WaveTrack *const pTrack = static_cast(mpData->pTrack); auto formatId = IdOfFormat(pTrack->GetSampleFormat()); @@ -384,7 +384,7 @@ public: private: void InitUserData(void *pUserData) override; - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void DestroyMenu() override { @@ -411,7 +411,7 @@ void RateMenuTable::InitUserData(void *pUserData) mpData = static_cast(pUserData); } -void RateMenuTable::InitMenu(Menu *pMenu) +void RateMenuTable::InitMenu(wxMenu *pMenu) { WaveTrack *const pTrack = static_cast(mpData->pTrack); const auto rateId = IdOfRate((int)pTrack->GetRate()); @@ -583,7 +583,7 @@ protected: WaveTrackMenuTable() : mpData(NULL) {mpTrack=NULL;} void InitUserData(void *pUserData) override; - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void DestroyMenu() override { @@ -637,7 +637,7 @@ static std::vector AllTypes() return result; } -void WaveTrackMenuTable::InitMenu(Menu *pMenu) +void WaveTrackMenuTable::InitMenu(wxMenu *pMenu) { WaveTrack *const pTrack = static_cast(mpData->pTrack); diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVZoomHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVZoomHandle.cpp index 4d3ec4f61..01f060a6b 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackVZoomHandle.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackVZoomHandle.cpp @@ -118,8 +118,7 @@ UIHandle::Result WaveTrackVZoomHandle::DoRelease( *pProject, pTrack, rect, RefreshCode::RefreshNone, event.m_y, doZoom }; - std::unique_ptr - pMenu(PopupMenuTable::BuildMenu(pParent, &table, &data)); + auto pMenu = PopupMenuTable::BuildMenu(pParent, &table, &data); // Accelerators only if zooming enabled. if( !bVZoom ) diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.cpp index 478b14e6a..bb24ff902 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.cpp @@ -266,7 +266,7 @@ PopupMenuTable &WaveformVRulerMenuTable::Instance() return instance; } -void WaveformVRulerMenuTable::InitMenu(Menu *pMenu) +void WaveformVRulerMenuTable::InitMenu(wxMenu *pMenu) { WaveTrackVRulerMenuTable::InitMenu(pMenu); diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.h b/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.h index b74238313..18db429a7 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveformVZoomHandle.h @@ -83,7 +83,7 @@ public: static PopupMenuTable &Instance(); private: - virtual void InitMenu(Menu *pMenu) override; + virtual void InitMenu(wxMenu *pMenu) override; void OnWaveformScaleType(wxCommandEvent &evt); }; diff --git a/src/tracks/timetrack/ui/TimeTrackControls.cpp b/src/tracks/timetrack/ui/TimeTrackControls.cpp index efb013241..cde280566 100644 --- a/src/tracks/timetrack/ui/TimeTrackControls.cpp +++ b/src/tracks/timetrack/ui/TimeTrackControls.cpp @@ -52,7 +52,7 @@ private: mpData = static_cast(pUserData); } - void InitMenu(Menu *pMenu) override + void InitMenu(wxMenu *pMenu) override { TimeTrack *const pTrack = static_cast(mpData->pTrack); diff --git a/src/tracks/ui/CommonTrackControls.cpp b/src/tracks/ui/CommonTrackControls.cpp index 91142c78b..dd5203561 100644 --- a/src/tracks/ui/CommonTrackControls.cpp +++ b/src/tracks/ui/CommonTrackControls.cpp @@ -91,7 +91,7 @@ private: void OnMoveTrack(wxCommandEvent &event); void InitUserData(void *pUserData) override; - void InitMenu(Menu *pMenu) override; + void InitMenu(wxMenu *pMenu) override; void DestroyMenu() override { @@ -112,7 +112,7 @@ void TrackMenuTable::InitUserData(void *pUserData) mpData = static_cast(pUserData); } -void TrackMenuTable::InitMenu(Menu *pMenu) +void TrackMenuTable::InitMenu(wxMenu *pMenu) { Track *const pTrack = mpData->pTrack; @@ -282,7 +282,7 @@ unsigned CommonTrackControls::DoContextMenu( PopupMenuTable *const pExtension = GetMenuExtension(track.get()); if (pExtension) - pMenu->Extend(pExtension); + PopupMenuTable::ExtendMenu( *pMenu, *pExtension ); pParent->PopupMenu (pMenu.get(), buttonRect.x + 1, buttonRect.y + buttonRect.height + 1); diff --git a/src/widgets/PopupMenuTable.cpp b/src/widgets/PopupMenuTable.cpp index 018a0a0db..57d46d253 100644 --- a/src/widgets/PopupMenuTable.cpp +++ b/src/widgets/PopupMenuTable.cpp @@ -11,14 +11,31 @@ Paul Licameli split from TrackPanel.cpp #include "../Audacity.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 tables; + void *pUserData; +}; + +PopupMenu::~PopupMenu() { // Event connections between the parent window and the singleton table // object must be broken when this menu is destroyed. Disconnect(); } -void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable) +void PopupMenu::Extend(PopupMenuTable *pTable) { pTable->InitUserData(pUserData); @@ -55,7 +72,8 @@ void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable) case PopupMenuTable::Entry::SubMenu: { const auto subTable = pEntry->subTable; - auto subMenu = BuildMenu( this->pParent, subTable, pUserData ); + auto subMenu = + PopupMenuTable::BuildMenu( this->pParent, subTable, pUserData ); this->AppendSubMenu( subMenu.release(), subTable->Caption().Translation()); } @@ -68,7 +86,7 @@ void PopupMenuTable::Menu::Extend(PopupMenuTable *pTable) tables.push_back( pTable ); } -void PopupMenuTable::Menu::DisconnectTable(PopupMenuTable *pTable) +void PopupMenu::DisconnectTable(PopupMenuTable *pTable) { for (const PopupMenuTable::Entry *pEntry = &*pTable->Get().begin(); pEntry->IsValid(); ++pEntry) { @@ -83,22 +101,28 @@ void PopupMenuTable::Menu::DisconnectTable(PopupMenuTable *pTable) pTable->DestroyMenu(); } -void PopupMenuTable::Menu::Disconnect() +void PopupMenu::Disconnect() { for ( auto pTable : tables ) DisconnectTable(pTable); } +} -void PopupMenuTable::InitMenu(Menu *) +void PopupMenuTable::InitMenu(wxMenu *) { } // static -std::unique_ptr PopupMenuTable::BuildMenu +std::unique_ptr PopupMenuTable::BuildMenu ( wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData ) { // Rebuild as needed each time. That makes it safe in case of language change. - std::unique_ptr theMenu{ safenew Menu( pParent, pUserData ) }; + auto theMenu = std::make_unique( pParent, pUserData ); theMenu->Extend(pTable); return theMenu; } + +void PopupMenuTable::ExtendMenu( wxMenu &menu, PopupMenuTable &otherTable ) +{ + dynamic_cast(menu).Extend(&otherTable); +} diff --git a/src/widgets/PopupMenuTable.h b/src/widgets/PopupMenuTable.h index a02a6acc9..50a24debc 100644 --- a/src/widgets/PopupMenuTable.h +++ b/src/widgets/PopupMenuTable.h @@ -62,27 +62,6 @@ public: : 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 tables; - void *pUserData; - }; - // Called before the menu items are appended. // Store user data, if needed. virtual void InitUserData(void *pUserData) = 0; @@ -90,22 +69,22 @@ public: // Called when the menu is about to pop up. // Your chance to enable and disable items. // Default implementation does nothing. - virtual void InitMenu(Menu *pMenu); + virtual void InitMenu(wxMenu *pMenu); // Called when menu is destroyed. virtual void DestroyMenu() = 0; // Optional pUserData gets passed to the InitUserData routines of tables. // No memory management responsibility is assumed by this function. - static std::unique_ptr BuildMenu + static std::unique_ptr BuildMenu (wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData = NULL); const TranslatableString &Caption() const { return mCaption; } -protected: - virtual void Populate() = 0; - void Clear() { mContents.clear(); } - + // menu must have been built by BuildMenu + // More items get added to the end of it + static void ExtendMenu( wxMenu &menu, PopupMenuTable &otherTable ); + using Entries = std::vector; const Entries& Get() { @@ -114,6 +93,10 @@ protected: return mContents; } +protected: + virtual void Populate() = 0; + void Clear() { mContents.clear(); } + Entries mContents; TranslatableString mCaption; }; @@ -128,7 +111,7 @@ which inherits from PopupMenuTable, DECLARE_POPUP_MENU(MyTable); virtual void InitUserData(void *pUserData); -virtual void InitMenu(Menu *pMenu); +virtual void InitMenu(wxMenu *pMenu); virtual void DestroyMenu(); Then in MyTable.cpp, @@ -139,7 +122,7 @@ void MyTable::InitUserData(void *pUserData) auto pData = static_cast(pUserData); } -void MyTable::InitMenu(Menu *pMenu) +void MyTable::InitMenu(wxMenu *pMenu) { // enable or disable menu items } @@ -168,7 +151,7 @@ auto pMenu = PopupMenuTable::BuildMenu(pParent, &myTable, &data); // Optionally: OtherTable otherTable; -pMenu->Extend(&otherTable); +PopupMenuTable::ExtendMenu( *pMenu, otherTable ); pParent->PopupMenu(pMenu.get(), event.m_x, event.m_y);