Get rid of indexes in dropdowns (#7278)

This commit is contained in:
Mykhailo Pylyp
2020-10-19 12:27:47 +03:00
committed by GitHub
parent b80578b1b9
commit 7e0574cba2
18 changed files with 469 additions and 628 deletions

View File

@@ -5,29 +5,34 @@
#include "BufferValidationHelpers.h"
#include <common\shared_constants.h>
#include <common\keyboard_layout_impl.h>
#include <modules\keyboardmanager\common\Helpers.h>
// Initialized to null
KeyboardManagerState* KeyDropDownControl::keyboardManagerState = nullptr;
// Get keys code list depending if Disable is in dropdown
std::vector<DWORD> KeyDropDownControl::GetKeyCodeList(bool isShortcut, bool renderDisable)
// Get selected value of dropdown or -1 if nothing is selected
DWORD KeyDropDownControl::GetSelectedValue(ComboBox comboBox)
{
auto list = keyboardManagerState->keyboardMap.GetKeyCodeList(isShortcut);
if (renderDisable)
{
list.insert(list.begin(), CommonSharedConstants::VK_DISABLED);
}
auto dataContext = comboBox.SelectedValue();
if (!dataContext)
return -1;
return list;
auto value = winrt::unbox_value<hstring>(dataContext);
return stoi(std::wstring(value));
}
void KeyDropDownControl::SetSelectedValue(std::wstring value)
{
this->dropDown.as<ComboBox>().SelectedValue(winrt::box_value(value));
}
// Get keys name list depending if Disable is in dropdown
std::vector<std::wstring> KeyDropDownControl::GetKeyNameList(bool isShortcut, bool renderDisable)
std::vector<std::pair<DWORD, std::wstring>> KeyDropDownControl::GetKeyList(bool isShortcut, bool renderDisable)
{
auto list = keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut);
if (renderDisable)
{
list.insert(list.begin(), keyboardManagerState->keyboardMap.GetKeyName(CommonSharedConstants::VK_DISABLED));
list.insert(list.begin(), { CommonSharedConstants::VK_DISABLED, keyboardManagerState->keyboardMap.GetKeyName(CommonSharedConstants::VK_DISABLED) });
}
return list;
@@ -51,8 +56,9 @@ void KeyDropDownControl::SetDefaultProperties(bool isShortcut, bool renderDisabl
dropDown.as<ComboBox>().MaxDropDownHeight(KeyboardManagerConstants::TableDropDownHeight);
// Initialise layout attribute
previousLayout = GetKeyboardLayout(0);
keyCodeList = GetKeyCodeList(isShortcut, renderDisable);
dropDown.as<ComboBox>().ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyNameList(isShortcut, renderDisable)));
dropDown.as<ComboBox>().SelectedValuePath(L"DataContext");
dropDown.as<ComboBox>().ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyList(isShortcut, renderDisable)));
// drop down open handler - to reload the items with the latest layout
dropDown.as<ComboBox>().DropDownOpened([&, isShortcut](winrt::Windows::Foundation::IInspectable const& sender, auto args) {
ComboBox currentDropDown = sender.as<ComboBox>();
@@ -82,8 +88,7 @@ void KeyDropDownControl::CheckAndUpdateKeyboardLayout(ComboBox currentDropDown,
// Check if the layout has changed
if (previousLayout != layout)
{
keyCodeList = GetKeyCodeList(isShortcut, renderDisable);
currentDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyNameList(isShortcut, renderDisable)));
currentDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyList(isShortcut, renderDisable)));
previousLayout = layout;
}
}
@@ -94,7 +99,8 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo
// drop down selection handler
auto onSelectionChange = [&, table, singleKeyControl, colIndex](winrt::Windows::Foundation::IInspectable const& sender) {
ComboBox currentDropDown = sender.as<ComboBox>();
int selectedKeyIndex = currentDropDown.SelectedIndex();
int selectedKeyCode = GetSelectedValue(currentDropDown);
// Get row index of the single key control
uint32_t controlIndex;
bool indexFound = table.Children().IndexOf(singleKeyControl, controlIndex);
@@ -104,7 +110,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo
int rowIndex = table.GetRow(singleKeyControl) - 1;
// Validate current remap selection
KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyIndex, keyCodeList, singleKeyRemapBuffer);
KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyCode, singleKeyRemapBuffer);
// If there is an error set the warning flyout
if (errorType != KeyboardManagerHelper::ErrorType::NoError)
@@ -132,7 +138,6 @@ 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)
{
ComboBox currentDropDown = dropDown.as<ComboBox>();
int selectedKeyIndex = currentDropDown.SelectedIndex();
uint32_t dropDownIndex = -1;
bool dropDownFound = parent.Children().IndexOf(currentDropDown, dropDownIndex);
// Get row index of the single key control
@@ -146,7 +151,7 @@ std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateSho
// GetRow will give the row index including the table header
rowIndex = table.GetRow(shortcutControl) - 1;
std::vector<int32_t> selectedIndices = GetSelectedIndicesFromStackPanel(parent);
std::vector<int32_t> selectedCodes = GetSelectedCodesFromStackPanel(parent);
std::wstring appName;
if (targetApp != nullptr)
@@ -155,7 +160,7 @@ std::pair<KeyboardManagerHelper::ErrorType, int> KeyDropDownControl::ValidateSho
}
// Validate shortcut element
validationResult = BufferValidationHelpers::ValidateShortcutBufferElement(rowIndex, colIndex, dropDownIndex, selectedIndices, appName, isHybridControl, keyCodeList, shortcutRemapBuffer, dropDownFound);
validationResult = BufferValidationHelpers::ValidateShortcutBufferElement(rowIndex, colIndex, dropDownIndex, selectedCodes, appName, isHybridControl, shortcutRemapBuffer, dropDownFound);
// Add or clear unused drop downs
if (validationResult.second == BufferValidationHelpers::DropDownAction::AddDropDown)
@@ -229,7 +234,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon
}
// Reset the buffer based on the new selected drop down items. Use static key code list since the KeyDropDownControl object might be deleted
std::vector selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(GetSelectedIndicesFromStackPanel(parent), GetKeyCodeList(true, colIndex == 1));
std::vector<int32_t> selectedKeyCodes = GetSelectedCodesFromStackPanel(parent);
if (!isHybridControl)
{
std::get<Shortcut>(shortcutRemapBuffer[validationResult.second].first[colIndex]).SetKeyCodes(selectedKeyCodes);
@@ -237,7 +242,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon
else
{
// If exactly one key is selected consider it to be a key remap
if (selectedKeyCodes.size() == 1)
if (GetNumberOfSelectedKeys(selectedKeyCodes) == 1)
{
shortcutRemapBuffer[validationResult.second].first[colIndex] = selectedKeyCodes[0];
}
@@ -294,12 +299,6 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon
});
}
// Function to set the selected index of the drop down
void KeyDropDownControl::SetSelectedIndex(int32_t index)
{
dropDown.as<ComboBox>().SelectedIndex(index);
}
// Function to return the combo box element of the drop down
ComboBox KeyDropDownControl::GetComboBox()
{
@@ -319,18 +318,18 @@ void KeyDropDownControl::AddDropDown(Grid table, StackPanel shortcutControl, Sta
}
// Function to get the list of key codes from the shortcut combo box stack panel
std::vector<int32_t> KeyDropDownControl::GetSelectedIndicesFromStackPanel(StackPanel parent)
std::vector<int32_t> KeyDropDownControl::GetSelectedCodesFromStackPanel(StackPanel parent)
{
std::vector<int32_t> selectedIndices;
std::vector<int32_t> selectedKeyCodes;
// Get selected indices for each drop down
for (int i = 0; i < (int)parent.Children().Size(); i++)
{
ComboBox ItDropDown = parent.Children().GetAt(i).as<ComboBox>();
selectedIndices.push_back(ItDropDown.SelectedIndex());
selectedKeyCodes.push_back(GetSelectedValue(ItDropDown));
}
return selectedIndices;
return selectedKeyCodes;
}
// Function for validating the selection of shortcuts for all the associated drop downs
@@ -340,9 +339,9 @@ void KeyDropDownControl::ValidateShortcutFromDropDownList(Grid table, StackPanel
for (int i = 0; i < keyDropDownControlObjects.size(); i++)
{
// Check for errors only if the current selection is a valid shortcut
std::vector<DWORD> selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(keyDropDownControlObjects[i]->GetSelectedIndicesFromStackPanel(parent), GetKeyCodeList(true, colIndex == 1));
std::vector<int32_t> selectedKeyCodes = GetSelectedCodesFromStackPanel(parent);
KeyShortcutUnion currentShortcut;
if (selectedKeyCodes.size() == 1 && isHybridControl)
if (GetNumberOfSelectedKeys(selectedKeyCodes) == 1 && isHybridControl)
{
currentShortcut = selectedKeyCodes[0];
}
@@ -354,7 +353,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())) && keyDropDownControlObjects[i]->GetComboBox().SelectedIndex() != -1)
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);
}
@@ -376,9 +375,7 @@ void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, Sta
parent.Children().Clear();
// Remove references to the old drop down objects to destroy them
keyDropDownControlObjects.clear();
std::vector<DWORD> shortcutKeyCodes = shortcut.GetKeyCodes();
std::vector<DWORD> keyCodeList = GetKeyCodeList(true, colIndex == 1);
if (shortcutKeyCodes.size() != 0)
{
bool ignoreWarning = false;
@@ -393,17 +390,19 @@ void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, Sta
for (int i = 0; i < shortcutKeyCodes.size(); i++)
{
// New drop down gets added automatically when the SelectedIndex is set
// New drop down gets added automatically when the SelectedValue(key code) is set
if (i < (int)parent.Children().Size())
{
ComboBox currentDropDown = parent.Children().GetAt(i).as<ComboBox>();
auto it = std::find(keyCodeList.begin(), keyCodeList.end(), shortcutKeyCodes[i]);
if (it != keyCodeList.end())
{
currentDropDown.SelectedIndex((int32_t)std::distance(keyCodeList.begin(), it));
}
currentDropDown.SelectedValue(winrt::box_value(std::to_wstring(shortcutKeyCodes[i])));
}
}
}
parent.UpdateLayout();
}
// Get number of selected keys. Do not count -1 and 0 values as they stand for Not selected and None
int KeyDropDownControl::GetNumberOfSelectedKeys(std::vector<int32_t> keyCodes)
{
return (int)std::count_if(keyCodes.begin(), keyCodes.end(), [](int32_t a) { return a != -1 && a != 0; });
}