1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-30 07:39:42 +02:00

Delay evaluation of checkmark states...

... so that more menu item descriptions can be statically constructed once only
This commit is contained in:
Paul Licameli 2019-01-09 14:14:40 -05:00
parent 512c27d422
commit 93c2bb9322
11 changed files with 57 additions and 24 deletions

View File

@ -160,12 +160,12 @@ int ModuleDispatch(ModuleDispatchTypes type)
c->SetCurrentMenu( pMenu );
c->AddSeparator();
// We add two new commands into the Analyze menu.
c->AddItem(
c->AddItem( *p,
_T("A New Command"), // internal name
XO("1st Experimental Command..."), //displayed name
ident, ModNullFN( OnFuncFirst ),
AudioIONotBusyFlag );
c->AddItem(
c->AddItem( *p,
_T("Another New Command"),
XO("2nd Experimental Command"),
ident, ModNullFN( OnFuncSecond ),

View File

@ -195,7 +195,7 @@ extern "C"
c->SetCurrentMenu(pMenu);
c->AddSeparator();
c->AddItem(wxT("NyqBench"),
c->AddItem( *p, wxT("NyqBench"),
XO("&Nyquist Workbench..."),
findme,
static_cast<CommandFunctorPointer>(&NyqBench::ShowNyqBench),

View File

@ -200,7 +200,7 @@ void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem )
else
if (const auto pCommand =
dynamic_cast<CommandItem*>( pItem )) {
manager.AddItem(
manager.AddItem( project,
pCommand->name, pCommand->label_in,
pCommand->finder, pCommand->callback,
pCommand->flags, pCommand->options

View File

@ -499,7 +499,8 @@ void CommandManager::ClearCurrentMenu()
void CommandManager::AddItem(const CommandID &name,
void CommandManager::AddItem(AudacityProject &project,
const CommandID &name,
const TranslatableString &label_in,
CommandHandlerFinder finder,
CommandFunctorPointer callback,
@ -528,10 +529,10 @@ void CommandManager::AddItem(const CommandID &name,
SetCommandFlags(name, flags);
auto checkmark = options.check;
if (checkmark >= 0) {
auto &checker = options.checker;
if (checker) {
CurrentMenu()->AppendCheckItem(ID, label);
CurrentMenu()->Check(ID, checkmark != 0);
CurrentMenu()->Check(ID, checker( project ));
}
else {
CurrentMenu()->Append(ID, label);
@ -540,6 +541,12 @@ void CommandManager::AddItem(const CommandID &name,
mbSeparatorAllowed = true;
}
auto CommandManager::Options::MakeCheckFn(
const wxString key, bool defaultValue ) -> CheckFn
{
return [=](AudacityProject&){ return gPrefs->ReadBool( key, defaultValue ); };
}
///
/// Add a list of menu items to the current menu. When the user selects any
/// one of these, the given functor will be called

View File

@ -141,6 +141,9 @@ class AUDACITY_DLL_API CommandManager final
// For specifying unusual arguments in AddItem
struct Options
{
// type of a function that determines checkmark state
using CheckFn = std::function< bool(AudacityProject&) >;
Options() {}
// Allow implicit construction from an accelerator string, which is
// a very common case
@ -153,8 +156,6 @@ class AUDACITY_DLL_API CommandManager final
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 (bool value = true) &&
{ bIsEffect = value; return std::move(*this); }
Options &&Parameter (const CommandParameter &value) &&
@ -168,14 +169,35 @@ class AUDACITY_DLL_API CommandManager final
Options &&AllowInMacros ( int value = 1 ) &&
{ allowInMacros = value; return std::move(*this); }
// Specify a constant check state
Options &&CheckState (bool value) && {
checker = value
? [](AudacityProject&){ return true; }
: [](AudacityProject&){ return false; }
;
return std::move(*this);
}
// CheckTest is overloaded
// Take arbitrary predicate
Options &&CheckTest (const CheckFn &fn) &&
{ checker = fn; return std::move(*this); }
// Take a preference path
Options &&CheckTest (const wxChar *key, bool defaultValue) && {
checker = MakeCheckFn( key, defaultValue );
return std::move(*this);
}
const wxChar *accel{ wxT("") };
int check{ -1 }; // default value means it's not a check item
CheckFn checker; // default value means it's not a check item
bool bIsEffect{ false };
CommandParameter parameter{};
TranslatableString longName{};
bool global{ false };
bool useStrictFlags{ false };
int allowInMacros{ -1 }; // 0 = never, 1 = always, -1 = deduce from label
private:
static CheckFn MakeCheckFn( const wxString key, bool defaultValue );
};
void AddItemList(const CommandID & name,
@ -186,7 +208,8 @@ class AUDACITY_DLL_API CommandManager final
CommandFlag flags,
bool bIsEffect = false);
void AddItem(const CommandID & name,
void AddItem(AudacityProject &project,
const CommandID & name,
const TranslatableString &label_in,
CommandHandlerFinder finder,
CommandFunctorPointer callback,

View File

@ -842,7 +842,6 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
{
using namespace MenuTable;
using Options = CommandManager::Options;
auto gAudioIO = AudioIO::Get();
return FinderScope( findCommandHandler ).Eval(
Menu( XO("T&ools"),
@ -899,12 +898,16 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
XXO("Simulate Recording Errors"),
FN(OnSimulateRecordingErrors),
AudioIONotBusyFlag,
Options{}.CheckState( gAudioIO->mSimulateRecordingErrors ) ),
Options{}.CheckTest(
[](AudacityProject&){
return AudioIO::Get()->mSimulateRecordingErrors; } ) ),
Command( wxT("DetectUpstreamDropouts"),
XXO("Detect Upstream Dropouts"),
FN(OnDetectUpstreamDropouts),
AudioIONotBusyFlag,
Options{}.CheckState( gAudioIO->mDetectUpstreamDropouts ) )
Options{}.CheckTest(
[](AudacityProject&){
return AudioIO::Get()->mDetectUpstreamDropouts; } ) )
#endif
) );
}

View File

@ -1384,8 +1384,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
XXO("&Move Selection with Tracks (on/off)"),
FN(OnMoveSelectionWithTracks),
AlwaysEnabledFlag,
Options{}.CheckState(
gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), 0L ) ) )
Options{}.CheckTest( wxT("/GUI/MoveSelectionWithTracks"), false ) )
),
#if 0
@ -1425,7 +1424,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
Command( wxT("SyncLock"), XXO("Sync-&Lock Tracks (on/off)"),
FN(OnSyncLock), AlwaysEnabledFlag,
Options{}.CheckState( gPrefs->Read(wxT("/GUI/SyncLockTracks"), 0L) ) )
Options{}.CheckTest( wxT("/GUI/SyncLockTracks"), false ) )
#endif
) );

View File

@ -1032,7 +1032,7 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
),
// Scrubbing sub-menu
Scrubber::Get( project ).Menu(),
Scrubber::Menu(),
CursorMenu,

View File

@ -457,7 +457,7 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& )
Separator(),
Command( wxT("AdvancedVZoom"), XXO("Advanced &Vertical Zooming"),
FN(OnAdvancedVZoom), AlwaysEnabledFlag,
Options{}.CheckState( gPrefs->Read(wxT("/GUI/VerticalZooming"), 0L) ) )
Options{}.CheckTest( wxT("/GUI/VerticalZooming"), false ) )
),
Menu( XO("T&rack Size"),
@ -538,10 +538,10 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& )
Command( wxT("ShowExtraMenus"), XXO("&Extra Menus (on/off)"),
FN(OnShowExtraMenus), AlwaysEnabledFlag,
Options{}.CheckState( gPrefs->Read(wxT("/GUI/ShowExtraMenus"), 0L) ) ),
Options{}.CheckTest( wxT("/GUI/ShowExtraMenus"), false ) ),
Command( wxT("ShowClipping"), XXO("&Show Clipping (on/off)"),
FN(OnShowClipping), AlwaysEnabledFlag,
Options{}.CheckState( gPrefs->Read(wxT("/GUI/ShowClipping"), 0L) ) )
Options{}.CheckTest( wxT("/GUI/ShowClipping"), false ) )
#if defined(EXPERIMENTAL_EFFECTS_RACK)
,
Command( wxT("ShowEffectsRack"), XXO("Show Effects Rack"),

View File

@ -1136,7 +1136,8 @@ MenuTable::BaseItemPtr Scrubber::Menu()
item.flags,
item.StatusTest
? // a checkmark item
Options{}.CheckState( (this->*item.StatusTest)() )
Options{}.CheckTest( [&item](AudacityProject &project){
return ( Scrubber::Get(project).*(item.StatusTest) )(); } )
: // not a checkmark item
Options{}
) );

View File

@ -118,7 +118,7 @@ public:
bool CanScrub() const;
// For the toolbar
MenuTable::BaseItemPtr Menu();
static MenuTable::BaseItemPtr Menu();
// For popup
void PopulatePopupMenu(wxMenu &menu);