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
This commit is contained in:
Arjun Balgovind 2020-05-08 17:34:24 -07:00 committed by GitHub
parent d329406eb8
commit 3a0a5a7754
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 209 additions and 98 deletions

View file

@ -186,12 +186,12 @@
<comment>Keyboard Manager remap keyboard header</comment>
</data>
<data name="KeyboardManager_RemapShortcutsButton.Content" xml:space="preserve">
<value>Redefine a shortcut</value>
<comment>Keyboard Manager edit shortcuts button</comment>
<value>Remap a shortcut</value>
<comment>Keyboard Manager remap shortcuts button</comment>
</data>
<data name="KeyboardManager_RemapShortcutsHeader.Text" xml:space="preserve">
<value>Edit Shortcuts</value>
<comment>Keyboard Manager edit shortcuts header</comment>
<value>Remap Shortcuts</value>
<comment>Keyboard Manager remap shortcuts header</comment>
</data>
<data name="PowerLauncher_Description.Text" xml:space="preserve">
<value>A quick launcher that has additional capabilities without sacrificing performance.</value>

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}
}
}
}

View file

@ -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<std::mutex> 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<FontIcon>();
ToolTip t = ToolTipService::GetToolTip(warning).as<ToolTip>();
t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey)));

View file

@ -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<std::mutex> 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<FontIcon>();
ToolTip t = ToolTipService::GetToolTip(warning).as<ToolTip>();
t.Content(box_value(KeyboardManagerHelper::GetErrorMessage(KeyboardManagerHelper::ErrorType::MissingKey)));

View file

@ -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;

View file

@ -25,12 +25,23 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
// Add to grid
parent.RowDefinitions().Append(RowDefinition());
parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl(), 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<std::ve
deleteSymbol.Glyph(L"\xE74D");
deleteShortcut.Content(deleteSymbol);
deleteShortcut.Background(Media::SolidColorBrush(Colors::Transparent()));
deleteShortcut.HorizontalAlignment(HorizontalAlignment::Center);
deleteShortcut.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
Button currentButton = sender.as<Button>();
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<FrameworkElement>());
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), 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::vector<std::ve
// delete the ShortcutControl objects so that they get destructed
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + bufferIndex);
});
parent.SetColumn(deleteShortcut, 2);
parent.SetColumn(deleteShortcut, KeyboardManagerConstants::ShortcutTableRemoveColIndex);
parent.SetRow(deleteShortcut, parent.RowDefinitions().Size() - 1);
parent.Children().Append(deleteShortcut);
warningIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
warningIcon.Glyph(L"\xE783");
warningIcon.HorizontalAlignment(HorizontalAlignment::Left);
warningIcon.HorizontalAlignment(HorizontalAlignment::Center);
ToolTipService::SetToolTip(warningIcon, warningMessage);
parent.SetColumn(warningIcon, 3);
parent.SetColumn(warningIcon, KeyboardManagerConstants::ShortcutTableWarningColIndex);
parent.SetRow(warningIcon, parent.RowDefinitions().Size() - 1);
parent.Children().Append(warningIcon);
parent.UpdateLayout();

View file

@ -35,6 +35,7 @@ public:
shortcutDropDownStackPanel.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
typeShortcut.Content(winrt::box_value(L"Type Shortcut"));
typeShortcut.Width(KeyboardManagerConstants::ShortcutTableDropDownWidth);
typeShortcut.Click([&, table, colIndex, warning, toolTip](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
keyboardManagerState->SetUIState(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);

View file

@ -24,14 +24,24 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
keyboardRemapControlObjects.push_back(std::move(newrow));
// Add to grid
int debug = parent.RowDefinitions().Size();
parent.RowDefinitions().Append(RowDefinition());
parent.SetColumn(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getSingleKeyRemapControl(), 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<s
deleteSymbol.Glyph(L"\xE74D");
deleteRemapKeys.Content(deleteSymbol);
deleteRemapKeys.Background(Media::SolidColorBrush(Colors::Transparent()));
deleteRemapKeys.HorizontalAlignment(HorizontalAlignment::Center);
deleteRemapKeys.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
Button currentButton = sender.as<Button>();
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<FrameworkElement>());
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), 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::vector<s
// delete the SingleKeyRemapControl objects so that they get destructed
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + bufferIndex);
});
parent.SetColumn(deleteRemapKeys, 2);
parent.SetColumn(deleteRemapKeys, KeyboardManagerConstants::RemapTableRemoveColIndex);
parent.SetRow(deleteRemapKeys, parent.RowDefinitions().Size() - 1);
parent.Children().Append(deleteRemapKeys);
warningIcon.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
warningIcon.Glyph(L"\xE783");
warningIcon.HorizontalAlignment(HorizontalAlignment::Left);
warningIcon.HorizontalAlignment(HorizontalAlignment::Center);
ToolTipService::SetToolTip(warningIcon, warningMessage);
parent.SetColumn(warningIcon, 3);
parent.SetColumn(warningIcon, KeyboardManagerConstants::RemapTableWarningColIndex);
parent.SetRow(warningIcon, parent.RowDefinitions().Size() - 1);
parent.Children().Append(warningIcon);
parent.UpdateLayout();

View file

@ -26,6 +26,7 @@ public:
singleKeyRemapDropDown(false, warning, toolTip)
{
typeKey.Content(winrt::box_value(L"Type Key"));
typeKey.Width(KeyboardManagerConstants::RemapTableDropDownWidth);
typeKey.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
keyboardManagerState->SetUIState(KeyboardManagerUIState::DetectSingleKeyRemapWindowActivated, EditKeyboardWindowHandle);
// Using the XamlRoot of the typeKey to get the root of the XAML host