1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-10 17:11:17 +02:00

Simplify menu-building calls...

... Just one CommandManager::AddItem overload, instead of two plus two
overloads of AddCheck.  Also remove SetLongName.  Use an options structure
instead for all those distinctions.

Also simplify all the repetition of equal flag and mask values.  It's only in
four cases where we need to make them different.
This commit is contained in:
Paul Licameli 2018-10-17 14:16:32 -04:00
commit d46f3a9e63
7 changed files with 622 additions and 742 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2360,7 +2360,7 @@ void AudacityProject::OnMenu(wxCommandEvent & event)
#endif #endif
bool handled = mCommandManager.HandleMenuID( bool handled = mCommandManager.HandleMenuID(
event.GetId(), GetMenuManager(*this).GetUpdateFlags(*this), event.GetId(), GetMenuManager(*this).GetUpdateFlags(*this),
NoFlagsSpecifed); NoFlagsSpecified);
if (handled) if (handled)
event.Skip(false); event.Skip(false);

View File

@ -58,7 +58,7 @@ enum CommandFlag : unsigned long long
AudioTracksSelectedFlag = 0x2000000000ULL, AudioTracksSelectedFlag = 0x2000000000ULL,
NoAutoSelect = 0x4000000000ULL, // jkc NoAutoSelect = 0x4000000000ULL, // jkc
NoFlagsSpecifed = ~0ULL NoFlagsSpecified = ~0ULL
}; };
// Prevent accidental misuse with narrower types // Prevent accidental misuse with narrower types

View File

@ -434,7 +434,6 @@ CommandManager::CommandManager():
bMakingOccultCommands( false ) bMakingOccultCommands( false )
{ {
mbSeparatorAllowed = false; mbSeparatorAllowed = false;
mLongNameForItem = "";
SetMaxList(); SetMaxList();
} }
@ -796,55 +795,20 @@ void CommandManager::InsertItem(const wxString & name,
void CommandManager::AddCheck(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
int checkmark)
{
AddItem(name, label, hasDialog, finder, callback, wxT(""),
NoFlagsSpecifed, NoFlagsSpecifed, checkmark);
}
void CommandManager::AddCheck(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
int checkmark,
CommandFlag flags,
CommandMask mask)
{
AddItem(name, label, hasDialog, finder, callback, wxT(""), flags, mask, checkmark);
}
void CommandManager::AddItem(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
CommandFlag flags,
CommandMask mask,
bool bIsEffect,
const CommandParameter &parameter)
{
AddItem(name, label, hasDialog, finder, callback, wxT(""), flags, mask, -1, bIsEffect, parameter);
}
void CommandManager::AddItem(const wxChar *name, void CommandManager::AddItem(const wxChar *name,
const wxChar *label_in, const wxChar *label_in,
bool hasDialog, bool hasDialog,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
const wxChar *accel,
CommandFlag flags, CommandFlag flags,
CommandMask mask, const Options &options)
int checkmark,
bool bIsEffect,
const CommandParameter &parameter)
{ {
auto mask = options.mask;
if (mask == NoFlagsSpecified)
mask = flags;
wxString cookedParameter; wxString cookedParameter;
const auto &parameter = options.parameter;
if( parameter == "" ) if( parameter == "" )
cookedParameter = name; cookedParameter = name;
else else
@ -852,19 +816,19 @@ void CommandManager::AddItem(const wxChar *name,
CommandListEntry *entry = CommandListEntry *entry =
NewIdentifier(name, NewIdentifier(name,
label_in, label_in,
mLongNameForItem, options.longName,
hasDialog, hasDialog,
accel, CurrentMenu(), finder, callback, options.accel, CurrentMenu(), finder, callback,
{}, 0, 0, bIsEffect, cookedParameter); {}, 0, 0, options.bIsEffect, cookedParameter);
mLongNameForItem = "";
int ID = entry->id; int ID = entry->id;
wxString label = GetLabelWithDisabledAccel(entry); wxString label = GetLabelWithDisabledAccel(entry);
if (flags != NoFlagsSpecifed || mask != NoFlagsSpecifed) { if (flags != NoFlagsSpecified || mask != NoFlagsSpecified) {
SetCommandFlags(name, flags, mask); SetCommandFlags(name, flags, mask);
} }
auto checkmark = options.check;
if (checkmark >= 0) { if (checkmark >= 0) {
CurrentMenu()->AppendCheckItem(ID, label); CurrentMenu()->AppendCheckItem(ID, label);
CurrentMenu()->Check(ID, checkmark != 0); CurrentMenu()->Check(ID, checkmark != 0);
@ -914,10 +878,9 @@ void CommandManager::AddCommand(const wxChar *name,
const wxChar *label, const wxChar *label,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
CommandFlag flags, CommandFlag flags)
CommandMask mask)
{ {
AddCommand(name, label, finder, callback, wxT(""), flags, mask); AddCommand(name, label, finder, callback, wxT(""), flags);
} }
void CommandManager::AddCommand(const wxChar *name, void CommandManager::AddCommand(const wxChar *name,
@ -925,14 +888,12 @@ void CommandManager::AddCommand(const wxChar *name,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
const wxChar *accel, const wxChar *accel,
CommandFlag flags, CommandFlag flags)
CommandMask mask)
{ {
NewIdentifier(name, label_in, label_in, false, accel, NULL, finder, callback, {}, 0, 0, false, {}); NewIdentifier(name, label_in, label_in, false, accel, NULL, finder, callback, {}, 0, 0, false, {});
if (flags != NoFlagsSpecifed || mask != NoFlagsSpecifed) { if (flags != NoFlagsSpecified)
SetCommandFlags(name, flags, mask); SetCommandFlags(name, flags, flags);
}
} }
void CommandManager::AddGlobalCommand(const wxChar *name, void CommandManager::AddGlobalCommand(const wxChar *name,
@ -1465,7 +1426,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
// LL: Why do they need to be disabled??? // LL: Why do they need to be disabled???
entry->enabled = false; entry->enabled = false;
auto cleanup = valueRestorer( entry->enabled, true ); auto cleanup = valueRestorer( entry->enabled, true );
return HandleCommandEntry(entry, NoFlagsSpecifed, NoFlagsSpecifed, &evt); return HandleCommandEntry(entry, NoFlagsSpecified, NoFlagsSpecified, &evt);
} }
wxWindow * pFocus = wxWindow::FindFocus(); wxWindow * pFocus = wxWindow::FindFocus();
@ -1542,12 +1503,12 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
{ {
return true; return true;
} }
return HandleCommandEntry(entry, flags, NoFlagsSpecifed, &temp); return HandleCommandEntry(entry, flags, NoFlagsSpecified, &temp);
} }
if (type == wxEVT_KEY_UP && entry->wantKeyup) if (type == wxEVT_KEY_UP && entry->wantKeyup)
{ {
return HandleCommandEntry(entry, flags, NoFlagsSpecifed, &temp); return HandleCommandEntry(entry, flags, NoFlagsSpecified, &temp);
} }
return false; return false;
@ -1912,6 +1873,8 @@ void CommandManager::WriteXML(XMLWriter &xmlFile) const
void CommandManager::SetDefaultFlags(CommandFlag flags, CommandMask mask) void CommandManager::SetDefaultFlags(CommandFlag flags, CommandMask mask)
{ {
if (mask == NoFlagsSpecified)
mask = flags;
mDefaultFlags = flags; mDefaultFlags = flags;
mDefaultMask = mask; mDefaultMask = mask;
} }
@ -1931,29 +1894,6 @@ void CommandManager::SetCommandFlags(const wxString &name,
} }
} }
void CommandManager::SetCommandFlags(const wxChar **names,
CommandFlag flags, CommandMask mask)
{
const wxChar **nptr = names;
while(*nptr) {
SetCommandFlags(wxString(*nptr), flags, mask);
nptr++;
}
}
void CommandManager::SetCommandFlags(CommandFlag flags, CommandMask mask, ...)
{
va_list list;
va_start(list, mask);
for(;;) {
const wxChar *name = va_arg(list, const wxChar *);
if (!name)
break;
SetCommandFlags(wxString(name), flags, mask);
}
va_end(list);
}
#if defined(__WXDEBUG__) #if defined(__WXDEBUG__)
void CommandManager::CheckDups() void CommandManager::CheckDups()
{ {

View File

@ -155,6 +155,38 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler
int checkmark = -1); int checkmark = -1);
*/ */
// For specifying unusual arguments in AddItem
struct Options
{
Options() {}
// Allow implicit construction from an accelerator string, which is
// a very common case
Options( const wxChar *accel_ ) : accel{ accel_ } {}
// A two-argument constructor for another common case
Options( const wxChar *accel_, const wxString &longName_ )
: accel{ accel_ }, longName{ longName_ } {}
Options &&Accel (const wxChar *value) &&
{ accel = value; return std::move(*this); }
Options &&CheckState (bool value) &&
{ check = value ? 1 : 0; return std::move(*this); }
Options &&IsEffect () &&
{ bIsEffect = true; return std::move(*this); }
Options &&Parameter (const CommandParameter &value) &&
{ parameter = value; return std::move(*this); }
Options &&Mask (CommandMask value) &&
{ mask = value; return std::move(*this); }
Options &&LongName (const wxString &value) &&
{ longName = value; return std::move(*this); }
const wxChar *accel{ wxT("") };
int check{ -1 }; // default value means it's not a check item
bool bIsEffect{ false };
CommandParameter parameter{};
CommandMask mask{ NoFlagsSpecified };
wxString longName{}; // translated
};
void AddItemList(const wxString & name, void AddItemList(const wxString & name,
const TranslatedInternalString items[], const TranslatedInternalString items[],
size_t nItems, size_t nItems,
@ -162,43 +194,13 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler
CommandFunctorPointer callback, CommandFunctorPointer callback,
bool bIsEffect = false); bool bIsEffect = false);
void AddCheck(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
int checkmark = 0);
void AddCheck(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
int checkmark,
CommandFlag flags,
CommandMask mask);
void AddItem(const wxChar *name,
const wxChar *label,
bool hasDialog,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
CommandFlag flags = NoFlagsSpecifed,
CommandMask mask = NoFlagsSpecifed,
bool bIsEffect = false,
const CommandParameter &parameter = CommandParameter{});
void AddItem(const wxChar *name, void AddItem(const wxChar *name,
const wxChar *label_in, const wxChar *label_in,
bool hasDialog, bool hasDialog,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
const wxChar *accel, CommandFlag flags = NoFlagsSpecified,
CommandFlag flags = NoFlagsSpecifed, const Options &options = {});
CommandMask mask = NoFlagsSpecifed,
int checkmark = -1,
bool bIsEffect = false,
const CommandParameter &parameter = CommandParameter{});
void AddSeparator(); void AddSeparator();
@ -208,16 +210,14 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler
const wxChar *label, const wxChar *label,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
CommandFlag flags = NoFlagsSpecifed, CommandFlag flags = NoFlagsSpecified);
CommandMask mask = NoFlagsSpecifed);
void AddCommand(const wxChar *name, void AddCommand(const wxChar *name,
const wxChar *label, const wxChar *label,
CommandHandlerFinder finder, CommandHandlerFinder finder,
CommandFunctorPointer callback, CommandFunctorPointer callback,
const wxChar *accel, const wxChar *accel,
CommandFlag flags = NoFlagsSpecifed, CommandFlag flags = NoFlagsSpecified);
CommandMask mask = NoFlagsSpecifed);
void AddGlobalCommand(const wxChar *name, void AddGlobalCommand(const wxChar *name,
const wxChar *label, const wxChar *label,
@ -230,23 +230,15 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler
// //
// For NEW items/commands // For NEW items/commands
void SetDefaultFlags(CommandFlag flags, CommandMask mask); void SetDefaultFlags(CommandFlag flags, CommandMask mask = NoFlagsSpecified);
CommandFlag GetDefaultFlags() const { return mDefaultFlags; } CommandFlag GetDefaultFlags() const { return mDefaultFlags; }
CommandMask GetDefaultMask() const { return mDefaultMask; } CommandMask GetDefaultMask() const { return mDefaultMask; }
void SwapMenuBars(); void SwapMenuBars();
void SetOccultCommands( bool bOccult); void SetOccultCommands( bool bOccult);
CommandManager * SetLongName( const wxString & name ){
mLongNameForItem = name;
return this;
}
void SetCommandFlags(const wxString &name, CommandFlag flags, CommandMask mask); void SetCommandFlags(const wxString &name, CommandFlag flags, CommandMask mask);
void SetCommandFlags(const wxChar **names,
CommandFlag flags, CommandMask mask);
// Pass multiple command names as const wxChar *, terminated by NULL
void SetCommandFlags(CommandFlag flags, CommandMask mask, ...);
// //
// Modifying menus // Modifying menus
@ -413,8 +405,6 @@ private:
std::unique_ptr<wxMenu> uCurrentMenu; std::unique_ptr<wxMenu> uCurrentMenu;
wxMenu *mCurrentMenu {}; wxMenu *mCurrentMenu {};
wxString mLongNameForItem;
CommandFlag mDefaultFlags; CommandFlag mDefaultFlags;
CommandMask mDefaultMask; CommandMask mDefaultMask;
bool bMakingOccultCommands; bool bMakingOccultCommands;

View File

@ -302,7 +302,7 @@ void EditToolBar::OnButton(wxCommandEvent &event)
auto flags = GetMenuManager(*p).GetUpdateFlags(*p); auto flags = GetMenuManager(*p).GetUpdateFlags(*p);
const CommandContext context( *GetActiveProject() ); const CommandContext context( *GetActiveProject() );
cm->HandleTextualCommand(EditToolbarButtonList[id].commandName, context, flags, NoFlagsSpecifed); cm->HandleTextualCommand(EditToolbarButtonList[id].commandName, context, flags, NoFlagsSpecified);
} }

View File

@ -1161,19 +1161,19 @@ void Scrubber::AddMenuItems()
cm->BeginSubMenu(_("Scru&bbing")); cm->BeginSubMenu(_("Scru&bbing"));
for (const auto &item : menuItems) { for (const auto &item : menuItems) {
if (item.StatusTest) if (item.StatusTest)
cm->AddCheck(item.name, wxGetTranslation(item.label), cm->AddItem( item.name, wxGetTranslation(item.label),
// No menu items yet have dialogs // No menu items yet have dialogs
false, false,
findme, static_cast<CommandFunctorPointer>(item.memFn), findme, static_cast<CommandFunctorPointer>(item.memFn),
false, item.flags,
item.flags, item.flags); CommandManager::Options{}.CheckState( false ) );
else else
// The start item // The start item
cm->AddItem(item.name, wxGetTranslation(item.label), cm->AddItem( item.name, wxGetTranslation(item.label),
// No menu items yet have dialogs // No menu items yet have dialogs
false, false,
findme, static_cast<CommandFunctorPointer>(item.memFn), findme, static_cast<CommandFunctorPointer>(item.memFn),
item.flags, item.flags); item.flags );
} }
cm->EndSubMenu(); cm->EndSubMenu();
CheckMenuItems(); CheckMenuItems();