1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-19 17:40:15 +02:00
audacity/src/widgets/PopupMenuTable.cpp
Paul Licameli 2f3604bdea Rewrite many calls to Connect() with Bind()...
... it's the more modern way, and does better type checking, without the
dubious casts of pointers-to-member-functions.
2018-02-21 19:28:11 -05:00

97 lines
2.6 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
PopupMenuTable.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "../Audacity.h"
#include "PopupMenuTable.h"
PopupMenuTable::Menu::~Menu()
{
// 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)
{
auto connect = [&]( const PopupMenuTable::Entry *pEntry ) {
this->pParent->Bind
(wxEVT_COMMAND_MENU_SELECTED,
pEntry->func, pTable, pEntry->id);
};
for (const PopupMenuTable::Entry *pEntry = &*pTable->Get().begin();
pEntry->IsValid(); ++pEntry) {
switch (pEntry->type) {
case PopupMenuTable::Entry::Item:
{
this->Append(pEntry->id, pEntry->caption);
connect( pEntry );
break;
}
case PopupMenuTable::Entry::RadioItem:
{
this->AppendRadioItem(pEntry->id, pEntry->caption);
connect( pEntry );
break;
}
case PopupMenuTable::Entry::CheckItem:
{
this->AppendCheckItem(pEntry->id, pEntry->caption);
connect( pEntry );
break;
}
case PopupMenuTable::Entry::Separator:
this->AppendSeparator();
break;
case PopupMenuTable::Entry::SubMenu:
{
const auto subTable = pEntry->subTable;
auto subMenu = BuildMenu( this->pParent, subTable, pUserData );
this->AppendSubMenu( subMenu.release(), pEntry->caption );
}
default:
break;
}
}
pTable->InitMenu(this, pUserData);
}
void PopupMenuTable::Menu::DisconnectTable(PopupMenuTable *pTable)
{
for (const PopupMenuTable::Entry *pEntry = &*pTable->Get().begin();
pEntry->IsValid(); ++pEntry) {
if ( pEntry->IsItem() )
pParent->Unbind( wxEVT_COMMAND_MENU_SELECTED,
pEntry->func, pTable, pEntry->id );
else if ( pEntry->IsSubMenu() )
// recur
DisconnectTable(pEntry->subTable);
}
pTable->DestroyMenu();
}
void PopupMenuTable::Menu::Disconnect()
{
for ( auto pTable : tables )
DisconnectTable(pTable);
}
// static
std::unique_ptr<PopupMenuTable::Menu> 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<Menu> theMenu{ safenew Menu( pParent, pUserData ) };
theMenu->Extend(pTable);
return std::move( theMenu );
}