2020-03-27 23:38:58 +08:00
# include "pch.h"
# include "SingleKeyRemapControl.h"
//Both static members are initialized to null
HWND SingleKeyRemapControl : : EditKeyboardWindowHandle = nullptr ;
KeyboardManagerState * SingleKeyRemapControl : : keyboardManagerState = nullptr ;
2020-04-10 00:20:19 +08:00
// Initialized as new vector
std : : vector < std : : vector < DWORD > > SingleKeyRemapControl : : singleKeyRemapBuffer ;
2020-03-27 23:38:58 +08:00
// 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.
2020-04-09 00:11:58 +08:00
void SingleKeyRemapControl : : AddNewControlKeyRemapRow ( StackPanel & parent , const DWORD & originalKey , const DWORD & newKey )
2020-03-27 23:38:58 +08:00
{
// 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.
2020-04-10 00:20:19 +08:00
SingleKeyRemapControl originalRemapKeyControl ( singleKeyRemapBuffer . size ( ) , 0 ) ;
2020-03-27 23:38:58 +08:00
tableRow . Children ( ) . Append ( originalRemapKeyControl . getSingleKeyRemapControl ( ) ) ;
// SingleKeyRemapControl for the new remap key.
2020-04-10 00:20:19 +08:00
SingleKeyRemapControl newRemapKeyControl ( singleKeyRemapBuffer . size ( ) , 1 ) ;
2020-03-27 23:38:58 +08:00
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 )
{
2020-04-10 00:20:19 +08:00
singleKeyRemapBuffer . push_back ( std : : vector < DWORD > { originalKey , newKey } ) ;
originalRemapKeyControl . singleKeyRemapText . Text ( winrt : : to_hstring ( keyboardManagerState - > keyboardMap . GetKeyName ( originalKey ) . c_str ( ) ) ) ;
newRemapKeyControl . singleKeyRemapText . Text ( winrt : : to_hstring ( keyboardManagerState - > keyboardMap . GetKeyName ( newKey ) . c_str ( ) ) ) ;
}
else
{
// Initialize both keys to NULL
singleKeyRemapBuffer . push_back ( std : : vector < DWORD > { NULL , NULL } ) ;
2020-03-27 23:38:58 +08:00
}
// 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 ) ;
2020-04-10 00:20:19 +08:00
// delete the row from the buffer. Since first child of the stackpanel is the header, the effective index starts from 1
singleKeyRemapBuffer . erase ( singleKeyRemapBuffer . begin ( ) + ( index - 1 ) ) ;
2020-03-27 23:38:58 +08:00
} ) ;
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
2020-04-10 00:20:19 +08:00
void SingleKeyRemapControl : : createDetectKeyWindow ( IInspectable const & sender , XamlRoot xamlRoot , std : : vector < std : : vector < DWORD > > & singleKeyRemapBuffer , KeyboardManagerState & keyboardManagerState , const int & rowIndex , const int & colIndex )
2020-03-27 23:38:58 +08:00
{
// ContentDialog for detecting remap key. This is the parent UI element.
ContentDialog detectRemapKeyBox ;
2020-04-09 05:31:31 +08:00
// TODO: Hardcoded light theme, since the app is not theme aware ATM.
detectRemapKeyBox . RequestedTheme ( ElementTheme : : Light ) ;
2020-03-27 23:38:58 +08:00
// 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 " ) ) ;
// Get the linked text block for the "Type Key" button that was clicked
TextBlock linkedRemapText = getSiblingElement ( sender ) . as < TextBlock > ( ) ;
// OK button
2020-04-10 00:20:19 +08:00
detectRemapKeyBox . PrimaryButtonClick ( [ = , & singleKeyRemapBuffer , & keyboardManagerState ] ( Windows : : UI : : Xaml : : Controls : : ContentDialog const & sender , ContentDialogButtonClickEventArgs const & ) {
2020-03-27 23:38:58 +08:00
// Save the detected key in the linked text block
DWORD detectedKey = keyboardManagerState . GetDetectedSingleRemapKey ( ) ;
2020-04-10 00:20:19 +08:00
2020-03-27 23:38:58 +08:00
if ( detectedKey ! = NULL )
{
2020-04-10 00:20:19 +08:00
singleKeyRemapBuffer [ rowIndex ] [ colIndex ] = detectedKey ;
linkedRemapText . Text ( winrt : : to_hstring ( keyboardManagerState . keyboardMap . GetKeyName ( detectedKey ) . c_str ( ) ) ) ;
2020-03-27 23:38:58 +08:00
}
// 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 ;
2020-04-09 05:31:31 +08:00
detectRemapKeyBox . Content ( stackPanel ) ;
2020-03-27 23:38:58 +08:00
// Header textblock
TextBlock text ;
text . Text ( winrt : : to_hstring ( " Key Pressed: " ) ) ;
text . Margin ( { 0 , 0 , 0 , 10 } ) ;
stackPanel . Children ( ) . Append ( text ) ;
2020-04-09 05:31:31 +08:00
// Target StackPanel to place the selected key
Windows : : UI : : Xaml : : Controls : : StackPanel keyStackPanel ;
stackPanel . Children ( ) . Append ( keyStackPanel ) ;
keyStackPanel . Orientation ( Orientation : : Horizontal ) ;
2020-03-27 23:38:58 +08:00
stackPanel . UpdateLayout ( ) ;
// Configure the keyboardManagerState to store the UI information.
2020-04-09 05:31:31 +08:00
keyboardManagerState . ConfigureDetectSingleKeyRemapUI ( keyStackPanel ) ;
2020-03-27 23:38:58 +08:00
// Show the dialog
detectRemapKeyBox . ShowAsync ( ) ;
}