Fix alt+mnemonic on macOS

This commit is contained in:
David Capello 2016-11-24 19:26:21 -03:00
parent 783acfc61a
commit 701170d85e
5 changed files with 24 additions and 22 deletions

View File

@ -161,10 +161,8 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
case ui::kKeyDownMessage:
if (isEnabled() && hasText()) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
bool mnemonicPressed =
(msg->altPressed() &&
mnemonicChar() &&
mnemonicChar() == tolower(keymsg->unicodeChar()));
bool mnemonicPressed = (msg->altPressed() &&
mnemonicCharPressed(keymsg));
if (mnemonicPressed ||
(hasFocus() && keymsg->scancode() == kKeySpace)) {

View File

@ -101,8 +101,7 @@ bool ButtonBase::onProcessMessage(Message* msg)
if (isEnabled()) {
bool mnemonicPressed =
(msg->altPressed() &&
mnemonicChar() &&
mnemonicChar() == tolower(keymsg->unicodeChar()));
mnemonicCharPressed(keymsg));
// For kButtonWidget
if (m_behaviorType == kButtonWidget) {

View File

@ -118,7 +118,7 @@ protected:
static MenuBox* get_base_menubox(Widget* widget);
static MenuBaseData* get_base(Widget* widget);
static MenuItem* check_for_letter(Menu* menu, int ascii);
static MenuItem* check_for_letter(Menu* menu, const KeyMessage* keymsg);
static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem);
static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem);
@ -485,17 +485,9 @@ bool MenuBox::onProcessMessage(Message* msg)
if (((this->type() == kMenuBoxWidget) && (msg->modifiers() == kKeyNoneModifier || // <-- Inside menu-boxes we can use letters without Alt modifier pressed
msg->modifiers() == kKeyAltModifier)) ||
((this->type() == kMenuBarWidget) && (msg->modifiers() == kKeyAltModifier))) {
int unicode = static_cast<KeyMessage*>(msg)->unicodeChar();
selected = check_for_letter(menu, unicode);
if (!selected) {
KeyScancode scancode = static_cast<KeyMessage*>(msg)->scancode();
if (scancode >= kKeyA && scancode <= kKeyZ)
selected = check_for_letter(menu, 'a' + scancode - kKeyA);
else if (scancode >= kKey0 && scancode <= kKey9)
selected = check_for_letter(menu, '0' + scancode - kKey0);
}
auto keymsg = static_cast<KeyMessage*>(msg);
if (selected) {
if (check_for_letter(menu, keymsg)) {
menu->highlightItem(selected, true, true, true);
return true;
}
@ -1194,15 +1186,14 @@ void MenuItem::executeClick()
Manager::getDefault()->enqueueMessage(msg);
}
static MenuItem* check_for_letter(Menu* menu, int ascii)
static MenuItem* check_for_letter(Menu* menu, const KeyMessage* keymsg)
{
for (auto child : menu->children()) {
if (child->type() != kMenuItemWidget)
continue;
MenuItem* menuitem = static_cast<MenuItem*>(child);
int mnemonic = menuitem->mnemonicChar();
if (mnemonic > 0 && mnemonic == std::tolower(ascii))
if (menuitem->mnemonicCharPressed(keymsg))
return menuitem;
}
return NULL;

View File

@ -1275,11 +1275,21 @@ int Widget::mnemonicChar() const
if (hasText()) {
for (int c=0; m_text[c]; ++c)
if ((m_text[c] == '&') && (m_text[c+1] != '&'))
return tolower(m_text[c+1]);
return std::tolower(m_text[c+1]);
}
return 0;
}
bool Widget::mnemonicCharPressed(const KeyMessage* keyMsg) const
{
int chr = mnemonicChar();
return
((chr) &&
((chr == std::tolower(keyMsg->unicodeChar())) ||
(chr >= 'a' && chr <= 'z' && keyMsg->scancode() == (kKeyA + chr - 'a')) ||
(chr >= '0' && chr <= '9' && keyMsg->scancode() == (kKey0 + chr - '0'))));
}
bool Widget::onProcessMessage(Message* msg)
{
ASSERT(msg != NULL);

View File

@ -31,14 +31,15 @@ namespace she {
namespace ui {
class InitThemeEvent;
class KeyMessage;
class LoadLayoutEvent;
class Manager;
class Message;
class MouseMessage;
class PaintEvent;
class SizeHintEvent;
class ResizeEvent;
class SaveLayoutEvent;
class SizeHintEvent;
class Theme;
class Window;
@ -348,6 +349,9 @@ namespace ui {
// (the underscored character, i.e. the letter after & symbol).
int mnemonicChar() const;
// Returns true if the mnemonic character is pressed.
bool mnemonicCharPressed(const ui::KeyMessage* keyMsg) const;
protected:
// ===============================================================
// MESSAGE PROCESSING