Ticket #7965: Keymap_modifiers_menu_1.diff

File Keymap_modifiers_menu_1.diff, 15.8 KB (added by jscipione, 13 years ago)

Replaces the "Switch Shortcuts to Windows/Linux" button with a drop down that switches between Haiku modifiers, Windows/Linux modifiers, and Mac modifiers.

  • src/preferences/keymap/KeymapWindow.cpp

    diff --git src/preferences/keymap/KeymapWindow.cpp src/preferences/keymap/KeymapWindow.cpp
    index 62924a2..872d9e6 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 =
     502        new BMenu(B_TRANSLATE("Set modifier keys"));
     503    fModifiersMenu->SetRadioMode(true);
     504    fModifiersMenu->SetLabelFromMarked(false);
     505
     506    fModifiersMenu->AddItem(
     507        new BMenuItem(B_TRANSLATE("Haiku modifier keys"),
     508            new BMessage(kMsgModifiersHaiku)), MODIFIERS_HAIKU);
     509    fModifiersMenu->AddItem(
     510        new BMenuItem(B_TRANSLATE("Windows/Linux modifier keys"),
     511            new BMessage(kMsgModifiersWinLinux)), MODIFIERS_WIN_LINUX);
     512    fModifiersMenu->AddItem(
     513        new BMenuItem(B_TRANSLATE("Mac modifier keys"),
     514            new BMessage(kMsgModifiersMac)), MODIFIERS_MAC);
     515
     516    return new BMenuField(NULL, fModifiersMenu);
     517}
     518
     519
    483520BView*
    484521KeymapWindow::_CreateMapLists()
    485522{
    KeymapWindow::_SetKeyboardLayout(const char* path)  
    584621}
    585622
    586623
    587 /*! Sets the label of the "Switch Shorcuts" button to make it more
    588     descriptive what will happen when you press that button.
    589 */
     624/*! Marks the item in the modifiers menu to the current mode */
    590625void
    591 KeymapWindow::_UpdateSwitchShortcutButton()
     626KeymapWindow::_UpdateModifiersMenu()
    592627{
    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");
     628    // Remove the custom item (may be added back)
     629    fModifiersMenu->RemoveItem(MODIFIERS_CUSTOM);
     630
     631    // To be in a mode the modifier keys must either be unmapped (== 0),
     632    // or mapped to the keys for the mode.
     633    if (_HaikuMode())
     634        fModifiersMenu->ItemAt(MODIFIERS_HAIKU)->SetMarked(true);
     635    else if (_WinLinuxMode())
     636        fModifiersMenu->ItemAt(MODIFIERS_WIN_LINUX)->SetMarked(true);
     637    else if (_MacMode())
     638        fModifiersMenu->ItemAt(MODIFIERS_MAC)->SetMarked(true);
     639    else {
     640        // Custom modifiers setting
     641        fModifiersMenu->AddItem(new BMenuItem(B_TRANSLATE("Custom"), NULL),
     642            MODIFIERS_CUSTOM);
     643        fModifiersMenu->ItemAt(MODIFIERS_CUSTOM)->SetMarked(true);
    600644    }
    601 
    602     fSwitchShortcutsButton->SetLabel(label);
    603645}
    604646
    605647
    KeymapWindow::_UpdateDeadKeyMenu()  
    648690
    649691
    650692void
    651 KeymapWindow::_UpdateButtons()
     693KeymapWindow::_UpdateControls()
    652694{
    653695    if (fCurrentMap != fAppliedMap) {
    654696        fCurrentMap.SetName(kCurrentKeymapName);
    KeymapWindow::_UpdateButtons()  
    658700    fRevertButton->SetEnabled(fCurrentMap != fPreviousMap);
    659701
    660702    _UpdateDeadKeyMenu();
    661     _UpdateSwitchShortcutButton();
     703    _UpdateModifiersMenu();
    662704}
    663705
    664706
     707/*! Set the modifiers keys */
    665708void
    666 KeymapWindow::_SwitchShortcutKeys()
     709KeymapWindow::_SetModifiers(uint8 mode)
    667710{
    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;
     711    key_map& keyMap = fCurrentMap.Map();
     712
     713    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     714    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     715    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     716    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     717    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     718    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     719
     720    if (_HaikuMode()) {
     721        switch (mode) {
     722            case MODIFIERS_HAIKU:
     723                // switching from Haiku mode to Haiku mode
     724                return;
     725
     726            case MODIFIERS_WIN_LINUX:
     727                // switching from Haiku mode to Windows/Linux mode
     728                // swap command and control keys
     729
     730                // swap left side
     731                keyMap.left_control_key = leftCommand;
     732                keyMap.left_command_key = leftControl;
     733
     734                // swap right side
     735                keyMap.right_control_key = rightCommand;
     736                keyMap.right_command_key = rightControl;
     737                break;
    672738
    673     // switch left side
    674     fCurrentMap.Map().left_command_key = leftControl;
    675     fCurrentMap.Map().left_control_key = leftCommand;
     739            case MODIFIERS_MAC:
     740                // switching from Haiku mode to Mac mode
     741                // swap command and option keys
    676742
    677     // switch right side
    678     fCurrentMap.Map().right_command_key = rightControl;
    679     fCurrentMap.Map().right_control_key = rightCommand;
     743                // swap left side
     744                keyMap.left_command_key = leftOption;
     745                keyMap.left_option_key = leftCommand;
     746
     747                // swap right side
     748                keyMap.right_command_key = rightOption;
     749                keyMap.right_option_key = rightCommand;
     750                break;
     751        }
     752    } else if (_WinLinuxMode()) {
     753        switch (mode) {
     754            case MODIFIERS_HAIKU:
     755                // switching from Windows/Linux mode to Haiku mode
     756                // swap command and control keys
     757
     758                // swap left side
     759                keyMap.left_control_key = leftCommand;
     760                keyMap.left_command_key = leftControl;
     761
     762                // swap right side
     763                keyMap.right_control_key = rightCommand;
     764                keyMap.right_command_key = rightControl;
     765                break;
     766
     767            case MODIFIERS_WIN_LINUX:
     768                // switching from Windows/Linux mode to Windows/Linux mode
     769                return;
     770
     771            case MODIFIERS_MAC:
     772                // switching from Windows/Linux mode to Mac mode
     773                // swap control and option keys
     774                // then swap command and option keys
     775
     776                // swap left side
     777                keyMap.left_control_key = leftCommand;
     778                keyMap.left_command_key = leftOption;
     779                keyMap.left_option_key = leftControl;
     780
     781                // swap right side
     782                keyMap.right_control_key = rightCommand;
     783                keyMap.right_command_key = rightOption;
     784                keyMap.right_option_key = rightControl;
     785                break;
     786        }
     787    } else if (_MacMode()) {
     788        switch (mode) {
     789            case MODIFIERS_HAIKU:
     790                // switching from Mac mode to Haiku mode
     791                // swap command and option keys
     792
     793                // swap left side
     794                keyMap.left_command_key = leftOption;
     795                keyMap.left_option_key = leftCommand;
     796
     797                // swap right side
     798                keyMap.right_command_key = rightOption;
     799                keyMap.right_option_key = rightCommand;
     800                break;
     801
     802            case MODIFIERS_WIN_LINUX:
     803                // switching from Mac mode to Windows/Linux mode
     804                // swap control and command
     805                // then swap command and option
     806
     807                // switch left side
     808                keyMap.left_control_key = leftOption;
     809                keyMap.left_command_key = leftControl;
     810                keyMap.left_option_key = leftCommand;
     811
     812                // switch right side
     813                keyMap.right_control_key = rightOption;
     814                keyMap.right_command_key = rightControl;
     815                keyMap.right_option_key = rightCommand;
     816                break;
     817
     818            case MODIFIERS_MAC:
     819                return;
     820        }
     821    } else { // Custom
     822        switch (mode) {
     823            // Set modifiers to Haiku mode, the default
     824            case MODIFIERS_HAIKU:
     825                // switch left side
     826                keyMap.left_control_key = kLeftControlKey;
     827                keyMap.left_command_key = kLeftCommandKey;
     828                keyMap.left_option_key  = kLeftOptionKey;
     829
     830                // switch right side
     831                keyMap.right_control_key = kRightControlKey;
     832                if (keyMap.right_control_key == 0
     833                    || keyMap.right_command_key == 0
     834                    || keyMap.right_option_key == 0) {
     835                    keyMap.right_command_key = 0;
     836                    keyMap.right_option_key  = kRightCommandKey;
     837                } else {
     838                    keyMap.right_command_key = kRightCommandKey;
     839                    keyMap.right_option_key  = kRightOptionKey;
     840                }
     841
     842                break;
     843
     844            // Set modifiers to Win/Linux mode, swap control and command
     845            case MODIFIERS_WIN_LINUX:
     846                // switch left side
     847                keyMap.left_control_key = kLeftCommandKey;
     848                keyMap.left_command_key = kLeftControlKey;
     849                keyMap.left_option_key  = kLeftOptionKey;
     850
     851                // switch right side
     852                keyMap.right_command_key = kRightControlKey;
     853                if (keyMap.right_control_key == 0
     854                    || keyMap.right_command_key == 0
     855                    || keyMap.right_option_key == 0) {
     856                    keyMap.right_control_key = 0;
     857                    keyMap.right_option_key  = kRightCommandKey;
     858                } else {
     859                    keyMap.right_control_key = kRightCommandKey;
     860                    keyMap.right_option_key  = kRightOptionKey;
     861                }
     862
     863                break;
     864
     865            // Set modifiers to Mac mode swap option and command
     866            case MODIFIERS_MAC:
     867                // switch left side
     868                keyMap.left_control_key  = kLeftControlKey;
     869                keyMap.left_command_key  = kLeftOptionKey;
     870                keyMap.left_option_key   = kLeftCommandKey;
     871
     872                // switch right side
     873                keyMap.right_control_key = kRightControlKey;
     874                if (keyMap.right_control_key == 0
     875                    || keyMap.right_command_key == 0
     876                    || keyMap.right_option_key == 0) {
     877                    keyMap.right_command_key = kRightCommandKey;
     878                    keyMap.right_option_key  = 0;
     879                } else {
     880                    keyMap.right_command_key = kRightOptionKey;
     881                    keyMap.right_option_key  = kRightCommandKey;
     882                }
     883
     884                break;
     885        }
     886    }
    680887
    681888    fKeyboardLayoutView->SetKeymap(&fCurrentMap);
    682     _UpdateButtons();
     889    _UpdateControls();
    683890}
    684891
    685892
    KeymapWindow::_SaveSettings() const  
    9431150
    9441151    return settings.Flatten(&file);
    9451152}
     1153
     1154
     1155bool
     1156KeymapWindow::_HaikuMode()
     1157{
     1158    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1159    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1160    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1161    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1162    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1163    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1164
     1165    return leftControl == kLeftControlKey && leftCommand == kLeftCommandKey
     1166        && leftOption == kLeftOptionKey
     1167        && (rightControl == kRightControlKey || rightControl == 0)
     1168        && (rightCommand == kRightCommandKey || rightCommand == kRightOptionKey
     1169            || rightCommand == 0)
     1170        && (rightOption == kRightOptionKey || rightOption == kRightCommandKey
     1171            || rightOption == 0);
     1172}
     1173
     1174
     1175bool
     1176KeymapWindow::_WinLinuxMode()
     1177{
     1178    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1179    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1180    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1181    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1182    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1183    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1184
     1185    return leftControl == kLeftCommandKey && leftCommand == kLeftControlKey
     1186        && leftOption == kLeftOptionKey
     1187        && (rightControl == kRightCommandKey || rightControl == kRightOptionKey ||
     1188            rightControl == 0)
     1189        && (rightCommand == kRightControlKey || rightCommand == 0)
     1190        && (rightOption == kRightOptionKey || rightOption == kRightCommandKey
     1191            || rightOption == 0);
     1192}
     1193
     1194
     1195bool
     1196KeymapWindow::_MacMode()
     1197{
     1198    uint32 leftControl = fCurrentMap.KeyForModifier(B_LEFT_CONTROL_KEY);
     1199    uint32 leftCommand = fCurrentMap.KeyForModifier(B_LEFT_COMMAND_KEY);
     1200    uint32 leftOption = fCurrentMap.KeyForModifier(B_LEFT_OPTION_KEY);
     1201    uint32 rightControl = fCurrentMap.KeyForModifier(B_RIGHT_CONTROL_KEY);
     1202    uint32 rightCommand = fCurrentMap.KeyForModifier(B_RIGHT_COMMAND_KEY);
     1203    uint32 rightOption = fCurrentMap.KeyForModifier(B_RIGHT_OPTION_KEY);
     1204
     1205    return leftControl == kLeftControlKey && leftCommand == kLeftOptionKey
     1206        && leftOption == kLeftCommandKey
     1207        && (rightControl == kRightControlKey || rightControl == 0)
     1208        && (rightCommand == kRightOptionKey || rightCommand == kRightCommandKey
     1209            || rightCommand == 0)
     1210        && (rightOption == kRightCommandKey || rightCommand == kRightOptionKey
     1211            || rightOption == 0);
     1212}
  • 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;