Refactored Keyboard Manager UI code and added unit tests for Keyboard Manager UI (#5718)

* Added tests for loading and saving remappings in the UI

* Added tests for ApplyRemappings methods

* Moved single key remap validation logic to separate method so that it can be tested

* Added tests for single key remap validation in UI

* Refactored shortcut validation code to be testable

* Added some shortcut validation tests

* Refactored code to be cleaner

* Added tests for action key and modifier key selection and formatted file

* Added tests for selecting None

* Added tests for selecting Null

* Added tests for WinL error

* Added CtrlAltDel tests

* Added tests for MapToSameKey

* Added tests for mapping repeated shortcut

* Fixed const correctness

* Clean up type names with type alias

* Clean up ValidateAndUpdateKeyBufferElement tests and tweak ValidateShortcutBufferElement signature

* Fixed bug when None selected

* Refactored one test as per test case framework

* Cleaned up more tests

* Cleaned up buffer validation tests

* Added tests for KBM Common Helpers and Shortcut
This commit is contained in:
Arjun Balgovind
2020-08-13 16:32:15 -07:00
committed by GitHub
parent 0b5749d491
commit 9e8b0d2807
30 changed files with 3077 additions and 602 deletions

View File

@@ -3,6 +3,7 @@
#include <sstream>
#include "../common/shared_constants.h"
#include <shlwapi.h>
#include "../common/keyboard_layout.h"
using namespace winrt::Windows::Foundation;
@@ -325,4 +326,59 @@ namespace KeyboardManagerHelper
return first.Size() > second.Size();
});
}
// Function to check if a modifier has been repeated in the previous drop downs
bool CheckRepeatedModifier(std::vector<DWORD>& currentKeys, int selectedKeyIndex, const std::vector<DWORD>& keyCodeList)
{
// check if modifier has already been added before in a previous drop down
int currentDropDownIndex = -1;
// Find the key index of the current drop down selection so that we skip that index while searching for repeated modifiers
for (int i = 0; i < currentKeys.size(); i++)
{
if (currentKeys[i] == keyCodeList[selectedKeyIndex])
{
currentDropDownIndex = i;
break;
}
}
bool matchPreviousModifier = false;
for (int i = 0; i < currentKeys.size(); i++)
{
// Skip the current drop down
if (i != currentDropDownIndex)
{
// If the key type for the newly added key matches any of the existing keys in the shortcut
if (KeyboardManagerHelper::GetKeyType(keyCodeList[selectedKeyIndex]) == KeyboardManagerHelper::GetKeyType(currentKeys[i]))
{
matchPreviousModifier = true;
break;
}
}
}
return matchPreviousModifier;
}
// Function to get the selected key codes from the list of selected indices
std::vector<DWORD> GetKeyCodesFromSelectedIndices(const std::vector<int32_t>& selectedIndices, const std::vector<DWORD>& keyCodeList)
{
std::vector<DWORD> keys;
for (int i = 0; i < selectedIndices.size(); i++)
{
int selectedKeyIndex = selectedIndices[i];
if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex)
{
// If None is not the selected key
if (keyCodeList[selectedKeyIndex] != 0)
{
keys.push_back(keyCodeList[selectedKeyIndex]);
}
}
}
return keys;
}
}

View File

@@ -15,6 +15,8 @@ namespace winrt
}
}
class LayoutMap;
namespace KeyboardManagerHelper
{
// Type to distinguish between keys
@@ -99,4 +101,10 @@ namespace KeyboardManagerHelper
// Function to sort a vector of shortcuts based on it's size
void SortShortcutVectorBasedOnSize(std::vector<Shortcut>& shortcutVector);
// Function to check if a modifier has been repeated in the previous drop downs
bool CheckRepeatedModifier(std::vector<DWORD>& currentKeys, int selectedKeyIndex, const std::vector<DWORD>& keyCodeList);
// Function to get the selected key codes from the list of selected indices
std::vector<DWORD> GetKeyCodesFromSelectedIndices(const std::vector<int32_t>& selectedIndices, const std::vector<DWORD>& keyCodeList);
}

View File

@@ -19,4 +19,9 @@ public:
targetShortcut(Shortcut()), isShortcutInvoked(false), winKeyInvoked(ModifierKey::Disabled)
{
}
inline bool operator==(const RemapShortcut& sc) const
{
return targetShortcut == sc.targetShortcut && isShortcutInvoked == sc.isShortcutInvoked && winKeyInvoked == sc.winKeyInvoked;
}
};

View File

@@ -17,6 +17,12 @@ Shortcut::Shortcut(const std::wstring& shortcutVK) :
}
}
// Constructor to initialize shortcut from a list of keys
Shortcut::Shortcut(const std::vector<DWORD>& keys)
{
SetKeyCodes(keys);
}
// Function to return the number of keys in the shortcut
int Shortcut::Size() const
{

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ModifierKey.h"
#include <variant>
class InputInterface;
class LayoutMap;
namespace KeyboardManagerHelper
@@ -26,6 +27,9 @@ public:
// Constructor to initialize Shortcut from it's virtual key code string representation.
Shortcut(const std::wstring& shortcutVK);
// Constructor to initialize shortcut from a list of keys
Shortcut(const std::vector<DWORD>& keys);
// == operator
inline bool operator==(const Shortcut& sc) const
{
@@ -166,3 +170,7 @@ public:
// Function to check if the shortcut is illegal (i.e. Win+L or Ctrl+Alt+Del)
KeyboardManagerHelper::ErrorType IsShortcutIllegal() const;
};
using RemapBufferItem = std::vector<std::variant<DWORD, Shortcut>>;
using RemapBufferRow = std::pair<RemapBufferItem, std::wstring>;
using RemapBuffer = std::vector<RemapBufferRow>;