FModel/FModel/Views/Resources/Controls/HotkeyTextBox.cs
GMatrixGames e21a3be55b
Update/net7 (#290)
* file-scoped namespace & net7.0

* Workflow
2022-06-11 20:07:59 -04:00

92 lines
3.2 KiB
C#

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using FModel.Framework;
namespace FModel.Views.Resources.Controls;
/// <summary>
/// https://tyrrrz.me/blog/hotkey-editor-control-in-wpf
/// </summary>
public class HotkeyTextBox : TextBox
{
public Hotkey HotKey
{
get => (Hotkey) GetValue(HotKeyProperty);
set => SetValue(HotKeyProperty, value);
}
public static readonly DependencyProperty HotKeyProperty = DependencyProperty.Register("HotKey", typeof(Hotkey),
typeof(HotkeyTextBox), new FrameworkPropertyMetadata(new Hotkey(Key.None), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, HotKeyChanged));
private static void HotKeyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender is not HotkeyTextBox control) return;
control.Text = control.HotKey.ToString();
}
public HotkeyTextBox()
{
IsReadOnly = true;
IsReadOnlyCaretVisible = false;
IsUndoEnabled = false;
if (ContextMenu != null)
ContextMenu.Visibility = Visibility.Collapsed;
Text = HotKey.ToString();
}
private static bool HasKeyChar(Key key) =>
// A - Z
key is >= Key.A and <= Key.Z or
// 0 - 9
Key.D0 and <= Key.D9 or
// Numpad 0 - 9
Key.NumPad0 and <= Key.NumPad9 or
// The rest
Key.OemQuestion or Key.OemQuotes or Key.OemPlus or Key.OemOpenBrackets or Key.OemCloseBrackets or Key.OemMinus or Key.DeadCharProcessed or Key.Oem1 or Key.Oem5 or Key.Oem7 or Key.OemPeriod or Key.OemComma or Key.Add or Key.Divide or Key.Multiply or Key.Subtract or Key.Oem102 or Key.Decimal;
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
e.Handled = true;
// Get modifiers and key data
var modifiers = Keyboard.Modifiers;
var key = e.Key;
switch (key)
{
// If nothing was pressed - return
case Key.None:
return;
// If Alt is used as modifier - the key needs to be extracted from SystemKey
case Key.System:
key = e.SystemKey;
break;
// If Delete/Backspace/Escape is pressed without modifiers - clear current value and return
case Key.Delete or Key.Back or Key.Escape when modifiers == ModifierKeys.None:
HotKey = new Hotkey(Key.None);
return;
// If the only key pressed is one of the modifier keys - return
case Key.LeftCtrl:
case Key.RightCtrl:
case Key.LeftAlt:
case Key.RightAlt:
case Key.LeftShift:
case Key.RightShift:
case Key.LWin:
case Key.RWin:
case Key.Clear:
case Key.OemClear:
case Key.Apps:
// If Enter/Space/Tab is pressed without modifiers - return
case Key.Enter or Key.Space or Key.Tab when modifiers == ModifierKeys.None:
return;
default:
// Set value
HotKey = new Hotkey(key, modifiers);
break;
}
}
}