1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-26 09:28:07 +02:00

Store a reference to a handler object in each PopupMenuItem

This commit is contained in:
Paul Licameli 2020-02-08 16:18:00 -05:00
parent e1e0869e26
commit 00a419a280
2 changed files with 39 additions and 29 deletions

View File

@ -92,35 +92,34 @@ void PopupMenuBuilder::DoEndGroup( Registry::GroupItem &item, const Path &path )
void PopupMenuBuilder::DoVisit( Registry::SingleItem &item, const Path &path ) void PopupMenuBuilder::DoVisit( Registry::SingleItem &item, const Path &path )
{ {
auto connect = [this]( const PopupMenuTable::Entry *pEntry ) {
mMenu->pParent->Bind
(wxEVT_COMMAND_MENU_SELECTED,
pEntry->func, mMenu->tables.back(), pEntry->id);
};
auto pEntry = static_cast<PopupMenuTableEntry*>( &item ); auto pEntry = static_cast<PopupMenuTableEntry*>( &item );
switch (pEntry->type) { switch (pEntry->type) {
case PopupMenuTable::Entry::Item: case PopupMenuTable::Entry::Item:
{ {
mMenu->Append(pEntry->id, pEntry->caption.Translation()); mMenu->Append(pEntry->id, pEntry->caption.Translation());
connect( pEntry );
break; break;
} }
case PopupMenuTable::Entry::RadioItem: case PopupMenuTable::Entry::RadioItem:
{ {
mMenu->AppendRadioItem(pEntry->id, pEntry->caption.Translation()); mMenu->AppendRadioItem(pEntry->id, pEntry->caption.Translation());
connect( pEntry );
break; break;
} }
case PopupMenuTable::Entry::CheckItem: case PopupMenuTable::Entry::CheckItem:
{ {
mMenu->AppendCheckItem(pEntry->id, pEntry->caption.Translation()); mMenu->AppendCheckItem(pEntry->id, pEntry->caption.Translation());
connect( pEntry );
break; break;
} }
default: default:
wxASSERT( false );
break; break;
} }
// This call necessary for externally registered items, else harmlessly
// redundant
pEntry->handler.InitUserData( mpUserData );
mMenu->pParent->Bind(
wxEVT_COMMAND_MENU_SELECTED, pEntry->func, &pEntry->handler, pEntry->id);
} }
void PopupMenuBuilder::DoSeparator() void PopupMenuBuilder::DoSeparator()
@ -150,7 +149,7 @@ void PopupMenuTable::Append(
const TranslatableString &string, wxCommandEventFunction memFn) const TranslatableString &string, wxCommandEventFunction memFn)
{ {
mStack.back()->items.push_back( std::make_unique<Entry>( mStack.back()->items.push_back( std::make_unique<Entry>(
stringId, type, id, string, memFn stringId, type, id, string, memFn, *this
) ); ) );
} }
@ -182,7 +181,8 @@ void PopupMenu::DisconnectTable(PopupMenuTable *pTable)
{ {
auto pEntry = static_cast<PopupMenuTableEntry*>( &item ); auto pEntry = static_cast<PopupMenuTableEntry*>( &item );
mMenu.pParent->Unbind( wxEVT_COMMAND_MENU_SELECTED, mMenu.pParent->Unbind( wxEVT_COMMAND_MENU_SELECTED,
pEntry->func, &mTable, pEntry->id ); pEntry->func, &pEntry->handler, pEntry->id );
pEntry->handler.DestroyMenu();
} }
PopupMenuTable &mTable; PopupMenuTable &mTable;
@ -191,8 +191,6 @@ void PopupMenu::DisconnectTable(PopupMenuTable *pTable)
PopupMenuDestroyer visitor{ *pTable, *this }; PopupMenuDestroyer visitor{ *pTable, *this };
Registry::Visit( visitor, pTable->Get( nullptr ).get() ); Registry::Visit( visitor, pTable->Get( nullptr ).get() );
pTable->DestroyMenu();
} }
void PopupMenu::Disconnect() void PopupMenu::Disconnect()
@ -202,7 +200,7 @@ void PopupMenu::Disconnect()
} }
} }
void PopupMenuTable::InitMenu(wxMenu *) void PopupMenuHandler::InitMenu(wxMenu *)
{ {
} }

View File

@ -27,6 +27,7 @@ class wxString;
#include "../Internat.h" #include "../Internat.h"
#include "../commands/CommandManager.h" #include "../commands/CommandManager.h"
class PopupMenuHandler;
class PopupMenuTable; class PopupMenuTable;
struct PopupMenuTableEntry : Registry::SingleItem struct PopupMenuTableEntry : Registry::SingleItem
@ -37,16 +38,17 @@ struct PopupMenuTableEntry : Registry::SingleItem
int id; int id;
TranslatableString caption; TranslatableString caption;
wxCommandEventFunction func; wxCommandEventFunction func;
PopupMenuTable *subTable; PopupMenuHandler &handler;
PopupMenuTableEntry( const Identifier &stringId, PopupMenuTableEntry( const Identifier &stringId,
Type type_, int id_, const TranslatableString &caption_, Type type_, int id_, const TranslatableString &caption_,
wxCommandEventFunction func_) wxCommandEventFunction func_, PopupMenuHandler &handler_ )
: SingleItem{ stringId } : SingleItem{ stringId }
, type(type_) , type(type_)
, id(id_) , id(id_)
, caption(caption_) , caption(caption_)
, func(func_) , func(func_)
, handler( handler_ )
{} {}
~PopupMenuTableEntry() override; ~PopupMenuTableEntry() override;
@ -70,7 +72,29 @@ struct PopupMenuSection
using ConcreteGroupItem< false >::ConcreteGroupItem; using ConcreteGroupItem< false >::ConcreteGroupItem;
}; };
class PopupMenuTable : public wxEvtHandler class PopupMenuHandler : public wxEvtHandler
{
public:
PopupMenuHandler() = default;
PopupMenuHandler( const PopupMenuHandler& ) = delete;
PopupMenuHandler& operator=( const PopupMenuHandler& ) = delete;
// Called before the menu items are appended.
// Store context data, if needed.
// May be called more than once before the menu opens.
virtual void InitUserData(void *pUserData) = 0;
// Called when the menu is about to pop up.
// Your chance to enable and disable items.
// Default implementation does nothing.
virtual void InitMenu(wxMenu *pMenu);
// Called when menu is destroyed.
// May be called more than once.
virtual void DestroyMenu() = 0;
};
class PopupMenuTable : public PopupMenuHandler
{ {
public: public:
using Entry = PopupMenuTableEntry; using Entry = PopupMenuTableEntry;
@ -81,18 +105,6 @@ public:
, mCaption{ caption } , mCaption{ caption }
{} {}
// Called before the menu items are appended.
// Store user data, if needed.
virtual void InitUserData(void *pUserData) = 0;
// Called when the menu is about to pop up.
// Your chance to enable and disable items.
// Default implementation does nothing.
virtual void InitMenu(wxMenu *pMenu);
// Called when menu is destroyed.
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<wxMenu> BuildMenu static std::unique_ptr<wxMenu> BuildMenu