mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-22 06:22:58 +02:00
Further fixes for keyboard handling
I'm pretty sure this gets all of the currently known issues, including the SHIFT+M not working, the Play buttons responding to SHIFT and CTRL, the ESC key canceling drags, and I'm pretty sure it even fixes but #784.
This commit is contained in:
@@ -729,15 +729,15 @@ void CommandManager::AddCommand(const wxChar *name,
|
||||
}
|
||||
}
|
||||
|
||||
void CommandManager::AddMetaCommand(const wxChar *name,
|
||||
const wxChar *label_in,
|
||||
CommandFunctor *callback,
|
||||
const wxChar *accel)
|
||||
void CommandManager::AddGlobalCommand(const wxChar *name,
|
||||
const wxChar *label_in,
|
||||
CommandFunctor *callback,
|
||||
const wxChar *accel)
|
||||
{
|
||||
CommandListEntry *entry = NewIdentifier(name, label_in, accel, NULL, callback, false, 0, 0);
|
||||
|
||||
entry->enabled = false;
|
||||
entry->isMeta = true;
|
||||
entry->isGlobal = true;
|
||||
entry->flags = 0;
|
||||
entry->mask = 0;
|
||||
}
|
||||
@@ -834,9 +834,8 @@ CommandListEntry *CommandManager::NewIdentifier(const wxString & name,
|
||||
entry->flags = mDefaultFlags;
|
||||
entry->mask = mDefaultMask;
|
||||
entry->enabled = true;
|
||||
entry->wantevent = (accel.Find(wxT("\twantevent")) != wxNOT_FOUND);
|
||||
entry->ignoredown = (accel.Find(wxT("\tignoredown")) != wxNOT_FOUND);
|
||||
entry->isMeta = false;
|
||||
entry->wantKeyup = (accel.Find(wxT("\twantKeyup")) != wxNOT_FOUND);
|
||||
entry->isGlobal = false;
|
||||
|
||||
// For key bindings for commands with a list, such as effects,
|
||||
// the name in prefs is the category name plus the effect name.
|
||||
@@ -1042,11 +1041,27 @@ void CommandManager::TellUserWhyDisallowed( wxUint32 flagsGot, wxUint32 flagsReq
|
||||
///
|
||||
///
|
||||
///
|
||||
bool CommandManager::FilterKeyEvent(AudacityProject *project, wxKeyEvent & evt, bool permit)
|
||||
bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit)
|
||||
{
|
||||
if (HandleMeta(evt))
|
||||
CommandListEntry *entry = mCommandKeyHash[KeyEventToKeyString(evt)];
|
||||
if (entry == NULL)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Global commands are tied to any specific project
|
||||
if (entry->isGlobal)
|
||||
{
|
||||
// Global commands are always disabled so they do not interfere with the
|
||||
// rest of the command handling. But, to use the common handler, we
|
||||
// enable it temporarily and then disable it again after handling.
|
||||
entry->enabled = true;
|
||||
bool ret = HandleCommandEntry(entry, 0xffffffff, 0xffffffff, &evt);
|
||||
entry->enabled = false;
|
||||
if (ret)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Any other keypresses must be destined for this project window.
|
||||
@@ -1059,10 +1074,13 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, wxKeyEvent & evt,
|
||||
|
||||
wxKeyEvent temp = evt;
|
||||
temp.SetEventType(wxEVT_KEY_DOWN);
|
||||
if (HandleKey(temp, flags, 0xFFFFFFFF))
|
||||
if (HandleCommandEntry(entry, flags, 0xffffffff, &evt))
|
||||
{
|
||||
temp.SetEventType(wxEVT_KEY_UP);
|
||||
HandleKey(temp, flags, 0xFFFFFFFF);
|
||||
if (entry->wantKeyup)
|
||||
{
|
||||
temp.SetEventType(wxEVT_KEY_UP);
|
||||
HandleCommandEntry(entry, flags, 0xffffffff, &evt);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1074,7 +1092,7 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, wxKeyEvent & evt,
|
||||
/// returning true iff successful. If you pass any flags,
|
||||
///the command won't be executed unless the flags are compatible
|
||||
///with the command's flags.
|
||||
bool CommandManager::HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt)
|
||||
bool CommandManager::HandleCommandEntry(const CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt)
|
||||
{
|
||||
if (!entry || !entry->enabled)
|
||||
return false;
|
||||
@@ -1114,53 +1132,6 @@ bool CommandManager::HandleMenuID(int id, wxUint32 flags, wxUint32 mask)
|
||||
return HandleCommandEntry( entry, flags, mask );
|
||||
}
|
||||
|
||||
///Call this when a key event is received.
|
||||
///If it matches a command, it will call the appropriate
|
||||
///CommandManagerListener function. If you pass any flags,
|
||||
///the command won't be executed unless the flags are compatible
|
||||
///with the command's flags.
|
||||
bool CommandManager::HandleKey(wxKeyEvent &evt, wxUint32 flags, wxUint32 mask)
|
||||
{
|
||||
wxString keyStr = KeyEventToKeyString(evt);
|
||||
CommandListEntry *entry = mCommandKeyHash[keyStr];
|
||||
|
||||
if (entry)
|
||||
{
|
||||
if (evt.GetEventType() == wxEVT_KEY_DOWN && !entry->ignoredown)
|
||||
{
|
||||
return HandleCommandEntry( entry, flags, mask, &evt );
|
||||
}
|
||||
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP && (entry->wantevent || entry->ignoredown))
|
||||
{
|
||||
return HandleCommandEntry( entry, flags, mask, &evt );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommandManager::HandleMeta(wxKeyEvent &evt)
|
||||
{
|
||||
wxString keyStr = KeyEventToKeyString(evt);
|
||||
CommandListEntry *entry = mCommandKeyHash[keyStr];
|
||||
|
||||
// Return unhandle if it isn't a meta command
|
||||
if (!entry || !entry->isMeta)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Meta commands are always disabled so they do not interfere with the
|
||||
// rest of the command handling. But, to use the common handler, we
|
||||
// enable it temporarily and then disable it again after handling.
|
||||
entry->enabled = true;
|
||||
bool ret = HandleCommandEntry( entry, 0xffffffff, 0xffffffff, &evt );
|
||||
entry->enabled = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// HandleTextualCommand() allows us a limitted version of script/batch
|
||||
/// behavior, since we can get from a string command name to the actual
|
||||
/// code to run.
|
||||
@@ -1471,7 +1442,7 @@ void CommandManager::CheckDups()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mCommandList[j]->label.AfterLast(wxT('\t')) == wxT("allowdup")) {
|
||||
if (mCommandList[j]->label.AfterLast(wxT('\t')) == wxT("allowDup")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -57,9 +57,8 @@ struct CommandListEntry
|
||||
int index;
|
||||
int count;
|
||||
bool enabled;
|
||||
bool wantevent;
|
||||
bool ignoredown;
|
||||
bool isMeta;
|
||||
bool wantKeyup;
|
||||
bool isGlobal;
|
||||
wxUint32 flags;
|
||||
wxUint32 mask;
|
||||
};
|
||||
@@ -150,10 +149,10 @@ class AUDACITY_DLL_API CommandManager: public XMLTagHandler
|
||||
unsigned int flags = NoFlagsSpecifed,
|
||||
unsigned int mask = NoFlagsSpecifed);
|
||||
|
||||
void AddMetaCommand(const wxChar *name,
|
||||
const wxChar *label,
|
||||
CommandFunctor *callback,
|
||||
const wxChar *accel);
|
||||
void AddGlobalCommand(const wxChar *name,
|
||||
const wxChar *label,
|
||||
CommandFunctor *callback,
|
||||
const wxChar *accel);
|
||||
//
|
||||
// Command masks
|
||||
//
|
||||
@@ -187,15 +186,11 @@ class AUDACITY_DLL_API CommandManager: public XMLTagHandler
|
||||
// Executing commands
|
||||
//
|
||||
|
||||
// "permit" allows filtering even if the active window is a child of the project.
|
||||
// "permit" allows filtering even if the active window isn't a child of the project.
|
||||
// Lyrics and MixerTrackCluster classes use it.
|
||||
bool FilterKeyEvent(AudacityProject *project, wxKeyEvent & evt, bool permit = false);
|
||||
bool HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt = NULL);
|
||||
bool FilterKeyEvent(AudacityProject *project, const wxKeyEvent & evt, bool permit = false);
|
||||
bool HandleMenuID(int id, wxUint32 flags, wxUint32 mask);
|
||||
bool HandleKey(wxKeyEvent &evt, wxUint32 flags, wxUint32 mask);
|
||||
bool HandleMeta(wxKeyEvent &evt);
|
||||
bool HandleTextualCommand(wxString & Str, wxUint32 flags, wxUint32 mask);
|
||||
void TellUserWhyDisallowed(wxUint32 flagsGot, wxUint32 flagsRequired);
|
||||
|
||||
//
|
||||
// Accessing
|
||||
@@ -228,17 +223,13 @@ class AUDACITY_DLL_API CommandManager: public XMLTagHandler
|
||||
// Loading/Saving
|
||||
//
|
||||
|
||||
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
|
||||
virtual void HandleXMLEndTag(const wxChar *tag);
|
||||
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
|
||||
virtual void WriteXML(XMLWriter &xmlFile);
|
||||
|
||||
protected:
|
||||
|
||||
wxMenuBar * CurrentMenuBar() const;
|
||||
wxMenuBar * GetMenuBar(wxString sMenu) const;
|
||||
wxMenu * CurrentSubMenu() const;
|
||||
wxMenu * CurrentMenu() const;
|
||||
//
|
||||
// Creating menus and adding commands
|
||||
//
|
||||
|
||||
int NextIdentifier(int ID);
|
||||
CommandListEntry *NewIdentifier(const wxString & name,
|
||||
@@ -256,10 +247,38 @@ protected:
|
||||
bool multi,
|
||||
int index,
|
||||
int count);
|
||||
|
||||
//
|
||||
// Executing commands
|
||||
//
|
||||
|
||||
bool HandleCommandEntry(const CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt = NULL);
|
||||
void TellUserWhyDisallowed(wxUint32 flagsGot, wxUint32 flagsRequired);
|
||||
|
||||
//
|
||||
// Modifying
|
||||
//
|
||||
|
||||
void Enable(CommandListEntry *entry, bool enabled);
|
||||
|
||||
//
|
||||
// Accessing
|
||||
//
|
||||
|
||||
wxMenuBar * CurrentMenuBar() const;
|
||||
wxMenuBar * GetMenuBar(wxString sMenu) const;
|
||||
wxMenu * CurrentSubMenu() const;
|
||||
wxMenu * CurrentMenu() const;
|
||||
wxString GetLabel(const CommandListEntry *entry) const;
|
||||
|
||||
//
|
||||
// Loading/Saving
|
||||
//
|
||||
|
||||
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
|
||||
virtual void HandleXMLEndTag(const wxChar *tag);
|
||||
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
|
||||
|
||||
private:
|
||||
MenuBarList mMenuBarList;
|
||||
SubMenuList mSubMenuList;
|
||||
|
Reference in New Issue
Block a user