diff --git a/src/Menus.cpp b/src/Menus.cpp index eb1ffa638..d14c68c39 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -285,6 +285,11 @@ static int SortEffectsByType(const PluginDescriptor **a, const PluginDescriptor /// changes in configured preferences - for example changes in key-bindings /// affect the short-cut key legend that appears beside each command, +// To supply the "finder" argument in AddItem calls +static CommandHandlerObject &ident(AudacityProject &project) { return project; } + +#define FN(X) ident, FNT(AudacityProject, this, & AudacityProject :: X) + void AudacityProject::CreateMenusAndCommands() { CommandManager *c = &mCommandManager; diff --git a/src/commands/CommandFunctors.h b/src/commands/CommandFunctors.h index 85882ff6f..a29f71c3b 100644 --- a/src/commands/CommandFunctors.h +++ b/src/commands/CommandFunctors.h @@ -14,6 +14,23 @@ #include "../MemoryX.h" class AudacityProject; +class wxEvtHandler; + +// Base class for objects, to whose member functions, the CommandManager will +// dispatch. +// +// It, or a subclass of it, must be the first base class of the object, and the +// first base class of that base class, etc., for the same reason that +// wxEvtHandler must be first (that is, the downcast from a pointer to the base +// to a pointer to the object, must be a vacuous operation). +// +// In fact, then, we just make it an alias of wxEvtHandler, in case you really +// need to inherit from wxEvtHandler for other reasons, and otherwise you +// couldn't satisfy the requirement for both base classes at once. +using CommandHandlerObject = wxEvtHandler; + +using CommandHandlerFinder = CommandHandlerObject &(*)(AudacityProject&); + class wxEvent; using CommandParameter = wxString; @@ -145,6 +162,4 @@ inline CommandFunctorPointer MakeFunctor(OBJ *This, // Now define the macro abbreviations that call the factory #define FNT(OBJ, This, X) (MakeFunctor(This, X )) -#define FN(X) FNT(AudacityProject, this, & AudacityProject :: X) - #endif diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index 03302106f..016d22fef 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -694,7 +694,8 @@ void CommandManager::ClearCurrentMenu() /// given functor will be called void CommandManager::InsertItem(const wxString & name, const wxString & label_in, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxString & after, int checkmark) { @@ -744,7 +745,7 @@ void CommandManager::InsertItem(const wxString & name, } } - CommandListEntry *entry = NewIdentifier(name, label_in, menu, callback, false, 0, 0); + CommandListEntry *entry = NewIdentifier(name, label_in, menu, finder, callback, false, 0, 0); int ID = entry->id; wxString label = GetLabel(entry); @@ -763,42 +764,49 @@ void CommandManager::InsertItem(const wxString & name, void CommandManager::AddCheck(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, int checkmark) { - AddItem(name, label, callback, wxT(""), NoFlagsSpecifed, NoFlagsSpecifed, checkmark); + AddItem(name, label, finder, callback, wxT(""), + NoFlagsSpecifed, NoFlagsSpecifed, checkmark); } void CommandManager::AddCheck(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, int checkmark, CommandFlag flags, CommandMask mask) { - AddItem(name, label, callback, wxT(""), flags, mask, checkmark); + AddItem(name, label, finder, callback, wxT(""), flags, mask, checkmark); } void CommandManager::AddItem(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, CommandFlag flags, CommandMask mask, const CommandParameter ¶meter) { - AddItem(name, label, callback, wxT(""), flags, mask, -1, parameter); + AddItem(name, label, finder, callback, wxT(""), flags, mask, -1, parameter); } void CommandManager::AddItem(const wxChar *name, const wxChar *label_in, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel, CommandFlag flags, CommandMask mask, int checkmark, const CommandParameter ¶meter) { - CommandListEntry *entry = NewIdentifier(name, label_in, accel, CurrentMenu(), callback, false, 0, 0, parameter); + CommandListEntry *entry = + NewIdentifier(name, label_in, accel, CurrentMenu(), finder, callback, + false, 0, 0, parameter); int ID = entry->id; wxString label = GetLabelWithDisabledAccel(entry); @@ -826,12 +834,14 @@ void CommandManager::AddItem(const wxChar *name, /// all of the items at once. void CommandManager::AddItemList(const wxString & name, const wxArrayString & labels, - const CommandFunctorPointer &callback) + CommandHandlerFinder finder, + CommandFunctorPointer callback) { for (size_t i = 0, cnt = labels.GetCount(); i < cnt; i++) { CommandListEntry *entry = NewIdentifier(name, labels[i], CurrentMenu(), + finder, callback, true, i, @@ -846,21 +856,23 @@ void CommandManager::AddItemList(const wxString & name, /// given function pointer will be called (via the CommandManagerListener) void CommandManager::AddCommand(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, CommandFlag flags, CommandMask mask) { - AddCommand(name, label, callback, wxT(""), flags, mask); + AddCommand(name, label, finder, callback, wxT(""), flags, mask); } void CommandManager::AddCommand(const wxChar *name, const wxChar *label_in, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel, CommandFlag flags, CommandMask mask) { - NewIdentifier(name, label_in, accel, NULL, callback, false, 0, 0, {}); + NewIdentifier(name, label_in, accel, NULL, finder, callback, false, 0, 0, {}); if (flags != NoFlagsSpecifed || mask != NoFlagsSpecifed) { SetCommandFlags(name, flags, mask); @@ -869,10 +881,13 @@ void CommandManager::AddCommand(const wxChar *name, void CommandManager::AddGlobalCommand(const wxChar *name, const wxChar *label_in, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel) { - CommandListEntry *entry = NewIdentifier(name, label_in, accel, NULL, callback, false, 0, 0, {}); + CommandListEntry *entry = + NewIdentifier(name, label_in, accel, NULL, finder, callback, + false, 0, 0, {}); entry->enabled = false; entry->isGlobal = true; @@ -906,7 +921,8 @@ int CommandManager::NextIdentifier(int ID) CommandListEntry *CommandManager::NewIdentifier(const wxString & name, const wxString & label, wxMenu *menu, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, bool multi, int index, int count) @@ -915,6 +931,7 @@ CommandListEntry *CommandManager::NewIdentifier(const wxString & name, label.BeforeFirst(wxT('\t')), label.AfterFirst(wxT('\t')), menu, + finder, callback, multi, index, @@ -925,7 +942,8 @@ CommandListEntry *CommandManager::NewIdentifier(const wxString & name, const wxString & label, const wxString & accel, wxMenu *menu, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, bool multi, int index, int count, @@ -977,6 +995,7 @@ CommandListEntry *CommandManager::NewIdentifier(const wxString & name, entry->labelPrefix = labelPrefix; entry->labelTop = wxMenuItem::GetLabelText(mCurrentMenuName); entry->menu = menu; + entry->finder = finder; entry->callback = callback; entry->multi = multi; entry->index = index; diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index c4561f76a..f662ea6f8 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -64,6 +64,7 @@ struct CommandListEntry wxString labelPrefix; wxString labelTop; wxMenu *menu; + CommandHandlerFinder finder; CommandFunctorPointer callback; CommandParameter parameter; bool multi; @@ -125,36 +126,42 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler void InsertItem(const wxString & name, const wxString & label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxString & after, int checkmark = -1); void AddItemList(const wxString & name, const wxArrayString & labels, - const CommandFunctorPointer &callback); + CommandHandlerFinder finder, + CommandFunctorPointer callback); void AddCheck(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, int checkmark = 0); void AddCheck(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, int checkmark, CommandFlag flags, CommandMask mask); void AddItem(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, CommandFlag flags = NoFlagsSpecifed, CommandMask mask = NoFlagsSpecifed, const CommandParameter ¶meter = {}); void AddItem(const wxChar *name, const wxChar *label_in, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel, CommandFlag flags = NoFlagsSpecifed, CommandMask mask = NoFlagsSpecifed, @@ -167,20 +174,23 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler // keyboard shortcut. void AddCommand(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, CommandFlag flags = NoFlagsSpecifed, CommandMask mask = NoFlagsSpecifed); void AddCommand(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel, CommandFlag flags = NoFlagsSpecifed, CommandMask mask = NoFlagsSpecifed); void AddGlobalCommand(const wxChar *name, const wxChar *label, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, const wxChar *accel); // // Command masks @@ -285,7 +295,8 @@ protected: CommandListEntry *NewIdentifier(const wxString & name, const wxString & label, wxMenu *menu, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, bool multi, int index, int count); @@ -293,7 +304,8 @@ protected: const wxString & label, const wxString & accel, wxMenu *menu, - const CommandFunctorPointer &callback, + CommandHandlerFinder finder, + CommandFunctorPointer callback, bool multi, int index, int count, diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index a14b77825..9e36d4ff7 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -1002,6 +1002,10 @@ bool Scrubber::CanScrub() const return cm->GetEnabled(menuItems[ 0 ].name); } +// To supply the "finder" argument +static CommandHandlerObject &findme(AudacityProject &project) +{ return project.GetScrubber(); } + void Scrubber::AddMenuItems() { auto cm = mProject->GetCommandManager(); @@ -1010,13 +1014,13 @@ void Scrubber::AddMenuItems() for (const auto &item : menuItems) { if (item.StatusTest) cm->AddCheck(item.name, wxGetTranslation(item.label), - FNT(Scrubber, this, item.memFn), + findme, FNT(Scrubber, this, item.memFn), false, item.flags, item.flags); else // The start item cm->AddItem(item.name, wxGetTranslation(item.label), - FNT(Scrubber, this, item.memFn), + findme, FNT(Scrubber, this, item.memFn), item.flags, item.flags); } cm->EndSubMenu();