diff --git a/Flow.Launcher/HotkeyControl.xaml b/Flow.Launcher/HotkeyControl.xaml index acf4a21ec..bea652d56 100644 --- a/Flow.Launcher/HotkeyControl.xaml +++ b/Flow.Launcher/HotkeyControl.xaml @@ -5,14 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - Height="24" - d:DesignHeight="300" + d:DesignHeight="45" d:DesignWidth="300" mc:Ignorable="d"> - - - - + - \ No newline at end of file + diff --git a/Flow.Launcher/HotkeyControl.xaml.cs b/Flow.Launcher/HotkeyControl.xaml.cs index 3da66caeb..f08a80147 100644 --- a/Flow.Launcher/HotkeyControl.xaml.cs +++ b/Flow.Launcher/HotkeyControl.xaml.cs @@ -1,4 +1,6 @@ using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -9,14 +11,37 @@ using Flow.Launcher.Helper; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Plugin; using System.Threading; +using NHotkey; namespace Flow.Launcher { - public partial class HotkeyControl : UserControl + public partial class HotkeyControl : UserControl, IDisposable, INotifyPropertyChanged { + public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register( + nameof(Hotkey), + typeof(string), + typeof(HotkeyControl), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) + ); public HotkeyModel CurrentHotkey { get; private set; } public bool CurrentHotkeyAvailable { get; private set; } + public string Hotkey + { + get => (string)GetValue(HotkeyProperty); + set + { + SetValue(HotkeyProperty, value); + OnPropertyChanged(nameof(KeysToDisplay)); + } + } + + public string[] KeysToDisplay => Hotkey.Split(" + "); + + #nullable enable + public EventHandler? Action { get; set; } + #nullable restore + public event EventHandler HotkeyChanged; /// @@ -29,6 +54,28 @@ namespace Flow.Launcher public HotkeyControl() { InitializeComponent(); + Loaded += HotkeyControl_Loaded; + } + + private void HotkeyControl_LostFocus(object o, RoutedEventArgs routedEventArgs) + { + HotKeyMapper.SetHotkey(CurrentHotkey, Action); + } + + private void HotkeyControl_GotFocus(object o, RoutedEventArgs routedEventArgs) + { + HotKeyMapper.RemoveHotkey(Hotkey); + } + + private void HotkeyControl_Loaded(object sender, RoutedEventArgs e) + { + _ = SetHotkeyAsync(Hotkey, false); + + if (Action is not null) + { + GotFocus += HotkeyControl_GotFocus; + LostFocus += HotkeyControl_LostFocus; + } } private CancellationTokenSource hotkeyUpdateSource; @@ -68,8 +115,8 @@ namespace Flow.Launcher public async Task SetHotkeyAsync(HotkeyModel keyModel, bool triggerValidate = true) { - tbHotkey.Text = keyModel.ToString(); - tbHotkey.Select(tbHotkey.Text.Length, 0); + // tbHotkey.Text = keyModel.ToString(); + // tbHotkey.Select(tbHotkey.Text.Length, 0); if (triggerValidate) { @@ -86,6 +133,7 @@ namespace Flow.Launcher if (CurrentHotkeyAvailable) { CurrentHotkey = keyModel; + Hotkey = keyModel.ToString(); // To trigger LostFocus FocusManager.SetFocusedElement(FocusManager.GetFocusScope(this), null); Keyboard.ClearFocus(); @@ -94,9 +142,10 @@ namespace Flow.Launcher else { CurrentHotkey = keyModel; + Hotkey = keyModel.ToString(); } } - + public Task SetHotkeyAsync(string keyStr, bool triggerValidate = true) { return SetHotkeyAsync(new HotkeyModel(keyStr), triggerValidate); @@ -104,12 +153,12 @@ namespace Flow.Launcher private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) => hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey); - public new bool IsFocused => tbHotkey.IsFocused; + // public new bool IsFocused => tbHotkey.IsFocused; private void tbHotkey_LostFocus(object sender, RoutedEventArgs e) { - tbHotkey.Text = CurrentHotkey?.ToString() ?? ""; - tbHotkey.Select(tbHotkey.Text.Length, 0); + // tbHotkey.Text = CurrentHotkey?.ToString() ?? ""; + // tbHotkey.Select(tbHotkey.Text.Length, 0); } private void tbHotkey_GotFocus(object sender, RoutedEventArgs e) @@ -137,5 +186,25 @@ namespace Flow.Launcher } tbMsg.Visibility = Visibility.Visible; } + + public void Dispose() + { + hotkeyUpdateSource?.Dispose(); + Loaded -= HotkeyControl_Loaded; + GotFocus -= HotkeyControl_GotFocus; + LostFocus -= HotkeyControl_LostFocus; + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private void OnButtonClicked(object sender, RoutedEventArgs e) + { + // TODO + } } } diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 96f80f0c5..e1b42e3d3 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -693,7 +693,7 @@ - @@ -720,7 +720,7 @@ - + @@ -2657,9 +2657,8 @@ Margin="0,0,0,0" HorizontalAlignment="Right" HorizontalContentAlignment="Right" - GotFocus="OnHotkeyControlFocused" - Loaded="OnHotkeyControlLoaded" - LostFocus="OnHotkeyControlFocusLost" /> + Hotkey="{Binding Settings.Hotkey}" + Action="OnToggleHotkey" />  @@ -2684,8 +2683,7 @@ Margin="0,0,0,0" HorizontalAlignment="Right" HorizontalContentAlignment="Right" - Loaded="OnPreviewHotkeyControlLoaded" - LostFocus="OnPreviewHotkeyControlFocusLost" + Hotkey="{Binding Settings.PreviewHotkey}" ValidateKeyGesture="True" />  diff --git a/Flow.Launcher/SettingWindow.xaml.cs b/Flow.Launcher/SettingWindow.xaml.cs index 7301be130..e7e9273bb 100644 --- a/Flow.Launcher/SettingWindow.xaml.cs +++ b/Flow.Launcher/SettingWindow.xaml.cs @@ -17,6 +17,7 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Navigation; +using NHotkey; using Button = System.Windows.Controls.Button; using Control = System.Windows.Controls.Control; using KeyEventArgs = System.Windows.Input.KeyEventArgs; @@ -110,41 +111,9 @@ namespace Flow.Launcher #region Hotkey - private void OnHotkeyControlLoaded(object sender, RoutedEventArgs e) + private void OnToggleHotkey(object sender, HotkeyEventArgs e) { - _ = HotkeyControl.SetHotkeyAsync(viewModel.Settings.Hotkey, false); - } - - private void OnHotkeyControlFocused(object sender, RoutedEventArgs e) - { - HotKeyMapper.RemoveHotkey(settings.Hotkey); - } - - private void OnHotkeyControlFocusLost(object sender, RoutedEventArgs e) - { - if (HotkeyControl.CurrentHotkeyAvailable) - { - HotKeyMapper.SetHotkey(HotkeyControl.CurrentHotkey, HotKeyMapper.OnToggleHotkey); - HotKeyMapper.RemoveHotkey(settings.Hotkey); - settings.Hotkey = HotkeyControl.CurrentHotkey.ToString(); - } - else - { - HotKeyMapper.SetHotkey(new HotkeyModel(settings.Hotkey), HotKeyMapper.OnToggleHotkey); - } - } - - private void OnPreviewHotkeyControlLoaded(object sender, RoutedEventArgs e) - { - _ = PreviewHotkeyControl.SetHotkeyAsync(settings.PreviewHotkey, false); - } - - private void OnPreviewHotkeyControlFocusLost(object sender, RoutedEventArgs e) - { - if (PreviewHotkeyControl.CurrentHotkeyAvailable) - { - settings.PreviewHotkey = PreviewHotkeyControl.CurrentHotkey.ToString(); - } + HotKeyMapper.OnToggleHotkey(sender, e); } private void OnDeleteCustomHotkeyClick(object sender, RoutedEventArgs e)