1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-16 16:10:06 +02:00

Command manager stores checkmark predicates...

... and we use them to simplify (the misnamed) MenuManager::ModifyToolbarMenus.

It looked wrong that statically constructed menu descriptions should ever hold
constant boolean checkmark values, rather than functions to re-eveluate the
checkmark state as needed.
This commit is contained in:
Paul Licameli 2020-02-01 11:14:22 -05:00
parent c3bbdbc50f
commit 7f4d61257a
8 changed files with 89 additions and 98 deletions

View File

@ -1287,37 +1287,8 @@ void MenuManager::ModifyToolbarMenus(AudacityProject &project)
// be deleted, so protect against it.
auto &toolManager = ToolManager::Get( project );
auto &commandManager = CommandManager::Get( project );
auto &settings = ProjectSettings::Get( project );
commandManager.Check(wxT("ShowScrubbingTB"),
toolManager.IsVisible(ScrubbingBarID));
commandManager.Check(wxT("ShowDeviceTB"),
toolManager.IsVisible(DeviceBarID));
commandManager.Check(wxT("ShowEditTB"),
toolManager.IsVisible(EditBarID));
commandManager.Check(wxT("ShowMeterTB"),
toolManager.IsVisible(MeterBarID));
commandManager.Check(wxT("ShowRecordMeterTB"),
toolManager.IsVisible(RecordMeterBarID));
commandManager.Check(wxT("ShowPlayMeterTB"),
toolManager.IsVisible(PlayMeterBarID));
commandManager.Check(wxT("ShowMixerTB"),
toolManager.IsVisible(MixerBarID));
commandManager.Check(wxT("ShowSelectionTB"),
toolManager.IsVisible(SelectionBarID));
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
commandManager.Check(wxT("ShowSpectralSelectionTB"),
toolManager.IsVisible(SpectralSelectionBarID));
#endif
commandManager.Check(wxT("ShowToolsTB"),
toolManager.IsVisible(ToolsBarID));
commandManager.Check(wxT("ShowTranscriptionTB"),
toolManager.IsVisible(TranscriptionBarID));
commandManager.Check(wxT("ShowTransportTB"),
toolManager.IsVisible(TransportBarID));
// Now, go through each toolbar, and call EnableDisableButtons()
for (int i = 0; i < ToolBarCount; i++) {
auto bar = toolManager.GetToolBar(i);
@ -1328,31 +1299,11 @@ void MenuManager::ModifyToolbarMenus(AudacityProject &project)
// These don't really belong here, but it's easier and especially so for
// the Edit toolbar and the sync-lock menu item.
bool active;
gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"),&active, false);
commandManager.Check(wxT("SoundActivation"), active);
#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
gPrefs->Read(wxT("/AudioIO/AutomatedInputLevelAdjustment"),&active, false);
commandManager.Check(wxT("AutomatedInputLevelAdjustmentOnOff"), active);
#endif
active = TracksPrefs::GetPinnedHeadPreference();
commandManager.Check(wxT("PinnedHead"), active);
#ifdef EXPERIMENTAL_DA
gPrefs->Read(wxT("/AudioIO/Duplex"),&active, false);
#else
gPrefs->Read(wxT("/AudioIO/Duplex"),&active, true);
#endif
commandManager.Check(wxT("Overdub"), active);
gPrefs->Read(wxT("/AudioIO/SWPlaythrough"),&active, false);
commandManager.Check(wxT("SWPlaythrough"), active);
gPrefs->Read(wxT("/GUI/SyncLockTracks"), &active, false);
settings.SetSyncLock(active);
commandManager.Check(wxT("SyncLock"), active);
gPrefs->Read(wxT("/GUI/TypeToCreateLabel"),&active, false);
commandManager.Check(wxT("TypeToCreateLabel"), active);
CommandManager::Get( project ).UpdateCheckmarks( project );
}
namespace

View File

@ -477,6 +477,15 @@ wxMenu * CommandManager::CurrentMenu() const
return tmpCurrentSubMenu;
}
void CommandManager::UpdateCheckmarks( AudacityProject &project )
{
for ( const auto &entry : mCommandList ) {
if ( entry->menu && entry->checkmarkFn && !entry->isOccult) {
entry->menu->Check( entry->id, entry->checkmarkFn( project ) );
}
}
}
void CommandManager::AddItem(AudacityProject &project,
@ -522,7 +531,7 @@ void CommandManager::AddItem(AudacityProject &project,
}
auto CommandManager::Options::MakeCheckFn(
const wxString key, bool defaultValue ) -> CheckFn
const wxString key, bool defaultValue ) -> CommandListEntry::CheckFn
{
return [=](AudacityProject&){ return gPrefs->ReadBool( key, defaultValue ); };
}
@ -689,6 +698,7 @@ CommandListEntry *CommandManager::NewIdentifier(const CommandID & nameIn,
entry->wantKeyup = (accel.Find(wxT("\twantKeyup")) != wxNOT_FOUND) || entry->skipKeydown;
entry->isGlobal = false;
entry->isOccult = bMakingOccultCommands;
entry->checkmarkFn = options.checker;
// Exclude accelerators that are in the MaxList.
// Note that the default is unaffected, intentionally so.

View File

@ -69,6 +69,11 @@ struct CommandListEntry
CommandHandlerFinder finder;
CommandFunctorPointer callback;
CommandParameter parameter;
// type of a function that determines checkmark state
using CheckFn = std::function< bool(AudacityProject&) >;
CheckFn checkmarkFn;
bool multi;
int index;
int count;
@ -139,9 +144,6 @@ 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
@ -167,17 +169,9 @@ 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) &&
Options &&CheckTest (const CommandListEntry::CheckFn &fn) &&
{ checker = fn; return std::move(*this); }
// Take a preference path
Options &&CheckTest (const wxChar *key, bool defaultValue) && {
@ -186,7 +180,7 @@ class AUDACITY_DLL_API CommandManager final
}
const wxChar *accel{ wxT("") };
CheckFn checker; // default value means it's not a check item
CommandListEntry::CheckFn checker; // default value means it's not a check item
bool bIsEffect{ false };
CommandParameter parameter{};
TranslatableString longName{};
@ -195,7 +189,8 @@ class AUDACITY_DLL_API CommandManager final
int allowInMacros{ -1 }; // 0 = never, 1 = always, -1 = deduce from label
private:
static CheckFn MakeCheckFn( const wxString key, bool defaultValue );
static CommandListEntry::CheckFn
MakeCheckFn( const wxString key, bool defaultValue );
};
void AddItemList(const CommandID & name,
@ -363,6 +358,8 @@ private:
wxMenu * CurrentSubMenu() const;
public:
wxMenu * CurrentMenu() const;
void UpdateCheckmarks( AudacityProject &project );
private:
wxString FormatLabelForMenu(const CommandListEntry *entry) const;
wxString FormatLabelWithDisabledAccel(const CommandListEntry *entry) const;

View File

@ -1,4 +1,5 @@
#include "../CommonCommandFlags.h"
#include "../Menus.h"
#include "../Prefs.h"
#include "../Project.h"
#include "../commands/CommandContext.h"
@ -114,11 +115,11 @@ void OnFullScreen(const CommandContext &context)
{
auto &project = context.project;
auto &window = GetProjectFrame( project );
auto &commandManager = CommandManager::Get( project );
bool bChecked = !window.wxTopLevelWindow::IsFullScreen();
window.wxTopLevelWindow::ShowFullScreen(bChecked);
commandManager.Check(wxT("FullScreenOnOff"), bChecked);
MenuManager::Get(project).ModifyToolbarMenus(project);
}
}; // struct Handler
@ -235,8 +236,9 @@ BaseItemPtr ExtraMiscItems()
Command( wxT("FullScreenOnOff"), XXO("&Full Screen (on/off)"),
FN(OnFullScreen),
AlwaysEnabledFlag,
Options{ key }.CheckState(
GetProjectFrame( project ).wxTopLevelWindow::IsFullScreen() ) );
Options{ key }.CheckTest( []( const AudacityProject &project ) {
return GetProjectFrame( project )
.wxTopLevelWindow::IsFullScreen(); } ) );
}
) );
}

View File

@ -592,8 +592,6 @@ BaseItemSharedPtr LabelEditMenus()
using namespace MenuTable;
using Options = CommandManager::Options;
static const auto checkOff = Options{}.CheckState( false );
static const auto NotBusyLabelsAndWaveFlags =
AudioIONotBusyFlag() |
LabelsSelectedFlag() | WaveTracksExistFlag() | TimeSelectedFlag();
@ -630,7 +628,8 @@ BaseItemSharedPtr LabelEditMenus()
Section( "",
Command( wxT("TypeToCreateLabel"),
XXO("&Type to Create a Label (on/off)"),
FN(OnToggleTypeToCreateLabel), AlwaysEnabledFlag, checkOff )
FN(OnToggleTypeToCreateLabel), AlwaysEnabledFlag,
Options{}.CheckTest(wxT("/GUI/TypeToCreateLabel"), false) )
)
), // first menu

View File

@ -255,12 +255,19 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
namespace{
using namespace MenuTable;
auto ToolbarCheckFn( int toolbarId ) -> CommandListEntry::CheckFn
{
return [toolbarId](AudacityProject &project){
auto &toolManager = ToolManager::Get( project );
return toolManager.IsVisible(toolbarId);
};
}
BaseItemSharedPtr ToolbarsMenu()
{
using Options = CommandManager::Options;
static const auto checkOff = Options{}.CheckState( false );
static BaseItemSharedPtr menu{
( FinderScope{ findCommandHandler },
Section( wxT("Toolbars"),
@ -275,56 +282,68 @@ BaseItemSharedPtr ToolbarsMenu()
/* i18n-hint: Clicking this menu item shows the toolbar
with the big buttons on it (play record etc)*/
Command( wxT("ShowTransportTB"), XXO("&Transport Toolbar"),
FN(OnShowTransportToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowTransportToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( TransportBarID ) ) ),
/* i18n-hint: Clicking this menu item shows a toolbar
that has some tools in it*/
Command( wxT("ShowToolsTB"), XXO("T&ools Toolbar"),
FN(OnShowToolsToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowToolsToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( ToolsBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
with the recording level meters*/
Command( wxT("ShowRecordMeterTB"), XXO("&Recording Meter Toolbar"),
FN(OnShowRecordMeterToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowRecordMeterToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( RecordMeterBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
with the playback level meter*/
Command( wxT("ShowPlayMeterTB"), XXO("&Playback Meter Toolbar"),
FN(OnShowPlayMeterToolBar), AlwaysEnabledFlag, checkOff )
FN(OnShowPlayMeterToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( PlayMeterBarID ) ) )
/* --i18nhint: Clicking this menu item shows the toolbar
which has sound level meters*/
//Command( wxT("ShowMeterTB"), XXO("Co&mbined Meter Toolbar"),
// FN(OnShowMeterToolBar), AlwaysEnabledFlag, checkOff ),
// FN(OnShowMeterToolBar), AlwaysEnabledFlag,
// Options{}.CheckTest( ToolbarCheckFn( MeterBarID ) ) )
,
/* i18n-hint: Clicking this menu item shows the toolbar
with the mixer*/
Command( wxT("ShowMixerTB"), XXO("Mi&xer Toolbar"),
FN(OnShowMixerToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowMixerToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( MixerBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar for editing*/
Command( wxT("ShowEditTB"), XXO("&Edit Toolbar"),
FN(OnShowEditToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowEditToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( EditBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
for transcription (currently just vary play speed)*/
Command( wxT("ShowTranscriptionTB"), XXO("Pla&y-at-Speed Toolbar"),
FN(OnShowTranscriptionToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowTranscriptionToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( TranscriptionBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
that enables Scrub or Seek playback and Scrub Ruler*/
Command( wxT("ShowScrubbingTB"), XXO("Scru&b Toolbar"),
FN(OnShowScrubbingToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowScrubbingToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( ScrubbingBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
that manages devices*/
Command( wxT("ShowDeviceTB"), XXO("&Device Toolbar"),
FN(OnShowDeviceToolBar), AlwaysEnabledFlag, checkOff ),
FN(OnShowDeviceToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( DeviceBarID ) ) ),
/* i18n-hint: Clicking this menu item shows the toolbar
for selecting a time range of audio*/
Command( wxT("ShowSelectionTB"), XXO("&Selection Toolbar"),
FN(OnShowSelectionToolBar), AlwaysEnabledFlag, checkOff )
FN(OnShowSelectionToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( SelectionBarID ) ) )
#ifdef EXPERIMENTAL_TIMER_TOOLBAR
,
/* i18n-hint: Clicking this menu item shows the toolbar
for viewing actual time of the cursor*/
Command( wxT("ShowTimerToolBarTB"), XXO("&Timer Toolbar"),
FN(OnShowTimerToolBar), AlwaysEnabledFlag, checkOff )
FN(OnShowTimerToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( TimerBarID ) ) )
#endif
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
,
@ -332,7 +351,8 @@ BaseItemSharedPtr ToolbarsMenu()
/* i18n-hint: Clicking this menu item shows the toolbar
for selecting a frequency range of audio*/
XXO("Spe&ctral Selection Toolbar"),
FN(OnShowSpectralSelectionToolBar), AlwaysEnabledFlag, checkOff )
FN(OnShowSpectralSelectionToolBar), AlwaysEnabledFlag,
Options{}.CheckTest( ToolbarCheckFn( SpectralSelectionBarID ) ) )
#endif
)
)

View File

@ -22,6 +22,7 @@
#include "../UndoManager.h"
#include "../WaveClip.h"
#include "../prefs/RecordingPrefs.h"
#include "../prefs/TracksPrefs.h"
#include "../WaveTrack.h"
#include "../ViewInfo.h"
#include "../commands/CommandContext.h"
@ -897,9 +898,6 @@ BaseItemSharedPtr TransportMenu()
{
using Options = CommandManager::Options;
static const auto checkOff = Options{}.CheckState( false );
static const auto checkOn = Options{}.CheckState( true );
static const auto CanStopFlags = AudioIONotBusyFlag() | CanStopAudioStreamFlag();
static BaseItemSharedPtr menu{
@ -982,7 +980,8 @@ BaseItemSharedPtr TransportMenu()
Command( wxT("SoundActivation"),
XXO("Sound A&ctivated Recording (on/off)"),
FN(OnToggleSoundActivated),
AudioIONotBusyFlag() | CanStopAudioStreamFlag(), checkOff )
AudioIONotBusyFlag() | CanStopAudioStreamFlag(),
Options{}.CheckTest(wxT("/AudioIO/SoundActivatedRecord"), false) )
),
Section( "",
@ -990,14 +989,24 @@ BaseItemSharedPtr TransportMenu()
FN(OnTogglePinnedHead),
// Switching of scrolling on and off is permitted
// even during transport
AlwaysEnabledFlag, checkOff ),
AlwaysEnabledFlag,
Options{}.CheckTest([](const AudacityProject&){
return TracksPrefs::GetPinnedHeadPreference(); } ) ),
Command( wxT("Overdub"), XXO("&Overdub (on/off)"),
FN(OnTogglePlayRecording),
AudioIONotBusyFlag() | CanStopAudioStreamFlag(), checkOn ),
AudioIONotBusyFlag() | CanStopAudioStreamFlag(),
Options{}.CheckTest( wxT("/AudioIO/Duplex"),
#ifdef EXPERIMENTAL_DA
false
#else
true
#endif
) ),
Command( wxT("SWPlaythrough"), XXO("So&ftware Playthrough (on/off)"),
FN(OnToggleSWPlaythrough),
AudioIONotBusyFlag() | CanStopAudioStreamFlag(), checkOff )
AudioIONotBusyFlag() | CanStopAudioStreamFlag(),
Options{}.CheckTest( wxT("/AudioIO/SWPlaythrough"), false ) )
#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
@ -1005,7 +1014,9 @@ BaseItemSharedPtr TransportMenu()
Command( wxT("AutomatedInputLevelAdjustmentOnOff"),
XXO("A&utomated Recording Level Adjustment (on/off)"),
FN(OnToggleAutomatedInputLevelAdjustment),
AudioIONotBusyFlag() | CanStopAudioStreamFlag(), checkOff )
AudioIONotBusyFlag() | CanStopAudioStreamFlag(),
Options{}.CheckTest(
wxT("/AudioIO/AutomatedInputLevelAdjustment"), false ) )
#endif
)
)

View File

@ -389,8 +389,6 @@ BaseItemSharedPtr ViewMenu()
{
using Options = CommandManager::Options;
static const auto checkOff = Options{}.CheckState( false );
static BaseItemSharedPtr menu{
( FinderScope{ findCommandHandler },
Menu( wxT("View"), XO("&View"),
@ -448,7 +446,10 @@ BaseItemSharedPtr ViewMenu()
#if defined(EXPERIMENTAL_EFFECTS_RACK)
,
Command( wxT("ShowEffectsRack"), XXO("Show Effects Rack"),
FN(OnShowEffectsRack), AlwaysEnabledFlag, checkOff )
FN(OnShowEffectsRack), AlwaysEnabledFlag,
Options{}.CheckTest( [](AudacityProject &project){
auto &rack = EffectRack::Get( project );
return rack.IsShown(); } ) )
#endif
)
) ) };