mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-10 17:37:45 +02:00
Menu descriptions mostly computed once only & have string identifiers
This commit is contained in:
commit
c77d4e1961
@ -113,7 +113,7 @@ void ModNullCallback::OnFuncSecond(const CommandContext &)
|
||||
}
|
||||
ModNullCallback * pModNullCallback=NULL;
|
||||
|
||||
#define ModNullFN(X) ident, static_cast<CommandFunctorPointer>(&ModNullCallback:: X)
|
||||
#define ModNullFN(X) static_cast<CommandFunctorPointer>((&ModNullCallback:: X))
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -160,15 +160,15 @@ 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
|
||||
ModNullFN( OnFuncFirst ),
|
||||
ident, ModNullFN( OnFuncFirst ),
|
||||
AudioIONotBusyFlag );
|
||||
c->AddItem(
|
||||
_T("Another New Command"),
|
||||
c->AddItem( *p,
|
||||
_T("Another New Command"),
|
||||
XO("2nd Experimental Command"),
|
||||
ModNullFN( OnFuncSecond ),
|
||||
ident, ModNullFN( OnFuncSecond ),
|
||||
AudioIONotBusyFlag );
|
||||
c->ClearCurrentMenu();
|
||||
}
|
||||
|
@ -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),
|
||||
|
109
src/Menus.cpp
109
src/Menus.cpp
@ -104,10 +104,14 @@ namespace MenuTable {
|
||||
|
||||
BaseItem::~BaseItem() {}
|
||||
|
||||
SharedItem::~SharedItem() {}
|
||||
|
||||
ComputedItem::~ComputedItem() {}
|
||||
|
||||
GroupItem::GroupItem( BaseItemPtrs &&items_ )
|
||||
: items{ std::move( items_ ) }
|
||||
SingleItem::~SingleItem() {}
|
||||
|
||||
GroupItem::GroupItem( const wxString &internalName, BaseItemPtrs &&items_ )
|
||||
: BaseItem{ internalName }, items{ std::move( items_ ) }
|
||||
{
|
||||
}
|
||||
void GroupItem::AppendOne( BaseItemPtr&& ptr )
|
||||
@ -116,16 +120,22 @@ void GroupItem::AppendOne( BaseItemPtr&& ptr )
|
||||
}
|
||||
GroupItem::~GroupItem() {}
|
||||
|
||||
MenuItem::MenuItem( const TranslatableString &title_, BaseItemPtrs &&items_ )
|
||||
: GroupItem{ std::move( items_ ) }, title{ title_ }
|
||||
TransparentGroupItem::~TransparentGroupItem() {}
|
||||
}
|
||||
|
||||
namespace MenuTable {
|
||||
|
||||
MenuItem::MenuItem( const wxString &internalName,
|
||||
const TranslatableString &title_, BaseItemPtrs &&items_ )
|
||||
: GroupItem{ internalName, std::move( items_ ) }, title{ title_ }
|
||||
{
|
||||
wxASSERT( !title.empty() );
|
||||
}
|
||||
MenuItem::~MenuItem() {}
|
||||
|
||||
ConditionalGroupItem::ConditionalGroupItem(
|
||||
Condition condition_, BaseItemPtrs &&items_ )
|
||||
: GroupItem{ std::move( items_ ) }, condition{ condition_ }
|
||||
const wxString &internalName, Condition condition_, BaseItemPtrs &&items_ )
|
||||
: GroupItem{ internalName, std::move( items_ ) }, condition{ condition_ }
|
||||
{
|
||||
}
|
||||
ConditionalGroupItem::~ConditionalGroupItem() {}
|
||||
@ -134,11 +144,11 @@ SeparatorItem::~SeparatorItem() {}
|
||||
|
||||
CommandItem::CommandItem(const CommandID &name_,
|
||||
const TranslatableString &label_in_,
|
||||
CommandHandlerFinder finder_,
|
||||
CommandFunctorPointer callback_,
|
||||
CommandFlag flags_,
|
||||
const CommandManager::Options &options_)
|
||||
: name{ name_ }, label_in{ label_in_ }
|
||||
const CommandManager::Options &options_,
|
||||
CommandHandlerFinder finder_)
|
||||
: SingleItem{ name_ }, label_in{ label_in_ }
|
||||
, finder{ finder_ }, callback{ callback_ }
|
||||
, flags{ flags_ }, options{ options_ }
|
||||
{}
|
||||
@ -146,11 +156,11 @@ CommandItem::~CommandItem() {}
|
||||
|
||||
CommandGroupItem::CommandGroupItem(const wxString &name_,
|
||||
std::initializer_list< ComponentInterfaceSymbol > items_,
|
||||
CommandHandlerFinder finder_,
|
||||
CommandFunctorPointer callback_,
|
||||
CommandFlag flags_,
|
||||
bool isEffect_)
|
||||
: name{ name_ }, items{ items_ }
|
||||
bool isEffect_,
|
||||
CommandHandlerFinder finder_)
|
||||
: SingleItem{ name_ }, items{ items_ }
|
||||
, finder{ finder_ }, callback{ callback_ }
|
||||
, flags{ flags_ }, isEffect{ isEffect_ }
|
||||
{}
|
||||
@ -158,10 +168,21 @@ CommandGroupItem::~CommandGroupItem() {}
|
||||
|
||||
SpecialItem::~SpecialItem() {}
|
||||
|
||||
CommandHandlerFinder FinderScope::sFinder =
|
||||
[](AudacityProject &project) -> CommandHandlerObject & {
|
||||
// If this default finder function is reached, then FinderScope should
|
||||
// have been used somewhere, or an explicit CommandHandlerFinder passed
|
||||
// to menu item constructors
|
||||
wxASSERT( false );
|
||||
return project;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const auto MenuPathStart = wxT("MenuBar");
|
||||
|
||||
void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem );
|
||||
|
||||
void VisitItems(
|
||||
@ -179,6 +200,12 @@ void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem )
|
||||
auto &manager = CommandManager::Get( project );
|
||||
|
||||
using namespace MenuTable;
|
||||
if (const auto pShared =
|
||||
dynamic_cast<SharedItem*>( pItem )) {
|
||||
auto delegate = pShared->ptr;
|
||||
VisitItem( project, delegate.get() );
|
||||
}
|
||||
else
|
||||
if (const auto pComputed =
|
||||
dynamic_cast<ComputedItem*>( pItem )) {
|
||||
// TODO maybe? memo-ize the results of the function, but that requires
|
||||
@ -191,7 +218,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
|
||||
@ -226,7 +253,7 @@ void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem )
|
||||
}
|
||||
else
|
||||
if (const auto pGroup =
|
||||
dynamic_cast<GroupItem*>( pItem )) {
|
||||
dynamic_cast<TransparentGroupItem*>( pItem )) {
|
||||
// recursion
|
||||
VisitItems( project, pGroup->items );
|
||||
}
|
||||
@ -251,45 +278,45 @@ void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem )
|
||||
/// changes in configured preferences - for example changes in key-bindings
|
||||
/// affect the short-cut key legend that appears beside each command,
|
||||
|
||||
MenuTable::BaseItemPtr FileMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr FileMenu();
|
||||
|
||||
MenuTable::BaseItemPtr EditMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr EditMenu();
|
||||
|
||||
MenuTable::BaseItemPtr SelectMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr SelectMenu();
|
||||
|
||||
MenuTable::BaseItemPtr ViewMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr ViewMenu();
|
||||
|
||||
MenuTable::BaseItemPtr TransportMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr TransportMenu();
|
||||
|
||||
MenuTable::BaseItemPtr TracksMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr TracksMenu();
|
||||
|
||||
MenuTable::BaseItemPtr GenerateMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr EffectMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr ToolsMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr GenerateMenu();
|
||||
MenuTable::BaseItemSharedPtr EffectMenu();
|
||||
MenuTable::BaseItemSharedPtr AnalyzeMenu();
|
||||
MenuTable::BaseItemSharedPtr ToolsMenu();
|
||||
|
||||
MenuTable::BaseItemPtr WindowMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr WindowMenu();
|
||||
|
||||
MenuTable::BaseItemPtr ExtraMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr ExtraMenu();
|
||||
|
||||
MenuTable::BaseItemPtr HelpMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr HelpMenu();
|
||||
|
||||
// Table of menu factories.
|
||||
// TODO: devise a registration system instead.
|
||||
static const auto menuTree = MenuTable::Items(
|
||||
FileMenu
|
||||
, EditMenu
|
||||
, SelectMenu
|
||||
, ViewMenu
|
||||
, TransportMenu
|
||||
, TracksMenu
|
||||
, GenerateMenu
|
||||
, EffectMenu
|
||||
, AnalyzeMenu
|
||||
, ToolsMenu
|
||||
, WindowMenu
|
||||
, ExtraMenu
|
||||
, HelpMenu
|
||||
static const auto menuTree = MenuTable::Items( MenuPathStart
|
||||
, FileMenu()
|
||||
, EditMenu()
|
||||
, SelectMenu()
|
||||
, ViewMenu()
|
||||
, TransportMenu()
|
||||
, TracksMenu()
|
||||
, GenerateMenu()
|
||||
, EffectMenu()
|
||||
, AnalyzeMenu()
|
||||
, ToolsMenu()
|
||||
, WindowMenu()
|
||||
, ExtraMenu()
|
||||
, HelpMenu()
|
||||
);
|
||||
|
||||
void MenuCreator::CreateMenusAndCommands(AudacityProject &project)
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
@ -382,7 +405,8 @@ private:
|
||||
std::unique_ptr< wxMenuBar > mTempMenuBar;
|
||||
};
|
||||
|
||||
// Define items that populate tables that describe menu trees
|
||||
// Define classes and functions that associate parts of the user interface
|
||||
// with path names
|
||||
namespace MenuTable {
|
||||
// TODO C++17: maybe use std::variant (discriminated unions) to achieve
|
||||
// polymorphism by other means, not needing unique_ptr and dynamic_cast
|
||||
@ -392,37 +416,72 @@ namespace MenuTable {
|
||||
// large.
|
||||
struct BaseItem {
|
||||
// declare at least one virtual function so dynamic_cast will work
|
||||
explicit
|
||||
BaseItem( const Identifier &internalName )
|
||||
: name{ internalName }
|
||||
{}
|
||||
virtual ~BaseItem();
|
||||
|
||||
const Identifier name;
|
||||
};
|
||||
using BaseItemPtr = std::unique_ptr<BaseItem>;
|
||||
using BaseItemSharedPtr = std::shared_ptr<BaseItem>;
|
||||
using BaseItemPtrs = std::vector<BaseItemPtr>;
|
||||
|
||||
|
||||
// The type of functions that generate menu table descriptions.
|
||||
// Return type is a shared_ptr to let the function decide whether to recycle
|
||||
// the object or rebuild it on demand each time.
|
||||
// Return value from the factory may be null.
|
||||
using Factory = std::function<
|
||||
std::shared_ptr< MenuTable::BaseItem >( AudacityProject & )
|
||||
>;
|
||||
// An item that delegates to another held in a shared pointer; this allows
|
||||
// static tables of items to be computed once and reused
|
||||
// The name of the delegate is significant for path calculations
|
||||
struct SharedItem final : BaseItem {
|
||||
explicit SharedItem( const BaseItemSharedPtr &ptr_ )
|
||||
: BaseItem{ wxEmptyString }
|
||||
, ptr{ ptr_ }
|
||||
{}
|
||||
~SharedItem() override;
|
||||
|
||||
BaseItemSharedPtr ptr;
|
||||
};
|
||||
|
||||
// A convenience function
|
||||
inline std::unique_ptr<SharedItem> Shared( const BaseItemSharedPtr &ptr )
|
||||
{ return std::make_unique<SharedItem>( ptr ); }
|
||||
|
||||
// An item that computes some other item to substitute for it, each time
|
||||
// the ComputedItem is visited
|
||||
// The name of the substitute is significant for path calculations
|
||||
struct ComputedItem final : BaseItem {
|
||||
// The type of functions that generate descriptions of items.
|
||||
// Return type is a shared_ptr to let the function decide whether to
|
||||
// recycle the object or rebuild it on demand each time.
|
||||
// Return value from the factory may be null
|
||||
using Factory = std::function< BaseItemSharedPtr( AudacityProject & ) >;
|
||||
|
||||
struct ComputedItem : BaseItem {
|
||||
explicit ComputedItem( const Factory &factory_ )
|
||||
: factory{ factory_ }
|
||||
: BaseItem( wxEmptyString )
|
||||
, factory{ factory_ }
|
||||
{}
|
||||
~ComputedItem() override;
|
||||
|
||||
Factory factory;
|
||||
};
|
||||
|
||||
// Common abstract base class for items that are not groups
|
||||
struct SingleItem : BaseItem {
|
||||
using BaseItem::BaseItem;
|
||||
~SingleItem() override = 0;
|
||||
};
|
||||
|
||||
// Common abstract base class for items that group other items
|
||||
struct GroupItem : BaseItem {
|
||||
// Construction from a previously built-up vector of pointers
|
||||
GroupItem( BaseItemPtrs &&items_ );
|
||||
// Construction from an internal name and a previously built-up
|
||||
// vector of pointers
|
||||
GroupItem( const wxString &internalName, BaseItemPtrs &&items_ );
|
||||
// In-line, variadic constructor that doesn't require building a vector
|
||||
template< typename... Args >
|
||||
GroupItem( Args&&... args )
|
||||
GroupItem( const wxString &internalName, Args&&... args )
|
||||
: BaseItem( internalName )
|
||||
{ Append( std::forward< Args >( args )... ); }
|
||||
~GroupItem() override;
|
||||
~GroupItem() override = 0;
|
||||
|
||||
BaseItemPtrs items;
|
||||
|
||||
@ -450,18 +509,35 @@ namespace MenuTable {
|
||||
// (Thus, a lambda can return a unique_ptr<BaseItem> rvalue even though
|
||||
// Factory's return type is shared_ptr, and the needed conversion is
|
||||
// appled implicitly.)
|
||||
void AppendOne( const Factory &factory )
|
||||
void AppendOne( const ComputedItem::Factory &factory )
|
||||
{ AppendOne( std::make_unique<ComputedItem>( factory ) ); }
|
||||
// This overload lets you supply a shared pointer to an item, directly
|
||||
template<typename Subtype>
|
||||
void AppendOne( const std::shared_ptr<Subtype> &ptr )
|
||||
{ AppendOne( std::make_unique<SharedItem>(ptr) ); }
|
||||
};
|
||||
|
||||
// Concrete subclass of GroupItem that adds nothing else
|
||||
// TransparentGroupItem with an empty name is transparent to item path calculations
|
||||
struct TransparentGroupItem final : GroupItem
|
||||
{
|
||||
using GroupItem::GroupItem;
|
||||
~TransparentGroupItem() override;
|
||||
};
|
||||
|
||||
// Define items that populate tables that specifically describe menu trees
|
||||
|
||||
// Describes a main menu in the toolbar, or a sub-menu
|
||||
struct MenuItem final : GroupItem {
|
||||
// Construction from a previously built-up vector of pointers
|
||||
MenuItem( const TranslatableString &title_, BaseItemPtrs &&items_ );
|
||||
// Construction from an internal name and a previously built-up
|
||||
// vector of pointers
|
||||
MenuItem( const wxString &internalName,
|
||||
const TranslatableString &title_, BaseItemPtrs &&items_ );
|
||||
// In-line, variadic constructor that doesn't require building a vector
|
||||
template< typename... Args >
|
||||
MenuItem(
|
||||
MenuItem( const wxString &internalName,
|
||||
const TranslatableString &title_, Args&&... args )
|
||||
: GroupItem{ std::forward<Args>(args)... }
|
||||
: GroupItem{ internalName, std::forward<Args>(args)... }
|
||||
, title{ title_ }
|
||||
{}
|
||||
~MenuItem() override;
|
||||
@ -469,15 +545,20 @@ namespace MenuTable {
|
||||
TranslatableString title;
|
||||
};
|
||||
|
||||
// Collects other items that are conditionally shown or hidden, but are
|
||||
// always available to macro programming
|
||||
struct ConditionalGroupItem final : GroupItem {
|
||||
using Condition = std::function< bool() >;
|
||||
|
||||
// Construction from a previously built-up vector of pointers
|
||||
ConditionalGroupItem( Condition condition_, BaseItemPtrs &&items_ );
|
||||
// Construction from an internal name and a previously built-up
|
||||
// vector of pointers
|
||||
ConditionalGroupItem( const wxString &internalName,
|
||||
Condition condition_, BaseItemPtrs &&items_ );
|
||||
// In-line, variadic constructor that doesn't require building a vector
|
||||
template< typename... Args >
|
||||
ConditionalGroupItem( Condition condition_, Args&&... args )
|
||||
: GroupItem{ std::forward<Args>(args)... }
|
||||
ConditionalGroupItem( const wxString &internalName,
|
||||
Condition condition_, Args&&... args )
|
||||
: GroupItem{ internalName, std::forward<Args>(args)... }
|
||||
, condition{ condition_ }
|
||||
{}
|
||||
~ConditionalGroupItem() override;
|
||||
@ -485,21 +566,67 @@ namespace MenuTable {
|
||||
Condition condition;
|
||||
};
|
||||
|
||||
struct SeparatorItem final : BaseItem
|
||||
// Describes a separator between menu items
|
||||
struct SeparatorItem final : SingleItem
|
||||
{
|
||||
SeparatorItem() : SingleItem{ wxEmptyString } {}
|
||||
~SeparatorItem() override;
|
||||
};
|
||||
|
||||
struct CommandItem final : BaseItem {
|
||||
// usage:
|
||||
// auto scope = FinderScope( findCommandHandler );
|
||||
// return Items( ... );
|
||||
//
|
||||
// or:
|
||||
// return FinderScope( findCommandHandler )
|
||||
// .Eval( Items( ... ) );
|
||||
//
|
||||
// where findCommandHandler names a function.
|
||||
// This is used before a sequence of many calls to Command() and
|
||||
// CommandGroup(), so that the finder argument need not be specified
|
||||
// in each call.
|
||||
class FinderScope : ValueRestorer< CommandHandlerFinder >
|
||||
{
|
||||
static CommandHandlerFinder sFinder;
|
||||
|
||||
public:
|
||||
static CommandHandlerFinder DefaultFinder() { return sFinder; }
|
||||
|
||||
explicit
|
||||
FinderScope( CommandHandlerFinder finder )
|
||||
: ValueRestorer( sFinder, finder )
|
||||
{}
|
||||
|
||||
// See usage comment above about this pass-through function
|
||||
template< typename Value > Value&& Eval( Value &&value ) const
|
||||
{ return std::forward<Value>(value); }
|
||||
};
|
||||
|
||||
// Describes one command in a menu
|
||||
struct CommandItem final : SingleItem {
|
||||
CommandItem(const CommandID &name_,
|
||||
const TranslatableString &label_in_,
|
||||
CommandHandlerFinder finder_,
|
||||
CommandFunctorPointer callback_,
|
||||
CommandFlag flags_,
|
||||
const CommandManager::Options &options_);
|
||||
const CommandManager::Options &options_,
|
||||
CommandHandlerFinder finder_);
|
||||
|
||||
// Takes a pointer to member function directly, and delegates to the
|
||||
// previous constructor; useful within the lifetime of a FinderScope
|
||||
template< typename Handler >
|
||||
CommandItem(const CommandID &name_,
|
||||
const TranslatableString &label_in_,
|
||||
void (Handler::*pmf)(const CommandContext&),
|
||||
CommandFlag flags_,
|
||||
const CommandManager::Options &options_,
|
||||
CommandHandlerFinder finder = FinderScope::DefaultFinder())
|
||||
: CommandItem(name_, label_in_,
|
||||
static_cast<CommandFunctorPointer>(pmf),
|
||||
flags_, options_, finder)
|
||||
{}
|
||||
|
||||
~CommandItem() override;
|
||||
|
||||
const CommandID name;
|
||||
const TranslatableString label_in;
|
||||
CommandHandlerFinder finder;
|
||||
CommandFunctorPointer callback;
|
||||
@ -507,16 +634,33 @@ namespace MenuTable {
|
||||
CommandManager::Options options;
|
||||
};
|
||||
|
||||
struct CommandGroupItem final : BaseItem {
|
||||
// Describes several successive commands in a menu that are closely related
|
||||
// and dispatch to one common callback, which will be passed a number
|
||||
// in the CommandContext identifying the command
|
||||
struct CommandGroupItem final : SingleItem {
|
||||
CommandGroupItem(const wxString &name_,
|
||||
std::initializer_list< ComponentInterfaceSymbol > items_,
|
||||
CommandHandlerFinder finder_,
|
||||
CommandFunctorPointer callback_,
|
||||
CommandFlag flags_,
|
||||
bool isEffect_);
|
||||
bool isEffect_,
|
||||
CommandHandlerFinder finder_);
|
||||
|
||||
// Takes a pointer to member function directly, and delegates to the
|
||||
// previous constructor; useful within the lifetime of a FinderScope
|
||||
template< typename Handler >
|
||||
CommandGroupItem(const wxString &name_,
|
||||
std::initializer_list< ComponentInterfaceSymbol > items_,
|
||||
void (Handler::*pmf)(const CommandContext&),
|
||||
CommandFlag flags_,
|
||||
bool isEffect_,
|
||||
CommandHandlerFinder finder = FinderScope::DefaultFinder())
|
||||
: CommandGroupItem(name_, items_,
|
||||
static_cast<CommandFunctorPointer>(pmf),
|
||||
flags_, isEffect_, finder)
|
||||
{}
|
||||
|
||||
~CommandGroupItem() override;
|
||||
|
||||
const wxString name;
|
||||
const std::vector<ComponentInterfaceSymbol> items;
|
||||
CommandHandlerFinder finder;
|
||||
CommandFunctorPointer callback;
|
||||
@ -526,12 +670,13 @@ namespace MenuTable {
|
||||
|
||||
// For manipulating the enclosing menu or sub-menu directly,
|
||||
// adding any number of items, not using the CommandManager
|
||||
struct SpecialItem final : BaseItem
|
||||
struct SpecialItem final : SingleItem
|
||||
{
|
||||
using Appender = std::function< void( AudacityProject&, wxMenu& ) >;
|
||||
|
||||
explicit SpecialItem( const Appender &fn_ )
|
||||
: fn{ fn_ }
|
||||
explicit SpecialItem( const wxString &internalName, const Appender &fn_ )
|
||||
: SingleItem{ internalName }
|
||||
, fn{ fn_ }
|
||||
{}
|
||||
~SpecialItem() override;
|
||||
|
||||
@ -543,76 +688,106 @@ namespace MenuTable {
|
||||
// Group items can be constructed two ways.
|
||||
// Pointers to subordinate items are moved into the result.
|
||||
// Null pointers are permitted, and ignored when building the menu.
|
||||
// Items are spliced into the enclosing menu
|
||||
// Items are spliced into the enclosing menu.
|
||||
// The name is untranslated and may be empty, to make the group transparent
|
||||
// in identification of items by path. Otherwise try to keep the name
|
||||
// stable across Audacity versions.
|
||||
template< typename... Args >
|
||||
inline BaseItemPtr Items( Args&&... args )
|
||||
{ return std::make_unique<GroupItem>(
|
||||
inline std::unique_ptr<TransparentGroupItem> Items(
|
||||
const wxString &internalName, Args&&... args )
|
||||
{ return std::make_unique<TransparentGroupItem>( internalName,
|
||||
std::forward<Args>(args)... ); }
|
||||
|
||||
// Menu items can be constructed two ways, as for group items
|
||||
// Items will appear in a main toolbar menu or in a sub-menu
|
||||
// Items will appear in a main toolbar menu or in a sub-menu.
|
||||
// The name is untranslated. Try to keep the name stable across Audacity
|
||||
// versions.
|
||||
// If the name of a menu is empty, then subordinate items cannot be located
|
||||
// by path.
|
||||
template< typename... Args >
|
||||
inline BaseItemPtr Menu(
|
||||
const TranslatableString &title, Args&&... args )
|
||||
inline std::unique_ptr<MenuItem> Menu(
|
||||
const wxString &internalName, const TranslatableString &title, Args&&... args )
|
||||
{ return std::make_unique<MenuItem>(
|
||||
title, std::forward<Args>(args)... ); }
|
||||
inline BaseItemPtr Menu(
|
||||
const TranslatableString &title, BaseItemPtrs &&items )
|
||||
{ return std::make_unique<MenuItem>( title, std::move( items ) ); }
|
||||
internalName, title, std::forward<Args>(args)... ); }
|
||||
inline std::unique_ptr<MenuItem> Menu(
|
||||
const wxString &internalName, const TranslatableString &title, BaseItemPtrs &&items )
|
||||
{ return std::make_unique<MenuItem>(
|
||||
internalName, title, std::move( items ) ); }
|
||||
|
||||
// Conditional group items can be constructed two ways, as for group items
|
||||
// These items register in the CommandManager but are not shown in menus
|
||||
// if the condition evaluates false.
|
||||
// The name is untranslated. Try to keep the name stable across Audacity
|
||||
// versions.
|
||||
// Name for conditional group must be non-empty.
|
||||
template< typename... Args >
|
||||
inline BaseItemPtr ConditionalItems(
|
||||
ConditionalGroupItem::Condition condition, Args&&... args )
|
||||
inline std::unique_ptr<ConditionalGroupItem> ConditionalItems(
|
||||
const wxString &internalName,
|
||||
ConditionalGroupItem::Condition condition, Args&&... args )
|
||||
{ return std::make_unique<ConditionalGroupItem>(
|
||||
condition, std::forward<Args>(args)... ); }
|
||||
inline BaseItemPtr ConditionalItems(
|
||||
ConditionalGroupItem::Condition condition, BaseItemPtrs &&items )
|
||||
internalName, condition, std::forward<Args>(args)... ); }
|
||||
inline std::unique_ptr<ConditionalGroupItem> ConditionalItems(
|
||||
const wxString &internalName, ConditionalGroupItem::Condition condition,
|
||||
BaseItemPtrs &&items )
|
||||
{ return std::make_unique<ConditionalGroupItem>(
|
||||
condition, std::move( items ) ); }
|
||||
internalName, condition, std::move( items ) ); }
|
||||
|
||||
// Make either a menu item or just a group, depending on the nonemptiness
|
||||
// of the title
|
||||
// of the title.
|
||||
// The name is untranslated and may be empty, to make the group transparent
|
||||
// in identification of items by path. Otherwise try to keep the name
|
||||
// stable across Audacity versions.
|
||||
// If the name of a menu is empty, then subordinate items cannot be located
|
||||
// by path.
|
||||
template< typename... Args >
|
||||
inline BaseItemPtr MenuOrItems(
|
||||
const TranslatableString &title, Args&&... args )
|
||||
{ if ( title.empty() ) return Items( std::forward<Args>(args)... );
|
||||
else return std::make_unique<MenuItem>(
|
||||
title, std::forward<Args>(args)... ); }
|
||||
const wxString &internalName, const TranslatableString &title, Args&&... args )
|
||||
{ if ( title.empty() )
|
||||
return Items( internalName, std::forward<Args>(args)... );
|
||||
else
|
||||
return std::make_unique<MenuItem>(
|
||||
internalName, title, std::forward<Args>(args)... ); }
|
||||
inline BaseItemPtr MenuOrItems(
|
||||
const wxString &internalName,
|
||||
const TranslatableString &title, BaseItemPtrs &&items )
|
||||
{ if ( title.empty() ) return Items( std::move( items ) );
|
||||
else return std::make_unique<MenuItem>( title, std::move( items ) ); }
|
||||
{ if ( title.empty() )
|
||||
return Items( internalName, std::move( items ) );
|
||||
else
|
||||
return std::make_unique<MenuItem>(
|
||||
internalName, title, std::move( items ) ); }
|
||||
|
||||
inline std::unique_ptr<SeparatorItem> Separator()
|
||||
{ return std::make_unique<SeparatorItem>(); }
|
||||
|
||||
template< typename Handler >
|
||||
inline std::unique_ptr<CommandItem> Command(
|
||||
const CommandID &name,
|
||||
const TranslatableString &label_in,
|
||||
CommandHandlerFinder finder, CommandFunctorPointer callback,
|
||||
CommandFlag flags, const CommandManager::Options &options = {})
|
||||
void (Handler::*pmf)(const CommandContext&),
|
||||
CommandFlag flags, const CommandManager::Options &options = {},
|
||||
CommandHandlerFinder finder = FinderScope::DefaultFinder())
|
||||
{
|
||||
return std::make_unique<CommandItem>(
|
||||
name, label_in, finder, callback, flags, options
|
||||
name, label_in, pmf, flags, options, finder
|
||||
);
|
||||
}
|
||||
|
||||
template< typename Handler >
|
||||
inline std::unique_ptr<CommandGroupItem> CommandGroup(
|
||||
const wxString &name,
|
||||
std::initializer_list< ComponentInterfaceSymbol > items,
|
||||
CommandHandlerFinder finder, CommandFunctorPointer callback,
|
||||
CommandFlag flags, bool isEffect = false)
|
||||
void (Handler::*pmf)(const CommandContext&),
|
||||
CommandFlag flags, bool isEffect = false,
|
||||
CommandHandlerFinder finder = FinderScope::DefaultFinder())
|
||||
{
|
||||
return std::make_unique<CommandGroupItem>(
|
||||
name, items, finder, callback, flags, isEffect
|
||||
name, items, pmf, flags, isEffect, finder
|
||||
);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<SpecialItem> Special(
|
||||
const SpecialItem::Appender &fn )
|
||||
{ return std::make_unique<SpecialItem>( fn ); }
|
||||
const wxString &name, const SpecialItem::Appender &fn )
|
||||
{ return std::make_unique<SpecialItem>( name, fn ); }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -821,15 +821,17 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& ClipActions::Handler :: X)
|
||||
#define FN(X) (& ClipActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& )
|
||||
// Under /MenuBar/Select
|
||||
MenuTable::BaseItemSharedPtr ClipSelectMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
return Menu( XO("Clip B&oundaries"),
|
||||
static BaseItemSharedPtr menu {
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Clip"), XO("Clip B&oundaries"),
|
||||
Command( wxT("SelPrevClipBoundaryToCursor"),
|
||||
XXO("Pre&vious Clip Boundary to Cursor"),
|
||||
FN(OnSelectPrevClipBoundaryToCursor),
|
||||
@ -844,15 +846,19 @@ MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& )
|
||||
Command( wxT("SelNextClip"), XXO("N&ext Clip"), FN(OnSelectNextClip),
|
||||
WaveTracksExistFlag,
|
||||
Options{ wxT("Alt+."), XO("Select Next Clip") } )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & )
|
||||
// Under /MenuBar/Transport/Cursor
|
||||
MenuTable::BaseItemSharedPtr ClipCursorItems()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
return Items(
|
||||
static BaseItemSharedPtr items{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxT("Clip"),
|
||||
Command( wxT("CursPrevClipBoundary"), XXO("Pre&vious Clip Boundary"),
|
||||
FN(OnCursorPrevClipBoundary),
|
||||
WaveTracksExistFlag,
|
||||
@ -861,19 +867,24 @@ MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & )
|
||||
FN(OnCursorNextClipBoundary),
|
||||
WaveTracksExistFlag,
|
||||
Options{}.LongName( XO("Cursor to Next Clip Boundary") ) )
|
||||
);
|
||||
) ) };
|
||||
return items;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraClipCursorItems( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra/Cursor
|
||||
MenuTable::BaseItemSharedPtr ExtraClipCursorItems()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Items(
|
||||
static BaseItemSharedPtr items{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxT("Clip"),
|
||||
Command( wxT("ClipLeft"), XXO("Clip L&eft"), FN(OnClipLeft),
|
||||
TracksExistFlag | TrackPanelHasFocus, wxT("\twantKeyup") ),
|
||||
Command( wxT("ClipRight"), XXO("Clip Rig&ht"), FN(OnClipRight),
|
||||
TracksExistFlag | TrackPanelHasFocus, wxT("\twantKeyup") )
|
||||
);
|
||||
) ) };
|
||||
return items;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -995,10 +995,9 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& EditActions::Handler :: X)
|
||||
#define FN(X) (& EditActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr LabelEditMenus( AudacityProject &project );
|
||||
MenuTable::BaseItemSharedPtr LabelEditMenus();
|
||||
|
||||
const ReservedCommandFlag
|
||||
CutCopyAvailableFlag{
|
||||
@ -1025,7 +1024,8 @@ const ReservedCommandFlag
|
||||
cutCopyOptions()
|
||||
};
|
||||
|
||||
MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr EditMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
@ -1052,14 +1052,17 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
#endif
|
||||
;
|
||||
|
||||
return Menu( XO("&Edit"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Edit"), XO("&Edit"),
|
||||
Command( wxT("Undo"), XXO("&Undo"), FN(OnUndo),
|
||||
AudioIONotBusyFlag | UndoAvailableFlag, wxT("Ctrl+Z") ),
|
||||
|
||||
Command( wxT("Redo"), XXO("&Redo"), FN(OnRedo),
|
||||
AudioIONotBusyFlag | RedoAvailableFlag, redoKey ),
|
||||
|
||||
Special( [](AudacityProject &project, wxMenu&) {
|
||||
Special( wxT("UndoItemsUpdateStep"),
|
||||
[](AudacityProject &project, wxMenu&) {
|
||||
// Change names in the CommandManager as a side-effect
|
||||
MenuManager::ModifyUndoMenuItems(project);
|
||||
}),
|
||||
@ -1086,7 +1089,7 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("R&emove Special"),
|
||||
Menu( wxT("RemoveSpecial"), XO("R&emove Special"),
|
||||
/* i18n-hint: (verb) Do a special kind of cut*/
|
||||
Command( wxT("SplitCut"), XXO("Spl&it Cut"), FN(OnSplitCut),
|
||||
NotBusyTimeAndTracksFlags,
|
||||
@ -1112,7 +1115,7 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("Clip B&oundaries"),
|
||||
Menu( wxT("Clip"), XO("Clip B&oundaries"),
|
||||
/* i18n-hint: (verb) It's an item on a menu. */
|
||||
Command( wxT("Split"), XXO("Sp&lit"), FN(OnSplit),
|
||||
AudioIONotBusyFlag | WaveTracksSelectedFlag,
|
||||
@ -1132,7 +1135,7 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LabelEditMenus,
|
||||
LabelEditMenus(),
|
||||
|
||||
Command( wxT("EditMetaData"), XXO("&Metadata..."), FN(OnEditMetadata),
|
||||
AudioIONotBusyFlag ),
|
||||
@ -1145,23 +1148,28 @@ MenuTable::BaseItemPtr EditMenu( AudacityProject & )
|
||||
|
||||
Command( wxT("Preferences"), XXO("Pre&ferences..."), FN(OnPreferences),
|
||||
AudioIONotBusyFlag, prefKey )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraEditMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraEditMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
static const auto flags =
|
||||
AudioIONotBusyFlag | TracksSelectedFlag | TimeSelectedFlag;
|
||||
return Menu( XO("&Edit"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Edit"), XO("&Edit"),
|
||||
Command( wxT("DeleteKey"), XXO("&Delete Key"), FN(OnDelete),
|
||||
(flags | NoAutoSelect),
|
||||
wxT("Backspace") ),
|
||||
Command( wxT("DeleteKey2"), XXO("Delete Key&2"), FN(OnDelete),
|
||||
(flags | NoAutoSelect),
|
||||
wxT("Delete") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
auto canSelectAll = [](const AudacityProject &project){
|
||||
|
@ -134,66 +134,73 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& ExtraActions::Handler :: X)
|
||||
#define FN(X) (& ExtraActions::Handler :: X)
|
||||
|
||||
// Imported menu item definitions
|
||||
|
||||
MenuTable::BaseItemPtr ExtraEditMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraSelectionMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraCursorMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraSeekMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraToolsMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraTransportMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraPlayAtSpeedMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraTrackMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraWindowItems( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraGlobalCommands( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraMenu( AudacityProject& );
|
||||
MenuTable::BaseItemPtr ExtraMixerMenu( AudacityProject & );
|
||||
MenuTable::BaseItemPtr ExtraDeviceMenu( AudacityProject & );
|
||||
MenuTable::BaseItemSharedPtr ExtraEditMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraSelectionMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraCursorMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraSeekMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraToolsMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraTransportMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraPlayAtSpeedMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraTrackMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraScriptablesIMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraScriptablesIIMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraWindowItems();
|
||||
MenuTable::BaseItemSharedPtr ExtraGlobalCommands();
|
||||
MenuTable::BaseItemSharedPtr ExtraFocusMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraMixerMenu();
|
||||
MenuTable::BaseItemSharedPtr ExtraDeviceMenu();
|
||||
MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject & );
|
||||
|
||||
// Table of menu factories.
|
||||
// TODO: devise a registration system instead.
|
||||
static const std::shared_ptr<MenuTable::BaseItem> extraItems = MenuTable::Items(
|
||||
ExtraTransportMenu
|
||||
, ExtraToolsMenu
|
||||
, ExtraMixerMenu
|
||||
, ExtraEditMenu
|
||||
, ExtraPlayAtSpeedMenu
|
||||
, ExtraSeekMenu
|
||||
, ExtraDeviceMenu
|
||||
, ExtraSelectionMenu
|
||||
|
||||
, MenuTable::Separator()
|
||||
|
||||
, ExtraGlobalCommands
|
||||
, ExtraFocusMenu
|
||||
, ExtraCursorMenu
|
||||
, ExtraTrackMenu
|
||||
, ExtraScriptablesIMenu
|
||||
, ExtraScriptablesIIMenu
|
||||
, ExtraMiscItems
|
||||
);
|
||||
|
||||
MenuTable::BaseItemPtr ExtraMenu( AudacityProject & )
|
||||
MenuTable::BaseItemSharedPtr ExtraMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
// Table of menu factories.
|
||||
// TODO: devise a registration system instead.
|
||||
static BaseItemSharedPtr extraItems{ Items( wxEmptyString
|
||||
, ExtraTransportMenu()
|
||||
, ExtraToolsMenu()
|
||||
, ExtraMixerMenu()
|
||||
, ExtraEditMenu()
|
||||
, ExtraPlayAtSpeedMenu()
|
||||
, ExtraSeekMenu()
|
||||
, ExtraDeviceMenu()
|
||||
, ExtraSelectionMenu()
|
||||
|
||||
, MenuTable::Separator()
|
||||
|
||||
, ExtraGlobalCommands()
|
||||
, ExtraFocusMenu()
|
||||
, ExtraCursorMenu()
|
||||
, ExtraTrackMenu()
|
||||
, ExtraScriptablesIMenu()
|
||||
, ExtraScriptablesIIMenu()
|
||||
|
||||
// Delayed evaluation:
|
||||
, ExtraMiscItems
|
||||
) };
|
||||
|
||||
static const auto pred =
|
||||
[]{ return gPrefs->ReadBool(wxT("/GUI/ShowExtraMenus"), false); };
|
||||
static const auto factory =
|
||||
[](AudacityProject &){ return extraItems; };
|
||||
return ConditionalItems( pred, Menu( XO("Ext&ra"), factory ) );
|
||||
static BaseItemSharedPtr menu{
|
||||
ConditionalItems( wxT("Optional"),
|
||||
pred, Menu( wxT("Extra"), XO("Ext&ra"), extraItems ) )
|
||||
};
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraMixerMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraMixerMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("Mi&xer"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Mixer"), XO("Mi&xer"),
|
||||
Command( wxT("OutputGain"), XXO("Ad&just Playback Volume..."),
|
||||
FN(OnOutputGain), AlwaysEnabledFlag ),
|
||||
Command( wxT("OutputGainInc"), XXO("&Increase Playback Volume"),
|
||||
@ -206,13 +213,17 @@ MenuTable::BaseItemPtr ExtraMixerMenu( AudacityProject & )
|
||||
FN(OnInputGainInc), AlwaysEnabledFlag ),
|
||||
Command( wxT("InputGainDec"), XXO("D&ecrease Recording Volume"),
|
||||
FN(OnInputGainDec), AlwaysEnabledFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraDeviceMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraDeviceMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("De&vice"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Device"), XO("De&vice"),
|
||||
Command( wxT("InputDevice"), XXO("Change &Recording Device..."),
|
||||
FN(OnInputDevice),
|
||||
AudioIONotBusyFlag, wxT("Shift+I") ),
|
||||
@ -224,9 +235,11 @@ MenuTable::BaseItemPtr ExtraDeviceMenu( AudacityProject & )
|
||||
Command( wxT("InputChannels"), XXO("Change Recording Cha&nnels..."),
|
||||
FN(OnInputChannels),
|
||||
AudioIONotBusyFlag, wxT("Shift+N") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project )
|
||||
{
|
||||
using namespace MenuTable;
|
||||
@ -241,7 +254,8 @@ MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project )
|
||||
;
|
||||
|
||||
// Not a menu.
|
||||
return Items(
|
||||
return FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxT("Misc"),
|
||||
// Accel key is not bindable.
|
||||
Command( wxT("FullScreenOnOff"), XXO("&Full Screen (on/off)"),
|
||||
FN(OnFullScreen),
|
||||
@ -249,8 +263,8 @@ MenuTable::BaseItemPtr ExtraMiscItems( AudacityProject &project )
|
||||
Options{ key }.CheckState(
|
||||
GetProjectFrame( project ).wxTopLevelWindow::IsFullScreen() ) ),
|
||||
|
||||
ExtraWindowItems
|
||||
);
|
||||
ExtraWindowItems()
|
||||
) );
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -549,15 +549,17 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& FileActions::Handler :: X)
|
||||
#define FN(X) (& FileActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
// under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr FileMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
return Menu( XO("&File"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("File"), XO("&File"),
|
||||
/*i18n-hint: "New" is an action (verb) to create a NEW project*/
|
||||
Command( wxT("New"), XXO("&New"), FN(OnNew),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+N") ),
|
||||
@ -577,7 +579,7 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu(
|
||||
Menu( wxT("Recent"),
|
||||
#ifdef __WXMAC__
|
||||
/* i18n-hint: This is the name of the menu item on Mac OS X only */
|
||||
XO("Open Recent")
|
||||
@ -586,7 +588,8 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
XO("Recent &Files")
|
||||
#endif
|
||||
,
|
||||
Special( [](AudacityProject &, wxMenu &theMenu){
|
||||
Special( wxT("PopulateRecentFilesStep"),
|
||||
[](AudacityProject &, wxMenu &theMenu){
|
||||
// Recent Files and Recent Projects menus
|
||||
auto &history = FileHistory::Global();
|
||||
history.UseMenu( &theMenu );
|
||||
@ -615,7 +618,7 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("&Save Project"),
|
||||
Menu( wxT("Save"), XO("&Save Project"),
|
||||
Command( wxT("Save"), XXO("&Save Project"), FN(OnSave),
|
||||
AudioIONotBusyFlag | UnsavedChangesFlag, wxT("Ctrl+S") ),
|
||||
Command( wxT("SaveAs"), XXO("Save Project &As..."), FN(OnSaveAs),
|
||||
@ -633,7 +636,7 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("&Export"),
|
||||
Menu( wxT("Export"), XO("&Export"),
|
||||
// Enable Export audio commands only when there are audio tracks.
|
||||
Command( wxT("ExportMp3"), XXO("Export as MP&3"), FN(OnExportMp3),
|
||||
AudioIONotBusyFlag | WaveTracksExistFlag ),
|
||||
@ -667,7 +670,7 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
#endif
|
||||
),
|
||||
|
||||
Menu( XO("&Import"),
|
||||
Menu( wxT("Import"), XO("&Import"),
|
||||
Command( wxT("ImportAudio"), XXO("&Audio..."), FN(OnImport),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+Shift+I") ),
|
||||
Command( wxT("ImportLabels"), XXO("&Labels..."), FN(OnImportLabels),
|
||||
@ -698,7 +701,8 @@ MenuTable::BaseItemPtr FileMenu( AudacityProject& )
|
||||
/* i18n-hint: (verb) It's item on a menu. */
|
||||
Command( wxT("Exit"), XXO("E&xit"), FN(OnExit),
|
||||
AlwaysEnabledFlag, wxT("Ctrl+Q") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -418,18 +418,15 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& HelpActions::Handler :: X)
|
||||
#define FN(X) (& HelpActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr HelpMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr HelpMenu()
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
wxApp::s_macHelpMenuTitleName = _("&Help");
|
||||
#endif
|
||||
|
||||
using namespace MenuTable;
|
||||
|
||||
return Menu( XO("&Help"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Help"), XO("&Help"),
|
||||
// QuickFix menu item not in Audacity 2.3.1 whilst we discuss further.
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
// DA: Has QuickFix menu item.
|
||||
@ -448,7 +445,7 @@ MenuTable::BaseItemPtr HelpMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("&Diagnostics"),
|
||||
Menu( wxT("Diagnostics"), XO("&Diagnostics"),
|
||||
Command( wxT("DeviceInfo"), XXO("Au&dio Device Info..."),
|
||||
FN(OnAudioDeviceInfo),
|
||||
AudioIONotBusyFlag ),
|
||||
@ -480,7 +477,8 @@ MenuTable::BaseItemPtr HelpMenu( AudacityProject & )
|
||||
#endif
|
||||
Command( wxT("About"), XXO("&About Audacity..."), FN(OnAbout),
|
||||
AlwaysEnabledFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -559,10 +559,10 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& LabelEditActions::Handler :: X)
|
||||
#define FN(X) (& LabelEditActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & )
|
||||
// Under /MenuBar/Edit
|
||||
MenuTable::BaseItemSharedPtr LabelEditMenus()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
@ -575,9 +575,11 @@ MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & )
|
||||
|
||||
// Returns TWO menus.
|
||||
|
||||
return Items(
|
||||
|
||||
Menu( XO("&Labels"),
|
||||
static BaseItemSharedPtr menus{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxEmptyString,
|
||||
|
||||
Menu( wxT("Labels"), XO("&Labels"),
|
||||
Command( wxT("EditLabels"), XXO("&Edit Labels..."), FN(OnEditLabels),
|
||||
AudioIONotBusyFlag ),
|
||||
|
||||
@ -607,7 +609,7 @@ MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & )
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("La&beled Audio"),
|
||||
Menu( wxT("Labeled"), XO("La&beled Audio"),
|
||||
/* i18n-hint: (verb)*/
|
||||
Command( wxT("CutLabels"), XXO("&Cut"), FN(OnCutLabels),
|
||||
AudioIONotBusyFlag | LabelsSelectedFlag | WaveTracksExistFlag |
|
||||
@ -653,7 +655,8 @@ MenuTable::BaseItemPtr LabelEditMenus( AudacityProject & )
|
||||
wxT("Alt+Shift+J") )
|
||||
) // second menu
|
||||
|
||||
); // two menus
|
||||
) ) }; // two menus
|
||||
return menus;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -553,30 +553,37 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& NavigationActions::Handler :: X)
|
||||
#define FN(X) (& NavigationActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr ExtraGlobalCommands( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraGlobalCommands()
|
||||
{
|
||||
// Ceci n'est pas un menu
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
return Items(
|
||||
|
||||
static BaseItemSharedPtr items{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxT("Navigation"),
|
||||
Command( wxT("PrevWindow"), XXO("Move Backward Through Active Windows"),
|
||||
FN(OnPrevWindow), AlwaysEnabledFlag,
|
||||
Options{ wxT("Alt+Shift+F6") }.IsGlobal() ),
|
||||
Command( wxT("NextWindow"), XXO("Move Forward Through Active Windows"),
|
||||
FN(OnNextWindow), AlwaysEnabledFlag,
|
||||
Options{ wxT("Alt+F6") }.IsGlobal() )
|
||||
);
|
||||
) ) };
|
||||
return items;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraFocusMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
static const auto FocusedTracksFlags = TracksExistFlag | TrackPanelHasFocus;
|
||||
|
||||
return Menu( XO("F&ocus"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Focus"), XO("F&ocus"),
|
||||
Command( wxT("PrevFrame"),
|
||||
XXO("Move &Backward from Toolbars to Tracks"), FN(OnPrevFrame),
|
||||
AlwaysEnabledFlag, wxT("Ctrl+Shift+F6") ),
|
||||
@ -599,7 +606,8 @@ MenuTable::BaseItemPtr ExtraFocusMenu( AudacityProject & )
|
||||
FocusedTracksFlags, wxT("Return") ),
|
||||
Command( wxT("ToggleAlt"), XXO("Toggle Focuse&d Track"), FN(OnToggle),
|
||||
FocusedTracksFlags, wxT("NUMPAD_ENTER") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -258,7 +258,7 @@ void AddEffectMenuItems(
|
||||
groupNames,
|
||||
groupPlugs, groupFlags, isDefault);
|
||||
|
||||
table.push_back( MenuOrItems(
|
||||
table.push_back( MenuOrItems( wxEmptyString,
|
||||
( bInSubmenu ? last : TranslatableString{} ), std::move( temp )
|
||||
) );
|
||||
|
||||
@ -283,7 +283,7 @@ void AddEffectMenuItems(
|
||||
AddEffectMenuItemGroup(temp,
|
||||
groupNames, groupPlugs, groupFlags, isDefault);
|
||||
|
||||
table.push_back( MenuOrItems(
|
||||
table.push_back( MenuOrItems( wxEmptyString,
|
||||
( bInSubmenu ? current : TranslatableString{} ), std::move( temp )
|
||||
) );
|
||||
}
|
||||
@ -585,8 +585,7 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions? ...
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& PluginActions::Handler :: X)
|
||||
#define FN(X) (& PluginActions::Handler :: X)
|
||||
|
||||
// ... buf first some more helper definitions, which use FN
|
||||
namespace {
|
||||
@ -632,6 +631,8 @@ void AddEffectMenuItemGroup(
|
||||
}
|
||||
|
||||
using namespace MenuTable;
|
||||
// This finder scope may be redundant, but harmless
|
||||
auto scope = FinderScope( findCommandHandler );
|
||||
auto pTable = &table;
|
||||
BaseItemPtrs temp1;
|
||||
|
||||
@ -666,7 +667,7 @@ void AddEffectMenuItemGroup(
|
||||
|
||||
i++;
|
||||
}
|
||||
pTable->push_back( Menu( name, std::move( temp2 ) ) );
|
||||
pTable->push_back( Menu( wxEmptyString, name, std::move( temp2 ) ) );
|
||||
i--;
|
||||
}
|
||||
else
|
||||
@ -701,7 +702,7 @@ void AddEffectMenuItemGroup(
|
||||
end = groupCnt;
|
||||
}
|
||||
// Done collecting
|
||||
table.push_back( Menu(
|
||||
table.push_back( Menu( wxEmptyString,
|
||||
XO("Plug-in %d to %d").Format( groupNdx + 1, end ),
|
||||
std::move( temp1 )
|
||||
) );
|
||||
@ -721,6 +722,8 @@ MenuTable::BaseItemPtrs PopulateMacrosMenu( CommandFlag flags )
|
||||
auto names = MacroCommands::GetNames(); // these names come from filenames
|
||||
int i;
|
||||
|
||||
// This finder scope may be redundant, but harmless
|
||||
auto scope = MenuTable::FinderScope( findCommandHandler );
|
||||
for (i = 0; i < (int)names.size(); i++) {
|
||||
auto MacroID = ApplyMacroDialog::MacroIdOfName( names[i] );
|
||||
result.push_back( MenuTable::Command( MacroID,
|
||||
@ -738,13 +741,16 @@ MenuTable::BaseItemPtrs PopulateMacrosMenu( CommandFlag flags )
|
||||
|
||||
// Menu definitions
|
||||
|
||||
MenuTable::BaseItemPtr GenerateMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr GenerateMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
// All of this is a bit hacky until we can get more things connected into
|
||||
// the plugin manager...sorry! :-(
|
||||
|
||||
return Menu( XO("&Generate"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Generate"), XO("&Generate"),
|
||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||
Command( wxT("ManageGenerators"), XXO("Add / Remove Plug-ins..."),
|
||||
FN(OnManageGenerators), AudioIONotBusyFlag ),
|
||||
@ -753,11 +759,15 @@ MenuTable::BaseItemPtr GenerateMenu( AudacityProject & )
|
||||
|
||||
#endif
|
||||
|
||||
Items( PopulateEffectsMenu(
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject &)
|
||||
{ return Items( wxEmptyString, PopulateEffectsMenu(
|
||||
EffectTypeGenerate,
|
||||
AudioIONotBusyFlag,
|
||||
AudioIONotBusyFlag) )
|
||||
);
|
||||
AudioIONotBusyFlag)
|
||||
); }
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
const ReservedCommandFlag
|
||||
@ -767,21 +777,16 @@ const ReservedCommandFlag
|
||||
}
|
||||
}; //lll
|
||||
|
||||
MenuTable::BaseItemPtr EffectMenu( AudacityProject &project )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr EffectMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
// All of this is a bit hacky until we can get more things connected into
|
||||
// the plugin manager...sorry! :-(
|
||||
|
||||
const auto &lastEffect = MenuManager::Get(project).mLastEffect;
|
||||
TranslatableString buildMenuLabel;
|
||||
if (!lastEffect.empty())
|
||||
buildMenuLabel = XO("Repeat %s")
|
||||
.Format( EffectManager::Get().GetCommandName(lastEffect) );
|
||||
else
|
||||
buildMenuLabel = XO("Repeat Last Effect");
|
||||
|
||||
return Menu( XO("Effe&ct"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Effect"), XO("Effe&ct"),
|
||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||
Command( wxT("ManageEffects"), XXO("Add / Remove Plug-ins..."),
|
||||
FN(OnManageEffects), AudioIONotBusyFlag ),
|
||||
@ -789,28 +794,49 @@ MenuTable::BaseItemPtr EffectMenu( AudacityProject &project )
|
||||
Separator(),
|
||||
|
||||
#endif
|
||||
Command( wxT("RepeatLastEffect"), buildMenuLabel,
|
||||
FN(OnRepeatLastEffect),
|
||||
AudioIONotBusyFlag | TimeSelectedFlag |
|
||||
WaveTracksSelectedFlag | HasLastEffectFlag,
|
||||
wxT("Ctrl+R") ),
|
||||
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject &project)
|
||||
{
|
||||
const auto &lastEffect = MenuManager::Get(project).mLastEffect;
|
||||
TranslatableString buildMenuLabel;
|
||||
if (!lastEffect.empty())
|
||||
buildMenuLabel = XO("Repeat %s")
|
||||
.Format( EffectManager::Get().GetCommandName(lastEffect) );
|
||||
else
|
||||
buildMenuLabel = XO("Repeat Last Effect");
|
||||
|
||||
return Command( wxT("RepeatLastEffect"), buildMenuLabel,
|
||||
FN(OnRepeatLastEffect),
|
||||
AudioIONotBusyFlag | TimeSelectedFlag |
|
||||
WaveTracksSelectedFlag | HasLastEffectFlag,
|
||||
wxT("Ctrl+R"), findCommandHandler );
|
||||
},
|
||||
|
||||
Separator(),
|
||||
|
||||
Items( PopulateEffectsMenu(
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject &)
|
||||
{ return Items( wxEmptyString, PopulateEffectsMenu(
|
||||
EffectTypeProcess,
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag,
|
||||
IsRealtimeNotActiveFlag ) )
|
||||
);
|
||||
IsRealtimeNotActiveFlag )
|
||||
); }
|
||||
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr AnalyzeMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
// All of this is a bit hacky until we can get more things connected into
|
||||
// the plugin manager...sorry! :-(
|
||||
|
||||
return Menu( XO("&Analyze"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Analyze"), XO("&Analyze"),
|
||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||
Command( wxT("ManageAnalyzers"), XXO("Add / Remove Plug-ins..."),
|
||||
FN(OnManageAnalyzers), AudioIONotBusyFlag ),
|
||||
@ -825,20 +851,26 @@ MenuTable::BaseItemPtr AnalyzeMenu( AudacityProject & )
|
||||
Command( wxT("PlotSpectrum"), XXO("Plot Spectrum..."), FN(OnPlotSpectrum),
|
||||
AudioIONotBusyFlag | WaveTracksSelectedFlag | TimeSelectedFlag ),
|
||||
|
||||
Items( PopulateEffectsMenu(
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject&)
|
||||
{ return Items( wxEmptyString, PopulateEffectsMenu(
|
||||
EffectTypeAnalyze,
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag,
|
||||
IsRealtimeNotActiveFlag ) )
|
||||
);
|
||||
IsRealtimeNotActiveFlag )
|
||||
); }
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr ToolsMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
auto gAudioIO = AudioIO::Get();
|
||||
|
||||
return Menu( XO("T&ools"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Tools"), XO("T&ools"),
|
||||
|
||||
#ifdef EXPERIMENTAL_EFFECT_MANAGEMENT
|
||||
Command( wxT("ManageTools"), XXO("Add / Remove Plug-ins..."),
|
||||
@ -851,7 +883,7 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
|
||||
Command( wxT("ManageMacros"), XXO("&Macros..."),
|
||||
FN(OnManageMacros), AudioIONotBusyFlag ),
|
||||
|
||||
Menu( XO("&Apply Macro"),
|
||||
Menu( wxT("Macros"), XO("&Apply Macro"),
|
||||
// Palette has no access key to ensure first letter navigation of
|
||||
// sub menu
|
||||
Command( wxT("ApplyMacrosPalette"), XXO("Palette..."),
|
||||
@ -859,7 +891,9 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Items( PopulateMacrosMenu( AudioIONotBusyFlag ) )
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject&)
|
||||
{ return Items( wxEmptyString, PopulateMacrosMenu( AudioIONotBusyFlag ) ); }
|
||||
),
|
||||
|
||||
Separator(),
|
||||
@ -878,10 +912,13 @@ MenuTable::BaseItemPtr ToolsMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Items( PopulateEffectsMenu(
|
||||
// Delayed evaluation:
|
||||
[](AudacityProject&)
|
||||
{ return Items( wxEmptyString, PopulateEffectsMenu(
|
||||
EffectTypeTool,
|
||||
AudioIONotBusyFlag,
|
||||
AudioIONotBusyFlag ) )
|
||||
AudioIONotBusyFlag )
|
||||
); }
|
||||
|
||||
#ifdef IS_ALPHA
|
||||
,
|
||||
@ -892,23 +929,31 @@ 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
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraScriptablesIMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
// These are the more useful to VI user Scriptables.
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
// i18n-hint: Scriptables are commands normally used from Python, Perl etc.
|
||||
return Menu( XO("Script&ables I"),
|
||||
Menu( wxT("Scriptables1"), XO("Script&ables I"),
|
||||
// Note that the PLUGIN_SYMBOL must have a space between words,
|
||||
// whereas the short-form used here must not.
|
||||
// (So if you did write "CompareAudio" for the PLUGIN_SYMBOL name, then
|
||||
@ -945,15 +990,19 @@ MenuTable::BaseItemPtr ExtraScriptablesIMenu( AudacityProject & )
|
||||
AudioIONotBusyFlag ),
|
||||
Command( wxT("SetProject"), XXO("Set Project..."), FN(OnAudacityCommand),
|
||||
AudioIONotBusyFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraScriptablesIIMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
// Less useful to VI users.
|
||||
return Menu( XO("Scripta&bles II"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Scriptables2"), XO("Scripta&bles II"),
|
||||
Command( wxT("Select"), XXO("Select..."), FN(OnAudacityCommand),
|
||||
AudioIONotBusyFlag ),
|
||||
Command( wxT("SetTrack"), XXO("Set Track..."), FN(OnAudacityCommand),
|
||||
@ -983,7 +1032,8 @@ MenuTable::BaseItemPtr ExtraScriptablesIIMenu( AudacityProject & )
|
||||
Command( wxT("Screenshot"), XXO("Screenshot (short format)..."),
|
||||
FN(OnAudacityCommand),
|
||||
AudioIONotBusyFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -1026,18 +1026,19 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& SelectActions::Handler :: X)
|
||||
#define FN(X) (& SelectActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr ClipSelectMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr ClipSelectMenu();
|
||||
|
||||
MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr SelectMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
/* i18n-hint: (verb) It's an item on a menu. */
|
||||
return Menu( XO("&Select"),
|
||||
Menu( wxT("Select"), XO("&Select"),
|
||||
Command( wxT("SelectAll"), XXO("&All"), FN(OnSelectAll),
|
||||
TracksExistFlag,
|
||||
Options{ wxT("Ctrl+A"), XO("Select All") } ),
|
||||
@ -1047,7 +1048,7 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("&Tracks"),
|
||||
Menu( wxT("Tracks"), XO("&Tracks"),
|
||||
Command( wxT("SelAllTracks"), XXO("In All &Tracks"),
|
||||
FN(OnSelectAllTracks),
|
||||
TracksExistFlag,
|
||||
@ -1064,7 +1065,7 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("R&egion"),
|
||||
Menu( wxT("Region"), XO("R&egion"),
|
||||
Command( wxT("SetLeftSelection"), XXO("&Left at Playback Position"),
|
||||
FN(OnSetLeftSelection), TracksExistFlag,
|
||||
Options{ wxT("["), XO("Set Selection Left at Play Position") } ),
|
||||
@ -1098,7 +1099,7 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
Menu( XO("S&pectral"),
|
||||
Menu( wxT("Spectral"), XO("S&pectral"),
|
||||
Command( wxT("ToggleSpectralSelection"),
|
||||
XXO("To&ggle Spectral Selection"), FN(OnToggleSpectralSelection),
|
||||
TracksExistFlag, wxT("Q") ),
|
||||
@ -1113,7 +1114,7 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ClipSelectMenu,
|
||||
ClipSelectMenu(),
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1135,13 +1136,17 @@ MenuTable::BaseItemPtr SelectMenu( AudacityProject& )
|
||||
Command( wxT("ZeroCross"), XXO("At &Zero Crossings"),
|
||||
FN(OnZeroCrossing), TracksSelectedFlag,
|
||||
Options{ wxT("Z"), XO("Select Zero Crossing") } )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraSelectionMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraSelectionMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("&Selection"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Select"), XO("&Selection"),
|
||||
Command( wxT("SnapToOff"), XXO("Snap-To &Off"), FN(OnSnapToOff),
|
||||
AlwaysEnabledFlag ),
|
||||
Command( wxT("SnapToNearest"), XXO("Snap-To &Nearest"),
|
||||
@ -1174,12 +1179,14 @@ MenuTable::BaseItemPtr ExtraSelectionMenu( AudacityProject & )
|
||||
FN(OnSelContractRight),
|
||||
TracksExistFlag | TrackPanelHasFocus,
|
||||
wxT("Ctrl+Shift+Left\twantKeyup") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ClipCursorItems( AudacityProject & );
|
||||
MenuTable::BaseItemSharedPtr ClipCursorItems();
|
||||
|
||||
MenuTable::BaseItemPtr CursorMenu( AudacityProject & )
|
||||
// Under /MenuBar/Transport
|
||||
MenuTable::BaseItemSharedPtr CursorMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
@ -1190,7 +1197,9 @@ MenuTable::BaseItemPtr CursorMenu( AudacityProject & )
|
||||
// GA: 'Skip to' moves the viewpoint to center of the track and preserves the
|
||||
// selection. 'Cursor to' does neither. 'Center at' might describe it better
|
||||
// than 'Skip'.
|
||||
return Menu( XO("&Cursor to"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Cursor"), XO("&Cursor to"),
|
||||
Command( wxT("CursSelStart"), XXO("Selection Star&t"),
|
||||
FN(OnCursorSelStart),
|
||||
TimeSelectedFlag,
|
||||
@ -1209,7 +1218,7 @@ MenuTable::BaseItemPtr CursorMenu( AudacityProject & )
|
||||
TracksSelectedFlag,
|
||||
Options{ wxT("K"), XO("Cursor to Track End") } ),
|
||||
|
||||
ClipCursorItems,
|
||||
ClipCursorItems(),
|
||||
|
||||
Command( wxT("CursProjectStart"), XXO("&Project Start"),
|
||||
FN(OnSkipStart),
|
||||
@ -1218,16 +1227,20 @@ MenuTable::BaseItemPtr CursorMenu( AudacityProject & )
|
||||
Command( wxT("CursProjectEnd"), XXO("Project E&nd"), FN(OnSkipEnd),
|
||||
CanStopFlags,
|
||||
Options{ wxT("End"), XO("Cursor to Project End") } )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraClipCursorItems( AudacityProject & );
|
||||
MenuTable::BaseItemSharedPtr ExtraClipCursorItems();
|
||||
|
||||
MenuTable::BaseItemPtr ExtraCursorMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraCursorMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Menu( XO("&Cursor"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Cursor"), XO("&Cursor"),
|
||||
Command( wxT("CursorLeft"), XXO("Cursor &Left"), FN(OnCursorLeft),
|
||||
TracksExistFlag | TrackPanelHasFocus,
|
||||
wxT("Left\twantKeyup\tallowDup") ),
|
||||
@ -1247,14 +1260,18 @@ MenuTable::BaseItemPtr ExtraCursorMenu( AudacityProject & )
|
||||
FN(OnCursorLongJumpRight),
|
||||
TracksExistFlag | TrackPanelHasFocus, wxT("Shift+.") ),
|
||||
|
||||
ExtraClipCursorItems
|
||||
);
|
||||
ExtraClipCursorItems()
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraSeekMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraSeekMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("See&k"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Seek"), XO("See&k"),
|
||||
Command( wxT("SeekLeftShort"), XXO("Short Seek &Left During Playback"),
|
||||
FN(OnSeekLeftShort), AudioIOBusyFlag, wxT("Left\tallowDup") ),
|
||||
Command( wxT("SeekRightShort"),
|
||||
@ -1264,7 +1281,8 @@ MenuTable::BaseItemPtr ExtraSeekMenu( AudacityProject & )
|
||||
FN(OnSeekLeftLong), AudioIOBusyFlag, wxT("Shift+Left\tallowDup") ),
|
||||
Command( wxT("SeekRightLong"), XXO("Long Seek Rig&ht During Playback"),
|
||||
FN(OnSeekRightLong), AudioIOBusyFlag, wxT("Shift+Right\tallowDup") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -251,17 +251,19 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& ToolbarActions::Handler :: X)
|
||||
#define FN(X) (& ToolbarActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& )
|
||||
// Under /MenuBar/View
|
||||
MenuTable::BaseItemSharedPtr ToolbarsMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
static const auto checkOff = Options{}.CheckState( false );
|
||||
|
||||
return Menu( XO("&Toolbars"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Toolbars"), XO("&Toolbars"),
|
||||
/* i18n-hint: (verb)*/
|
||||
Command( wxT("ResetToolbars"), XXO("Reset Toolb&ars"),
|
||||
FN(OnResetToolBars), AlwaysEnabledFlag ),
|
||||
@ -330,13 +332,17 @@ MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& )
|
||||
XXO("Spe&ctral Selection Toolbar"),
|
||||
FN(OnShowSpectralSelectionToolBar), AlwaysEnabledFlag, checkOff )
|
||||
#endif
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraToolsMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraToolsMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("T&ools"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Tools"), XO("T&ools"),
|
||||
Command( wxT("SelectTool"), XXO("&Selection Tool"), FN(OnSelectTool),
|
||||
AlwaysEnabledFlag, wxT("F1") ),
|
||||
Command( wxT("EnvelopeTool"), XXO("&Envelope Tool"),
|
||||
@ -353,7 +359,8 @@ MenuTable::BaseItemPtr ExtraToolsMenu( AudacityProject & )
|
||||
AlwaysEnabledFlag, wxT("A") ),
|
||||
Command( wxT("NextTool"), XXO("&Next Tool"), FN(OnNextTool),
|
||||
AlwaysEnabledFlag, wxT("D") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -1274,17 +1274,19 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& TrackActions::Handler :: X)
|
||||
#define FN(X) (& TrackActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr TracksMenu()
|
||||
{
|
||||
// Tracks Menu (formerly Project Menu)
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
return Menu( XO("&Tracks"),
|
||||
Menu( XO("Add &New"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Tracks"), XO("&Tracks"),
|
||||
Menu( wxT("Add"), XO("Add &New"),
|
||||
Command( wxT("NewMonoTrack"), XXO("&Mono Track"), FN(OnNewWaveTrack),
|
||||
AudioIONotBusyFlag, wxT("Ctrl+Shift+N") ),
|
||||
Command( wxT("NewStereoTrack"), XXO("&Stereo Track"),
|
||||
@ -1299,7 +1301,8 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("Mi&x"),
|
||||
Menu( wxT("Mix"), XO("Mi&x"),
|
||||
// Delayed evaluation
|
||||
// Stereo to Mono is an oddball command that is also subject to control
|
||||
// by the plug-in manager, as if an effect. Decide whether to show or
|
||||
// hide it.
|
||||
@ -1311,7 +1314,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
return Command( wxT("Stereo to Mono"),
|
||||
XXO("Mix Stereo Down to &Mono"), FN(OnStereoToMono),
|
||||
AudioIONotBusyFlag | StereoRequiredFlag |
|
||||
WaveTracksSelectedFlag );
|
||||
WaveTracksSelectedFlag, Options{}, findCommandHandler );
|
||||
else
|
||||
return {};
|
||||
},
|
||||
@ -1334,14 +1337,14 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
Menu( XO("M&ute/Unmute"),
|
||||
Menu( wxT("Mute"), XO("M&ute/Unmute"),
|
||||
Command( wxT("MuteAllTracks"), XXO("&Mute All Tracks"),
|
||||
FN(OnMuteAllTracks), AudioIONotBusyFlag, wxT("Ctrl+U") ),
|
||||
Command( wxT("UnmuteAllTracks"), XXO("&Unmute All Tracks"),
|
||||
FN(OnUnmuteAllTracks), AudioIONotBusyFlag, wxT("Ctrl+Shift+U") )
|
||||
),
|
||||
|
||||
Menu( XO("&Pan"),
|
||||
Menu( wxT("Pan"), XO("&Pan"),
|
||||
// As Pan changes are not saved on Undo stack,
|
||||
// pan settings for all tracks
|
||||
// in the project could very easily be lost unless we
|
||||
@ -1361,7 +1364,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("&Align Tracks"), // XO("Just Move Tracks"),
|
||||
Menu( wxT("Align"), XO("&Align Tracks"), // XO("Just Move Tracks"),
|
||||
// Mutual alignment of tracks independent of selection or zero
|
||||
CommandGroup(wxT("Align"),
|
||||
{
|
||||
@ -1372,7 +1375,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
|
||||
Separator(),
|
||||
|
||||
// Alignment commands using selection or zero
|
||||
// Alignment commands using selection or zero
|
||||
CommandGroup(wxT("Align"),
|
||||
alignLabels,
|
||||
FN(OnAlign), AudioIONotBusyFlag | TracksSelectedFlag),
|
||||
@ -1383,14 +1386,13 @@ 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
|
||||
// TODO: Can these labels be made clearer?
|
||||
// Do we need this sub-menu at all?
|
||||
Menu( XO("Move Sele&ction and Tracks"), {
|
||||
Menu( wxT("MoveSelectionAndTracks"), XO("Move Sele&ction and Tracks"), {
|
||||
CommandGroup(wxT("AlignMove"), alignLabels,
|
||||
FN(OnAlignMoveSel), AudioIONotBusyFlag | TracksSelectedFlag),
|
||||
} ),
|
||||
@ -1406,7 +1408,7 @@ MenuTable::BaseItemPtr TracksMenu( AudacityProject & )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("S&ort Tracks"),
|
||||
Menu( wxT("Sort"), XO("S&ort Tracks"),
|
||||
Command( wxT("SortByTime"), XXO("By &Start Time"), FN(OnSortTime),
|
||||
TracksExistFlag,
|
||||
Options{}.LongName( XO("Sort by Time") ) ),
|
||||
@ -1424,17 +1426,20 @@ 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
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraTrackMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraTrackMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Menu( XO("&Track"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Track"), XO("&Track"),
|
||||
Command( wxT("TrackPan"), XXO("Change P&an on Focused Track..."),
|
||||
FN(OnTrackPan),
|
||||
TrackPanelHasFocus | TracksExistFlag, wxT("Shift+P") ),
|
||||
@ -1478,7 +1483,8 @@ MenuTable::BaseItemPtr ExtraTrackMenu( AudacityProject & )
|
||||
Command( wxT("TrackMoveBottom"), XXO("Move Focused Track to &Bottom"),
|
||||
FN(OnTrackMoveBottom),
|
||||
AudioIONotBusyFlag | TrackPanelHasFocus | TracksExistFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -966,12 +966,12 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& TransportActions::Handler :: X)
|
||||
#define FN(X) (& TransportActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr CursorMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr CursorMenu();
|
||||
|
||||
MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr TransportMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
@ -981,10 +981,12 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
|
||||
static const auto CanStopFlags = AudioIONotBusyFlag | CanStopAudioStreamFlag;
|
||||
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
/* i18n-hint: 'Transport' is the name given to the set of controls that
|
||||
play, record, pause etc. */
|
||||
return Menu( XO("Tra&nsport"),
|
||||
Menu( XO("Pl&aying"),
|
||||
Menu( wxT("Transport"), XO("Tra&nsport"),
|
||||
Menu( wxT("Play"), XO("Pl&aying"),
|
||||
/* i18n-hint: (verb) Start or Stop audio playback*/
|
||||
Command( wxT("PlayStop"), XXO("Pl&ay/Stop"), FN(OnPlayStop),
|
||||
CanStopAudioStreamFlag, wxT("Space") ),
|
||||
@ -996,14 +998,17 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
CanStopAudioStreamFlag, wxT("P") )
|
||||
),
|
||||
|
||||
Menu( XO("&Recording"),
|
||||
Menu( wxT("Record"), XO("&Recording"),
|
||||
/* i18n-hint: (verb)*/
|
||||
Command( wxT("Record1stChoice"), XXO("&Record"), FN(OnRecord),
|
||||
CanStopFlags, wxT("R") ),
|
||||
|
||||
// The OnRecord2ndChoice function is: if normal record records beside,
|
||||
// it records below, if normal record records below, it records beside.
|
||||
// TODO: Do 'the right thing' with other options like TimerRecord.
|
||||
Command( wxT("Record2ndChoice"),
|
||||
// Delayed evaluation in case gPrefs is not yet defined
|
||||
[](const AudacityProject&)
|
||||
{ return Command( wxT("Record2ndChoice"),
|
||||
// Our first choice is bound to R (by default)
|
||||
// and gets the prime position.
|
||||
// We supply the name for the 'other one' here.
|
||||
@ -1011,8 +1016,9 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
(gPrefs->ReadBool("/GUI/PreferNewTrackRecord", false)
|
||||
? XO("&Append Record") : XO("Record &New Track")),
|
||||
FN(OnRecord2ndChoice), CanStopFlags,
|
||||
wxT("Shift+R")
|
||||
),
|
||||
wxT("Shift+R"),
|
||||
findCommandHandler
|
||||
); },
|
||||
|
||||
Command( wxT("TimerRecord"), XXO("&Timer Record..."),
|
||||
FN(OnTimerRecord), CanStopFlags, wxT("Shift+T") ),
|
||||
@ -1032,15 +1038,15 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
),
|
||||
|
||||
// Scrubbing sub-menu
|
||||
Scrubber::Get( project ).Menu(),
|
||||
Scrubber::Menu(),
|
||||
|
||||
CursorMenu,
|
||||
CursorMenu(),
|
||||
|
||||
Separator(),
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Menu( XO("Pla&y Region"),
|
||||
Menu( wxT("PlayRegion"), XO("Pla&y Region"),
|
||||
Command( wxT("LockPlayRegion"), XXO("&Lock"), FN(OnLockPlayRegion),
|
||||
PlayRegionNotLockedFlag ),
|
||||
Command( wxT("UnlockPlayRegion"), XXO("&Unlock"),
|
||||
@ -1052,7 +1058,7 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
Command( wxT("RescanDevices"), XXO("R&escan Audio Devices"),
|
||||
FN(OnRescanDevices), AudioIONotBusyFlag | CanStopAudioStreamFlag ),
|
||||
|
||||
Menu( XO("Transport &Options"),
|
||||
Menu( wxT("Options"), XO("Transport &Options"),
|
||||
// Sound Activated recording options
|
||||
Command( wxT("SoundActivationLevel"),
|
||||
XXO("Sound Activation Le&vel..."), FN(OnSoundActivated),
|
||||
@ -1085,13 +1091,17 @@ MenuTable::BaseItemPtr TransportMenu( AudacityProject &project )
|
||||
AudioIONotBusyFlag | CanStopAudioStreamFlag, checkOff )
|
||||
#endif
|
||||
)
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraTransportMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraTransportMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("T&ransport"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Transport"), XO("T&ransport"),
|
||||
// PlayStop is already in the menus.
|
||||
/* i18n-hint: (verb) Start playing audio*/
|
||||
Command( wxT("Play"), XXO("Pl&ay"), FN(OnPlayStop),
|
||||
@ -1133,13 +1143,17 @@ MenuTable::BaseItemPtr ExtraTransportMenu( AudacityProject & )
|
||||
Command(wxT("KeyboardScrubForwards"), XXO("Scrub For&wards"),
|
||||
FN(OnKeyboardScrubForwards),
|
||||
CaptureNotBusyFlag | CanStopAudioStreamFlag, wxT("I\twantKeyup"))
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraPlayAtSpeedMenu( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra
|
||||
MenuTable::BaseItemSharedPtr ExtraPlayAtSpeedMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("&Play-at-Speed"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("PlayAtSpeed"), XO("&Play-at-Speed"),
|
||||
/* i18n-hint: 'Normal Play-at-Speed' doesn't loop or cut preview. */
|
||||
Command( wxT("PlayAtSpeed"), XXO("Normal Pl&ay-at-Speed"),
|
||||
FN(OnPlayAtSpeed), CaptureNotBusyFlag ),
|
||||
@ -1163,7 +1177,8 @@ MenuTable::BaseItemPtr ExtraPlayAtSpeedMenu( AudacityProject & )
|
||||
Command( wxT("MoveToNextLabel"), XXO("Move to &Next Label"),
|
||||
FN(OnMoveToNextLabel),
|
||||
CaptureNotBusyFlag | TrackPanelHasFocus, wxT("Alt+Right") )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -430,20 +430,22 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &project) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& ViewActions::Handler :: X)
|
||||
#define FN(X) (& ViewActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr ToolbarsMenu( AudacityProject& );
|
||||
MenuTable::BaseItemSharedPtr ToolbarsMenu();
|
||||
|
||||
MenuTable::BaseItemPtr ViewMenu( AudacityProject& )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr ViewMenu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
static const auto checkOff = Options{}.CheckState( false );
|
||||
|
||||
return Menu( XO("&View"),
|
||||
Menu( XO("&Zoom"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("View"), XO("&View"),
|
||||
Menu( wxT("Zoom"), XO("&Zoom"),
|
||||
Command( wxT("ZoomIn"), XXO("Zoom &In"), FN(OnZoomIn),
|
||||
ZoomInAvailableFlag, wxT("Ctrl+1") ),
|
||||
Command( wxT("ZoomNormal"), XXO("Zoom &Normal"), FN(OnZoomNormal),
|
||||
@ -457,10 +459,10 @@ 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"),
|
||||
Menu( wxT("TrackSize"), XO("T&rack Size"),
|
||||
Command( wxT("FitInWindow"), XXO("&Fit to Width"), FN(OnZoomFit),
|
||||
TracksExistFlag, wxT("Ctrl+F") ),
|
||||
Command( wxT("FitV"), XXO("Fit to &Height"), FN(OnZoomFitV),
|
||||
@ -471,7 +473,7 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& )
|
||||
FN(OnExpandAllTracks), TracksExistFlag, wxT("Ctrl+Shift+X") )
|
||||
),
|
||||
|
||||
Menu( XO("Sk&ip to"),
|
||||
Menu( wxT("SkipTo"), XO("Sk&ip to"),
|
||||
Command( wxT("SkipSelStart"), XXO("Selection Sta&rt"),
|
||||
FN(OnGoSelStart), TimeSelectedFlag,
|
||||
Options{ wxT("Ctrl+["), XO("Skip to Selection Start") } ),
|
||||
@ -532,22 +534,24 @@ MenuTable::BaseItemPtr ViewMenu( AudacityProject& )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ToolbarsMenu,
|
||||
ToolbarsMenu(),
|
||||
|
||||
Separator(),
|
||||
|
||||
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"),
|
||||
FN(OnShowEffectsRack), AlwaysEnabledFlag, checkOff )
|
||||
#endif
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
|
||||
}
|
||||
|
||||
#undef FN
|
||||
|
@ -116,16 +116,18 @@ static CommandHandlerObject &findCommandHandler(AudacityProject &) {
|
||||
|
||||
// Menu definitions
|
||||
|
||||
#define FN(X) findCommandHandler, \
|
||||
static_cast<CommandFunctorPointer>(& WindowActions::Handler :: X)
|
||||
#define FN(X) (& WindowActions::Handler :: X)
|
||||
|
||||
MenuTable::BaseItemPtr WindowMenu( AudacityProject & )
|
||||
// Under /MenuBar
|
||||
MenuTable::BaseItemSharedPtr WindowMenu()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// poor imitation of the Mac Windows Menu
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using namespace MenuTable;
|
||||
return Menu( XO("&Window"),
|
||||
static BaseItemSharedPtr menu{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Menu( wxT("Window"), XO("&Window"),
|
||||
/* i18n-hint: Standard Macintosh Window menu item: Make (the current
|
||||
* window) shrink to an icon on the dock */
|
||||
Command( wxT("MacMinimize"), XXO("&Minimize"), FN(OnMacMinimize),
|
||||
@ -141,20 +143,24 @@ MenuTable::BaseItemPtr WindowMenu( AudacityProject & )
|
||||
* windows un-hidden */
|
||||
Command( wxT("MacBringAllToFront"), XXO("&Bring All to Front"),
|
||||
FN(OnMacBringAllToFront), AlwaysEnabledFlag )
|
||||
);
|
||||
) ) };
|
||||
return menu;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraWindowItems( AudacityProject & )
|
||||
// Under /MenuBar/Optional/Extra/Misc
|
||||
MenuTable::BaseItemSharedPtr ExtraWindowItems()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
|
||||
return Items(
|
||||
static BaseItemSharedPtr items{
|
||||
FinderScope( findCommandHandler ).Eval(
|
||||
Items( wxT("MacWindows"),
|
||||
/* i18n-hint: Shrink all project windows to icons on the Macintosh
|
||||
tooldock */
|
||||
Command( wxT("MacMinimizeAll"), XXO("Minimize All Projects"),
|
||||
FN(OnMacMinimizeAll),
|
||||
AlwaysEnabledFlag, wxT("Ctrl+Alt+M") )
|
||||
);
|
||||
) ) };
|
||||
return items;
|
||||
}
|
||||
|
||||
#undef FN
|
||||
@ -162,12 +168,12 @@ MenuTable::BaseItemPtr ExtraWindowItems( AudacityProject & )
|
||||
#else
|
||||
|
||||
// Not WXMAC. Stub functions.
|
||||
MenuTable::BaseItemPtr WindowMenu( AudacityProject & )
|
||||
MenuTable::BaseItemSharedPtr WindowMenu()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MenuTable::BaseItemPtr ExtraWindowItems( AudacityProject & )
|
||||
MenuTable::BaseItemSharedPtr ExtraWindowItems()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -360,6 +360,10 @@ wxString GUIPrefs::SetLang( const wxString & lang )
|
||||
// we're not using them yet...
|
||||
using future1 = decltype( XO("Master Gain Control") );
|
||||
|
||||
#ifdef __WXMAC__
|
||||
wxApp::s_macHelpMenuTitleName = _("&Help");
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ static const ReservedCommandFlag
|
||||
HasWaveDataFlag{ HasWaveDataPred }; // jkc
|
||||
|
||||
namespace {
|
||||
const struct MenuItem {
|
||||
struct MenuItem {
|
||||
CommandID name;
|
||||
TranslatableString label;
|
||||
TranslatableString status;
|
||||
@ -268,7 +268,11 @@ namespace {
|
||||
bool (Scrubber::*StatusTest)() const;
|
||||
|
||||
const TranslatableString &GetStatus() const { return status; }
|
||||
} menuItems[] = {
|
||||
};
|
||||
using MenuItems = std::vector< MenuItem >;
|
||||
const MenuItems &menuItems()
|
||||
{
|
||||
static MenuItems theItems{
|
||||
/* i18n-hint: These commands assist the user in finding a sound by ear. ...
|
||||
"Scrubbing" is variable-speed playback, ...
|
||||
"Seeking" is normal speed playback but with skips, ...
|
||||
@ -287,13 +291,13 @@ namespace {
|
||||
AlwaysEnabledFlag,
|
||||
&Scrubber::OnToggleScrubRuler, false, &Scrubber::ShowsBar,
|
||||
},
|
||||
};
|
||||
return theItems;
|
||||
};
|
||||
|
||||
enum { nMenuItems = sizeof(menuItems) / sizeof(*menuItems) };
|
||||
|
||||
inline const MenuItem &FindMenuItem(bool seek)
|
||||
{
|
||||
return *std::find_if(menuItems, menuItems + nMenuItems,
|
||||
return *std::find_if(menuItems().begin(), menuItems().end(),
|
||||
[=](const MenuItem &item) {
|
||||
return seek == item.seek;
|
||||
}
|
||||
@ -1055,7 +1059,7 @@ BEGIN_EVENT_TABLE(Scrubber, wxEvtHandler)
|
||||
EVT_MENU(CMD_ID + 2, THUNK(OnToggleScrubRuler))
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static_assert(nMenuItems == 3, "wrong number of items");
|
||||
//static_assert(menuItems().size() == 3, "wrong number of items");
|
||||
|
||||
static auto sPlayAtSpeedStatus = XO("Playing at Speed");
|
||||
|
||||
@ -1101,7 +1105,7 @@ registeredStatusWidthFunction{
|
||||
if ( field == stateStatusBarField ) {
|
||||
TranslatableStrings strings;
|
||||
// Note that Scrubbing + Paused is not allowed.
|
||||
for (const auto &item : menuItems)
|
||||
for (const auto &item : menuItems())
|
||||
strings.push_back( item.GetStatus() );
|
||||
strings.push_back(
|
||||
XO("%s Paused.").Format( sPlayAtSpeedStatus )
|
||||
@ -1121,35 +1125,44 @@ bool Scrubber::CanScrub() const
|
||||
HasWaveDataPred( *mProject );
|
||||
}
|
||||
|
||||
// To supply the "finder" argument
|
||||
static CommandHandlerObject &findme(AudacityProject &project)
|
||||
{ return Scrubber::Get( project ); }
|
||||
|
||||
MenuTable::BaseItemPtr Scrubber::Menu()
|
||||
MenuTable::BaseItemSharedPtr Scrubber::Menu()
|
||||
{
|
||||
using namespace MenuTable;
|
||||
using Options = CommandManager::Options;
|
||||
|
||||
MenuTable::BaseItemPtrs ptrs;
|
||||
for (const auto &item : menuItems) {
|
||||
ptrs.push_back( MenuTable::Command( item.name, item.label,
|
||||
findme, static_cast<CommandFunctorPointer>(item.memFn),
|
||||
item.flags,
|
||||
item.StatusTest
|
||||
? // a checkmark item
|
||||
Options{}.CheckState( (this->*item.StatusTest)() )
|
||||
: // not a checkmark item
|
||||
Options{}
|
||||
) );
|
||||
}
|
||||
|
||||
return MenuTable::Menu( XO("Scru&bbing"), std::move( ptrs ) );
|
||||
static BaseItemSharedPtr menu {
|
||||
FinderScope(
|
||||
[](AudacityProject &project) -> CommandHandlerObject&
|
||||
{ return Scrubber::Get( project ); }
|
||||
).Eval(
|
||||
MenuTable::Menu( wxT("Scrubbing"),
|
||||
XO("Scru&bbing"),
|
||||
[]{
|
||||
BaseItemPtrs ptrs;
|
||||
for (const auto &item : menuItems()) {
|
||||
ptrs.push_back( MenuTable::Command( item.name, item.label,
|
||||
item.memFn,
|
||||
item.flags,
|
||||
item.StatusTest
|
||||
? // a checkmark item
|
||||
Options{}.CheckTest( [&item](AudacityProject &project){
|
||||
return ( Scrubber::Get(project).*(item.StatusTest) )(); } )
|
||||
: // not a checkmark item
|
||||
Options{}
|
||||
) );
|
||||
}
|
||||
return ptrs;
|
||||
}()
|
||||
) ) };
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void Scrubber::PopulatePopupMenu(wxMenu &menu)
|
||||
{
|
||||
int id = CMD_ID;
|
||||
auto &cm = CommandManager::Get( *mProject );
|
||||
for (const auto &item : menuItems) {
|
||||
for (const auto &item : menuItems()) {
|
||||
if (cm.GetEnabled(item.name)) {
|
||||
auto test = item.StatusTest;
|
||||
menu.Append(id, item.label.Translation(), wxString{},
|
||||
@ -1164,7 +1177,7 @@ void Scrubber::PopulatePopupMenu(wxMenu &menu)
|
||||
void Scrubber::CheckMenuItems()
|
||||
{
|
||||
auto &cm = CommandManager::Get( *mProject );
|
||||
for (const auto &item : menuItems) {
|
||||
for (const auto &item : menuItems()) {
|
||||
auto test = item.StatusTest;
|
||||
if (test)
|
||||
cm.Check(item.name, (this->*test)());
|
||||
|
@ -118,7 +118,7 @@ public:
|
||||
bool CanScrub() const;
|
||||
|
||||
// For the toolbar
|
||||
MenuTable::BaseItemPtr Menu();
|
||||
static MenuTable::BaseItemSharedPtr Menu();
|
||||
// For popup
|
||||
void PopulatePopupMenu(wxMenu &menu);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user