Display keys in Shorcut modal as buttons (#1996)

* Display keys in Shorcut modal as buttons

* Refactor: rename currentShortcutUI and currentSingleKeyUI

* Change GetKeyVector signature
This commit is contained in:
Tomas Agustin Raies
2020-04-08 14:31:31 -07:00
committed by Udit Singh
parent 52c12731cb
commit 70495d9ce9
6 changed files with 143 additions and 73 deletions

View File

@@ -3,7 +3,7 @@
// Constructor
KeyboardManagerState::KeyboardManagerState() :
uiState(KeyboardManagerUIState::Deactivated), currentUIWindow(nullptr), currentShortcutTextBlock(nullptr), currentSingleKeyRemapTextBlock(nullptr), detectedRemapKey(NULL)
uiState(KeyboardManagerUIState::Deactivated), currentUIWindow(nullptr), currentShortcutUI(nullptr), currentSingleKeyUI(nullptr), detectedRemapKey(NULL)
{
}
@@ -50,18 +50,18 @@ void KeyboardManagerState::ResetUIState()
SetUIState(KeyboardManagerUIState::Deactivated);
// Reset the shortcut UI stored variables
std::unique_lock<std::mutex> currentShortcutTextBlock_lock(currentShortcutTextBlock_mutex);
currentShortcutTextBlock = nullptr;
currentShortcutTextBlock_lock.unlock();
std::unique_lock<std::mutex> currentShortcutUI_lock(currentShortcutUI_mutex);
currentShortcutUI = nullptr;
currentShortcutUI_lock.unlock();
std::unique_lock<std::mutex> detectedShortcut_lock(detectedShortcut_mutex);
detectedShortcut.Reset();
detectedShortcut_lock.unlock();
// Reset all the single key remap UI stored variables.
std::unique_lock<std::mutex> currentSingleKeyRemapTextBlock_lock(currentSingleKeyRemapTextBlock_mutex);
currentSingleKeyRemapTextBlock = nullptr;
currentSingleKeyRemapTextBlock_lock.unlock();
std::unique_lock<std::mutex> currentSingleKeyUI_lock(currentSingleKeyUI_mutex);
currentSingleKeyUI = nullptr;
currentSingleKeyUI_lock.unlock();
std::unique_lock<std::mutex> detectedRemapKey_lock(detectedRemapKey_mutex);
detectedRemapKey = NULL;
@@ -115,81 +115,120 @@ bool KeyboardManagerState::AddSingleKeyRemap(const DWORD& originalKey, const DWO
}
// 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)
void KeyboardManagerState::ConfigureDetectShortcutUI(const StackPanel& textBlock)
{
std::lock_guard<std::mutex> lock(currentShortcutTextBlock_mutex);
currentShortcutTextBlock = textBlock;
std::lock_guard<std::mutex> lock(currentShortcutUI_mutex);
currentShortcutUI = 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)
void KeyboardManagerState::ConfigureDetectSingleKeyRemapUI(const StackPanel& textBlock)
{
std::lock_guard<std::mutex> lock(currentSingleKeyRemapTextBlock_mutex);
currentSingleKeyRemapTextBlock = textBlock;
std::lock_guard<std::mutex> lock(currentSingleKeyUI_mutex);
currentSingleKeyUI = textBlock;
}
void KeyboardManagerState::AddKeyToLayout(const StackPanel& panel, const hstring& key)
{
// Textblock to display the detected key
TextBlock remapKey;
Border border;
border.Padding({ 20, 10, 20, 10 });
border.Margin({0, 0, 10, 0 });
border.Background(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::LightGray() });
remapKey.Foreground(Windows::UI::Xaml::Media::SolidColorBrush{ Windows::UI::Colors::Black() });
remapKey.FontSize(20);
border.HorizontalAlignment(HorizontalAlignment::Left);
border.Child(remapKey);
remapKey.Text(key);
panel.Children().Append(border);
}
// Function to update the detect shortcut UI based on the entered keys
void KeyboardManagerState::UpdateDetectShortcutUI()
{
std::lock_guard<std::mutex> currentShortcutTextBlock_lock(currentShortcutTextBlock_mutex);
if (currentShortcutTextBlock == nullptr)
std::lock_guard<std::mutex> currentShortcutUI_lock(currentShortcutUI_mutex);
if (currentShortcutUI == nullptr)
{
return;
}
std::unique_lock<std::mutex> detectedShortcut_lock(detectedShortcut_mutex);
hstring shortcutString = detectedShortcut.ToHstring();
std::vector<hstring> shortcut = detectedShortcut.GetKeyVector();
detectedShortcut_lock.unlock();
// Since this function is invoked from the back-end thread, in order to update the UI the dispatcher must be used.
currentShortcutTextBlock.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]() {
currentShortcutTextBlock.Text(shortcutString);
currentShortcutUI.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [this, shortcut]() {
currentShortcutUI.Children().Clear();
for (auto& key : shortcut)
{
AddKeyToLayout(currentShortcutUI, key);
}
currentShortcutUI.UpdateLayout();
});
}
// Function to update the detect remap key UI based on the entered key.
void KeyboardManagerState::UpdateDetectSingleKeyRemapUI()
{
std::lock_guard<std::mutex> currentSingleKeyRemapTextBlock_lock(currentSingleKeyRemapTextBlock_mutex);
if (currentSingleKeyRemapTextBlock == nullptr)
std::lock_guard<std::mutex> currentSingleKeyUI_lock(currentSingleKeyUI_mutex);
if (currentSingleKeyUI == nullptr)
{
return;
}
std::unique_lock<std::mutex> detectedRemapKey_lock(detectedRemapKey_mutex);
hstring remapKeyString = winrt::to_hstring((unsigned int)detectedRemapKey);
hstring key = winrt::to_hstring((unsigned int)detectedRemapKey);
detectedRemapKey_lock.unlock();
// 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);
currentSingleKeyUI.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [this, key]() {
currentSingleKeyUI.Children().Clear();
AddKeyToLayout(currentSingleKeyUI, key);
currentSingleKeyUI.UpdateLayout();
});
}
// Function to return the currently detected shortcut which is displayed on the UI
Shortcut KeyboardManagerState::GetDetectedShortcut()
{
std::unique_lock<std::mutex> lock(currentShortcutTextBlock_mutex);
hstring detectedShortcutString = currentShortcutTextBlock.Text();
std::unique_lock<std::mutex> lock(currentShortcutUI_mutex);
std::vector<winrt::hstring> keys;
if (currentShortcutUI.Children().Size() > 0)
{
for (auto border : currentShortcutUI.Children())
{
auto keyString = border.as<Border>().Child().as<TextBlock>().Text();
keys.push_back(keyString);
}
}
lock.unlock();
return Shortcut::CreateShortcut(detectedShortcutString);
return Shortcut::CreateShortcut(keys);
}
// Function to return the currently detected remap key which is displayed on the UI
DWORD KeyboardManagerState::GetDetectedSingleRemapKey()
{
std::unique_lock<std::mutex> lock(currentSingleKeyRemapTextBlock_mutex);
hstring remapKeyString = currentSingleKeyRemapTextBlock.Text();
lock.unlock();
std::wstring remapKeyWString = remapKeyString.c_str();
DWORD remapKey = NULL;
if (!remapKeyString.empty())
std::unique_lock<std::mutex> lock(currentSingleKeyUI_mutex);
DWORD key = 0;
if (currentSingleKeyUI.Children().Size() > 0)
{
remapKey = std::stoul(remapKeyWString);
auto border = currentSingleKeyUI.Children().GetAt(0);
auto keyString = border.as<Border>().Child().as<TextBlock>().Text();
key = std::stoul(keyString.c_str());
}
return remapKey;
lock.unlock();
return key;
}
// 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.