using BetterGenshinImpact.Model;
using System.Windows;
using System.Windows.Input;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using TextBox = Wpf.Ui.Controls.TextBox;
namespace BetterGenshinImpact.View.Controls.HotKey;
public class HotKeyTextBox : TextBox
{
public static readonly DependencyProperty HotkeyTypeNameProperty = DependencyProperty.Register(
nameof(HotKeyTypeName),
typeof(string),
typeof(HotKeyTextBox),
new FrameworkPropertyMetadata(
default(string),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
)
);
///
/// 热键类型 (中文)
///
public string HotKeyTypeName
{
get => (string)GetValue(HotkeyTypeNameProperty);
set => SetValue(HotkeyTypeNameProperty, value);
}
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey),
typeof(Model.HotKey),
typeof(HotKeyTextBox),
new FrameworkPropertyMetadata(
default(Model.HotKey),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
(sender, _) =>
{
var control = (HotKeyTextBox)sender;
control.Text = control.Hotkey.ToString();
}
)
);
public Model.HotKey Hotkey
{
get => (Model.HotKey)GetValue(HotkeyProperty);
set => SetValue(HotkeyProperty, value);
}
public HotKeyTextBox()
{
IsReadOnly = true;
IsReadOnlyCaretVisible = false;
IsUndoEnabled = false;
if (ContextMenu is not null)
ContextMenu.Visibility = Visibility.Collapsed;
Text = Hotkey.ToString();
}
private static bool HasKeyChar(Key key) =>
key
is
// A - Z
>= 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 args)
{
args.Handled = true;
// Get modifiers and key data
var modifiers = Keyboard.Modifiers;
var key = args.Key;
// If nothing was pressed - return
if (key == Key.None)
return;
// If Alt is used as modifier - the key needs to be extracted from SystemKey
if (key == Key.System)
key = args.SystemKey;
// If Delete/Backspace/Escape is pressed without modifiers - clear current value and return
if (key is Key.Delete or Key.Back or Key.Escape && modifiers == ModifierKeys.None)
{
Hotkey = Model.HotKey.None;
return;
}
// If the only key pressed is one of the modifier keys - return
if (
key
is Key.LeftCtrl
or Key.RightCtrl
or Key.LeftAlt
or Key.RightAlt
or Key.LeftShift
or Key.RightShift
or Key.LWin
or Key.RWin
or Key.Clear
or Key.OemClear
or Key.Apps
)
return;
// If Enter/Space/Tab is pressed without modifiers - return
if (key is Key.Enter or Key.Tab && modifiers == ModifierKeys.None)
return;
if (HotKeyTypeName == HotKeyTypeEnum.GlobalRegister.ToChineseName() && key is Key.Enter or Key.Space or Key.Tab && modifiers == ModifierKeys.None)
return;
// If key has a character and pressed without modifiers or only with Shift - return
if (HotKeyTypeName == HotKeyTypeEnum.GlobalRegister.ToChineseName() && HasKeyChar(key) && modifiers is ModifierKeys.None or ModifierKeys.Shift)
return;
// Set value
Hotkey = new Model.HotKey(key, modifiers);
}
///
/// 支持鼠标侧键配置
///
///
protected override void OnPreviewMouseDown(MouseButtonEventArgs args)
{
if (args.ChangedButton is MouseButton.XButton1 or MouseButton.XButton2)
{
if (HotKeyTypeName == HotKeyTypeEnum.GlobalRegister.ToChineseName())
{
Hotkey = new Model.HotKey(Key.None);
}
else
{
Hotkey = new Model.HotKey(Key.None, ModifierKeys.None, args.ChangedButton);
}
}
}
}