When a text field is focused disable only native menu items with a shortcut related to Entry fields

Related to #1577 and https://community.aseprite.org/t/480
This commit is contained in:
David Capello 2017-09-26 16:39:33 -03:00
parent ed744bb223
commit cab7f6d70a
3 changed files with 77 additions and 27 deletions

View File

@ -33,6 +33,7 @@
#include "tinyxml.h" #include "tinyxml.h"
#include <cctype>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
@ -40,11 +41,52 @@ namespace app {
using namespace ui; using namespace ui;
// TODO Move this to she layer
static const int kUnicodeEsc = 27;
static const int kUnicodeEnter = '\r'; // 10
static const int kUnicodeInsert = 0xF727; // NSInsertFunctionKey
static const int kUnicodeDel = 0xF728; // NSDeleteFunctionKey
static const int kUnicodeHome = 0xF729; // NSHomeFunctionKey
static const int kUnicodeEnd = 0xF72B; // NSEndFunctionKey
static const int kUnicodePageUp = 0xF72C; // NSPageUpFunctionKey
static const int kUnicodePageDown = 0xF72D; // NSPageDownFunctionKey
static const int kUnicodeLeft = 0xF702; // NSLeftArrowFunctionKey
static const int kUnicodeRight = 0xF703; // NSRightArrowFunctionKey
static const int kUnicodeUp = 0xF700; // NSUpArrowFunctionKey
static const int kUnicodeDown = 0xF701; // NSDownArrowFunctionKey
static void destroy_instance(AppMenus* instance) static void destroy_instance(AppMenus* instance)
{ {
delete instance; delete instance;
} }
static bool is_text_entry_shortcut(const she::Shortcut& shortcut)
{
const she::KeyModifiers mod = shortcut.modifiers();
const int chr = shortcut.unicode();
const int lchr = std::tolower(chr);
bool result =
((mod == she::KeyModifiers::kKeyNoneModifier ||
mod == she::KeyModifiers::kKeyShiftModifier) &&
chr >= 32 && chr < 0xF000)
||
((mod == she::KeyModifiers::kKeyCmdModifier ||
mod == she::KeyModifiers::kKeyCtrlModifier) &&
(lchr == 'a' || lchr == 'c' || lchr == 'v' || lchr == 'x'))
||
(chr == kUnicodeInsert ||
chr == kUnicodeDel ||
chr == kUnicodeHome ||
chr == kUnicodeEnd ||
chr == kUnicodeLeft ||
chr == kUnicodeRight ||
chr == kUnicodeEsc ||
chr == kUnicodeEnter);
return result;
}
static bool can_call_global_shortcut(const she::Shortcut& shortcut) static bool can_call_global_shortcut(const she::Shortcut& shortcut)
{ {
ui::Manager* manager = ui::Manager::getDefault(); ui::Manager* manager = ui::Manager::getDefault();
@ -60,7 +102,7 @@ static bool can_call_global_shortcut(const she::Shortcut& shortcut)
// in a text field. // in a text field.
(focus == nullptr || (focus == nullptr ||
focus->type() != ui::kEntryWidget || focus->type() != ui::kEntryWidget ||
shortcut.modifiers() != she::KeyModifiers::kKeyNoneModifier); !is_text_entry_shortcut(shortcut));
} }
// TODO this should be on "she" library (or we should use // TODO this should be on "she" library (or we should use
@ -127,7 +169,7 @@ static int from_scancode_to_unicode(KeyScancode scancode)
0xF70D, // kKeyF10 0xF70D, // kKeyF10
0xF70E, // kKeyF11 0xF70E, // kKeyF11
0xF70F, // kKeyF12 0xF70F, // kKeyF12
27, // kKeyEsc kUnicodeEsc, // kKeyEsc
'~', // kKeyTilde '~', // kKeyTilde
'-', // kKeyMinus '-', // kKeyMinus
'=', // kKeyEquals '=', // kKeyEquals
@ -135,7 +177,7 @@ static int from_scancode_to_unicode(KeyScancode scancode)
9, // kKeyTab 9, // kKeyTab
'[', // kKeyOpenbrace '[', // kKeyOpenbrace
']', // kKeyClosebrace ']', // kKeyClosebrace
'\r', // kKeyEnter // 10, kKeyEnter kUnicodeEnter, // kKeyEnter
':', // kKeyColon ':', // kKeyColon
'\'', // kKeyQuote '\'', // kKeyQuote
'\\', // kKeyBackslash '\\', // kKeyBackslash
@ -144,16 +186,16 @@ static int from_scancode_to_unicode(KeyScancode scancode)
'.', // kKeyStop '.', // kKeyStop
'/', // kKeySlash '/', // kKeySlash
' ', // kKeySpace ' ', // kKeySpace
0xF727, // kKeyInsert (NSInsertFunctionKey) kUnicodeInsert, // kKeyInsert (NSInsertFunctionKey)
0xF728, // kKeyDel (NSDeleteFunctionKey) kUnicodeDel, // kKeyDel (NSDeleteFunctionKey)
0xF729, // kKeyHome (NSHomeFunctionKey) kUnicodeHome, // kKeyHome (NSHomeFunctionKey)
0xF72B, // kKeyEnd (NSEndFunctionKey) kUnicodeEnd, // kKeyEnd (NSEndFunctionKey)
0xF72C, // kKeyPageUp (NSPageUpFunctionKey) kUnicodePageUp, // kKeyPageUp (NSPageUpFunctionKey)
0xF72D, // kKeyPageDown (NSPageDownFunctionKey) kUnicodePageDown, // kKeyPageDown (NSPageDownFunctionKey)
0xF702, // kKeyLeft (NSLeftArrowFunctionKey) kUnicodeLeft, // kKeyLeft (NSLeftArrowFunctionKey)
0xF703, // kKeyRight (NSRightArrowFunctionKey) kUnicodeRight, // kKeyRight (NSRightArrowFunctionKey)
0xF700, // kKeyUp (NSUpArrowFunctionKey) kUnicodeUp, // kKeyUp (NSUpArrowFunctionKey)
0xF701, // kKeyDown (NSDownArrowFunctionKey) kUnicodeDown, // kKeyDown (NSDownArrowFunctionKey)
'/', // kKeySlashPad '/', // kKeySlashPad
'*', // kKeyAsterisk '*', // kKeyAsterisk
0, // kKeyMinusPad 0, // kKeyMinusPad
@ -665,19 +707,19 @@ void AppMenus::createNativeSubmenus(she::Menu* osMenu, const ui::Menu* uiMenu)
info.type = she::MenuItemInfo::Normal; info.type = she::MenuItemInfo::Normal;
info.text = child->text(); info.text = child->text();
info.shortcut = shortcut; info.shortcut = shortcut;
info.execute = [child, shortcut]{ info.execute = [appMenuItem]{
if (can_call_global_shortcut(shortcut)) if (can_call_global_shortcut(appMenuItem->nativeShortcut()))
((ui::MenuItem*)child)->executeClick(); appMenuItem->executeClick();
}; };
info.validate = [child, shortcut](she::MenuItem* item) { info.validate = [appMenuItem](she::MenuItem* osItem) {
if (can_call_global_shortcut(shortcut)) { if (can_call_global_shortcut(appMenuItem->nativeShortcut())) {
((ui::MenuItem*)child)->validateItem(); appMenuItem->validateItem();
item->setEnabled(child->isEnabled()); osItem->setEnabled(appMenuItem->isEnabled());
item->setChecked(child->isSelected()); osItem->setChecked(appMenuItem->isSelected());
} }
else { else {
// Disable item when there are a modal window // Disable item when there are a modal window
item->setEnabled(false); osItem->setEnabled(false);
} }
}; };
} }
@ -690,7 +732,7 @@ void AppMenus::createNativeSubmenus(she::Menu* osMenu, const ui::Menu* uiMenu)
if (osItem) { if (osItem) {
osMenu->addItem(osItem); osMenu->addItem(osItem);
if (appMenuItem) if (appMenuItem)
appMenuItem->setNativeMenuItem(osItem); appMenuItem->setNativeMenuItem(osItem, info.shortcut);
if (child->type() == ui::kMenuItemWidget && if (child->type() == ui::kMenuItemWidget &&
((ui::MenuItem*)child)->hasSubmenu()) { ((ui::MenuItem*)child)->hasSubmenu()) {

View File

@ -49,15 +49,19 @@ void AppMenuItem::setKey(Key* key)
syncNativeMenuItemKeyShortcut(); syncNativeMenuItemKeyShortcut();
} }
void AppMenuItem::setNativeMenuItem(she::MenuItem* nativeMenuItem) void AppMenuItem::setNativeMenuItem(she::MenuItem* nativeMenuItem,
const she::Shortcut& nativeShortcut)
{ {
m_nativeMenuItem = nativeMenuItem; m_nativeMenuItem = nativeMenuItem;
m_nativeShortcut = nativeShortcut;
} }
void AppMenuItem::syncNativeMenuItemKeyShortcut() void AppMenuItem::syncNativeMenuItemKeyShortcut()
{ {
if (m_nativeMenuItem) if (m_nativeMenuItem) {
m_nativeMenuItem->setShortcut(get_os_shortcut_from_key(m_key)); m_nativeShortcut = get_os_shortcut_from_key(m_key);
m_nativeMenuItem->setShortcut(m_nativeShortcut);
}
} }
// static // static

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include "app/commands/params.h" #include "app/commands/params.h"
#include "she/shortcut.h"
#include "ui/menu.h" #include "ui/menu.h"
namespace she { namespace she {
@ -35,7 +36,9 @@ namespace app {
const Params& getParams() const { return m_params; } const Params& getParams() const { return m_params; }
she::MenuItem* nativeMenuItem() { return m_nativeMenuItem; } she::MenuItem* nativeMenuItem() { return m_nativeMenuItem; }
void setNativeMenuItem(she::MenuItem* nativeMenuItem); const she::Shortcut& nativeShortcut() const { return m_nativeShortcut; }
void setNativeMenuItem(she::MenuItem* nativeMenuItem,
const she::Shortcut& nativeShortcut);
void syncNativeMenuItemKeyShortcut(); void syncNativeMenuItemKeyShortcut();
static void setContextParams(const Params& params); static void setContextParams(const Params& params);
@ -51,6 +54,7 @@ namespace app {
Command* m_command; Command* m_command;
Params m_params; Params m_params;
she::MenuItem* m_nativeMenuItem; she::MenuItem* m_nativeMenuItem;
she::Shortcut m_nativeShortcut;
static Params s_contextParams; static Params s_contextParams;
}; };