Fix duplicate modifier and clean up code

This commit is contained in:
Hongtao Zhang 2024-04-17 23:10:31 -05:00
parent fd620f4ea8
commit 1d858d3357
2 changed files with 71 additions and 124 deletions

View file

@ -6,7 +6,7 @@ using System.Windows.Input;
namespace Flow.Launcher.Infrastructure.Hotkey
{
public class HotkeyModel
public record struct HotkeyModel
{
public bool Alt { get; set; }
public bool Shift { get; set; }
@ -17,8 +17,7 @@ namespace Flow.Launcher.Infrastructure.Hotkey
private static readonly Dictionary<Key, string> specialSymbolDictionary = new Dictionary<Key, string>
{
{Key.Space, "Space"},
{Key.Oem3, "~"}
{ Key.Space, "Space" }, { Key.Oem3, "~" }
};
public ModifierKeys ModifierKeys
@ -30,18 +29,22 @@ namespace Flow.Launcher.Infrastructure.Hotkey
{
modifierKeys |= ModifierKeys.Alt;
}
if (Shift)
{
modifierKeys |= ModifierKeys.Shift;
}
if (Win)
{
modifierKeys |= ModifierKeys.Windows;
}
if (Ctrl)
{
modifierKeys |= ModifierKeys.Control;
}
return modifierKeys;
}
}
@ -66,31 +69,37 @@ namespace Flow.Launcher.Infrastructure.Hotkey
{
return;
}
List<string> keys = hotkeyString.Replace(" ", "").Split('+').ToList();
if (keys.Contains("Alt"))
{
Alt = true;
keys.Remove("Alt");
}
if (keys.Contains("Shift"))
{
Shift = true;
keys.Remove("Shift");
}
if (keys.Contains("Win"))
{
Win = true;
keys.Remove("Win");
}
if (keys.Contains("Ctrl"))
{
Ctrl = true;
keys.Remove("Ctrl");
}
if (keys.Count == 1)
{
string charKey = keys[0];
KeyValuePair<Key, string>? specialSymbolPair = specialSymbolDictionary.FirstOrDefault(pair => pair.Value == charKey);
KeyValuePair<Key, string>? specialSymbolPair =
specialSymbolDictionary.FirstOrDefault(pair => pair.Value == charKey);
if (specialSymbolPair.Value.Value != null)
{
CharKey = specialSymbolPair.Value.Key;
@ -103,7 +112,6 @@ namespace Flow.Launcher.Infrastructure.Hotkey
}
catch (ArgumentException)
{
}
}
}
@ -111,33 +119,39 @@ namespace Flow.Launcher.Infrastructure.Hotkey
public override string ToString()
{
List<string> keys = new List<string>();
if (Ctrl)
return string.Join(" + ", EnumerateDisplayKeys());
}
public IEnumerable<string> EnumerateDisplayKeys()
{
if (Ctrl && CharKey is not (Key.LeftCtrl or Key.RightCtrl))
{
keys.Add("Ctrl");
yield return "Ctrl";
}
if (Alt)
if (Alt && CharKey is not (Key.LeftAlt or Key.RightAlt))
{
keys.Add("Alt");
yield return "Alt";
}
if (Shift)
if (Shift && CharKey is not (Key.LeftShift or Key.RightShift))
{
keys.Add("Shift");
yield return "Shift";
}
if (Win)
if (Win && CharKey is not (Key.LWin or Key.RWin))
{
keys.Add("Win");
yield return "Win";
}
if (CharKey != Key.None)
{
keys.Add(specialSymbolDictionary.ContainsKey(CharKey)
? specialSymbolDictionary[CharKey]
: CharKey.ToString());
yield return specialSymbolDictionary.TryGetValue(CharKey, out var value)
? value
: CharKey.ToString();
}
return string.Join(" + ", keys);
}
/// <summary>
/// Validate hotkey
/// </summary>
@ -164,11 +178,13 @@ namespace Flow.Launcher.Infrastructure.Hotkey
{
KeyGesture keyGesture = new KeyGesture(CharKey, ModifierKeys);
}
catch (System.Exception e) when (e is NotSupportedException || e is InvalidEnumArgumentException)
catch (System.Exception e) when
(e is NotSupportedException || e is InvalidEnumArgumentException)
{
return false;
}
}
if (ModifierKeys == ModifierKeys.None)
{
return !IsPrintableCharacter(CharKey);
@ -206,18 +222,6 @@ namespace Flow.Launcher.Infrastructure.Hotkey
key == Key.Decimal;
}
public override bool Equals(object obj)
{
if (obj is HotkeyModel other)
{
return ModifierKeys == other.ModifierKeys && CharKey == other.CharKey;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return HashCode.Combine(ModifierKeys, CharKey);

View file

@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@ -13,12 +11,13 @@ using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Plugin;
using Flow.Launcher.ViewModel;
using NHotkey;
using JetBrains.Annotations;
#nullable enable
namespace Flow.Launcher
{
public partial class HotkeyControl : UserControl, INotifyPropertyChanged
public partial class HotkeyControl : INotifyPropertyChanged
{
/// <summary>
/// Designed for Preview Hotkey and KeyGesture.
@ -42,29 +41,32 @@ namespace Flow.Launcher
set { SetValue(DefaultHotkeyProperty, value); }
}
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey), typeof(string), typeof(HotkeyControl),
new PropertyMetadata(default(string), OnHotkeyChanged));
private static void OnHotkeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is HotkeyControl hotkeyControl)
if (d is not HotkeyControl hotkeyControl)
{
hotkeyControl.SetKeysToDisplay(new HotkeyModel(hotkeyControl.Hotkey));
hotkeyControl.CurrentHotkey = new HotkeyModel(hotkeyControl.Hotkey);
return;
}
hotkeyControl.SetKeysToDisplay(new HotkeyModel(hotkeyControl.Hotkey));
hotkeyControl.CurrentHotkey = new HotkeyModel(hotkeyControl.Hotkey);
}
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
nameof(ChangeHotkey), typeof(ICommand), typeof(HotkeyControl), new PropertyMetadata(default(ICommand)));
public ICommand ChangeHotkey
public ICommand? ChangeHotkey
{
get { return (ICommand)GetValue(ChangeHotkeyProperty); }
set { SetValue(ChangeHotkeyProperty, value); }
}
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey), typeof(string), typeof(HotkeyControl),
new PropertyMetadata("", OnHotkeyChanged));
public string Hotkey
{
get { return (string)GetValue(HotkeyProperty); }
@ -122,19 +124,13 @@ namespace Flow.Launcher
tbMsg.SetResourceReference(TextBox.ForegroundProperty, "Color05B");
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void HotkeyBtn_OnLostFocus(object sender, RoutedEventArgs e)
{
HotkeyBtn.IsChecked = false;
RegisterHotkey();
}
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
@ -162,7 +158,7 @@ namespace Flow.Launcher
public ObservableCollection<string> KeysToDisplay { get; set; } = new ObservableCollection<string>();
public HotkeyModel CurrentHotkey { get; private set; }
public HotkeyModel CurrentHotkey { get; private set; } = new(false, false, false, false, Key.None);
public void StartRecording()
@ -186,7 +182,7 @@ namespace Flow.Launcher
try
{
var converter = new KeyGestureConverter();
var key = (KeyGesture)converter.ConvertFromString(CurrentHotkey.ToString())!;
_ = (KeyGesture)converter.ConvertFromString(CurrentHotkey.ToString())!;
}
catch (Exception e) when (e is NotSupportedException or InvalidEnumArgumentException)
{
@ -226,12 +222,14 @@ namespace Flow.Launcher
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
if (hotkeyAvailable)
if (!hotkeyAvailable)
{
Hotkey = keyModel.ToString();
SetKeysToDisplay(CurrentHotkey);
ChangeHotkey?.Execute(keyModel);
return;
}
Hotkey = keyModel.ToString();
SetKeysToDisplay(CurrentHotkey);
ChangeHotkey?.Execute(keyModel);
}
else
{
@ -245,62 +243,24 @@ namespace Flow.Launcher
if (!string.IsNullOrEmpty(Hotkey))
HotKeyMapper.RemoveHotkey(Hotkey);
Hotkey = "";
SetKeysToDisplay(KeysToDisplay, new List<string>());
SetKeysToDisplay(new HotkeyModel(false, false, false, false, Key.None));
HotkeyBtn.IsChecked = false;
}
private void SetKeysToDisplay(HotkeyModel hotkey)
private void SetKeysToDisplay(HotkeyModel? hotkey)
{
KeysToDisplay.Clear();
if (hotkey.Alt)
{
KeysToDisplay.Add("Alt");
}
if (hotkey.Ctrl)
{
KeysToDisplay.Add("Ctrl");
}
if (hotkey.Shift)
{
KeysToDisplay.Add("Shift");
}
if (hotkey.Win)
{
KeysToDisplay.Add("Win");
}
if (hotkey.CharKey != Key.None)
{
KeysToDisplay.Add(hotkey.CharKey.ToString());
}
}
private void SetKeysToDisplay(ICollection<string> container, ICollection<string>? keys)
{
container.Clear();
if (keys == null)
if (hotkey == null || hotkey == default(HotkeyModel))
{
KeysToDisplay.Add(EmptyHotkey);
return;
}
foreach (var key in keys)
foreach (var key in hotkey.Value.EnumerateDisplayKeys()!)
{
container.Add(key);
KeysToDisplay.Add(key);
}
if (!keys.Any())
{
container.Add(EmptyHotkey);
}
}
public void RegisterHotkey()
{
SetHotkey(Hotkey, true);
}
public void SetHotkey(string? keyStr, bool triggerValidate = true)
@ -309,29 +269,12 @@ namespace Flow.Launcher
}
private void HotkeyBtn_OnChecked(object sender, RoutedEventArgs e)
{
StartRecording();
}
private void HotkeyBtn_OnChecked(object sender, RoutedEventArgs e) => StartRecording();
private void HotkeyBtn_OnUnchecked(object sender, RoutedEventArgs e)
{
StopRecording();
}
private void ResetButton_OnClick(object sender, RoutedEventArgs e)
{
ResetToDefault();
}
private void ResetButton_OnClick(object sender, RoutedEventArgs e) => ResetToDefault();
private void DeleteBtn_OnClick(object sender, RoutedEventArgs e) => Delete();
private void DeleteBtn_OnClick(object sender, RoutedEventArgs e)
{
Delete();
}
public void StopRecordingBtn_Click(object sender, RoutedEventArgs e)
{
StopRecording();
}
private void StopRecordingBtn_Click(object sender, RoutedEventArgs e) => StopRecording();
}
}