mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Fix duplicate modifier and clean up code
This commit is contained in:
parent
fd620f4ea8
commit
1d858d3357
2 changed files with 71 additions and 124 deletions
|
|
@ -6,7 +6,7 @@ using System.Windows.Input;
|
||||||
|
|
||||||
namespace Flow.Launcher.Infrastructure.Hotkey
|
namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
{
|
{
|
||||||
public class HotkeyModel
|
public record struct HotkeyModel
|
||||||
{
|
{
|
||||||
public bool Alt { get; set; }
|
public bool Alt { get; set; }
|
||||||
public bool Shift { 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>
|
private static readonly Dictionary<Key, string> specialSymbolDictionary = new Dictionary<Key, string>
|
||||||
{
|
{
|
||||||
{Key.Space, "Space"},
|
{ Key.Space, "Space" }, { Key.Oem3, "~" }
|
||||||
{Key.Oem3, "~"}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public ModifierKeys ModifierKeys
|
public ModifierKeys ModifierKeys
|
||||||
|
|
@ -30,18 +29,22 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
{
|
{
|
||||||
modifierKeys |= ModifierKeys.Alt;
|
modifierKeys |= ModifierKeys.Alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Shift)
|
if (Shift)
|
||||||
{
|
{
|
||||||
modifierKeys |= ModifierKeys.Shift;
|
modifierKeys |= ModifierKeys.Shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Win)
|
if (Win)
|
||||||
{
|
{
|
||||||
modifierKeys |= ModifierKeys.Windows;
|
modifierKeys |= ModifierKeys.Windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ctrl)
|
if (Ctrl)
|
||||||
{
|
{
|
||||||
modifierKeys |= ModifierKeys.Control;
|
modifierKeys |= ModifierKeys.Control;
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifierKeys;
|
return modifierKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,31 +69,37 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> keys = hotkeyString.Replace(" ", "").Split('+').ToList();
|
List<string> keys = hotkeyString.Replace(" ", "").Split('+').ToList();
|
||||||
if (keys.Contains("Alt"))
|
if (keys.Contains("Alt"))
|
||||||
{
|
{
|
||||||
Alt = true;
|
Alt = true;
|
||||||
keys.Remove("Alt");
|
keys.Remove("Alt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.Contains("Shift"))
|
if (keys.Contains("Shift"))
|
||||||
{
|
{
|
||||||
Shift = true;
|
Shift = true;
|
||||||
keys.Remove("Shift");
|
keys.Remove("Shift");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.Contains("Win"))
|
if (keys.Contains("Win"))
|
||||||
{
|
{
|
||||||
Win = true;
|
Win = true;
|
||||||
keys.Remove("Win");
|
keys.Remove("Win");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.Contains("Ctrl"))
|
if (keys.Contains("Ctrl"))
|
||||||
{
|
{
|
||||||
Ctrl = true;
|
Ctrl = true;
|
||||||
keys.Remove("Ctrl");
|
keys.Remove("Ctrl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.Count == 1)
|
if (keys.Count == 1)
|
||||||
{
|
{
|
||||||
string charKey = keys[0];
|
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)
|
if (specialSymbolPair.Value.Value != null)
|
||||||
{
|
{
|
||||||
CharKey = specialSymbolPair.Value.Key;
|
CharKey = specialSymbolPair.Value.Key;
|
||||||
|
|
@ -103,7 +112,6 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -111,33 +119,39 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
List<string> keys = new List<string>();
|
return string.Join(" + ", EnumerateDisplayKeys());
|
||||||
if (Ctrl)
|
}
|
||||||
|
|
||||||
|
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)
|
if (CharKey != Key.None)
|
||||||
{
|
{
|
||||||
keys.Add(specialSymbolDictionary.ContainsKey(CharKey)
|
yield return specialSymbolDictionary.TryGetValue(CharKey, out var value)
|
||||||
? specialSymbolDictionary[CharKey]
|
? value
|
||||||
: CharKey.ToString());
|
: CharKey.ToString();
|
||||||
}
|
}
|
||||||
return string.Join(" + ", keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validate hotkey
|
/// Validate hotkey
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -164,11 +178,13 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
{
|
{
|
||||||
KeyGesture keyGesture = new KeyGesture(CharKey, ModifierKeys);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModifierKeys == ModifierKeys.None)
|
if (ModifierKeys == ModifierKeys.None)
|
||||||
{
|
{
|
||||||
return !IsPrintableCharacter(CharKey);
|
return !IsPrintableCharacter(CharKey);
|
||||||
|
|
@ -206,18 +222,6 @@ namespace Flow.Launcher.Infrastructure.Hotkey
|
||||||
key == Key.Decimal;
|
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()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return HashCode.Combine(ModifierKeys, CharKey);
|
return HashCode.Combine(ModifierKeys, CharKey);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
@ -13,12 +11,13 @@ using Flow.Launcher.Core.Resource;
|
||||||
using Flow.Launcher.Helper;
|
using Flow.Launcher.Helper;
|
||||||
using Flow.Launcher.Infrastructure.Hotkey;
|
using Flow.Launcher.Infrastructure.Hotkey;
|
||||||
using Flow.Launcher.Plugin;
|
using Flow.Launcher.Plugin;
|
||||||
using Flow.Launcher.ViewModel;
|
using JetBrains.Annotations;
|
||||||
using NHotkey;
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
namespace Flow.Launcher
|
namespace Flow.Launcher
|
||||||
{
|
{
|
||||||
public partial class HotkeyControl : UserControl, INotifyPropertyChanged
|
public partial class HotkeyControl : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Designed for Preview Hotkey and KeyGesture.
|
/// Designed for Preview Hotkey and KeyGesture.
|
||||||
|
|
@ -42,29 +41,32 @@ namespace Flow.Launcher
|
||||||
set { SetValue(DefaultHotkeyProperty, value); }
|
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)
|
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));
|
return;
|
||||||
hotkeyControl.CurrentHotkey = new HotkeyModel(hotkeyControl.Hotkey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hotkeyControl.SetKeysToDisplay(new HotkeyModel(hotkeyControl.Hotkey));
|
||||||
|
hotkeyControl.CurrentHotkey = new HotkeyModel(hotkeyControl.Hotkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
|
||||||
nameof(ChangeHotkey), typeof(ICommand), typeof(HotkeyControl), new PropertyMetadata(default(ICommand)));
|
nameof(ChangeHotkey), typeof(ICommand), typeof(HotkeyControl), new PropertyMetadata(default(ICommand)));
|
||||||
|
|
||||||
public ICommand ChangeHotkey
|
public ICommand? ChangeHotkey
|
||||||
{
|
{
|
||||||
get { return (ICommand)GetValue(ChangeHotkeyProperty); }
|
get { return (ICommand)GetValue(ChangeHotkeyProperty); }
|
||||||
set { SetValue(ChangeHotkeyProperty, value); }
|
set { SetValue(ChangeHotkeyProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
|
||||||
|
nameof(Hotkey), typeof(string), typeof(HotkeyControl),
|
||||||
|
new PropertyMetadata("", OnHotkeyChanged));
|
||||||
|
|
||||||
public string Hotkey
|
public string Hotkey
|
||||||
{
|
{
|
||||||
get { return (string)GetValue(HotkeyProperty); }
|
get { return (string)GetValue(HotkeyProperty); }
|
||||||
|
|
@ -122,19 +124,13 @@ namespace Flow.Launcher
|
||||||
tbMsg.SetResourceReference(TextBox.ForegroundProperty, "Color05B");
|
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));
|
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) =>
|
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
|
||||||
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
|
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
|
||||||
|
|
@ -162,7 +158,7 @@ namespace Flow.Launcher
|
||||||
public ObservableCollection<string> KeysToDisplay { get; set; } = new ObservableCollection<string>();
|
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()
|
public void StartRecording()
|
||||||
|
|
@ -186,7 +182,7 @@ namespace Flow.Launcher
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var converter = new KeyGestureConverter();
|
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)
|
catch (Exception e) when (e is NotSupportedException or InvalidEnumArgumentException)
|
||||||
{
|
{
|
||||||
|
|
@ -226,12 +222,14 @@ namespace Flow.Launcher
|
||||||
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
|
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
|
||||||
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
|
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
|
||||||
|
|
||||||
if (hotkeyAvailable)
|
if (!hotkeyAvailable)
|
||||||
{
|
{
|
||||||
Hotkey = keyModel.ToString();
|
return;
|
||||||
SetKeysToDisplay(CurrentHotkey);
|
|
||||||
ChangeHotkey?.Execute(keyModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hotkey = keyModel.ToString();
|
||||||
|
SetKeysToDisplay(CurrentHotkey);
|
||||||
|
ChangeHotkey?.Execute(keyModel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -245,62 +243,24 @@ namespace Flow.Launcher
|
||||||
if (!string.IsNullOrEmpty(Hotkey))
|
if (!string.IsNullOrEmpty(Hotkey))
|
||||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||||
Hotkey = "";
|
Hotkey = "";
|
||||||
SetKeysToDisplay(KeysToDisplay, new List<string>());
|
SetKeysToDisplay(new HotkeyModel(false, false, false, false, Key.None));
|
||||||
HotkeyBtn.IsChecked = false;
|
HotkeyBtn.IsChecked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetKeysToDisplay(HotkeyModel hotkey)
|
private void SetKeysToDisplay(HotkeyModel? hotkey)
|
||||||
{
|
{
|
||||||
KeysToDisplay.Clear();
|
KeysToDisplay.Clear();
|
||||||
if (hotkey.Alt)
|
|
||||||
{
|
|
||||||
KeysToDisplay.Add("Alt");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hotkey.Ctrl)
|
if (hotkey == null || hotkey == default(HotkeyModel))
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
KeysToDisplay.Add(EmptyHotkey);
|
||||||
return;
|
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)
|
public void SetHotkey(string? keyStr, bool triggerValidate = true)
|
||||||
|
|
@ -309,29 +269,12 @@ namespace Flow.Launcher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void HotkeyBtn_OnChecked(object sender, RoutedEventArgs e)
|
private void HotkeyBtn_OnChecked(object sender, RoutedEventArgs e) => StartRecording();
|
||||||
{
|
|
||||||
StartRecording();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HotkeyBtn_OnUnchecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
StopRecording();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetButton_OnClick(object sender, RoutedEventArgs e)
|
private void ResetButton_OnClick(object sender, RoutedEventArgs e) => ResetToDefault();
|
||||||
{
|
private void DeleteBtn_OnClick(object sender, RoutedEventArgs e) => Delete();
|
||||||
ResetToDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteBtn_OnClick(object sender, RoutedEventArgs e)
|
private void StopRecordingBtn_Click(object sender, RoutedEventArgs e) => StopRecording();
|
||||||
{
|
|
||||||
Delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopRecordingBtn_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
StopRecording();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue