Remap Keyboard UI (dev/keyboardManager) (#1698)
* Added initial UI implementation * Added backend logic for remap key interaction * Added single key remap control * Updated Edit keyboardWindow UI * Commented out ui logic * Fixed issue with remap window UI and uncommented the code * Updated customdialog window foreground color * Updated buttons foreground color * Added info header * Added null check for detected key * Removed fully qualified namespaces * updated the background color as ligtht gray
This commit is contained in:
parent
90ddcb30bf
commit
f48040a4d7
8 changed files with 392 additions and 14 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Constructor
|
||||
KeyboardManagerState::KeyboardManagerState() :
|
||||
uiState(KeyboardManagerUIState::Deactivated), currentUIWindow(nullptr), currentShortcutTextBlock(nullptr)
|
||||
uiState(KeyboardManagerUIState::Deactivated), currentUIWindow(nullptr), currentShortcutTextBlock(nullptr), currentSingleKeyRemapTextBlock(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,10 @@ void KeyboardManagerState::ResetUIState()
|
|||
SetUIState(KeyboardManagerUIState::Deactivated);
|
||||
currentShortcutTextBlock = nullptr;
|
||||
detectedShortcut.clear();
|
||||
|
||||
// Reset all the single key remap stored variables.
|
||||
currentSingleKeyRemapTextBlock = nullptr;
|
||||
detectedRemapKey = NULL;
|
||||
}
|
||||
|
||||
// Function to clear the OS Level shortcut remapping table
|
||||
|
@ -54,18 +58,36 @@ void KeyboardManagerState::ClearOSLevelShortcuts()
|
|||
osLevelShortcutReMap.clear();
|
||||
}
|
||||
|
||||
// Function to clear the Keys remapping table.
|
||||
void KeyboardManagerState::ClearSingleKeyRemaps()
|
||||
{
|
||||
singleKeyReMap.clear();
|
||||
}
|
||||
|
||||
// Function to add a new OS level shortcut remapping
|
||||
void KeyboardManagerState::AddOSLevelShortcut(const std::vector<DWORD>& originalSC, const std::vector<WORD>& newSC)
|
||||
{
|
||||
osLevelShortcutReMap[originalSC] = std::make_pair(newSC, false);
|
||||
}
|
||||
|
||||
// Function to add a new OS level shortcut remapping
|
||||
void KeyboardManagerState::AddSingleKeyRemap(const DWORD& originalKey, const WORD& newRemapKey)
|
||||
{
|
||||
singleKeyReMap[originalKey] = newRemapKey;
|
||||
}
|
||||
|
||||
// Function to set the textblock of the detect shortcut UI so that it can be accessed by the hook
|
||||
void KeyboardManagerState::ConfigureDetectShortcutUI(const TextBlock& textBlock)
|
||||
{
|
||||
currentShortcutTextBlock = textBlock;
|
||||
}
|
||||
|
||||
// Function to set the textblock of the detect remap key UI so that it can be accessed by the hook
|
||||
void KeyboardManagerState::ConfigureDetectSingleKeyRemapUI(const TextBlock& textBlock)
|
||||
{
|
||||
currentSingleKeyRemapTextBlock = textBlock;
|
||||
}
|
||||
|
||||
// Function to update the detect shortcut UI based on the entered keys
|
||||
void KeyboardManagerState::UpdateDetectShortcutUI()
|
||||
{
|
||||
|
@ -82,6 +104,22 @@ void KeyboardManagerState::UpdateDetectShortcutUI()
|
|||
});
|
||||
}
|
||||
|
||||
// Function to update the detect remap key UI based on the entered key.
|
||||
void KeyboardManagerState::UpdateDetectSingleKeyRemapUI()
|
||||
{
|
||||
if (currentSingleKeyRemapTextBlock == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hstring remapKeyString = winrt::to_hstring((unsigned int)detectedRemapKey);
|
||||
|
||||
// Since this function is invoked from the back-end thread, in order to update the UI the dispatcher must be used.
|
||||
currentSingleKeyRemapTextBlock.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]() {
|
||||
currentSingleKeyRemapTextBlock.Text(remapKeyString);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to return the currently detected shortcut which is displayed on the UI
|
||||
std::vector<DWORD> KeyboardManagerState::GetDetectedShortcut()
|
||||
{
|
||||
|
@ -91,12 +129,28 @@ std::vector<DWORD> KeyboardManagerState::GetDetectedShortcut()
|
|||
return convertWStringVectorToIntegerVector<DWORD>(detectedShortcutVector);
|
||||
}
|
||||
|
||||
// Function to return the currently detected remap key which is displayed on the UI
|
||||
DWORD KeyboardManagerState::GetDetectedSingleRemapKey()
|
||||
{
|
||||
hstring remapKeyString = currentSingleKeyRemapTextBlock.Text();
|
||||
std::wstring remapKeyWString = remapKeyString.c_str();
|
||||
DWORD remapKey = NULL;
|
||||
if (!remapKeyString.empty())
|
||||
{
|
||||
remapKey = std::stoul(remapKeyWString);
|
||||
}
|
||||
|
||||
return remapKey;
|
||||
}
|
||||
|
||||
// Function which can be used in HandleKeyboardHookEvent before the single key remap event to use the UI and suppress events while the remap window is active.
|
||||
bool KeyboardManagerState::DetectKeyUIBackend(LowlevelKeyboardEvent* data)
|
||||
bool KeyboardManagerState::DetectSingleRemapKeyUIBackend(LowlevelKeyboardEvent* data)
|
||||
{
|
||||
// Check if the detect key UI window has been activated
|
||||
if (CheckUIState(KeyboardManagerUIState::DetectKeyWindowActivated))
|
||||
if (CheckUIState(KeyboardManagerUIState::DetectSingleKeyRemapWindowActivated))
|
||||
{
|
||||
detectedRemapKey = data->lParam->vkCode;
|
||||
UpdateDetectSingleKeyRemapUI();
|
||||
// Suppress the keyboard event
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ enum class KeyboardManagerUIState
|
|||
// If set to this value then there is no keyboard manager window currently active that requires a hook
|
||||
Deactivated,
|
||||
// If set to this value then the detect key window is currently active and it requires a hook
|
||||
DetectKeyWindowActivated,
|
||||
DetectSingleKeyRemapWindowActivated,
|
||||
// If set to this value then the detect shortcut window is currently active and it requires a hook
|
||||
DetectShortcutWindowActivated
|
||||
};
|
||||
|
@ -29,8 +29,14 @@ private:
|
|||
// Vector to store the shortcut detected in the detect shortcut UI window. This is used in both the backend and the UI.
|
||||
std::vector<DWORD> detectedShortcut;
|
||||
|
||||
// Store detected remap key in the remap UI window. This is used in both the backend and the UI.
|
||||
DWORD detectedRemapKey;
|
||||
|
||||
// Stores the UI element which is to be updated based on the remap key entered.
|
||||
TextBlock currentSingleKeyRemapTextBlock;
|
||||
|
||||
// Stores the UI element which is to be updated based on the shortcut entered
|
||||
winrt::Windows::UI::Xaml::Controls::TextBlock currentShortcutTextBlock;
|
||||
TextBlock currentShortcutTextBlock;
|
||||
|
||||
public:
|
||||
// Maps which store the remappings for each of the features. The bool fields should be initalised to false. They are used to check the current state of the shortcut (i.e is that particular shortcut currently pressed down or not).
|
||||
|
@ -64,20 +70,35 @@ public:
|
|||
// Function to clear the OS Level shortcut remapping table
|
||||
void ClearOSLevelShortcuts();
|
||||
|
||||
// Function to clear the Keys remapping table
|
||||
void ClearSingleKeyRemaps();
|
||||
|
||||
// Function to add a new single key remapping
|
||||
void AddSingleKeyRemap(const DWORD& originalKey, const WORD& newRemapKey);
|
||||
|
||||
// Function to add a new OS level shortcut remapping
|
||||
void AddOSLevelShortcut(const std::vector<DWORD>& originalSC, const std::vector<WORD>& newSC);
|
||||
|
||||
// Function to set the textblock of the detect shortcut UI so that it can be accessed by the hook
|
||||
void ConfigureDetectShortcutUI(const winrt::Windows::UI::Xaml::Controls::TextBlock& textBlock);
|
||||
void ConfigureDetectShortcutUI(const TextBlock& textBlock);
|
||||
|
||||
// Function to set the textblock of the detect remap key UI so that it can be accessed by the hook
|
||||
void ConfigureDetectSingleKeyRemapUI(const TextBlock& textBlock);
|
||||
|
||||
// Function to update the detect shortcut UI based on the entered keys
|
||||
void UpdateDetectShortcutUI();
|
||||
|
||||
// Function to update the detect remap key UI based on the entered key.
|
||||
void UpdateDetectSingleKeyRemapUI();
|
||||
|
||||
// Function to return the currently detected shortcut which is displayed on the UI
|
||||
std::vector<DWORD> GetDetectedShortcut();
|
||||
|
||||
// Function to return the currently detected remap key which is displayed on the UI
|
||||
DWORD GetDetectedSingleRemapKey();
|
||||
|
||||
// Function which can be used in HandleKeyboardHookEvent before the single key remap event to use the UI and suppress events while the remap window is active.
|
||||
bool DetectKeyUIBackend(LowlevelKeyboardEvent* data);
|
||||
bool DetectSingleRemapKeyUIBackend(LowlevelKeyboardEvent* data);
|
||||
|
||||
// Function which can be used in HandleKeyboardHookEvent before the os level shortcut remap event to use the UI and suppress events while the remap window is active.
|
||||
bool DetectShortcutUIBackend(LowlevelKeyboardEvent* data);
|
||||
|
|
|
@ -262,7 +262,7 @@ public:
|
|||
intptr_t HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) noexcept
|
||||
{
|
||||
// If the Detect Key Window is currently activated, then suppress the keyboard event
|
||||
if (keyboardManagerState.DetectKeyUIBackend(data))
|
||||
if (keyboardManagerState.DetectSingleRemapKeyUIBackend(data))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "pch.h"
|
||||
#include "EditKeyboardWindow.h"
|
||||
#include "SingleKeyRemapControl.h"
|
||||
|
||||
LRESULT CALLBACK EditKeyboardWindowProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
|
@ -38,8 +39,8 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
|||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
400,
|
||||
400,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
hInst,
|
||||
|
@ -63,14 +64,148 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
|
|||
// Update the xaml island window size becuase initially is 0,0
|
||||
SetWindowPos(hWndXamlIslandEditKeyboardWindow, 0, 0, 0, 400, 400, SWP_SHOWWINDOW);
|
||||
|
||||
//Creating the Xaml content
|
||||
// Creating the Xaml content. xamlContainer is the parent UI element
|
||||
Windows::UI::Xaml::Controls::StackPanel xamlContainer;
|
||||
xamlContainer.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
Windows::UI::Xaml::Controls::Button bt;
|
||||
bt.Content(winrt::box_value(winrt::to_hstring("Don't Type key")));
|
||||
xamlContainer.Children().Append(bt);
|
||||
|
||||
// Header for the window
|
||||
Windows::UI::Xaml::Controls::StackPanel header;
|
||||
header.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
|
||||
header.Margin({ 10, 10, 10, 30 });
|
||||
header.Spacing(10);
|
||||
|
||||
// Header text
|
||||
TextBlock headerText;
|
||||
headerText.Text(winrt::to_hstring("Remap Keyboard"));
|
||||
headerText.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
headerText.FontSize(30);
|
||||
headerText.Margin({ 0, 0, 1000, 0 });
|
||||
|
||||
// Header Cancel button
|
||||
Button cancelButton;
|
||||
cancelButton.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
cancelButton.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
cancelButton.Content(winrt::box_value(winrt::to_hstring("Cancel")));
|
||||
cancelButton.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
|
||||
// Close the window since settings do not need to be saved
|
||||
PostMessage(_hWndEditKeyboardWindow, WM_CLOSE, 0, 0);
|
||||
});
|
||||
|
||||
// Text block for information about remap key section.
|
||||
TextBlock keyRemapInfoHeader;
|
||||
keyRemapInfoHeader.Text(winrt::to_hstring("Select the key you want to remap, original key, and it's new output when pressed, the new key"));
|
||||
keyRemapInfoHeader.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
keyRemapInfoHeader.Margin({ 0, 0, 0, 10 });
|
||||
|
||||
// Table to display the key remaps
|
||||
Windows::UI::Xaml::Controls::StackPanel keyRemapTable;
|
||||
keyRemapTable.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
keyRemapTable.Margin({ 10, 10, 10, 20 });
|
||||
keyRemapTable.Spacing(10);
|
||||
|
||||
// Header row of the keys remap table
|
||||
Windows::UI::Xaml::Controls::StackPanel tableHeaderRow;
|
||||
tableHeaderRow.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
tableHeaderRow.Spacing(100);
|
||||
tableHeaderRow.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
|
||||
|
||||
// First header textblock in the header row of the keys remap table
|
||||
TextBlock originalKeyRemapHeader;
|
||||
originalKeyRemapHeader.Text(winrt::to_hstring("Original Key:"));
|
||||
originalKeyRemapHeader.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
originalKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
|
||||
originalKeyRemapHeader.Margin({ 0, 0, 0, 10 });
|
||||
tableHeaderRow.Children().Append(originalKeyRemapHeader);
|
||||
|
||||
// Second header textblock in the header row of the keys remap table
|
||||
TextBlock newKeyRemapHeader;
|
||||
newKeyRemapHeader.Text(winrt::to_hstring("New Key:"));
|
||||
newKeyRemapHeader.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
newKeyRemapHeader.FontWeight(Text::FontWeights::Bold());
|
||||
newKeyRemapHeader.Margin({ 0, 0, 0, 10 });
|
||||
tableHeaderRow.Children().Append(newKeyRemapHeader);
|
||||
|
||||
keyRemapTable.Children().Append(tableHeaderRow);
|
||||
|
||||
// Message to display success/failure of saving settings.
|
||||
TextBlock settingsMessage;
|
||||
|
||||
// Main Header Apply button
|
||||
Button applyButton;
|
||||
applyButton.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
applyButton.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
applyButton.Content(winrt::box_value(winrt::to_hstring("Apply")));
|
||||
applyButton.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
|
||||
bool isSuccess = true;
|
||||
// Clear existing Key Remaps
|
||||
keyboardManagerState.ClearSingleKeyRemaps();
|
||||
|
||||
// Save the keys that are valid and report if any of them were invalid
|
||||
for (unsigned int i = 1; i < keyRemapTable.Children().Size(); i++)
|
||||
{
|
||||
StackPanel currentRow = keyRemapTable.Children().GetAt(i).as<StackPanel>();
|
||||
hstring originalKeyString = currentRow.Children().GetAt(0).as<StackPanel>().Children().GetAt(1).as<TextBlock>().Text();
|
||||
hstring newKeyString = currentRow.Children().GetAt(1).as<StackPanel>().Children().GetAt(1).as<TextBlock>().Text();
|
||||
if (!originalKeyString.empty() && !newKeyString.empty())
|
||||
{
|
||||
DWORD originalKey = std::stoi(originalKeyString.c_str());
|
||||
DWORD newKey = std::stoi(newKeyString.c_str());
|
||||
keyboardManagerState.AddSingleKeyRemap(originalKey, newKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
isSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSuccess)
|
||||
{
|
||||
settingsMessage.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Green() });
|
||||
settingsMessage.Text(winrt::to_hstring("Remapping successful!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsMessage.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Red() });
|
||||
settingsMessage.Text(winrt::to_hstring("All remappings were not successfully applied."));
|
||||
}
|
||||
});
|
||||
|
||||
header.Children().Append(headerText);
|
||||
header.Children().Append(cancelButton);
|
||||
header.Children().Append(applyButton);
|
||||
header.Children().Append(settingsMessage);
|
||||
|
||||
// Store handle of edit keyboard window
|
||||
SingleKeyRemapControl::EditKeyboardWindowHandle = _hWndEditKeyboardWindow;
|
||||
// Store keyboard manager state
|
||||
SingleKeyRemapControl::keyboardManagerState = &keyboardManagerState;
|
||||
|
||||
// Load existing remaps into UI
|
||||
for (const auto& it : keyboardManagerState.singleKeyReMap)
|
||||
{
|
||||
SingleKeyRemapControl::AddNewControlKeyRemapRow(keyRemapTable, it.first, it.second);
|
||||
}
|
||||
|
||||
// Add remap key button
|
||||
Windows::UI::Xaml::Controls::Button addRemapKey;
|
||||
addRemapKey.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
addRemapKey.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
FontIcon plusSymbol;
|
||||
plusSymbol.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
plusSymbol.Glyph(L"\xE109");
|
||||
addRemapKey.Content(plusSymbol);
|
||||
addRemapKey.Margin({ 10 });
|
||||
addRemapKey.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
|
||||
SingleKeyRemapControl::AddNewControlKeyRemapRow(keyRemapTable);
|
||||
});
|
||||
|
||||
xamlContainer.Children().Append(header);
|
||||
xamlContainer.Children().Append(keyRemapInfoHeader);
|
||||
xamlContainer.Children().Append(keyRemapTable);
|
||||
xamlContainer.Children().Append(addRemapKey);
|
||||
xamlContainer.UpdateLayout();
|
||||
desktopSource.Content(xamlContainer);
|
||||
|
||||
////End XAML Island section
|
||||
if (_hWndEditKeyboardWindow)
|
||||
{
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShortcutControl.cpp" />
|
||||
<ClCompile Include="SingleKeyRemapControl.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EditKeyboardWindow.h" />
|
||||
|
@ -111,6 +112,7 @@
|
|||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="MainWindow.h" />
|
||||
<ClInclude Include="ShortcutControl.h" />
|
||||
<ClInclude Include="SingleKeyRemapControl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<ClCompile Include="EditShortcutsWindow.cpp" />
|
||||
<ClCompile Include="ShortcutControl.cpp" />
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="SingleKeyRemapControl.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MainWindow.h" />
|
||||
|
@ -13,6 +14,7 @@
|
|||
<ClInclude Include="EditShortcutsWindow.h" />
|
||||
<ClInclude Include="ShortcutControl.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="SingleKeyRemapControl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
115
src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp
Normal file
115
src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "pch.h"
|
||||
#include "SingleKeyRemapControl.h"
|
||||
|
||||
//Both static members are initialized to null
|
||||
HWND SingleKeyRemapControl::EditKeyboardWindowHandle = nullptr;
|
||||
KeyboardManagerState* SingleKeyRemapControl::keyboardManagerState = nullptr;
|
||||
|
||||
// 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(StackPanel& parent, const DWORD& originalKey, const WORD& newKey)
|
||||
{
|
||||
// Parent element for the row
|
||||
Windows::UI::Xaml::Controls::StackPanel tableRow;
|
||||
tableRow.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
tableRow.Spacing(100);
|
||||
tableRow.Orientation(Windows::UI::Xaml::Controls::Orientation::Horizontal);
|
||||
|
||||
// SingleKeyRemapControl for the original key.
|
||||
SingleKeyRemapControl originalRemapKeyControl;
|
||||
tableRow.Children().Append(originalRemapKeyControl.getSingleKeyRemapControl());
|
||||
|
||||
// SingleKeyRemapControl for the new remap key.
|
||||
SingleKeyRemapControl newRemapKeyControl;
|
||||
tableRow.Children().Append(newRemapKeyControl.getSingleKeyRemapControl());
|
||||
|
||||
// Set the key text if the two keys are not null (i.e. default args)
|
||||
if (originalKey != NULL && newKey != NULL)
|
||||
{
|
||||
originalRemapKeyControl.singleKeyRemapText.Text(winrt::to_hstring((unsigned int)originalKey));
|
||||
newRemapKeyControl.singleKeyRemapText.Text(winrt::to_hstring((unsigned int)newKey));
|
||||
}
|
||||
|
||||
// Delete row button
|
||||
Windows::UI::Xaml::Controls::Button deleteRemapKeys;
|
||||
deleteRemapKeys.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
deleteRemapKeys.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
FontIcon deleteSymbol;
|
||||
deleteSymbol.FontFamily(Xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
||||
deleteSymbol.Glyph(L"\xE74D");
|
||||
deleteRemapKeys.Content(deleteSymbol);
|
||||
deleteRemapKeys.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
|
||||
StackPanel currentRow = sender.as<Button>().Parent().as<StackPanel>();
|
||||
uint32_t index;
|
||||
parent.Children().IndexOf(currentRow, index);
|
||||
parent.Children().RemoveAt(index);
|
||||
});
|
||||
tableRow.Children().Append(deleteRemapKeys);
|
||||
parent.Children().Append(tableRow);
|
||||
}
|
||||
|
||||
// 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
|
||||
StackPanel SingleKeyRemapControl::getSingleKeyRemapControl()
|
||||
{
|
||||
return singleKeyRemapControlLayout;
|
||||
}
|
||||
|
||||
// Function to create the detect remap key UI window
|
||||
void SingleKeyRemapControl::createDetectKeyWindow(IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState)
|
||||
{
|
||||
// ContentDialog for detecting remap key. This is the parent UI element.
|
||||
ContentDialog detectRemapKeyBox;
|
||||
|
||||
// ContentDialog requires manually setting the XamlRoot (https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.contentdialog#contentdialog-in-appwindow-or-xaml-islands)
|
||||
detectRemapKeyBox.XamlRoot(xamlRoot);
|
||||
detectRemapKeyBox.Title(box_value(L"Press a key on selected keyboard:"));
|
||||
detectRemapKeyBox.PrimaryButtonText(to_hstring(L"OK"));
|
||||
detectRemapKeyBox.IsSecondaryButtonEnabled(false);
|
||||
detectRemapKeyBox.CloseButtonText(to_hstring(L"Cancel"));
|
||||
detectRemapKeyBox.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
detectRemapKeyBox.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
|
||||
// Get the linked text block for the "Type Key" button that was clicked
|
||||
TextBlock linkedRemapText = getSiblingElement(sender).as<TextBlock>();
|
||||
|
||||
// OK button
|
||||
detectRemapKeyBox.PrimaryButtonClick([=, &keyboardManagerState](Windows::UI::Xaml::Controls::ContentDialog const& sender, ContentDialogButtonClickEventArgs const&) {
|
||||
// Save the detected key in the linked text block
|
||||
DWORD detectedKey = keyboardManagerState.GetDetectedSingleRemapKey();
|
||||
if (detectedKey != NULL)
|
||||
{
|
||||
linkedRemapText.Text(winrt::to_hstring((unsigned int)detectedKey));
|
||||
}
|
||||
|
||||
// Reset the keyboard manager UI state
|
||||
keyboardManagerState.ResetUIState();
|
||||
});
|
||||
|
||||
// Cancel button
|
||||
detectRemapKeyBox.CloseButtonClick([&keyboardManagerState](Windows::UI::Xaml::Controls::ContentDialog const& sender, ContentDialogButtonClickEventArgs const&) {
|
||||
// Reset the keyboard manager UI state
|
||||
keyboardManagerState.ResetUIState();
|
||||
});
|
||||
|
||||
// StackPanel parent for the displayed text in the dialog
|
||||
Windows::UI::Xaml::Controls::StackPanel stackPanel;
|
||||
stackPanel.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
|
||||
// Header textblock
|
||||
TextBlock text;
|
||||
text.Text(winrt::to_hstring("Key Pressed:"));
|
||||
text.Margin({ 0, 0, 0, 10 });
|
||||
|
||||
// Textblock to display the detected key
|
||||
TextBlock remapKey;
|
||||
|
||||
stackPanel.Children().Append(text);
|
||||
stackPanel.Children().Append(remapKey);
|
||||
stackPanel.UpdateLayout();
|
||||
detectRemapKeyBox.Content(stackPanel);
|
||||
|
||||
// Configure the keyboardManagerState to store the UI information.
|
||||
keyboardManagerState.ConfigureDetectSingleKeyRemapUI(remapKey);
|
||||
|
||||
// Show the dialog
|
||||
detectRemapKeyBox.ShowAsync();
|
||||
}
|
49
src/modules/keyboardmanager/ui/SingleKeyRemapControl.h
Normal file
49
src/modules/keyboardmanager/ui/SingleKeyRemapControl.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
#include <keyboardmanager/common/KeyboardManagerState.h>
|
||||
|
||||
class SingleKeyRemapControl
|
||||
{
|
||||
private:
|
||||
// Textblock to display the selected remap key
|
||||
TextBlock singleKeyRemapText;
|
||||
|
||||
// Button to type the remap key
|
||||
Button typeKey;
|
||||
|
||||
// StackPanel to parent the above controls
|
||||
StackPanel singleKeyRemapControlLayout;
|
||||
|
||||
public:
|
||||
// Handle to the current Edit Keyboard Window
|
||||
static HWND EditKeyboardWindowHandle;
|
||||
// Pointer to the keyboard manager state
|
||||
static KeyboardManagerState* keyboardManagerState;
|
||||
|
||||
SingleKeyRemapControl()
|
||||
{
|
||||
typeKey.Content(winrt::box_value(winrt::to_hstring("Type Key")));
|
||||
typeKey.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
typeKey.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
|
||||
typeKey.Click([&](IInspectable const& sender, RoutedEventArgs const&) {
|
||||
keyboardManagerState->SetUIState(KeyboardManagerUIState::DetectSingleKeyRemapWindowActivated, EditKeyboardWindowHandle);
|
||||
// Using the XamlRoot of the typeKey to get the root of the XAML host
|
||||
createDetectKeyWindow(sender, sender.as<Button>().XamlRoot(), *keyboardManagerState);
|
||||
});
|
||||
|
||||
singleKeyRemapControlLayout.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
|
||||
singleKeyRemapControlLayout.Margin({ 0, 0, 0, 10 });
|
||||
singleKeyRemapControlLayout.Spacing(10);
|
||||
|
||||
singleKeyRemapControlLayout.Children().Append(typeKey);
|
||||
singleKeyRemapControlLayout.Children().Append(singleKeyRemapText);
|
||||
}
|
||||
|
||||
// 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(StackPanel& parent, const DWORD& originalKey = NULL, const WORD& 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
|
||||
StackPanel getSingleKeyRemapControl();
|
||||
|
||||
// Function to create the detect remap keys UI window
|
||||
void createDetectKeyWindow(IInspectable const& sender, XamlRoot xamlRoot, KeyboardManagerState& keyboardManagerState);
|
||||
};
|
Loading…
Reference in a new issue