From 3a0a5a7754b2fbfac99c2affd0289ea7c889d31b Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Fri, 8 May 2020 17:34:24 -0700 Subject: [PATCH] KBM - UI Tweaks (#2798) * Fixed foreground issue and added arrow * Tweaked Remap Keyboard UI * Fix errors in warning handling and update UI layout * Tweaked sizes and centered to screen * Changed size to scale based on resolution * Fixed comments --- .../Strings/en-us/Resources.resw | 8 +-- .../keyboardmanager/common/Helpers.cpp | 2 +- .../common/KeyboardManagerConstants.h | 37 +++++++++++ .../keyboardmanager/common/Shortcut.cpp | 35 +++++------ .../keyboardmanager/ui/EditKeyboardWindow.cpp | 58 +++++++++++------ .../ui/EditShortcutsWindow.cpp | 63 ++++++++++++------- .../keyboardmanager/ui/KeyDropDownControl.cpp | 29 +++++---- .../keyboardmanager/ui/ShortcutControl.cpp | 35 +++++++---- .../keyboardmanager/ui/ShortcutControl.h | 3 +- .../ui/SingleKeyRemapControl.cpp | 36 +++++++---- .../ui/SingleKeyRemapControl.h | 1 + 11 files changed, 209 insertions(+), 98 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index 0bac7bad9d..ef1625a5a0 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -186,12 +186,12 @@ Keyboard Manager remap keyboard header - Redefine a shortcut - Keyboard Manager edit shortcuts button + Remap a shortcut + Keyboard Manager remap shortcuts button - Edit Shortcuts - Keyboard Manager edit shortcuts header + Remap Shortcuts + Keyboard Manager remap shortcuts header A quick launcher that has additional capabilities without sacrificing performance. diff --git a/src/modules/keyboardmanager/common/Helpers.cpp b/src/modules/keyboardmanager/common/Helpers.cpp index cc9d065d4e..e6f267105c 100644 --- a/src/modules/keyboardmanager/common/Helpers.cpp +++ b/src/modules/keyboardmanager/common/Helpers.cpp @@ -102,7 +102,7 @@ namespace KeyboardManagerHelper else if ((GetKeyType(first) == GetKeyType(second)) && GetKeyType(first) != KeyType::Action) { // If the keys are of the same modifier type and overlapping, i.e. one is L/R and other is common - if ((first == VK_LWIN && second == VK_RWIN) || (first == VK_LCONTROL && second == VK_RCONTROL) || (first == VK_LMENU && second == VK_RMENU) || (first == VK_LSHIFT && second == VK_RSHIFT)) + if (((first == VK_LWIN && second == VK_RWIN) || (first == VK_RWIN && second == VK_LWIN)) || ((first == VK_LCONTROL && second == VK_RCONTROL) || (first == VK_RCONTROL && second == VK_LCONTROL)) || ((first == VK_LMENU && second == VK_RMENU) || (first == VK_RMENU && second == VK_LMENU)) || ((first == VK_LSHIFT && second == VK_RSHIFT) || (first == VK_RSHIFT && second == VK_LSHIFT))) { return ErrorType::NoError; } diff --git a/src/modules/keyboardmanager/common/KeyboardManagerConstants.h b/src/modules/keyboardmanager/common/KeyboardManagerConstants.h index 38a5ddcaa7..13c0dcda19 100644 --- a/src/modules/keyboardmanager/common/KeyboardManagerConstants.h +++ b/src/modules/keyboardmanager/common/KeyboardManagerConstants.h @@ -38,4 +38,41 @@ namespace KeyboardManagerConstants // Initial value for tooltip inline const winrt::hstring ToolTipInitialContent = L"Initialised"; + + // Minimum and maximum size of a shortcut + inline const long MinShortcutSize = 2; + inline const long MaxShortcutSize = 3; + + // Default window sizes + inline const double DefaultEditKeyboardWindowWidth = 0.4; + inline const double DefaultEditKeyboardWindowHeight = 0.55; + inline const double DefaultEditShortcutsWindowWidth = 0.52; + inline const double DefaultEditShortcutsWindowHeight = 0.55; + + // Key Remap table constants + inline const long RemapTableColCount = 5; + inline const long RemapTableHeaderCount = 2; + inline const long RemapTableOriginalColIndex = 0; + inline const long RemapTableArrowColIndex = 1; + inline const long RemapTableNewColIndex = 2; + inline const long RemapTableRemoveColIndex = 3; + inline const long RemapTableWarningColIndex = 4; + inline const long RemapTableDropDownWidth = 110; + + // Shortcut table constants + inline const long ShortcutTableColCount = 5; + inline const long ShortcutTableHeaderCount = 2; + inline const long ShortcutTableOriginalColIndex = 0; + inline const long ShortcutTableArrowColIndex = 1; + inline const long ShortcutTableNewColIndex = 2; + inline const long ShortcutTableRemoveColIndex = 3; + inline const long ShortcutTableWarningColIndex = 4; + inline const long ShortcutTableDropDownWidth = 110; + inline const long ShortcutTableDropDownSpacing = 10; + + // Drop down height used for both Edit Keyboard and Edit Shortcuts + inline const long TableDropDownHeight = 200; + inline const long TableArrowColWidth = 20; + inline const long TableRemoveColWidth = 20; + inline const long TableWarningColWidth = 20; } \ No newline at end of file diff --git a/src/modules/keyboardmanager/common/Shortcut.cpp b/src/modules/keyboardmanager/common/Shortcut.cpp index 1b9be377b2..f3d3eb03a7 100644 --- a/src/modules/keyboardmanager/common/Shortcut.cpp +++ b/src/modules/keyboardmanager/common/Shortcut.cpp @@ -775,25 +775,24 @@ KeyboardManagerHelper::ErrorType Shortcut::DoKeysOverlap(const Shortcut& first, { return KeyboardManagerHelper::ErrorType::SameShortcutPreviouslyMapped; } - // If both have win key modifiers and one is the both version then there will be an overlap - else if (first.winKey != ModifierKey::Disabled && second.winKey != ModifierKey::Disabled && (first.winKey == ModifierKey::Both || second.winKey == ModifierKey::Both)) + // action keys match + else if (first.actionKey == second.actionKey) { - return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut; - } - // If both have ctrl key modifiers and one is the both version then there will be an overlap - else if (first.ctrlKey != ModifierKey::Disabled && second.ctrlKey != ModifierKey::Disabled && (first.ctrlKey == ModifierKey::Both || second.ctrlKey == ModifierKey::Both)) - { - return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut; - } - // If both have alt key modifiers and one is the both version then there will be an overlap - else if (first.altKey != ModifierKey::Disabled && second.altKey != ModifierKey::Disabled && (first.altKey == ModifierKey::Both || second.altKey == ModifierKey::Both)) - { - return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut; - } - // If both have shift key modifiers and one is the both version then there will be an overlap - else if (first.shiftKey != ModifierKey::Disabled && second.shiftKey != ModifierKey::Disabled && (first.shiftKey == ModifierKey::Both || second.shiftKey == ModifierKey::Both)) - { - return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut; + // corresponding modifiers are either both disabled or both not disabled - this ensures that both match in types of modifers i.e. Ctrl(l/r/c) Shift (l/r/c) A matches Ctrl(l/r/c) Shift (l/r/c) A + if (((first.winKey != ModifierKey::Disabled && second.winKey != ModifierKey::Disabled) || (first.winKey == ModifierKey::Disabled && second.winKey == ModifierKey::Disabled)) && + ((first.ctrlKey != ModifierKey::Disabled && second.ctrlKey != ModifierKey::Disabled) || (first.ctrlKey == ModifierKey::Disabled && second.ctrlKey == ModifierKey::Disabled)) && + ((first.altKey != ModifierKey::Disabled && second.altKey != ModifierKey::Disabled) || (first.altKey == ModifierKey::Disabled && second.altKey == ModifierKey::Disabled)) && + ((first.shiftKey != ModifierKey::Disabled && second.shiftKey != ModifierKey::Disabled) || (first.shiftKey == ModifierKey::Disabled && second.shiftKey == ModifierKey::Disabled))) + { + // If one of the modifier is common + if ((first.winKey == ModifierKey::Both || second.winKey == ModifierKey::Both) || + (first.ctrlKey == ModifierKey::Both || second.ctrlKey == ModifierKey::Both) || + (first.altKey == ModifierKey::Both || second.altKey == ModifierKey::Both) || + (first.shiftKey == ModifierKey::Both || second.shiftKey == ModifierKey::Both)) + { + return KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut; + } + } } } diff --git a/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp b/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp index 04eba2cd5d..bda6cbd485 100644 --- a/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp +++ b/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp @@ -40,15 +40,22 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan isEditKeyboardWindowRegistrationCompleted = true; } + // Find center screen coordinates + RECT desktopRect; + GetClientRect(GetDesktopWindow(), &desktopRect); + // Calculate resolution dependent window size + int windowWidth = KeyboardManagerConstants::DefaultEditKeyboardWindowWidth * desktopRect.right; + int windowHeight = KeyboardManagerConstants::DefaultEditKeyboardWindowHeight * desktopRect.bottom; + // Window Creation HWND _hWndEditKeyboardWindow = CreateWindow( szWindowClass, L"Remap Keyboard", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, + (desktopRect.right / 2) - (windowWidth / 2), + (desktopRect.bottom / 2) - (windowHeight / 2), + windowWidth, + windowHeight, NULL, NULL, hInst, @@ -58,6 +65,11 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan MessageBox(NULL, L"Call to CreateWindow failed!", L"Error", NULL); return; } + // Ensures the window is in foreground on first startup. If this is not done, the window appears behind because the thread is not on the foreground. + if (_hWndEditKeyboardWindow) + { + SetForegroundWindow(_hWndEditKeyboardWindow); + } // Store the newly created Edit Keyboard window's handle. std::unique_lock hwndLock(editKeyboardWindowMutex); @@ -99,27 +111,35 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan keyRemapInfoHeader.Text(L"Select the key you want to change (Original Key) and the key you want it to become (New Key)."); keyRemapInfoHeader.Margin({ 10, 0, 0, 10 }); keyRemapInfoHeader.FontWeight(Text::FontWeights::SemiBold()); + keyRemapInfoHeader.TextWrapping(TextWrapping::Wrap); TextBlock keyRemapInfoExample; keyRemapInfoExample.Text(L"For example, if you want to press A and get B, Key A would be your \"Original Key\" and Key B would be your \"New Key\"."); keyRemapInfoExample.Margin({ 10, 0, 0, 20 }); keyRemapInfoExample.FontStyle(Text::FontStyle::Italic); + keyRemapInfoExample.TextWrapping(TextWrapping::Wrap); // Table to display the key remaps Grid keyRemapTable; - ColumnDefinition firstColumn; - ColumnDefinition secondColumn; - ColumnDefinition thirdColumn; - thirdColumn.MaxWidth(100); - ColumnDefinition fourthColumn; - fourthColumn.MaxWidth(100); + ColumnDefinition originalColumn; + originalColumn.MinWidth(KeyboardManagerConstants::RemapTableDropDownWidth); + originalColumn.MaxWidth(KeyboardManagerConstants::RemapTableDropDownWidth); + ColumnDefinition arrowColumn; + arrowColumn.MinWidth(KeyboardManagerConstants::TableArrowColWidth); + ColumnDefinition newColumn; + newColumn.MinWidth(KeyboardManagerConstants::RemapTableDropDownWidth); + newColumn.MaxWidth(KeyboardManagerConstants::RemapTableDropDownWidth); + ColumnDefinition removeColumn; + removeColumn.MinWidth(KeyboardManagerConstants::TableRemoveColWidth); + ColumnDefinition warnColumn; + warnColumn.MinWidth(KeyboardManagerConstants::TableWarningColWidth); keyRemapTable.Margin({ 10, 10, 10, 20 }); keyRemapTable.HorizontalAlignment(HorizontalAlignment::Stretch); - keyRemapTable.ColumnSpacing(10); - keyRemapTable.ColumnDefinitions().Append(firstColumn); - keyRemapTable.ColumnDefinitions().Append(secondColumn); - keyRemapTable.ColumnDefinitions().Append(thirdColumn); - keyRemapTable.ColumnDefinitions().Append(fourthColumn); + keyRemapTable.ColumnDefinitions().Append(originalColumn); + keyRemapTable.ColumnDefinitions().Append(arrowColumn); + keyRemapTable.ColumnDefinitions().Append(newColumn); + keyRemapTable.ColumnDefinitions().Append(removeColumn); + keyRemapTable.ColumnDefinitions().Append(warnColumn); keyRemapTable.RowDefinitions().Append(RowDefinition()); // First header textblock in the header row of the keys remap table @@ -134,9 +154,9 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan newKeyRemapHeader.FontWeight(Text::FontWeights::Bold()); newKeyRemapHeader.Margin({ 0, 0, 0, 10 }); - keyRemapTable.SetColumn(originalKeyRemapHeader, 0); + keyRemapTable.SetColumn(originalKeyRemapHeader, KeyboardManagerConstants::RemapTableOriginalColIndex); keyRemapTable.SetRow(originalKeyRemapHeader, 0); - keyRemapTable.SetColumn(newKeyRemapHeader, 1); + keyRemapTable.SetColumn(newKeyRemapHeader, KeyboardManagerConstants::RemapTableNewColIndex); keyRemapTable.SetRow(newKeyRemapHeader, 0); keyRemapTable.Children().Append(originalKeyRemapHeader); @@ -274,8 +294,8 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan isSuccess = KeyboardManagerHelper::ErrorType::RemapUnsuccessful; // Show tooltip warning on the problematic row uint32_t warningIndex; - // 2 at start, 4 in each row, and last element of each row - warningIndex = 1 + (i + 1) * 4; + // headers at start, colcount in each row, and last element of each row + warningIndex = KeyboardManagerConstants::RemapTableHeaderCount + ((i + 1) * KeyboardManagerConstants::RemapTableColCount) - 1; FontIcon warning = keyRemapTable.Children().GetAt(warningIndex).as(); ToolTip t = ToolTipService::GetToolTip(warning).as(); t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey))); diff --git a/src/modules/keyboardmanager/ui/EditShortcutsWindow.cpp b/src/modules/keyboardmanager/ui/EditShortcutsWindow.cpp index 6c6473e06c..dfece46917 100644 --- a/src/modules/keyboardmanager/ui/EditShortcutsWindow.cpp +++ b/src/modules/keyboardmanager/ui/EditShortcutsWindow.cpp @@ -41,15 +41,22 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa isEditShortcutsWindowRegistrationCompleted = true; } + // Find center screen coordinates + RECT desktopRect; + GetClientRect(GetDesktopWindow(), &desktopRect); + // Calculate resolution dependent window size + int windowWidth = KeyboardManagerConstants::DefaultEditShortcutsWindowWidth * desktopRect.right; + int windowHeight = KeyboardManagerConstants::DefaultEditShortcutsWindowHeight * desktopRect.bottom; + // Window Creation HWND _hWndEditShortcutsWindow = CreateWindow( szWindowClass, - L"Edit Shortcuts", + L"Remap Shortcuts", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, - CW_USEDEFAULT, + (desktopRect.right / 2) - (windowWidth / 2), + (desktopRect.bottom / 2) - (windowHeight / 2), + windowWidth, + windowHeight, NULL, NULL, hInst, @@ -59,6 +66,11 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa MessageBox(NULL, L"Call to CreateWindow failed!", L"Error", NULL); return; } + // Ensures the window is in foreground on first startup. If this is not done, the window appears behind because the thread is not on the foreground. + if (_hWndEditShortcutsWindow) + { + SetForegroundWindow(_hWndEditShortcutsWindow); + } // Store the newly created Edit Shortcuts window's handle. std::unique_lock hwndLock(editShortcutsWindowMutex); @@ -81,9 +93,9 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa // Header text TextBlock headerText; - headerText.Text(L"Edit Shortcuts"); + headerText.Text(L"Remap Shortcuts"); headerText.FontSize(30); - headerText.Margin({ 0, 0, 100, 0 }); + headerText.Margin({ 0, 0, 0, 0 }); header.SetAlignLeftWithPanel(headerText, true); // Cancel button @@ -100,27 +112,36 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa shortcutRemapInfoHeader.Text(L"Select shortcut you want to change (Original Shortcut) and the shortcut (New Shortcut) you want it to invoke."); shortcutRemapInfoHeader.Margin({ 10, 0, 0, 10 }); shortcutRemapInfoHeader.FontWeight(Text::FontWeights::SemiBold()); + shortcutRemapInfoHeader.TextWrapping(TextWrapping::Wrap); TextBlock shortcutRemapInfoExample; shortcutRemapInfoExample.Text(L"For example, if you want Ctrl+C to paste, Ctrl+C is the Original Shortcut and Ctrl+V is the New Shortcut."); shortcutRemapInfoExample.Margin({ 10, 0, 0, 20 }); shortcutRemapInfoExample.FontStyle(Text::FontStyle::Italic); + shortcutRemapInfoExample.TextWrapping(TextWrapping::Wrap); // Table to display the shortcuts Windows::UI::Xaml::Controls::Grid shortcutTable; - ColumnDefinition firstColumn; - ColumnDefinition secondColumn; - ColumnDefinition thirdColumn; - thirdColumn.MaxWidth(100); - ColumnDefinition fourthColumn; - fourthColumn.MaxWidth(100); + Grid keyRemapTable; + ColumnDefinition originalColumn; + originalColumn.MinWidth(3 * KeyboardManagerConstants::ShortcutTableDropDownWidth + 2 * KeyboardManagerConstants::ShortcutTableDropDownSpacing); + originalColumn.MaxWidth(3 * KeyboardManagerConstants::ShortcutTableDropDownWidth + 2 * KeyboardManagerConstants::ShortcutTableDropDownSpacing); + ColumnDefinition arrowColumn; + arrowColumn.MinWidth(KeyboardManagerConstants::TableArrowColWidth); + ColumnDefinition newColumn; + newColumn.MinWidth(3 * KeyboardManagerConstants::ShortcutTableDropDownWidth + 2 * KeyboardManagerConstants::ShortcutTableDropDownSpacing); + newColumn.MaxWidth(3 * KeyboardManagerConstants::ShortcutTableDropDownWidth + 2 * KeyboardManagerConstants::ShortcutTableDropDownSpacing); + ColumnDefinition removeColumn; + removeColumn.MinWidth(KeyboardManagerConstants::TableRemoveColWidth); + ColumnDefinition warnColumn; + warnColumn.MinWidth(KeyboardManagerConstants::TableWarningColWidth); shortcutTable.Margin({ 10, 10, 10, 20 }); shortcutTable.HorizontalAlignment(HorizontalAlignment::Stretch); - shortcutTable.ColumnSpacing(10); - shortcutTable.ColumnDefinitions().Append(firstColumn); - shortcutTable.ColumnDefinitions().Append(secondColumn); - shortcutTable.ColumnDefinitions().Append(thirdColumn); - shortcutTable.ColumnDefinitions().Append(fourthColumn); + shortcutTable.ColumnDefinitions().Append(originalColumn); + shortcutTable.ColumnDefinitions().Append(arrowColumn); + shortcutTable.ColumnDefinitions().Append(newColumn); + shortcutTable.ColumnDefinitions().Append(removeColumn); + shortcutTable.ColumnDefinitions().Append(warnColumn); shortcutTable.RowDefinitions().Append(RowDefinition()); // First header textblock in the header row of the shortcut table @@ -135,9 +156,9 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa newShortcutHeader.FontWeight(Text::FontWeights::Bold()); newShortcutHeader.Margin({ 0, 0, 0, 10 }); - shortcutTable.SetColumn(originalShortcutHeader, 0); + shortcutTable.SetColumn(originalShortcutHeader, KeyboardManagerConstants::ShortcutTableOriginalColIndex); shortcutTable.SetRow(originalShortcutHeader, 0); - shortcutTable.SetColumn(newShortcutHeader, 1); + shortcutTable.SetColumn(newShortcutHeader, KeyboardManagerConstants::ShortcutTableNewColIndex); shortcutTable.SetRow(newShortcutHeader, 0); shortcutTable.Children().Append(originalShortcutHeader); @@ -205,7 +226,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa // Show tooltip warning on the problematic row uint32_t warningIndex; // 2 at start, 4 in each row, and last element of each row - warningIndex = 1 + (i + 1) * 4; + warningIndex = KeyboardManagerConstants::ShortcutTableHeaderCount + ((i + 1) * KeyboardManagerConstants::ShortcutTableColCount) - 1; FontIcon warning = shortcutTable.Children().GetAt(warningIndex).as(); ToolTip t = ToolTipService::GetToolTip(warning).as(); t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey))); diff --git a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp index 90f09a5e41..c0b08f35b3 100644 --- a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp +++ b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp @@ -8,8 +8,15 @@ KeyboardManagerState* KeyDropDownControl::keyboardManagerState = nullptr; // Function to set properties apart from the SelectionChanged event handler void KeyDropDownControl::SetDefaultProperties(bool isShortcut) { - dropDown.Width(100); - dropDown.MaxDropDownHeight(200); + if (!isShortcut) + { + dropDown.Width(KeyboardManagerConstants::RemapTableDropDownWidth); + } + else + { + dropDown.Width(KeyboardManagerConstants::ShortcutTableDropDownWidth); + } + dropDown.MaxDropDownHeight(KeyboardManagerConstants::TableDropDownHeight); // Initialise layout attribute previousLayout = GetKeyboardLayout(0); keyCodeList = keyboardManagerState->keyboardMap.GetKeyCodeList(isShortcut); @@ -49,7 +56,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& singleKeyC if (indexFound) { KeyboardManagerHelper::ErrorType errorType = KeyboardManagerHelper::ErrorType::NoError; - int rowIndex = (controlIndex - 2) / 4; + int rowIndex = (controlIndex - KeyboardManagerConstants::RemapTableHeaderCount) / KeyboardManagerConstants::RemapTableColCount; // Check if the element was not found or the index exceeds the known keys if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex) { @@ -66,7 +73,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& singleKeyC { if (i != rowIndex) { - KeyboardManagerHelper::ErrorType result = KeyboardManagerHelper::DoKeysOverlap(singleKeyRemapBuffer[i][0], keyCodeList[selectedKeyIndex]); + KeyboardManagerHelper::ErrorType result = KeyboardManagerHelper::DoKeysOverlap(singleKeyRemapBuffer[i][colIndex], keyCodeList[selectedKeyIndex]); if (result != KeyboardManagerHelper::ErrorType::NoError) { errorType = result; @@ -126,7 +133,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo if (controlIindexFound) { - int rowIndex = (controlIndex - 2) / 4; + int rowIndex = (controlIndex - KeyboardManagerConstants::ShortcutTableHeaderCount) / KeyboardManagerConstants::ShortcutTableColCount; if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex && dropDownFound) { // If only 1 drop down and action key is chosen: Warn that a modifier must be chosen @@ -139,7 +146,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo else if (dropDownIndex == parent.Children().Size() - 1) { // If last drop down and a modifier is selected: add a new drop down (max of 5 drop downs should be enforced) - if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() < 3) + if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() < KeyboardManagerConstants::MaxShortcutSize) { // If it matched any of the previous modifiers then reset that drop down if (CheckRepeatedModifier(parent, dropDownIndex, selectedKeyIndex, keyCodeList)) @@ -154,7 +161,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo } } // If last drop down and a modifier is selected but there are already 5 drop downs: warn the user - else if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() >= 3) + else if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && parent.Children().Size() >= KeyboardManagerConstants::MaxShortcutSize) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutOneActionKey; @@ -181,7 +188,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo // If not, the modifier key will be set } // If None is selected and there are more than 2 drop downs - else if (keyCodeList[selectedKeyIndex] == 0 && parent.Children().Size() > 2) + else if (keyCodeList[selectedKeyIndex] == 0 && parent.Children().Size() > KeyboardManagerConstants::MinShortcutSize) { // delete drop down parent.Children().RemoveAt(dropDownIndex); @@ -189,7 +196,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo keyDropDownControlObjects.erase(keyDropDownControlObjects.begin() + dropDownIndex); parent.UpdateLayout(); } - else if (keyCodeList[selectedKeyIndex] == 0 && parent.Children().Size() <= 2) + else if (keyCodeList[selectedKeyIndex] == 0 && parent.Children().Size() <= KeyboardManagerConstants::MinShortcutSize) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutAtleast2Keys; @@ -240,7 +247,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo Shortcut tempShortcut; tempShortcut.SetKeyCodes(GetKeysFromStackPanel(parent)); // Check if the value being set is the same as the other column - if (shortcutRemapBuffer[rowIndex][std::abs(int(colIndex) - 1)] == tempShortcut) + if (shortcutRemapBuffer[rowIndex][std::abs(int(colIndex) - 1)] == tempShortcut && shortcutRemapBuffer[rowIndex][std::abs(int(colIndex) - 1)].IsValidShortcut() && tempShortcut.IsValidShortcut()) { errorType = KeyboardManagerHelper::ErrorType::MapToSameShortcut; } @@ -252,7 +259,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel& shortcutCo { if (i != rowIndex) { - KeyboardManagerHelper::ErrorType result = Shortcut::DoKeysOverlap(shortcutRemapBuffer[i][0], tempShortcut); + KeyboardManagerHelper::ErrorType result = Shortcut::DoKeysOverlap(shortcutRemapBuffer[i][colIndex], tempShortcut); if (result != KeyboardManagerHelper::ErrorType::NoError) { errorType = result; diff --git a/src/modules/keyboardmanager/ui/ShortcutControl.cpp b/src/modules/keyboardmanager/ui/ShortcutControl.cpp index 6323ed7442..125df64479 100644 --- a/src/modules/keyboardmanager/ui/ShortcutControl.cpp +++ b/src/modules/keyboardmanager/ui/ShortcutControl.cpp @@ -25,12 +25,23 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vectorgetShortcutControl(), 0); + parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl(), KeyboardManagerConstants::ShortcutTableOriginalColIndex); parent.SetRow(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl(), parent.RowDefinitions().Size() - 1); - parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl(), 1); + parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl(), KeyboardManagerConstants::ShortcutTableNewColIndex); parent.SetRow(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl(), parent.RowDefinitions().Size() - 1); // ShortcutControl for the original shortcut parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl()); + + // Arrow icon + FontIcon arrowIcon; + arrowIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets")); + arrowIcon.Glyph(L"\xE72A"); + arrowIcon.VerticalAlignment(VerticalAlignment::Center); + arrowIcon.HorizontalAlignment(HorizontalAlignment::Center); + parent.SetColumn(arrowIcon, KeyboardManagerConstants::ShortcutTableArrowColIndex); + parent.SetRow(arrowIcon, parent.RowDefinitions().Size() - 1); + parent.Children().Append(arrowIcon); + // ShortcutControl for the new shortcut parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl()); @@ -41,26 +52,28 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector(); uint32_t index; // Get index of delete button UIElementCollection children = parent.Children(); children.IndexOf(currentButton, index); - uint32_t lastIndexInRow = index + 1; + uint32_t lastIndexInRow = index + ((KeyboardManagerConstants::ShortcutTableColCount - 1) - KeyboardManagerConstants::ShortcutTableRemoveColIndex); // Change the row index of elements appearing after the current row, as we will delete the row definition for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i++) { int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as()); parent.SetRow(children.GetAt(i).as(), elementRowIndex - 1); } - parent.Children().RemoveAt(lastIndexInRow); - parent.Children().RemoveAt(lastIndexInRow - 1); - parent.Children().RemoveAt(lastIndexInRow - 2); - parent.Children().RemoveAt(lastIndexInRow - 3); + + for (int i = 0; i < KeyboardManagerConstants::ShortcutTableColCount; i++) + { + parent.Children().RemoveAt(lastIndexInRow - i); + } // Calculate row index in the buffer from the grid child index (first two children are header elements and then three children in each row) - int bufferIndex = (lastIndexInRow - 2) / 4; + int bufferIndex = (lastIndexInRow - KeyboardManagerConstants::ShortcutTableHeaderCount) / KeyboardManagerConstants::ShortcutTableColCount; // Delete the row definition parent.RowDefinitions().RemoveAt(bufferIndex + 1); // delete the row from the buffer @@ -68,15 +81,15 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vectorSetUIState(KeyboardManagerUIState::DetectShortcutWindowActivated, EditShortcutsWindowHandle); // Using the XamlRoot of the typeShortcut to get the root of the XAML host @@ -42,7 +43,7 @@ public: }); shortcutControlLayout.Margin({ 0, 0, 0, 10 }); - shortcutControlLayout.Spacing(10); + shortcutControlLayout.Spacing(KeyboardManagerConstants::ShortcutTableDropDownSpacing); shortcutControlLayout.Children().Append(typeShortcut); shortcutControlLayout.Children().Append(shortcutDropDownStackPanel); diff --git a/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp b/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp index 3cb45f81f8..1b21d4006d 100644 --- a/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp +++ b/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp @@ -24,14 +24,24 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vectorgetSingleKeyRemapControl(), 0); + parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getSingleKeyRemapControl(), KeyboardManagerConstants::RemapTableOriginalColIndex); parent.SetRow(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getSingleKeyRemapControl(), parent.RowDefinitions().Size() - 1); - parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl(), 1); + parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl(), KeyboardManagerConstants::RemapTableNewColIndex); parent.SetRow(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl(), parent.RowDefinitions().Size() - 1); // SingleKeyRemapControl for the original key. parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getSingleKeyRemapControl()); + + // Arrow icon + FontIcon arrowIcon; + arrowIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets")); + arrowIcon.Glyph(L"\xE72A"); + arrowIcon.VerticalAlignment(VerticalAlignment::Center); + arrowIcon.HorizontalAlignment(HorizontalAlignment::Center); + parent.SetColumn(arrowIcon, KeyboardManagerConstants::RemapTableArrowColIndex); + parent.SetRow(arrowIcon, parent.RowDefinitions().Size() - 1); + parent.Children().Append(arrowIcon); + // SingleKeyRemapControl for the new remap key parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl()); @@ -64,26 +74,28 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector(); uint32_t index; // Get index of delete button UIElementCollection children = parent.Children(); children.IndexOf(currentButton, index); - uint32_t lastIndexInRow = index + 1; + uint32_t lastIndexInRow = index + ((KeyboardManagerConstants::RemapTableColCount - 1) - KeyboardManagerConstants::RemapTableRemoveColIndex); // Change the row index of elements appearing after the current row, as we will delete the row definition for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i++) { int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as()); parent.SetRow(children.GetAt(i).as(), elementRowIndex - 1); } - parent.Children().RemoveAt(lastIndexInRow); - parent.Children().RemoveAt(lastIndexInRow - 1); - parent.Children().RemoveAt(lastIndexInRow - 2); - parent.Children().RemoveAt(lastIndexInRow - 3); + + for (int i = 0; i < KeyboardManagerConstants::RemapTableColCount; i++) + { + parent.Children().RemoveAt(lastIndexInRow - i); + } // Calculate row index in the buffer from the grid child index (first two children are header elements and then three children in each row) - int bufferIndex = (lastIndexInRow - 2) / 4; + int bufferIndex = (lastIndexInRow - KeyboardManagerConstants::RemapTableHeaderCount) / KeyboardManagerConstants::RemapTableColCount; // Delete the row definition parent.RowDefinitions().RemoveAt(bufferIndex + 1); // delete the row from the buffer. @@ -91,15 +103,15 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vectorSetUIState(KeyboardManagerUIState::DetectSingleKeyRemapWindowActivated, EditKeyboardWindowHandle); // Using the XamlRoot of the typeKey to get the root of the XAML host