[KBM] Added banded rows (#7787)

* Added banded rows

* Fix build after merge

* accessibility names, capturing static row indexes by lambda

* Fix position of targetApp textbox

* fix wrong path for textbox
This commit is contained in:
Mykhailo Pylyp
2020-11-06 16:24:11 +02:00
committed by GitHub
parent 01e9be9180
commit 8a1d2611d8
13 changed files with 196 additions and 263 deletions

View File

@@ -360,4 +360,12 @@ namespace KeyboardManagerHelper
// If we have at least two keys equal to 'selectedKeyCode' than modifier was repeated
return numberOfSameType > 1;
}
winrt::Windows::Foundation::IInspectable GetWrapped(const winrt::Windows::Foundation::IInspectable& element, double width)
{
StackPanel sp = StackPanel();
sp.Width(width);
sp.Children().Append(element.as<FrameworkElement>());
return sp;
}
}

View File

@@ -107,4 +107,6 @@ namespace KeyboardManagerHelper
// Function to check if a modifier has been repeated in the previous drop downs
bool CheckRepeatedModifier(const std::vector<int32_t>& currentKeys, int selectedKeyCodes);
winrt::Windows::Foundation::IInspectable GetWrapped(const winrt::Windows::Foundation::IInspectable& element, double width);
}

View File

@@ -79,15 +79,18 @@ namespace KeyboardManagerConstants
inline const long ShortcutTableNewColIndex = 2;
inline const long ShortcutTableTargetAppColIndex = 3;
inline const long ShortcutTableRemoveColIndex = 4;
inline const long ShortcutArrowColumnWidth = 90;
inline const DWORD64 ShortcutTableDropDownWidth = 110;
inline const DWORD64 ShortcutTableDropDownSpacing = 10;
inline const long ShortcutOriginColumnWidth = 3 * ShortcutTableDropDownWidth + 2 * ShortcutTableDropDownSpacing;
inline const long ShortcutTargetColumnWidth = 3 * ShortcutTableDropDownWidth + 2 * ShortcutTableDropDownSpacing + 25;
// Drop down height used for both Edit Keyboard and Edit Shortcuts
inline const DWORD64 TableDropDownHeight = 200;
inline const DWORD64 TableArrowColWidth = 20;
inline const DWORD64 TableArrowColWidth = 230;
inline const DWORD64 TableRemoveColWidth = 20;
inline const DWORD64 TableWarningColWidth = 20;
inline const DWORD64 TableTargetAppColWidth = ShortcutTableDropDownWidth + 50;
inline const DWORD64 TableTargetAppColWidth = ShortcutTableDropDownWidth + TableRemoveColWidth * 2;
// Shared style constants for both Remap Table and Shortcut Table
inline const DWORD64 HeaderButtonWidth = 100;

View File

@@ -199,45 +199,24 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
keyRemapInfoExample.TextWrapping(TextWrapping::Wrap);
// Table to display the key remaps
Grid keyRemapTable;
ColumnDefinition originalColumn;
originalColumn.MinWidth(KeyboardManagerConstants::RemapTableDropDownWidth);
originalColumn.MaxWidth(KeyboardManagerConstants::RemapTableDropDownWidth);
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);
keyRemapTable.Margin({ 10, 10, 10, 20 });
keyRemapTable.HorizontalAlignment(HorizontalAlignment::Stretch);
keyRemapTable.ColumnDefinitions().Append(originalColumn);
keyRemapTable.ColumnDefinitions().Append(arrowColumn);
keyRemapTable.ColumnDefinitions().Append(newColumn);
keyRemapTable.ColumnDefinitions().Append(removeColumn);
keyRemapTable.RowDefinitions().Append(RowDefinition());
keyRemapTable.MinWidth(KeyboardManagerConstants::EditKeyboardTableMinWidth);
StackPanel keyRemapTable;
// First header textblock in the header row of the keys remap table
TextBlock originalKeyRemapHeader;
originalKeyRemapHeader.Text(GET_RESOURCE_STRING(IDS_EDITKEYBOARD_SOURCEHEADER));
originalKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
originalKeyRemapHeader.Margin({ 0, 0, 0, 10 });
StackPanel originalKeyHeaderContainer = KeyboardManagerHelper::GetWrapped(originalKeyRemapHeader, KeyboardManagerConstants::RemapTableDropDownWidth + KeyboardManagerConstants::TableArrowColWidth).as<StackPanel>();
// Second header textblock in the header row of the keys remap table
TextBlock newKeyRemapHeader;
newKeyRemapHeader.Text(GET_RESOURCE_STRING(IDS_EDITKEYBOARD_TARGETHEADER));
newKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
newKeyRemapHeader.Margin({ 0, 0, 0, 10 });
keyRemapTable.SetColumn(originalKeyRemapHeader, KeyboardManagerConstants::RemapTableOriginalColIndex);
keyRemapTable.SetRow(originalKeyRemapHeader, 0);
keyRemapTable.SetColumn(newKeyRemapHeader, KeyboardManagerConstants::RemapTableNewColIndex);
keyRemapTable.SetRow(newKeyRemapHeader, 0);
keyRemapTable.Children().Append(originalKeyRemapHeader);
keyRemapTable.Children().Append(newKeyRemapHeader);
StackPanel tableHeader = StackPanel();
tableHeader.Orientation(Orientation::Horizontal);
tableHeader.Margin({ 10, 0, 0, 10 });
tableHeader.Children().Append(originalKeyHeaderContainer);
tableHeader.Children().Append(newKeyRemapHeader);
// Store handle of edit keyboard window
SingleKeyRemapControl::EditKeyboardWindowHandle = _hWndEditKeyboardWindow;
@@ -328,6 +307,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
// Remapping table
StackPanel mappingsPanel;
mappingsPanel.Children().Append(tableHeader);
mappingsPanel.Children().Append(keyRemapTable);
mappingsPanel.Children().Append(addRemapKey);

View File

@@ -158,60 +158,33 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
shortcutRemapInfoExample.TextWrapping(TextWrapping::Wrap);
// Table to display the shortcuts
Windows::UI::Xaml::Controls::Grid shortcutTable;
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 targetAppColumn;
targetAppColumn.MinWidth(KeyboardManagerConstants::TableTargetAppColWidth);
ColumnDefinition removeColumn;
removeColumn.MinWidth(KeyboardManagerConstants::TableRemoveColWidth);
shortcutTable.Margin({ 10, 10, 10, 20 });
shortcutTable.HorizontalAlignment(HorizontalAlignment::Stretch);
shortcutTable.ColumnDefinitions().Append(originalColumn);
shortcutTable.ColumnDefinitions().Append(arrowColumn);
shortcutTable.ColumnDefinitions().Append(newColumn);
shortcutTable.ColumnDefinitions().Append(targetAppColumn);
shortcutTable.ColumnDefinitions().Append(removeColumn);
shortcutTable.RowDefinitions().Append(RowDefinition());
shortcutTable.MinWidth(KeyboardManagerConstants::EditShortcutsTableMinWidth);
StackPanel shortcutTable;
// First header textblock in the header row of the shortcut table
TextBlock originalShortcutHeader;
originalShortcutHeader.Text(GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_SOURCEHEADER));
originalShortcutHeader.FontWeight(Text::FontWeights::Bold());
originalShortcutHeader.Margin({ 0, 0, 0, 10 });
// Second header textblock in the header row of the shortcut table
TextBlock newShortcutHeader;
newShortcutHeader.Text(GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_TARGETHEADER));
newShortcutHeader.FontWeight(Text::FontWeights::Bold());
newShortcutHeader.Margin({ 0, 0, 0, 10 });
// Third header textblock in the header row of the shortcut table
TextBlock targetAppHeader;
targetAppHeader.Text(GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_TARGETAPPHEADER));
targetAppHeader.Width(KeyboardManagerConstants::ShortcutTableDropDownWidth);
targetAppHeader.FontWeight(Text::FontWeights::Bold());
targetAppHeader.Margin({ 0, 0, 0, 10 });
targetAppHeader.HorizontalAlignment(HorizontalAlignment::Center);
shortcutTable.SetColumn(originalShortcutHeader, KeyboardManagerConstants::ShortcutTableOriginalColIndex);
shortcutTable.SetRow(originalShortcutHeader, 0);
shortcutTable.SetColumn(newShortcutHeader, KeyboardManagerConstants::ShortcutTableNewColIndex);
shortcutTable.SetRow(newShortcutHeader, 0);
shortcutTable.SetColumn(targetAppHeader, KeyboardManagerConstants::ShortcutTableTargetAppColIndex);
shortcutTable.SetRow(targetAppHeader, 0);
shortcutTable.Children().Append(originalShortcutHeader);
shortcutTable.Children().Append(newShortcutHeader);
shortcutTable.Children().Append(targetAppHeader);
StackPanel tableHeader = StackPanel();
tableHeader.Orientation(Orientation::Horizontal);
tableHeader.Margin({ 10, 0, 0, 10 });
auto originalShortcutContainer = KeyboardManagerHelper::GetWrapped(originalShortcutHeader, KeyboardManagerConstants::ShortcutOriginColumnWidth + (double)KeyboardManagerConstants::ShortcutArrowColumnWidth);
tableHeader.Children().Append(originalShortcutContainer.as<FrameworkElement>());
auto newShortcutHeaderContainer = KeyboardManagerHelper::GetWrapped(newShortcutHeader, KeyboardManagerConstants::ShortcutTargetColumnWidth);
tableHeader.Children().Append(newShortcutHeaderContainer.as<FrameworkElement>());
tableHeader.Children().Append(targetAppHeader);
// Store handle of edit shortcuts window
ShortcutControl::EditShortcutsWindowHandle = _hWndEditShortcutsWindow;
@@ -289,7 +262,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
plusSymbol.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
plusSymbol.Glyph(L"\xE109");
addShortcut.Content(plusSymbol);
addShortcut.Margin({ 10, 0, 0, 25 });
addShortcut.Margin({ 10, 10, 0, 25 });
addShortcut.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
ShortcutControl::AddNewShortcutControlRow(shortcutTable, keyboardRemapControlObjects);
@@ -315,6 +288,7 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
// Remapping table
StackPanel mappingsPanel;
mappingsPanel.Children().Append(tableHeader);
mappingsPanel.Children().Append(shortcutTable);
mappingsPanel.Children().Append(addShortcut);

View File

@@ -100,29 +100,25 @@ void KeyDropDownControl::CheckAndUpdateKeyboardLayout(ComboBox currentDropDown,
}
// Function to set selection handler for single key remap drop down. Needs to be called after the constructor since the singleKeyControl StackPanel is null if called in the constructor
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyControl, int colIndex, RemapBuffer& singleKeyRemapBuffer)
void KeyDropDownControl::SetSelectionHandler(StackPanel& table, StackPanel row, int colIndex, RemapBuffer& singleKeyRemapBuffer)
{
// drop down selection handler
auto onSelectionChange = [&, table, singleKeyControl, colIndex](winrt::Windows::Foundation::IInspectable const& sender) {
auto onSelectionChange = [&, table, row, colIndex](winrt::Windows::Foundation::IInspectable const& sender) {
uint32_t rowIndex = -1;
if (!table.Children().IndexOf(row, rowIndex))
{
return;
}
ComboBox currentDropDown = sender.as<ComboBox>();
int selectedKeyCode = GetSelectedValue(currentDropDown);
// Validate current remap selection
KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyCode, singleKeyRemapBuffer);
// Get row index of the single key control
uint32_t controlIndex;
bool indexFound = table.Children().IndexOf(singleKeyControl, controlIndex);
if (indexFound)
// If there is an error set the warning flyout
if (errorType != KeyboardManagerHelper::ErrorType::NoError)
{
// GetRow will give the row index including the table header
int rowIndex = table.GetRow(singleKeyControl) - 1;
// Validate current remap selection
KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyCode, singleKeyRemapBuffer);
// If there is an error set the warning flyout
if (errorType != KeyboardManagerHelper::ErrorType::NoError)
{
SetDropDownError(currentDropDown, KeyboardManagerHelper::GetErrorMessage(errorType));
}
SetDropDownError(currentDropDown, KeyboardManagerHelper::GetErrorMessage(errorType));
}
};
@@ -141,22 +137,17 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo
});
}
std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateShortcutSelection(Grid table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateShortcutSelection(StackPanel table, StackPanel row, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
{
ComboBox currentDropDown = dropDown.as<ComboBox>();
uint32_t dropDownIndex = -1;
bool dropDownFound = parent.Children().IndexOf(currentDropDown, dropDownIndex);
// Get row index of the single key control
uint32_t controlIndex;
bool controlIindexFound = table.Children().IndexOf(shortcutControl, controlIndex);
int rowIndex = -1;
std::pair<KeyboardManagerHelper::ErrorType, BufferValidationHelpers::DropDownAction> validationResult = std::make_pair(KeyboardManagerHelper::ErrorType::NoError, BufferValidationHelpers::DropDownAction::NoAction);
uint32_t rowIndex;
bool controlIindexFound = table.Children().IndexOf(row, rowIndex);
if (controlIindexFound)
{
// GetRow will give the row index including the table header
rowIndex = table.GetRow(shortcutControl) - 1;
std::vector<int32_t> selectedCodes = GetSelectedCodesFromStackPanel(parent);
std::wstring appName;
@@ -171,7 +162,7 @@ std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateSho
// Add or clear unused drop downs
if (validationResult.second == BufferValidationHelpers::DropDownAction::AddDropDown)
{
AddDropDown(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
AddDropDown(table, row, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
}
else if (validationResult.second == BufferValidationHelpers::DropDownAction::ClearUnusedDropDowns)
{
@@ -224,10 +215,10 @@ std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateSho
}
// Function to set selection handler for shortcut drop down. Needs to be called after the constructor since the shortcutControl StackPanel is null if called in the constructor
void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox& targetApp, bool isHybridControl, bool isSingleKeyWindow)
void KeyDropDownControl::SetSelectionHandler(StackPanel& table, StackPanel row, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox& targetApp, bool isHybridControl, bool isSingleKeyWindow)
{
auto onSelectionChange = [&, table, shortcutControl, colIndex, parent, targetApp, isHybridControl, isSingleKeyWindow](winrt::Windows::Foundation::IInspectable const& sender) {
std::pair<KeyboardManagerHelper::ErrorType, int> validationResult = ValidateShortcutSelection(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
auto onSelectionChange = [&, table, row, colIndex, parent, targetApp, isHybridControl, isSingleKeyWindow](winrt::Windows::Foundation::IInspectable const& sender) {
std::pair<KeyboardManagerHelper::ErrorType, int> validationResult = ValidateShortcutSelection(table, row, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
// Check if the drop down row index was identified from the return value of validateSelection
if (validationResult.second != -1)
@@ -236,7 +227,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon
if (validationResult.first != KeyboardManagerHelper::ErrorType::NoError)
{
// Validate all the drop downs
ValidateShortcutFromDropDownList(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
ValidateShortcutFromDropDownList(table, row, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
}
// Reset the buffer based on the new selected drop down items. Use static key code list since the KeyDropDownControl object might be deleted
@@ -312,11 +303,13 @@ ComboBox KeyDropDownControl::GetComboBox()
}
// Function to add a drop down to the shortcut stack panel
void KeyDropDownControl::AddDropDown(Grid table, StackPanel shortcutControl, StackPanel parent, const int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, bool ignoreWarning)
void KeyDropDownControl::AddDropDown(StackPanel& table, StackPanel row, StackPanel parent, const int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, bool ignoreWarning)
{
keyDropDownControlObjects.emplace_back(std::make_unique<KeyDropDownControl>(true, ignoreWarning, colIndex == 1));
parent.Children().Append(keyDropDownControlObjects[keyDropDownControlObjects.size() - 1]->GetComboBox());
keyDropDownControlObjects[keyDropDownControlObjects.size() - 1]->SetSelectionHandler(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
uint32_t index;
bool found = table.Children().IndexOf(row, index);
keyDropDownControlObjects[keyDropDownControlObjects.size() - 1]->SetSelectionHandler(table, row, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
parent.UpdateLayout();
// Update accessible name
@@ -339,7 +332,7 @@ std::vector<int32_t> KeyDropDownControl::GetSelectedCodesFromStackPanel(StackPan
}
// Function for validating the selection of shortcuts for all the associated drop downs
void KeyDropDownControl::ValidateShortcutFromDropDownList(Grid table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
void KeyDropDownControl::ValidateShortcutFromDropDownList(StackPanel table, StackPanel row, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
{
// Iterate over all drop downs from left to right in that row/col and validate if there is an error in any of the drop downs. After this the state should be error-free (if it is a valid shortcut)
for (int i = 0; i < keyDropDownControlObjects.size(); i++)
@@ -361,7 +354,7 @@ void KeyDropDownControl::ValidateShortcutFromDropDownList(Grid table, StackPanel
// If the key/shortcut is valid and that drop down is not empty
if (((currentShortcut.index() == 0 && std::get<DWORD>(currentShortcut) != NULL) || (currentShortcut.index() == 1 && std::get<Shortcut>(currentShortcut).IsValidShortcut())) && GetSelectedValue(keyDropDownControlObjects[i]->GetComboBox()) != -1)
{
keyDropDownControlObjects[i]->ValidateShortcutSelection(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
keyDropDownControlObjects[i]->ValidateShortcutSelection(table, row, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow);
}
}
}
@@ -375,7 +368,7 @@ void KeyDropDownControl::SetDropDownError(ComboBox currentDropDown, hstring mess
}
// Function to add a shortcut to the UI control as combo boxes
void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, RemapBuffer& remapBuffer, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, StackPanel table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, RemapBuffer& remapBuffer, StackPanel row, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow)
{
// Delete the existing drop down menus
parent.Children().Clear();
@@ -392,7 +385,7 @@ void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, Sta
ignoreWarning = true;
}
KeyDropDownControl::AddDropDown(table, controlLayout, parent, colIndex, remapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow, ignoreWarning);
KeyDropDownControl::AddDropDown(table, row, parent, colIndex, remapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow, ignoreWarning);
for (int i = 0; i < shortcutKeyCodes.size(); i++)
{

View File

@@ -13,7 +13,6 @@ namespace winrt::Windows
namespace UI::Xaml::Controls
{
struct StackPanel;
struct Grid;
struct ComboBox;
struct Flyout;
struct TextBlock;
@@ -63,25 +62,25 @@ public:
}
// Function to set selection handler for single key remap drop down. Needs to be called after the constructor since the singleKeyControl StackPanel is null if called in the constructor
void SetSelectionHandler(winrt::Windows::UI::Xaml::Controls::Grid& table, winrt::Windows::UI::Xaml::Controls::StackPanel singleKeyControl, int colIndex, RemapBuffer& singleKeyRemapBuffer);
void SetSelectionHandler(StackPanel& table, StackPanel row, int colIndex, RemapBuffer& singleKeyRemapBuffer);
// Function for validating the selection of shortcuts for the drop down
std::pair<KeyboardManagerHelper::ErrorType, int> ValidateShortcutSelection(winrt::Windows::UI::Xaml::Controls::Grid table, winrt::Windows::UI::Xaml::Controls::StackPanel shortcutControl, winrt::Windows::UI::Xaml::Controls::StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
std::pair<KeyboardManagerHelper::ErrorType, int> ValidateShortcutSelection(StackPanel table, StackPanel row, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
// Function to set selection handler for shortcut drop down. Needs to be called after the constructor since the shortcutControl StackPanel is null if called in the constructor
void SetSelectionHandler(winrt::Windows::UI::Xaml::Controls::Grid& table, winrt::Windows::UI::Xaml::Controls::StackPanel shortcutControl, winrt::Windows::UI::Xaml::Controls::StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox& targetApp, bool isHybridControl, bool isSingleKeyWindow);
// Function to set selection handler for shortcut drop down.
void SetSelectionHandler(StackPanel& table, StackPanel row, winrt::Windows::UI::Xaml::Controls::StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox& targetApp, bool isHybridControl, bool isSingleKeyWindow);
// Function to return the combo box element of the drop down
ComboBox GetComboBox();
// Function to add a drop down to the shortcut stack panel
static void AddDropDown(winrt::Windows::UI::Xaml::Controls::Grid table, winrt::Windows::UI::Xaml::Controls::StackPanel shortcutControl, winrt::Windows::UI::Xaml::Controls::StackPanel parent, const int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, bool ignoreWarning = false);
static void AddDropDown(StackPanel& table, StackPanel row, winrt::Windows::UI::Xaml::Controls::StackPanel parent, const int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, bool ignoreWarning = false);
// Function to get the list of key codes from the shortcut combo box stack panel
static std::vector<int32_t> GetSelectedCodesFromStackPanel(StackPanel parent);
// Function for validating the selection of shortcuts for all the associated drop downs
static void ValidateShortcutFromDropDownList(Grid table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
static void ValidateShortcutFromDropDownList(StackPanel table, StackPanel row, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
// Function to set the warning message
void SetDropDownError(winrt::Windows::UI::Xaml::Controls::ComboBox currentDropDown, winrt::hstring message);
@@ -90,7 +89,7 @@ public:
void SetSelectedValue(std::wstring value);
// Function to add a shortcut to the UI control as combo boxes
static void AddShortcutToControl(Shortcut shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, RemapBuffer& remapBuffer, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
static void AddShortcutToControl(Shortcut shortcut, StackPanel table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, RemapBuffer& remapBuffer, StackPanel row, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow);
// Get keys name list depending if Disable is in dropdown
static std::vector<std::pair<DWORD,std::wstring>> GetKeyList(bool isShortcut, bool renderDisable);

View File

@@ -14,7 +14,7 @@ KeyboardManagerState* ShortcutControl::keyboardManagerState = nullptr;
// Initialized as new vector
RemapBuffer ShortcutControl::shortcutRemapBuffer;
ShortcutControl::ShortcutControl(Grid table, const int colIndex, TextBox targetApp)
ShortcutControl::ShortcutControl(StackPanel table, StackPanel row, const int colIndex, TextBox targetApp)
{
shortcutDropDownStackPanel = StackPanel();
typeShortcut = Button();
@@ -26,20 +26,19 @@ ShortcutControl::ShortcutControl(Grid table, const int colIndex, TextBox targetA
typeShortcut.as<Button>().Content(winrt::box_value(GET_RESOURCE_STRING(IDS_TYPE_BUTTON)));
typeShortcut.as<Button>().Width(KeyboardManagerConstants::ShortcutTableDropDownWidth);
typeShortcut.as<Button>().Click([&, table, colIndex, isHybridControl, targetApp](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
typeShortcut.as<Button>().Click([&, table, row, colIndex, isHybridControl, targetApp](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
createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), *keyboardManagerState, colIndex, table, keyDropDownControlObjects, shortcutControlLayout.as<StackPanel>(), targetApp, isHybridControl, false, EditShortcutsWindowHandle, shortcutRemapBuffer);
createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), *keyboardManagerState, colIndex, table, keyDropDownControlObjects, row, targetApp, isHybridControl, false, EditShortcutsWindowHandle, shortcutRemapBuffer);
});
// Set an accessible name for the type shortcut button
typeShortcut.as<Button>().SetValue(Automation::AutomationProperties::NameProperty(), box_value(GET_RESOURCE_STRING(IDS_TYPE_BUTTON)));
shortcutControlLayout.as<StackPanel>().Margin({ 0, 0, 0, 10 });
shortcutControlLayout.as<StackPanel>().Spacing(KeyboardManagerConstants::ShortcutTableDropDownSpacing);
shortcutControlLayout.as<StackPanel>().Children().Append(typeShortcut.as<Button>());
shortcutControlLayout.as<StackPanel>().Children().Append(shortcutDropDownStackPanel.as<StackPanel>());
KeyDropDownControl::AddDropDown(table, shortcutControlLayout.as<StackPanel>(), shortcutDropDownStackPanel.as<StackPanel>(), colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, false);
KeyDropDownControl::AddDropDown(table, row, shortcutDropDownStackPanel.as<StackPanel>(), colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, false);
shortcutControlLayout.as<StackPanel>().UpdateLayout();
}
@@ -65,25 +64,31 @@ void ShortcutControl::UpdateAccessibleNames(StackPanel sourceColumn, StackPanel
}
// Function to add a new row to the shortcut table. If the originalKeys and newKeys args are provided, then the displayed shortcuts are set to those values.
void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, const Shortcut& originalKeys, const KeyShortcutUnion& newKeys, const std::wstring& targetAppName)
void ShortcutControl::AddNewShortcutControlRow(StackPanel& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, const Shortcut& originalKeys, const KeyShortcutUnion& newKeys, const std::wstring& targetAppName)
{
// Textbox for target application
TextBox targetAppTextBox;
// Create new ShortcutControl objects dynamically so that we does not get destructed
std::vector<std::unique_ptr<ShortcutControl>> newrow;
newrow.emplace_back(std::make_unique<ShortcutControl>(parent, 0, targetAppTextBox));
newrow.emplace_back(std::make_unique<ShortcutControl>(parent, 1, targetAppTextBox));
StackPanel row = StackPanel();
parent.Children().Append(row);
newrow.emplace_back(std::make_unique<ShortcutControl>(parent, row, 0, targetAppTextBox));
newrow.emplace_back(std::make_unique<ShortcutControl>(parent, row, 1, targetAppTextBox));
keyboardRemapControlObjects.push_back(std::move(newrow));
row.Padding({10, 10, 10, 10});
row.Orientation(Orientation::Horizontal);
auto brush = Windows::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"SystemControlBackgroundListLowBrush")).as<Windows::UI::Xaml::Media::SolidColorBrush>();
if (keyboardRemapControlObjects.size() % 2)
{
row.Background(brush);
}
// Add to grid
parent.RowDefinitions().Append(RowDefinition());
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(), 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());
auto origin = keyboardRemapControlObjects.back()[0]->getShortcutControl();
origin.Width(KeyboardManagerConstants::ShortcutOriginColumnWidth);
row.Children().Append(origin);
// Arrow icon
FontIcon arrowIcon;
@@ -91,17 +96,17 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
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);
auto arrowIconContainer = KeyboardManagerHelper::GetWrapped(arrowIcon, KeyboardManagerConstants::ShortcutArrowColumnWidth).as<StackPanel>();
arrowIconContainer.Orientation(Orientation::Vertical);
arrowIconContainer.VerticalAlignment(VerticalAlignment::Center);
row.Children().Append(arrowIconContainer);
// ShortcutControl for the new shortcut
parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl());
auto target = keyboardRemapControlObjects.back()[1]->getShortcutControl();
target.Width(KeyboardManagerConstants::ShortcutTargetColumnWidth);
row.Children().Append(target);
targetAppTextBox.Width(KeyboardManagerConstants::ShortcutTableDropDownWidth);
targetAppTextBox.Margin({ 0, 0, 0, KeyboardManagerConstants::ShortcutTableDropDownSpacing });
targetAppTextBox.VerticalAlignment(VerticalAlignment::Bottom);
targetAppTextBox.HorizontalAlignment(HorizontalAlignment::Center);
targetAppTextBox.PlaceholderText(KeyboardManagerConstants::DefaultAppName);
targetAppTextBox.Text(targetAppName);
@@ -112,22 +117,14 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
});
// LostFocus handler will be called whenever text is updated by a user and then they click something else or tab to another control. Does not get called if Text is updated while the TextBox isn't in focus (i.e. from code)
targetAppTextBox.LostFocus([&keyboardRemapControlObjects, parent, targetAppTextBox](auto const& sender, auto const& e) {
targetAppTextBox.LostFocus([&keyboardRemapControlObjects, parent, row, targetAppTextBox](auto const& sender, auto const& e) {
// Get index of targetAppTextBox button
UIElementCollection children = parent.Children();
uint32_t index;
bool indexFound = children.IndexOf(targetAppTextBox, index);
// IndexOf could fail if the the row got deleted after LostFocus handler was invoked. In this case it should return
if (!indexFound)
uint32_t rowIndex;
if (!parent.Children().IndexOf(row, rowIndex))
{
return;
}
uint32_t lastIndexInRow = index + ((KeyboardManagerConstants::ShortcutTableColCount - 1) - KeyboardManagerConstants::ShortcutTableTargetAppColIndex);
// Calculate row index in the buffer from the grid child index (first set of children are header elements and then three children in each row)
int rowIndex = (lastIndexInRow - KeyboardManagerConstants::ShortcutTableHeaderCount) / KeyboardManagerConstants::ShortcutTableColCount;
// rowIndex could be out of bounds if the the row got deleted after LostFocus handler was invoked. In this case it should return
if (rowIndex >= keyboardRemapControlObjects.size())
{
@@ -135,8 +132,8 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
}
// Validate both set of drop downs
KeyDropDownControl::ValidateShortcutFromDropDownList(parent, keyboardRemapControlObjects[rowIndex][0]->getShortcutControl(), keyboardRemapControlObjects[rowIndex][0]->shortcutDropDownStackPanel.as<StackPanel>(), 0, ShortcutControl::shortcutRemapBuffer, keyboardRemapControlObjects[rowIndex][0]->keyDropDownControlObjects, targetAppTextBox, false, false);
KeyDropDownControl::ValidateShortcutFromDropDownList(parent, keyboardRemapControlObjects[rowIndex][1]->getShortcutControl(), keyboardRemapControlObjects[rowIndex][1]->shortcutDropDownStackPanel.as<StackPanel>(), 1, ShortcutControl::shortcutRemapBuffer, keyboardRemapControlObjects[rowIndex][1]->keyDropDownControlObjects, targetAppTextBox, true, false);
KeyDropDownControl::ValidateShortcutFromDropDownList(parent, row, keyboardRemapControlObjects[rowIndex][0]->shortcutDropDownStackPanel.as<StackPanel>(), 0, ShortcutControl::shortcutRemapBuffer, keyboardRemapControlObjects[rowIndex][0]->keyDropDownControlObjects, targetAppTextBox, false, false);
KeyDropDownControl::ValidateShortcutFromDropDownList(parent, row, keyboardRemapControlObjects[rowIndex][1]->shortcutDropDownStackPanel.as<StackPanel>(), 1, ShortcutControl::shortcutRemapBuffer, keyboardRemapControlObjects[rowIndex][1]->keyDropDownControlObjects, targetAppTextBox, true, false);
// Reset the buffer based on the selected drop down items
std::get<Shortcut>(shortcutRemapBuffer[rowIndex].first[0]).SetKeyCodes(KeyDropDownControl::GetSelectedCodesFromStackPanel(keyboardRemapControlObjects[rowIndex][0]->shortcutDropDownStackPanel.as<StackPanel>()));
@@ -173,9 +170,14 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
ShortcutControl::SetAccessibleNameForTextBox(targetAppTextBox, rowIndex + 1);
});
parent.SetColumn(targetAppTextBox, KeyboardManagerConstants::ShortcutTableTargetAppColIndex);
parent.SetRow(targetAppTextBox, parent.RowDefinitions().Size() - 1);
parent.Children().Append(targetAppTextBox);
// We need two containers in order to align it horizontally and vertically
StackPanel targetAppHorizontal = KeyboardManagerHelper::GetWrapped(targetAppTextBox, KeyboardManagerConstants::TableTargetAppColWidth).as<StackPanel>();
targetAppHorizontal.Orientation(Orientation::Horizontal);
targetAppHorizontal.HorizontalAlignment(HorizontalAlignment::Left);
StackPanel targetAppContainer = KeyboardManagerHelper::GetWrapped(targetAppHorizontal, KeyboardManagerConstants::TableTargetAppColWidth).as<StackPanel>();
targetAppContainer.Orientation(Orientation::Vertical);
targetAppContainer.VerticalAlignment(VerticalAlignment::Bottom);
row.Children().Append(targetAppContainer);
// Delete row button
Windows::UI::Xaml::Controls::Button deleteShortcut;
@@ -185,12 +187,12 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
deleteShortcut.Content(deleteSymbol);
deleteShortcut.Background(Media::SolidColorBrush(Colors::Transparent()));
deleteShortcut.HorizontalAlignment(HorizontalAlignment::Center);
deleteShortcut.Click([&](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
deleteShortcut.Click([&, parent, row, brush](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
Button currentButton = sender.as<Button>();
uint32_t index;
uint32_t rowIndex;
// Get index of delete button
UIElementCollection children = parent.Children();
bool indexFound = children.IndexOf(currentButton, index);
bool indexFound = children.IndexOf(row, rowIndex);
// IndexOf could fail if the the row got deleted and the button handler was invoked twice. In this case it should return
if (!indexFound)
@@ -198,39 +200,24 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
return;
}
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++)
for (uint32_t i = rowIndex + 1; i < children.Size(); i++)
{
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), elementRowIndex - 1);
StackPanel row = children.GetAt(i).as<StackPanel>();
row.Background(i % 2 ? brush : Media::SolidColorBrush(Colors::Transparent()));
StackPanel sourceCol = row.Children().GetAt(0).as<StackPanel>();
StackPanel targetCol = row.Children().GetAt(2).as<StackPanel>();
TextBox targetApp = row.Children().GetAt(3).as<StackPanel>()
.Children().GetAt(0).as<StackPanel>()
.Children().GetAt(0).as<TextBox>();
Button delButton = row.Children().GetAt(4).as<StackPanel>().Children().GetAt(0).as<Button>();
UpdateAccessibleNames(sourceCol, targetCol, targetApp, delButton, i);
}
// Update accessible names for each row after the deleted row
for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i += KeyboardManagerConstants::ShortcutTableColCount)
{
// Get row index from grid
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
StackPanel sourceCol = children.GetAt(i + KeyboardManagerConstants::ShortcutTableOriginalColIndex).as<StackPanel>();
StackPanel targetCol = children.GetAt(i + KeyboardManagerConstants::ShortcutTableNewColIndex).as<StackPanel>();
TextBox targetApp = children.GetAt(i + KeyboardManagerConstants::ShortcutTableTargetAppColIndex).as<TextBox>();
Button delButton = children.GetAt(i + KeyboardManagerConstants::ShortcutTableRemoveColIndex).as<Button>();
UpdateAccessibleNames(sourceCol, targetCol, targetApp, delButton, elementRowIndex);
}
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 set of children are header elements and then three children in each row)
int bufferIndex = (lastIndexInRow - KeyboardManagerConstants::ShortcutTableHeaderCount) / KeyboardManagerConstants::ShortcutTableColCount;
// Delete the row definition
parent.RowDefinitions().RemoveAt(bufferIndex + 1);
// delete the row from the buffer
shortcutRemapBuffer.erase(shortcutRemapBuffer.begin() + bufferIndex);
// delete the ShortcutControl objects so that they get destructed
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + bufferIndex);
children.RemoveAt(rowIndex);
parent.UpdateLayout();
shortcutRemapBuffer.erase(shortcutRemapBuffer.begin() + rowIndex);
// delete the SingleKeyRemapControl objects so that they get destructed
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + rowIndex);
});
// To set the accessible name of the delete button
@@ -241,20 +228,22 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
deleteShortcuttoolTip.Content(box_value(GET_RESOURCE_STRING(IDS_DELETE_REMAPPING_BUTTON)));
ToolTipService::SetToolTip(deleteShortcut, deleteShortcuttoolTip);
parent.SetColumn(deleteShortcut, KeyboardManagerConstants::ShortcutTableRemoveColIndex);
parent.SetRow(deleteShortcut, parent.RowDefinitions().Size() - 1);
parent.Children().Append(deleteShortcut);
StackPanel deleteShortcutContainer = StackPanel();
deleteShortcutContainer.Children().Append(deleteShortcut);
deleteShortcutContainer.Orientation(Orientation::Vertical);
deleteShortcutContainer.VerticalAlignment(VerticalAlignment::Center);
row.Children().Append(deleteShortcutContainer);
parent.UpdateLayout();
// Set accessible names
UpdateAccessibleNames(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl(), keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl(), targetAppTextBox, deleteShortcut, parent.RowDefinitions().Size() - 1);
UpdateAccessibleNames(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getShortcutControl(), keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getShortcutControl(), targetAppTextBox, deleteShortcut, (int)keyboardRemapControlObjects.size());
// Set the shortcut text if the two vectors are not empty (i.e. default args)
if (originalKeys.IsValidShortcut() && !(newKeys.index() == 0 && std::get<DWORD>(newKeys) == NULL) && !(newKeys.index() == 1 && !std::get<Shortcut>(newKeys).IsValidShortcut()))
{
// change to load app name
shortcutRemapBuffer.push_back(std::make_pair<RemapBufferItem, std::wstring>(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring(targetAppName)));
KeyDropDownControl::AddShortcutToControl(originalKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->shortcutDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 0, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->keyDropDownControlObjects, shortcutRemapBuffer, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->shortcutControlLayout.as<StackPanel>(), targetAppTextBox, false, false);
KeyDropDownControl::AddShortcutToControl(originalKeys, parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->shortcutDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 0, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->keyDropDownControlObjects, shortcutRemapBuffer, row, targetAppTextBox, false, false);
if (newKeys.index() == 0)
{
@@ -262,7 +251,7 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector<std::ve
}
else
{
KeyDropDownControl::AddShortcutToControl(std::get<Shortcut>(newKeys), parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->shortcutDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 1, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects, shortcutRemapBuffer, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->shortcutControlLayout.as<StackPanel>(), targetAppTextBox, true, false);
KeyDropDownControl::AddShortcutToControl(std::get<Shortcut>(newKeys), parent, keyboardRemapControlObjects.back()[1]->shortcutDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 1, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects, shortcutRemapBuffer, row, targetAppTextBox, true, false);
}
}
else
@@ -279,7 +268,7 @@ StackPanel ShortcutControl::getShortcutControl()
}
// Function to create the detect shortcut UI window
void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState, const int colIndex, Grid table, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, HWND parentWindow, RemapBuffer& remapBuffer)
void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState, const int colIndex, StackPanel table, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, StackPanel row, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, HWND parentWindow, RemapBuffer& remapBuffer)
{
// ContentDialog for detecting shortcuts. This is the parent UI element.
ContentDialog detectShortcutBox;
@@ -310,7 +299,7 @@ void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IIn
table,
targetApp,
&keyDropDownControlObjects,
controlLayout,
row,
isHybridControl,
isSingleKeyWindow,
&remapBuffer] {
@@ -320,7 +309,7 @@ void ShortcutControl::createDetectShortcutWindow(winrt::Windows::Foundation::IIn
if (!detectedShortcutKeys.IsEmpty())
{
// The shortcut buffer gets set in this function
KeyDropDownControl::AddShortcutToControl(detectedShortcutKeys, table, linkedShortcutStackPanel, keyboardManagerState, colIndex, keyDropDownControlObjects, remapBuffer, controlLayout, targetApp, isHybridControl, isSingleKeyWindow);
KeyDropDownControl::AddShortcutToControl(detectedShortcutKeys, table, linkedShortcutStackPanel, keyboardManagerState, colIndex, keyDropDownControlObjects, remapBuffer, row, targetApp, isHybridControl, isSingleKeyWindow);
}
// Hide the type shortcut UI
detectShortcutBox.Hide();

View File

@@ -10,7 +10,6 @@ namespace winrt::Windows::UI::Xaml
namespace Controls
{
struct StackPanel;
struct Grid;
struct TextBox;
struct Button;
}
@@ -45,14 +44,14 @@ public:
std::vector<std::unique_ptr<KeyDropDownControl>> keyDropDownControlObjects;
// constructor
ShortcutControl(Grid table, const int colIndex, TextBox targetApp);
ShortcutControl(StackPanel table, StackPanel row, const int colIndex, TextBox targetApp);
// Function to add a new row to the shortcut table. If the originalKeys and newKeys args are provided, then the displayed shortcuts are set to those values.
static void AddNewShortcutControlRow(Grid& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, const Shortcut& originalKeys = Shortcut(), const KeyShortcutUnion& newKeys = Shortcut(), const std::wstring& targetAppName = L"");
static void AddNewShortcutControlRow(StackPanel& parent, std::vector<std::vector<std::unique_ptr<ShortcutControl>>>& keyboardRemapControlObjects, const Shortcut& originalKeys = Shortcut(), const KeyShortcutUnion& newKeys = Shortcut(), const std::wstring& targetAppName = L"");
// Function to return the stack panel element of the ShortcutControl. This is the externally visible UI element which can be used to add it to other layouts
StackPanel getShortcutControl();
// Function to create the detect shortcut UI window
static void createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState, const int colIndex, Grid table, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, HWND parentWindow, RemapBuffer& remapBuffer);
static void createDetectShortcutWindow(winrt::Windows::Foundation::IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState, const int colIndex, StackPanel table, std::vector<std::unique_ptr<KeyDropDownControl>>& keyDropDownControlObjects, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, HWND parentWindow, RemapBuffer& remapBuffer);
};

View File

@@ -15,14 +15,13 @@ KeyboardManagerState* SingleKeyRemapControl::keyboardManagerState = nullptr;
// Initialized as new vector
RemapBuffer SingleKeyRemapControl::singleKeyRemapBuffer;
SingleKeyRemapControl::SingleKeyRemapControl(Grid table, const int colIndex)
SingleKeyRemapControl::SingleKeyRemapControl(StackPanel table, StackPanel row, const int colIndex)
{
typeKey = Button();
typeKey.as<Button>().Width(KeyboardManagerConstants::RemapTableDropDownWidth);
typeKey.as<Button>().Content(winrt::box_value(GET_RESOURCE_STRING(IDS_TYPE_BUTTON)));
singleKeyRemapControlLayout = StackPanel();
singleKeyRemapControlLayout.as<StackPanel>().Margin({ 0, 0, 0, 10 });
singleKeyRemapControlLayout.as<StackPanel>().Spacing(10);
singleKeyRemapControlLayout.as<StackPanel>().Children().Append(typeKey.as<Button>());
@@ -32,7 +31,7 @@ SingleKeyRemapControl::SingleKeyRemapControl(Grid table, const int colIndex)
keyDropDownControlObjects.emplace_back(std::make_unique<KeyDropDownControl>(false));
singleKeyRemapControlLayout.as<StackPanel>().Children().Append(keyDropDownControlObjects[0]->GetComboBox());
// Set selection handler for the drop down
keyDropDownControlObjects[0]->SetSelectionHandler(table, singleKeyRemapControlLayout.as<StackPanel>(), colIndex, singleKeyRemapBuffer);
keyDropDownControlObjects[0]->SetSelectionHandler(table, row, colIndex, singleKeyRemapBuffer);
}
// Hybrid column
@@ -41,12 +40,11 @@ SingleKeyRemapControl::SingleKeyRemapControl(Grid table, const int colIndex)
hybridDropDownStackPanel = StackPanel();
hybridDropDownStackPanel.as<StackPanel>().Spacing(KeyboardManagerConstants::ShortcutTableDropDownSpacing);
hybridDropDownStackPanel.as<StackPanel>().Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
KeyDropDownControl::AddDropDown(table, singleKeyRemapControlLayout.as<StackPanel>(), hybridDropDownStackPanel.as<StackPanel>(), colIndex, singleKeyRemapBuffer, keyDropDownControlObjects, nullptr, true, true);
KeyDropDownControl::AddDropDown(table, row, hybridDropDownStackPanel.as<StackPanel>(), colIndex, singleKeyRemapBuffer, keyDropDownControlObjects, nullptr, true, true);
singleKeyRemapControlLayout.as<StackPanel>().Children().Append(hybridDropDownStackPanel.as<StackPanel>());
}
StackPanel controlStackPanel = singleKeyRemapControlLayout.as<StackPanel>();
typeKey.as<Button>().Click([&, table, colIndex, controlStackPanel](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
typeKey.as<Button>().Click([&, table, colIndex, row](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
// Using the XamlRoot of the typeKey to get the root of the XAML host
if (colIndex == 0)
{
@@ -56,7 +54,7 @@ SingleKeyRemapControl::SingleKeyRemapControl(Grid table, const int colIndex)
else
{
keyboardManagerState->SetUIState(KeyboardManagerUIState::DetectShortcutWindowInEditKeyboardWindowActivated, EditKeyboardWindowHandle);
ShortcutControl::createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), *keyboardManagerState, colIndex, table, keyDropDownControlObjects, controlStackPanel, nullptr, true, true, EditKeyboardWindowHandle, singleKeyRemapBuffer);
ShortcutControl::createDetectShortcutWindow(sender, sender.as<Button>().XamlRoot(), *keyboardManagerState, colIndex, table, keyDropDownControlObjects, row, nullptr, true, true, EditKeyboardWindowHandle, singleKeyRemapBuffer);
}
});
@@ -72,35 +70,43 @@ void SingleKeyRemapControl::UpdateAccessibleNames(StackPanel sourceColumn, Stack
}
// Function to add a new row to the remap keys table. If the originalKey and newKey args are provided, then the displayed remap keys are set to those values.
void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>>& keyboardRemapControlObjects, const DWORD originalKey, const KeyShortcutUnion newKey)
void SingleKeyRemapControl::AddNewControlKeyRemapRow(StackPanel& parent, std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>>& keyboardRemapControlObjects, const DWORD originalKey, const KeyShortcutUnion newKey)
{
// Create new SingleKeyRemapControl objects dynamically so that we does not get destructed
std::vector<std::unique_ptr<SingleKeyRemapControl>> newrow;
newrow.emplace_back(std::make_unique<SingleKeyRemapControl>(parent, 0));
newrow.emplace_back(std::make_unique<SingleKeyRemapControl>(parent, 1));
StackPanel row = StackPanel();
parent.Children().Append(row);
newrow.emplace_back(std::make_unique<SingleKeyRemapControl>(parent, row, 0));
newrow.emplace_back(std::make_unique<SingleKeyRemapControl>(parent, row, 1));
keyboardRemapControlObjects.push_back(std::move(newrow));
// Add to grid
parent.RowDefinitions().Append(RowDefinition());
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(), 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());
row.Padding({10, 10, 10, 10});
row.Orientation(Orientation::Horizontal);
auto brush = Windows::UI::Xaml::Application::Current().Resources().Lookup(box_value(L"SystemControlBackgroundListLowBrush")).as<Windows::UI::Xaml::Media::SolidColorBrush>();
if (keyboardRemapControlObjects.size() % 2)
{
row.Background(brush);
}
// SingleKeyRemapControl for the original key.
auto originalElement = keyboardRemapControlObjects.back()[0]->getSingleKeyRemapControl();
originalElement.Width(KeyboardManagerConstants::RemapTableDropDownWidth);
row.Children().Append(originalElement);
// Arrow icon
FontIcon arrowIcon;
arrowIcon.FontFamily(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);
auto arrowIconContainer = KeyboardManagerHelper::GetWrapped(arrowIcon, KeyboardManagerConstants::TableArrowColWidth).as<StackPanel>();
arrowIconContainer.Orientation(Orientation::Vertical);
arrowIconContainer.VerticalAlignment(VerticalAlignment::Center);
row.Children().Append(arrowIconContainer);
// SingleKeyRemapControl for the new remap key
parent.Children().Append(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl());
auto targetElement = keyboardRemapControlObjects.back()[1]->getSingleKeyRemapControl();
targetElement.Width(KeyboardManagerConstants::ShortcutTargetColumnWidth);
row.Children().Append(targetElement);
// Set the key text if the two keys are not null (i.e. default args)
if (originalKey != NULL && !(newKey.index() == 0 && std::get<DWORD>(newKey) == NULL) && !(newKey.index() == 1 && !std::get<Shortcut>(newKey).IsValidShortcut()))
@@ -113,7 +119,7 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
}
else
{
KeyDropDownControl::AddShortcutToControl(std::get<Shortcut>(newKey), parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->hybridDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 1, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects, singleKeyRemapBuffer, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->singleKeyRemapControlLayout.as<StackPanel>(), nullptr, true, true);
KeyDropDownControl::AddShortcutToControl(std::get<Shortcut>(newKey), parent, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->hybridDropDownStackPanel.as<StackPanel>(), *keyboardManagerState, 1, keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects, singleKeyRemapBuffer, row, nullptr, true, true);
}
}
else
@@ -130,51 +136,34 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
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;
deleteRemapKeys.Click([&, parent, row, brush](winrt::Windows::Foundation::IInspectable const& sender, RoutedEventArgs const&) {
uint32_t rowIndex;
// Get index of delete button
UIElementCollection children = parent.Children();
bool indexFound = children.IndexOf(currentButton, index);
bool indexFound = children.IndexOf(row, rowIndex);
// IndexOf could fail if the the row got deleted and the button handler was invoked twice. In this case it should return
if (!indexFound)
{
return;
}
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++)
// Update accessible names and background for each row after the deleted row
for (uint32_t i = rowIndex + 1; i < children.Size(); i++)
{
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
parent.SetRow(children.GetAt(i).as<FrameworkElement>(), elementRowIndex - 1);
StackPanel row = children.GetAt(i).as<StackPanel>();
row.Background(i % 2 ? brush : Media::SolidColorBrush(Colors::Transparent()));
StackPanel sourceCol = row.Children().GetAt(0).as<StackPanel>();
StackPanel targetCol = row.Children().GetAt(2).as<StackPanel>();
Button delButton = row.Children().GetAt(3).as<Button>();
UpdateAccessibleNames(sourceCol, targetCol, delButton, i);
}
// Update accessible names for each row after the deleted row
for (uint32_t i = lastIndexInRow + 1; i < children.Size(); i += KeyboardManagerConstants::RemapTableColCount)
{
// Get row index from grid
int32_t elementRowIndex = parent.GetRow(children.GetAt(i).as<FrameworkElement>());
StackPanel sourceCol = children.GetAt(i + KeyboardManagerConstants::RemapTableOriginalColIndex).as<StackPanel>();
StackPanel targetCol = children.GetAt(i + KeyboardManagerConstants::RemapTableNewColIndex).as<StackPanel>();
Button delButton = children.GetAt(i + KeyboardManagerConstants::RemapTableRemoveColIndex).as<Button>();
UpdateAccessibleNames(sourceCol, targetCol, delButton, elementRowIndex);
}
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 - KeyboardManagerConstants::RemapTableHeaderCount) / KeyboardManagerConstants::RemapTableColCount;
// Delete the row definition
parent.RowDefinitions().RemoveAt(bufferIndex + 1);
// delete the row from the buffer.
singleKeyRemapBuffer.erase(singleKeyRemapBuffer.begin() + bufferIndex);
children.RemoveAt(rowIndex);
parent.UpdateLayout();
singleKeyRemapBuffer.erase(singleKeyRemapBuffer.begin() + rowIndex);
// delete the SingleKeyRemapControl objects so that they get destructed
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + bufferIndex);
keyboardRemapControlObjects.erase(keyboardRemapControlObjects.begin() + rowIndex);
});
// To set the accessible name of the delete button
@@ -184,14 +173,11 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector<s
ToolTip deleteRemapKeystoolTip;
deleteRemapKeystoolTip.Content(box_value(GET_RESOURCE_STRING(IDS_DELETE_REMAPPING_BUTTON)));
ToolTipService::SetToolTip(deleteRemapKeys, deleteRemapKeystoolTip);
parent.SetColumn(deleteRemapKeys, KeyboardManagerConstants::RemapTableRemoveColIndex);
parent.SetRow(deleteRemapKeys, parent.RowDefinitions().Size() - 1);
parent.Children().Append(deleteRemapKeys);
row.Children().Append(deleteRemapKeys);
parent.UpdateLayout();
// Set accessible names
UpdateAccessibleNames(keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->getSingleKeyRemapControl(), keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->getSingleKeyRemapControl(), deleteRemapKeys, parent.RowDefinitions().Size() - 1);
UpdateAccessibleNames(keyboardRemapControlObjects.back()[0]->getSingleKeyRemapControl(), keyboardRemapControlObjects.back()[1]->getSingleKeyRemapControl(), deleteRemapKeys, (int)keyboardRemapControlObjects.size());
}
// Function to return the stack panel element of the SingleKeyRemapControl. This is the externally visible UI element which can be used to add it to other layouts

View File

@@ -40,10 +40,10 @@ public:
static RemapBuffer singleKeyRemapBuffer;
// constructor
SingleKeyRemapControl(Grid table, const int colIndex);
SingleKeyRemapControl(StackPanel table, StackPanel row, const int colIndex);
// Function to add a new row to the remap keys table. If the originalKey and newKey args are provided, then the displayed remap keys are set to those values.
static void AddNewControlKeyRemapRow(winrt::Windows::UI::Xaml::Controls::Grid& parent, std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>>& keyboardRemapControlObjects, const DWORD originalKey = NULL, const KeyShortcutUnion newKey = NULL);
static void AddNewControlKeyRemapRow(StackPanel& parent, std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>>& keyboardRemapControlObjects, const DWORD originalKey = NULL, const KeyShortcutUnion newKey = NULL);
// Function to return the stack panel element of the SingleKeyRemapControl. This is the externally visible UI element which can be used to add it to other layouts
winrt::Windows::UI::Xaml::Controls::StackPanel getSingleKeyRemapControl();

View File

@@ -4,10 +4,10 @@
namespace UIHelpers
{
// This method sets focus to the first Type button on the last row of the Grid
void SetFocusOnTypeButtonInLastRow(Grid& parent, long colCount)
void SetFocusOnTypeButtonInLastRow(StackPanel& parent, long colCount)
{
// First element in the last row (StackPanel)
StackPanel firstElementInLastRow = parent.Children().GetAt(parent.Children().Size() - colCount).as<StackPanel>();
StackPanel firstElementInLastRow = parent.Children().GetAt(parent.Children().Size() - 1).as<StackPanel>().Children().GetAt(0).as<StackPanel>();
// Type button is the first child in the StackPanel
Button firstTypeButtonInLastRow = firstElementInLastRow.Children().GetAt(0).as<Button>();

View File

@@ -4,5 +4,5 @@
namespace UIHelpers
{
// This method sets focus to the first Type button on the last row of the Grid
void SetFocusOnTypeButtonInLastRow(Grid& parent, long colCount);
void SetFocusOnTypeButtonInLastRow(StackPanel& parent, long colCount);
}