diff --git a/src/preferences/keymap/KeyboardLayoutView.cpp b/src/preferences/keymap/KeyboardLayoutView.cpp index 3705faf1e8..2cb77f0bef 100644 --- a/src/preferences/keymap/KeyboardLayoutView.cpp +++ b/src/preferences/keymap/KeyboardLayoutView.cpp @@ -1,6 +1,11 @@ /* * Copyright 2009-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2013-2014 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * John Scipione, jscipione@gmail.com */ @@ -33,6 +38,116 @@ static const rgb_color kDeadKeyColor = {152, 203, 255, 255}; static const rgb_color kLitIndicatorColor = {116, 212, 83, 255}; +static const char* +name_for_modifier(uint32 modifier, bool pretty) +{ + if (modifier == B_CAPS_LOCK) + return pretty ? B_TRANSLATE("Caps lock") : "caps_key"; + else if (modifier == B_NUM_LOCK) + return pretty ? B_TRANSLATE("Num lock") : "num_key"; + else if (modifier == B_SCROLL_LOCK) + return pretty ? B_TRANSLATE("Scroll lock") : "scroll_key"; + else if (modifier == B_SHIFT_KEY) { + return pretty ? B_TRANSLATE_COMMENT("Shift", "Shift key") + : "shift_key"; + } else if (modifier == B_LEFT_SHIFT_KEY) + return pretty ? B_TRANSLATE("Left shift") : "left_shift_key"; + else if (modifier == B_RIGHT_SHIFT_KEY) + return pretty ? B_TRANSLATE("Right shift") : "right_shift_key"; + else if (modifier == B_COMMAND_KEY) { + return pretty ? B_TRANSLATE_COMMENT("Command", "Command key") + : "command_key"; + } else if (modifier == B_LEFT_COMMAND_KEY) + return pretty ? B_TRANSLATE("Left command") : "left_command_key"; + else if (modifier == B_RIGHT_COMMAND_KEY) + return pretty ? B_TRANSLATE("Right command") : "right_command_key"; + else if (modifier == B_CONTROL_KEY) { + return pretty ? B_TRANSLATE_COMMENT("Control", "Control key") + : "control_key"; + } else if (modifier == B_LEFT_CONTROL_KEY) + return pretty ? B_TRANSLATE("Left control") : "left_control_key"; + else if (modifier == B_RIGHT_CONTROL_KEY) + return pretty ? B_TRANSLATE("Right control") : "right_control_key"; + else if (modifier == B_OPTION_KEY) { + return pretty ? B_TRANSLATE_COMMENT("Option", "Option key") + : "option_key"; + } else if (modifier == B_LEFT_OPTION_KEY) + return pretty ? B_TRANSLATE("Left option") : "left_option_key"; + else if (modifier == B_RIGHT_OPTION_KEY) + return pretty ? B_TRANSLATE("Right option") : "right_option_key"; + else if (modifier == B_MENU_KEY) + return pretty ? B_TRANSLATE_COMMENT("Menu", "Menu key") : "menu_key"; + + return NULL; +} + + +static BMenuItem* +swap_modifiers_menu_item(Keymap* map, uint32 modifier, uint32 displayModifier, + uint32 oldCode, uint32 newCode) +{ + int32 mask = B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY; + const char* oldName = name_for_modifier(oldCode == 0x00 ? modifier + : map->Modifier(oldCode) & ~mask, false); + const char* newName = name_for_modifier(newCode == 0x00 ? modifier + : map->Modifier(newCode) & ~mask, false); + + BMessage* message = new BMessage(kMsgUpdateModifierKeys); + if (newName != NULL) + message->AddUInt32(newName, oldCode); + + if (oldName != NULL) + message->AddUInt32(oldName, newCode); + + if (oldCode == newCode) + message->AddBool("unset", true); + + return new BMenuItem(name_for_modifier(displayModifier, true), message); +} + + +static bool +is_left_modifier_key(uint32 keyCode) +{ + return keyCode == 0x4b // left shift + || keyCode == 0x5d // left command + || keyCode == 0x5c // left control + || keyCode == 0x66; // left option +} + + +static bool +is_right_modifier_key(uint32 keyCode) +{ + return keyCode == 0x56 // right shift + || keyCode == 0x5f // right command + || keyCode == 0x60 // right control + || keyCode == 0x67 // right option + || keyCode == 0x68; // menu +} + + +static bool +is_lock_key(uint32 keyCode) +{ + return keyCode == 0x3b // caps lock + || keyCode == 0x22 // num lock + || keyCode == 0x0f; // scroll lock +} + + +static bool +is_mappable_to_modifier(uint32 keyCode) +{ + return is_left_modifier_key(keyCode) + || is_right_modifier_key(keyCode) + || is_lock_key(keyCode); +} + + +// #pragma mark - KeyboardLayoutView + + KeyboardLayoutView::KeyboardLayoutView(const char* name) : BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS), @@ -164,96 +279,119 @@ KeyboardLayoutView::MouseDown(BPoint point) } if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0 - || ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0 - && (modifiers() & B_CONTROL_KEY) != 0)) { - if (_IsMappableToModifierKey(key->code)) { - // pop up the modifier keys menu - BPopUpMenu* modifiersPopUp = new BPopUpMenu("Modifiers pop up", - true, true, B_ITEMS_IN_COLUMN); - const key_map& map = fKeymap->Map(); - BMenuItem* item = NULL; + || ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0 + && (modifiers() & B_CONTROL_KEY) != 0)) { + // secondary mouse button, pop up a swap context menu + if (!is_mappable_to_modifier(key->code)) { + // ToDo: pop up a list of alternative characters + fButtons = buttons; + return; + } - item = _SwapModifiersMenuItem(B_LEFT_SHIFT_KEY, key->code, - map.left_shift_key); + // pop up the modifier keys menu + BPopUpMenu* modifiersPopUp = new BPopUpMenu("Modifiers pop up", + true, true, B_ITEMS_IN_COLUMN); + const key_map& map = fKeymap->Map(); + bool isLockKey = is_lock_key(key->code); + BMenuItem* item = NULL; + + if (is_left_modifier_key(key->code) || isLockKey) { + item = swap_modifiers_menu_item(fKeymap, B_LEFT_SHIFT_KEY, + isLockKey ? B_LEFT_SHIFT_KEY : B_SHIFT_KEY, + map.left_shift_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.left_shift_key) item->SetMarked(true); - item = _SwapModifiersMenuItem(B_LEFT_CONTROL_KEY, key->code, - map.left_control_key); + item = swap_modifiers_menu_item(fKeymap, B_LEFT_CONTROL_KEY, + isLockKey ? B_LEFT_CONTROL_KEY : B_CONTROL_KEY, + map.left_control_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.left_control_key) item->SetMarked(true); - item = _SwapModifiersMenuItem(B_LEFT_OPTION_KEY, key->code, - map.left_option_key); + item = swap_modifiers_menu_item(fKeymap, B_LEFT_OPTION_KEY, + isLockKey ? B_LEFT_OPTION_KEY : B_OPTION_KEY, + map.left_option_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.left_option_key) item->SetMarked(true); - item = _SwapModifiersMenuItem(B_LEFT_COMMAND_KEY, key->code, - map.left_command_key); + item = swap_modifiers_menu_item(fKeymap, B_LEFT_COMMAND_KEY, + isLockKey ? B_LEFT_COMMAND_KEY : B_COMMAND_KEY, + map.left_command_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.left_command_key) item->SetMarked(true); + } - modifiersPopUp->AddSeparatorItem(); + if (is_right_modifier_key(key->code) || isLockKey) { + if (isLockKey) + modifiersPopUp->AddSeparatorItem(); - item = _SwapModifiersMenuItem(B_RIGHT_SHIFT_KEY, - key->code, map.right_shift_key); + item = swap_modifiers_menu_item(fKeymap, B_RIGHT_SHIFT_KEY, + isLockKey ? B_RIGHT_SHIFT_KEY : B_SHIFT_KEY, + map.right_shift_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.right_shift_key) item->SetMarked(true); - item = _SwapModifiersMenuItem(B_RIGHT_CONTROL_KEY, - key->code, map.right_control_key); + item = swap_modifiers_menu_item(fKeymap, B_RIGHT_CONTROL_KEY, + isLockKey ? B_RIGHT_CONTROL_KEY : B_CONTROL_KEY, + map.right_control_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.right_control_key) item->SetMarked(true); + } - item = _SwapModifiersMenuItem(B_MENU_KEY, key->code, map.menu_key); - modifiersPopUp->AddItem(item); - if (key->code == map.menu_key) - item->SetMarked(true); + item = swap_modifiers_menu_item(fKeymap, B_MENU_KEY, B_MENU_KEY, + map.menu_key, key->code); + modifiersPopUp->AddItem(item); + if (key->code == map.menu_key) + item->SetMarked(true); - item = _SwapModifiersMenuItem(B_RIGHT_OPTION_KEY, key->code, - map.right_option_key); + if (is_right_modifier_key(key->code) || isLockKey) { + item = swap_modifiers_menu_item(fKeymap, B_RIGHT_OPTION_KEY, + isLockKey ? B_RIGHT_OPTION_KEY : B_OPTION_KEY, + map.right_option_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.right_option_key) item->SetMarked(true); - item = _SwapModifiersMenuItem(B_RIGHT_COMMAND_KEY, key->code, - map.right_command_key); + item = swap_modifiers_menu_item(fKeymap, B_RIGHT_COMMAND_KEY, + isLockKey ? B_RIGHT_COMMAND_KEY : B_COMMAND_KEY, + map.right_command_key, key->code); modifiersPopUp->AddItem(item); if (key->code == map.right_command_key) item->SetMarked(true); - - modifiersPopUp->AddSeparatorItem(); - - item = _SwapModifiersMenuItem(B_CAPS_LOCK, key->code, - map.caps_key); - modifiersPopUp->AddItem(item); - if (key->code == map.caps_key) - item->SetMarked(true); - - item = _SwapModifiersMenuItem(B_NUM_LOCK, key->code, map.num_key); - modifiersPopUp->AddItem(item); - if (key->code == map.num_key) - item->SetMarked(true); - - item = _SwapModifiersMenuItem(B_SCROLL_LOCK, key->code, - map.scroll_key); - modifiersPopUp->AddItem(item); - if (key->code == map.scroll_key) - item->SetMarked(true); - - modifiersPopUp->SetAsyncAutoDestruct(true); - if (modifiersPopUp->SetTargetForItems(Window()) == B_OK) - modifiersPopUp->Go(ConvertToScreen(point), true); } + + modifiersPopUp->AddSeparatorItem(); + + item = swap_modifiers_menu_item(fKeymap, B_CAPS_LOCK, B_CAPS_LOCK, + map.caps_key, key->code); + modifiersPopUp->AddItem(item); + if (key->code == map.caps_key) + item->SetMarked(true); + + item = swap_modifiers_menu_item(fKeymap, B_NUM_LOCK, B_NUM_LOCK, + map.num_key, key->code); + modifiersPopUp->AddItem(item); + if (key->code == map.num_key) + item->SetMarked(true); + + item = swap_modifiers_menu_item(fKeymap, B_SCROLL_LOCK, B_SCROLL_LOCK, + map.scroll_key, key->code); + modifiersPopUp->AddItem(item); + if (key->code == map.scroll_key) + item->SetMarked(true); + + modifiersPopUp->SetAsyncAutoDestruct(true); + if (modifiersPopUp->SetTargetForItems(Window()) == B_OK) + modifiersPopUp->Go(ConvertToScreen(point), true); } else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0 && (fButtons & B_TERTIARY_MOUSE_BUTTON) == 0) { - // toggle the "deadness" of dead keys via middle mouse button + // tertiary mouse button, toggle the "deadness" of dead keys bool isEnabled = false; uint8 deadKey = fKeymap->DeadKey(key->code, fModifiers, &isEnabled); if (deadKey > 0) { @@ -1276,72 +1414,3 @@ KeyboardLayoutView::_SendFakeKeyDown(const Key* key) fTarget.SendMessage(&message); } - - -BMenuItem* -KeyboardLayoutView::_SwapModifiersMenuItem(uint32 modifier, uint32 oldCode, - uint32 newCode) -{ - int32 mask = B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY; - const char* oldName = _NameForModifier(fKeymap->Modifier(oldCode) & ~mask); - const char* newName = _NameForModifier(fKeymap->Modifier(newCode) & ~mask); - - BMessage* message = new BMessage(kMsgUpdateModifierKeys); - message->AddUInt32(newName, oldCode); - message->AddUInt32(oldName, newCode); - - if (oldCode == newCode) - message->AddBool("unset", true); - - return new BMenuItem(_NameForModifier(modifier, true), message); -} - - -const char* -KeyboardLayoutView::_NameForModifier(uint32 modifier, bool pretty) const -{ - if (modifier == B_CAPS_LOCK) - return pretty ? B_TRANSLATE("Caps lock") : "caps_key"; - else if (modifier == B_NUM_LOCK) - return pretty ? B_TRANSLATE("Num lock") : "num_key"; - else if (modifier == B_SCROLL_LOCK) - return pretty ? B_TRANSLATE("Scroll lock") : "scroll_key"; - else if (modifier == B_LEFT_SHIFT_KEY) - return pretty ? B_TRANSLATE("Left shift") : "left_shift_key"; - else if (modifier == B_RIGHT_SHIFT_KEY) - return pretty ? B_TRANSLATE("Right shift") : "right_shift_key"; - else if (modifier == B_LEFT_COMMAND_KEY) - return pretty ? B_TRANSLATE("Left command") : "left_command_key"; - else if (modifier == B_RIGHT_COMMAND_KEY) - return pretty ? B_TRANSLATE("Right command") : "right_command_key"; - else if (modifier == B_LEFT_CONTROL_KEY) - return pretty ? B_TRANSLATE("Left control") : "left_control_key"; - else if (modifier == B_RIGHT_CONTROL_KEY) - return pretty ? B_TRANSLATE("Right control") : "right_control_key"; - else if (modifier == B_LEFT_OPTION_KEY) - return pretty ? B_TRANSLATE("Left option") : "left_option_key"; - else if (modifier == B_RIGHT_OPTION_KEY) - return pretty ? B_TRANSLATE("Right option") : "right_option_key"; - else if (modifier == B_MENU_KEY) - return pretty ? B_TRANSLATE_COMMENT("Menu", "Menu key") : "menu_key"; - - return NULL; -} - - -bool -KeyboardLayoutView::_IsMappableToModifierKey(uint32 keyCode) const -{ - return keyCode == 0x3b // caps lock - || keyCode == 0x22 // num lock - || keyCode == 0x0f // scroll lock - || keyCode == 0x4b // left shift - || keyCode == 0x56 // right shift - || keyCode == 0x5d // left command - || keyCode == 0x5f // right command - || keyCode == 0x5c // left control - || keyCode == 0x60 // right control - || keyCode == 0x66 // left option - || keyCode == 0x67 // right option - || keyCode == 0x68; // menu -} diff --git a/src/preferences/keymap/KeyboardLayoutView.h b/src/preferences/keymap/KeyboardLayoutView.h index bae153e031..738dbd8352 100644 --- a/src/preferences/keymap/KeyboardLayoutView.h +++ b/src/preferences/keymap/KeyboardLayoutView.h @@ -1,6 +1,11 @@ /* * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2013-2014 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * John Scipione, jscipione@gmail.com */ #ifndef KEYBOARD_LAYOUT_VIEW_H #define KEYBOARD_LAYOUT_VIEW_H @@ -92,11 +97,6 @@ private: void _SetFontSize(BView* view, key_kind keyKind); void _EvaluateDropTarget(BPoint point); void _SendFakeKeyDown(const Key* key); - BMenuItem* _SwapModifiersMenuItem(uint32 modifier, - uint32 oldCode, uint32 newCode); - const char* _NameForModifier(uint32 modifier, - bool pretty = false) const; - bool _IsMappableToModifierKey(uint32 keyCode) const; BBitmap* fOffscreenBitmap; BView* fOffscreenView; diff --git a/src/preferences/keymap/KeymapWindow.cpp b/src/preferences/keymap/KeymapWindow.cpp index 8a855460fa..bee9325d5e 100644 --- a/src/preferences/keymap/KeymapWindow.cpp +++ b/src/preferences/keymap/KeymapWindow.cpp @@ -1,12 +1,13 @@ /* - * Copyright 2004-2010 Haiku Inc. All rights reserved. + * Copyright 2004-2014 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: - * Sandor Vroemisse - * Jérôme Duval * Alexandre Deckner, alex@zappotek.com - * Axel Dörfler, axeld@pinc-software.de. + * Axel Dörfler, axeld@pinc-software.de + * Jérôme Duval + * John Scipione, jscipione@gmai.com + * Sandor Vroemisse */ @@ -325,55 +326,57 @@ KeymapWindow::MessageReceived(BMessage* message) if (message->FindBool("unset", &unset) != B_OK) unset = false; - if (message->FindUInt32("left_shift_key", &keyCode) == B_OK) - fCurrentMap.SetModifier(unset ? 0 : keyCode, B_LEFT_SHIFT_KEY); + if (message->FindUInt32("left_shift_key", &keyCode) == B_OK) { + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, + B_LEFT_SHIFT_KEY); + } if (message->FindUInt32("right_shift_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_RIGHT_SHIFT_KEY); } if (message->FindUInt32("left_control_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_LEFT_CONTROL_KEY); } if (message->FindUInt32("right_control_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_RIGHT_CONTROL_KEY); } if (message->FindUInt32("left_option_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_LEFT_OPTION_KEY); } if (message->FindUInt32("right_option_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_RIGHT_OPTION_KEY); } if (message->FindUInt32("left_command_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_LEFT_COMMAND_KEY); } if (message->FindUInt32("right_command_key", &keyCode) == B_OK) { - fCurrentMap.SetModifier(unset ? 0 : keyCode, + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_RIGHT_COMMAND_KEY); } if (message->FindUInt32("menu_key", &keyCode) == B_OK) - fCurrentMap.SetModifier(unset ? 0 : keyCode, B_MENU_KEY); + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_MENU_KEY); if (message->FindUInt32("caps_key", &keyCode) == B_OK) - fCurrentMap.SetModifier(unset ? 0 : keyCode, B_CAPS_LOCK); + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_CAPS_LOCK); if (message->FindUInt32("num_key", &keyCode) == B_OK) - fCurrentMap.SetModifier(unset ? 0 : keyCode, B_NUM_LOCK); + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_NUM_LOCK); if (message->FindUInt32("scroll_key", &keyCode) == B_OK) - fCurrentMap.SetModifier(unset ? 0 : keyCode, B_SCROLL_LOCK); + fCurrentMap.SetModifier(unset ? 0x00 : keyCode, B_SCROLL_LOCK); _UpdateButtons(); fKeyboardLayoutView->SetKeymap(&fCurrentMap); diff --git a/src/preferences/keymap/KeymapWindow.h b/src/preferences/keymap/KeymapWindow.h index 1ef7dc5839..366ba0756f 100644 --- a/src/preferences/keymap/KeymapWindow.h +++ b/src/preferences/keymap/KeymapWindow.h @@ -1,12 +1,13 @@ /* - * Copyright 2004-2009 Haiku Inc. All rights reserved. + * Copyright 2004-2014 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: - * Sandor Vroemisse - * Jérôme Duval * Alexandre Deckner, alex@zappotek.com - * Axel Dörfler, axeld@pinc-software.de. + * Axel Dörfler, axeld@pinc-software.de + * Jérôme Duval + * John Scipione, jscipione@gmai.com + * Sandor Vroemisse */ #ifndef KEYMAP_WINDOW_H #define KEYMAP_WINDOW_H