Ticket #7965: Keymap_modifiers_menu_2.diff

File Keymap_modifiers_menu_2.diff, 14.4 KB (added by jscipione, 13 years ago)

This patch changes "Set modifier keys" to "Select modifier keys". Since I can't reliably return you to a known state if you have custom keymaps set I simply disable the other menu options in this case. So you can switch between Haiku mode, Win/LInux mode, and Mac mode freely, but if you do something custom you are on your own.

  • src/preferences/keymap/KeymapWindow.cpp

    diff --git src/preferences/keymap/KeymapWindow.cpp src/preferences/keymap/KeymapWindow.cpp
    index 62924a2..7a2bd5c 100644
     
    2828#include <MenuField.h>
    2929#include <MenuItem.h>
    3030#include <Path.h>
    31 #include <PopUpMenu.h>
    3231#include <Screen.h>
    3332#include <ScrollView.h>
    3433#include <StringView.h>
    static const uint32 kMsgMenuFileSaveAs = 'mMFA';  
    4746
    4847static const uint32 kChangeKeyboardLayout = 'cKyL';
    4948
    50 static const uint32 kMsgSwitchShortcuts = 'swSc';
     49static const uint32 kMsgModifiersHaiku = 'mHku';
     50static const uint32 kMsgModifiersWinLinux = 'mW/L';
     51static const uint32 kMsgModifiersMac = 'mMac';
    5152
    5253static const uint32 kMsgMenuFontChanged = 'mMFC';
    5354
    static const char* kDeadKeyTriggerNone = "<none>";  
    6768
    6869static const char* kCurrentKeymapName = "(Current)";
    6970
     71static const uint32 kLeftControlKey  = 0x5c;
     72static const uint32 kLeftOptionKey   = 0x66;
     73static const uint32 kLeftCommandKey  = 0x5d;
     74static const uint32 kRightControlKey = 0x60;
     75static const uint32 kRightOptionKey  = 0x67;
     76static const uint32 kRightCommandKey = 0x5f;
     77
     78enum {
     79    MODIFIERS_HAIKU,
     80    MODIFIERS_WIN_LINUX,
     81    MODIFIERS_MAC,
     82    MODIFIERS_CUSTOM
     83};
    7084
    7185KeymapWindow::KeymapWindow()
    7286    :
    KeymapWindow::KeymapWindow()  
    8195    fTextControl = new BTextControl(B_TRANSLATE("Sample and clipboard:"),
    8296        "", NULL);
    8397
    84     fSwitchShortcutsButton = new BButton("switch", "",
    85         new BMessage(kMsgSwitchShortcuts));
    86 
    8798    fRevertButton = new BButton("revertButton", B_TRANSLATE("Revert"),
    8899        new BMessage(kMsgRevertKeymap));
    89100
    KeymapWindow::KeymapWindow()  
    98109                .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
    99110                    .Add(_CreateDeadKeyMenuField(), 0.0)
    100111                    .AddGlue()
    101                     .Add(fSwitchShortcutsButton))
     112                    .Add(_CreateModifiersMenuField(), 0.0))
    102113                .Add(fTextControl)
    103114                .AddGlue(0.0)
    104115                .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
    KeymapWindow::KeymapWindow()  
    152163    fAppliedMap = fCurrentMap;
    153164    fCurrentMap.SetTarget(this, new BMessage(kMsgKeymapUpdated));
    154165
    155     _UpdateButtons();
    156 
    157     _UpdateDeadKeyMenu();
    158     _UpdateSwitchShortcutButton();
     166    _UpdateControls();
    159167
    160168    Unlock();
    161169}
    KeymapWindow::MessageReceived(BMessage* message)  
    234242            break;
    235243        }
    236244
    237         case kMsgSwitchShortcuts:
    238             _SwitchShortcutKeys();
     245        case kMsgModifiersHaiku:
     246            _SetModifiers(MODIFIERS_HAIKU);
     247            break;
     248
     249        case kMsgModifiersWinLinux:
     250            _SetModifiers(MODIFIERS_WIN_LINUX);
     251            break;
     252
     253        case kMsgModifiersMac:
     254            _SetModifiers(MODIFIERS_MAC);
    239255            break;
    240256
    241257        case kMsgMenuFontChanged:
    KeymapWindow::MessageReceived(BMessage* message)  
    283299                fAppliedMap = fCurrentMap;
    284300                fKeyboardLayoutView->SetKeymap(&fCurrentMap);
    285301                _UseKeymap();
    286                 _UpdateButtons();
     302                _UpdateControls();
    287303            }
    288304            break;
    289305        }
    290306
    291307        case kMsgRevertKeymap:
    292308            _RevertKeymap();
    293             _UpdateButtons();
     309            _UpdateControls();
    294310            break;
    295311
    296312        case kMsgKeymapUpdated:
    297             _UpdateButtons();
     313            _UpdateControls();
    298314            fSystemListView->DeselectAll();
    299315            fUserListView->Select(0L);
    300316            break;
    KeymapWindow::_CreateMenu()  
    429445BMenuField*
    430446KeymapWindow::_CreateDeadKeyMenuField()
    431447{
    432     BPopUpMenu* deadKeyMenu = new BPopUpMenu(B_TRANSLATE("Select dead keys"),
    433         false, false);
     448    BMenu* deadKeyMenu = new BMenu(B_TRANSLATE("Select dead keys"));
    434449
    435450    fAcuteMenu = new BMenu(B_TRANSLATE("Acute trigger"));
    436451    fAcuteMenu->SetRadioMode(true);
    KeymapWindow::_CreateDeadKeyMenuField()  
    480495}
    481496
    482497
     498BMenuField*
     499KeymapWindow::_CreateModifiersMenuField()
     500{
     501    fModifiersMenu = new BMenu(B_TRANSLATE("Select modifier keys"));
     502    fModifiersMenu->SetRadioMode(true);
     503    fModifiersMenu->SetLabelFromMarked(false);
     504
     505    fModifiersMenu->AddItem(
     506        new BMenuItem(B_TRANSLATE("Haiku modifier keys"),
     507            new BMessage(kMsgModifiersHaiku)), MODIFIERS_HAIKU);
     508    fModifiersMenu->AddItem(
     509        new BMenuItem(B_TRANSLATE("Windows/Linux modifier keys"),
     510            new BMessage(kMsgModifiersWinLinux)), MODIFIERS_WIN_LINUX);
     511    fModifiersMenu->AddItem(
     512        new BMenuItem(B_TRANSLATE("Mac modifier keys"),
     513            new BMessage(kMsgModifiersMac)), MODIFIERS_MAC);
     514
     515    return new BMenuField(NULL, fModifiersMenu);
     516}
     517
     518
    483519BView*
    484520KeymapWindow::_CreateMapLists()
    485521{
    KeymapWindow::_SetKeyboardLayout(const char* path)  
    584620}
    585621
    586622
    587 /*! Sets the label of the "Switch Shorcuts" button to make it more
    588     descriptive what will happen when you press that button.
    589 */
     623/*! Marks the item in the modifiers menu to the current mode */
    590624void
    591 KeymapWindow::_UpdateSwitchShortcutButton()
     625KeymapWindow::_UpdateModifiersMenu()
    592626{
    593     const char* label = B_TRANSLATE("Switch shortcut keys");
    594     if (fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY) == 0x5d
    595         && fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY) == 0x5c) {
    596         label = B_TRANSLATE("Switch shortcut keys to Windows/Linux mode");
    597     } else if (fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY) == 0x5c
    598         && fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY) == 0x5d) {
    599         label = B_TRANSLATE("Switch shortcut keys to Haiku mode");
     627    // Enable the default items (diabled again if custom keymap)
     628    fModifiersMenu->ItemAt(MODIFIERS_HAIKU)->SetEnabled(true);
     629    fModifiersMenu->ItemAt(MODIFIERS_WIN_LINUX)->SetEnabled(true);
     630    fModifiersMenu->ItemAt(MODIFIERS_MAC)->SetEnabled(true);
     631    // Remove the custom item (added back if custom keymap)
     632    fModifiersMenu->RemoveItem(MODIFIERS_CUSTOM);
     633
     634    // To be in a mode the modifier keys must either be unmapped (== 0),
     635    // or mapped to the keys for the mode.
     636    if (_HaikuMode())
     637        fModifiersMenu->ItemAt(MODIFIERS_HAIKU)->SetMarked(true);
     638    else if (_WinLinuxMode())
     639        fModifiersMenu->ItemAt(MODIFIERS_WIN_LINUX)->SetMarked(true);
     640    else if (_MacMode())
     641        fModifiersMenu->ItemAt(MODIFIERS_MAC)->SetMarked(true);
     642    else {
     643        // Custom modifier settings
     644
     645        // Disable the default menu items
     646        fModifiersMenu->ItemAt(MODIFIERS_HAIKU)->SetEnabled(false);
     647        fModifiersMenu->ItemAt(MODIFIERS_WIN_LINUX)->SetEnabled(false);
     648        fModifiersMenu->ItemAt(MODIFIERS_MAC)->SetEnabled(false);
     649
     650        // Add custom menu item to the menu and mark it
     651        fModifiersMenu->AddItem(new BMenuItem(B_TRANSLATE("Custom"), NULL),
     652            MODIFIERS_CUSTOM);
     653        fModifiersMenu->ItemAt(MODIFIERS_CUSTOM)->SetMarked(true);
    600654    }
    601 
    602     fSwitchShortcutsButton->SetLabel(label);
    603655}
    604656
    605657
    KeymapWindow::_UpdateDeadKeyMenu()  
    648700
    649701
    650702void
    651 KeymapWindow::_UpdateButtons()
     703KeymapWindow::_UpdateControls()
    652704{
    653705    if (fCurrentMap != fAppliedMap) {
    654706        fCurrentMap.SetName(kCurrentKeymapName);
    KeymapWindow::_UpdateButtons()  
    658710    fRevertButton->SetEnabled(fCurrentMap != fPreviousMap);
    659711
    660712    _UpdateDeadKeyMenu();
    661     _UpdateSwitchShortcutButton();
     713    _UpdateModifiersMenu();
    662714}
    663715
    664716
     717/*! Set the modifiers keys */
    665718void
    666 KeymapWindow::_SwitchShortcutKeys()
     719KeymapWindow::_SetModifiers(uint8 mode)
    667720{
    668     uint32 leftCommand = fCurrentMap.Map().left_command_key;
    669     uint32 leftControl = fCurrentMap.Map().left_control_key;
    670     uint32 rightCommand = fCurrentMap.Map().right_command_key;
    671     uint32 rightControl = fCurrentMap.Map().right_control_key;
     721    key_map& keyMap = fCurrentMap.Map();
     722
     723    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     724    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     725    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     726    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     727    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     728    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     729
     730    if (_HaikuMode()) {
     731        switch (mode) {
     732            case MODIFIERS_HAIKU:
     733                // switching from Haiku mode to Haiku mode
     734                return;
     735
     736            case MODIFIERS_WIN_LINUX:
     737                // switching from Haiku mode to Windows/Linux mode
     738                // swap command and control keys
     739
     740                // swap left side
     741                keyMap.left_control_key = leftCommand;
     742                keyMap.left_command_key = leftControl;
     743
     744                // swap right side
     745                keyMap.right_control_key = rightCommand;
     746                keyMap.right_command_key = rightControl;
     747                break;
     748
     749            case MODIFIERS_MAC:
     750                // switching from Haiku mode to Mac mode
     751                // swap command and option keys
     752
     753                // swap left side
     754                keyMap.left_command_key = leftOption;
     755                keyMap.left_option_key = leftCommand;
     756
     757                // swap right side
     758                keyMap.right_command_key = rightOption;
     759                keyMap.right_option_key = rightCommand;
     760                break;
     761        }
     762    } else if (_WinLinuxMode()) {
     763        switch (mode) {
     764            case MODIFIERS_HAIKU:
     765                // switching from Windows/Linux mode to Haiku mode
     766                // swap command and control keys
     767
     768                // swap left side
     769                keyMap.left_control_key = leftCommand;
     770                keyMap.left_command_key = leftControl;
     771
     772                // swap right side
     773                keyMap.right_control_key = rightCommand;
     774                keyMap.right_command_key = rightControl;
     775                break;
    672776
    673     // switch left side
    674     fCurrentMap.Map().left_command_key = leftControl;
    675     fCurrentMap.Map().left_control_key = leftCommand;
     777            case MODIFIERS_WIN_LINUX:
     778                // switching from Windows/Linux mode to Windows/Linux mode
     779                return;
    676780
    677     // switch right side
    678     fCurrentMap.Map().right_command_key = rightControl;
    679     fCurrentMap.Map().right_control_key = rightCommand;
     781            case MODIFIERS_MAC:
     782                // switching from Windows/Linux mode to Mac mode
     783                // swap control and option keys
     784                // then swap command and option keys
     785
     786                // swap left side
     787                keyMap.left_control_key = leftCommand;
     788                keyMap.left_command_key = leftOption;
     789                keyMap.left_option_key = leftControl;
     790
     791                // swap right side
     792                keyMap.right_control_key = rightCommand;
     793                keyMap.right_command_key = rightOption;
     794                keyMap.right_option_key = rightControl;
     795                break;
     796        }
     797    } else if (_MacMode()) {
     798        switch (mode) {
     799            case MODIFIERS_HAIKU:
     800                // switching from Mac mode to Haiku mode
     801                // swap command and option keys
     802
     803                // swap left side
     804                keyMap.left_command_key = leftOption;
     805                keyMap.left_option_key = leftCommand;
     806
     807                // swap right side
     808                keyMap.right_command_key = rightOption;
     809                keyMap.right_option_key = rightCommand;
     810                break;
     811
     812            case MODIFIERS_WIN_LINUX:
     813                // switching from Mac mode to Windows/Linux mode
     814                // swap control and command
     815                // then swap command and option
     816
     817                // switch left side
     818                keyMap.left_control_key = leftOption;
     819                keyMap.left_command_key = leftControl;
     820                keyMap.left_option_key = leftCommand;
     821
     822                // switch right side
     823                keyMap.right_control_key = rightOption;
     824                keyMap.right_command_key = rightControl;
     825                keyMap.right_option_key = rightCommand;
     826                break;
     827
     828            case MODIFIERS_MAC:
     829                return;
     830        }
     831    }
    680832
    681833    fKeyboardLayoutView->SetKeymap(&fCurrentMap);
    682     _UpdateButtons();
     834    _UpdateControls();
    683835}
    684836
    685837
    KeymapWindow::_SaveSettings() const  
    9431095
    9441096    return settings.Flatten(&file);
    9451097}
     1098
     1099
     1100bool
     1101KeymapWindow::_HaikuMode()
     1102{
     1103    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1104    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1105    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1106    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1107    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1108    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1109
     1110    return leftControl == kLeftControlKey && leftCommand == kLeftCommandKey
     1111        && leftOption == kLeftOptionKey
     1112        && (rightControl == kRightControlKey || rightControl == 0)
     1113        && (rightCommand == kRightCommandKey || rightCommand == kRightOptionKey
     1114            || rightCommand == 0)
     1115        && (rightOption == kRightOptionKey || rightOption == kRightCommandKey
     1116            || rightOption == 0);
     1117}
     1118
     1119
     1120bool
     1121KeymapWindow::_WinLinuxMode()
     1122{
     1123    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1124    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1125    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1126    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1127    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1128    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1129
     1130    return leftControl == kLeftCommandKey && leftCommand == kLeftControlKey
     1131        && leftOption == kLeftOptionKey
     1132        && (rightControl == kRightCommandKey || rightControl == kRightOptionKey ||
     1133            rightControl == 0)
     1134        && (rightCommand == kRightControlKey || rightCommand == 0)
     1135        && (rightOption == kRightOptionKey || rightOption == kRightCommandKey
     1136            || rightOption == 0);
     1137}
     1138
     1139
     1140bool
     1141KeymapWindow::_MacMode()
     1142{
     1143    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1144    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1145    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1146    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1147    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1148    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1149
     1150    return leftControl == kLeftControlKey && leftCommand == kLeftOptionKey
     1151        && leftOption == kLeftCommandKey
     1152        && (rightControl == kRightControlKey || rightControl == 0)
     1153        && (rightCommand == kRightOptionKey || rightCommand == kRightCommandKey
     1154            || rightCommand == 0)
     1155        && (rightOption == kRightCommandKey || rightCommand == kRightOptionKey
     1156            || rightOption == 0);
     1157}
  • src/preferences/keymap/KeymapWindow.h

    diff --git src/preferences/keymap/KeymapWindow.h src/preferences/keymap/KeymapWindow.h
    index cc6cb4b..1091d0b 100644
    protected:  
    4242            void                _AddKeyboardLayouts(BMenu* menu);
    4343            status_t            _SetKeyboardLayout(const char* path);
    4444
    45             void                _UpdateSwitchShortcutButton();
    46             void                _UpdateButtons();
    47             void                _SwitchShortcutKeys();
     45            void                _UpdateModifiersMenu();
     46            void                _UpdateControls();
     47
     48            void                _SetModifiers(uint8);
    4849
    4950            void                _UseKeymap();
    5051            void                _RevertKeymap();
    5152
    5253            BMenuField*         _CreateDeadKeyMenuField();
     54            BMenuField*         _CreateModifiersMenuField();
    5355            void                _UpdateDeadKeyMenu();
    5456
    5557            void                _FillSystemMaps();
    protected:  
    6769            status_t            _SaveSettings() const;
    6870
    6971private:
     72            bool                _HaikuMode();
     73            bool                _WinLinuxMode();
     74            bool                _MacMode();
     75
    7076            BListView*          fSystemListView;
    7177            BListView*          fUserListView;
    7278            BButton*            fRevertButton;
    private:  
    7480            BMenu*              fFontMenu;
    7581            KeyboardLayoutView* fKeyboardLayoutView;
    7682            BTextControl*       fTextControl;
    77             BButton*            fSwitchShortcutsButton;
     83            BMenu*              fModifiersMenu;
    7884            BMenu*              fAcuteMenu;
    7985            BMenu*              fCircumflexMenu;
    8086            BMenu*              fDiaeresisMenu;