mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
WIP: new HotkeyControl
This commit is contained in:
parent
da630039d1
commit
914f400956
4 changed files with 132 additions and 64 deletions
|
|
@ -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">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Popup
|
||||
x:Name="popup"
|
||||
AllowDrop="True"
|
||||
|
|
@ -43,14 +39,50 @@
|
|||
</Border>
|
||||
</Popup>
|
||||
|
||||
<TextBox
|
||||
x:Name="tbHotkey"
|
||||
Margin="0,0,18,0"
|
||||
VerticalContentAlignment="Center"
|
||||
input:InputMethod.IsInputMethodEnabled="False"
|
||||
GotFocus="tbHotkey_GotFocus"
|
||||
LostFocus="tbHotkey_LostFocus"
|
||||
PreviewKeyDown="TbHotkey_OnPreviewKeyDown"
|
||||
TabIndex="100" />
|
||||
<Button FontSize="13" FontWeight="Bold" Foreground="{DynamicResource Color01B}" Click="OnButtonClicked">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border
|
||||
x:Name="ButtonBorder"
|
||||
Background="{DynamicResource Color12B}"
|
||||
BorderBrush="{DynamicResource ButtonInsideBorder}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource CustomContextHover}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
|
||||
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource ButtonMousePressedInsideBorder}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
<Button.Content>
|
||||
<ItemsControl ItemsSource="{Binding Path=KeysToDisplay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border
|
||||
Margin="6"
|
||||
Padding="10,5,10,5"
|
||||
Background="{DynamicResource SystemAccentColorLight2Brush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Height="30">
|
||||
<TextBlock Text="{Binding}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
</UserControl>
|
||||
|
|
|
|||
|
|
@ -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<HotkeyEventArgs>? Action { get; set; }
|
||||
#nullable restore
|
||||
|
||||
public event EventHandler HotkeyChanged;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@
|
|||
</ItemsControl>
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
<Border
|
||||
Margin="0,30,0,0"
|
||||
Padding="0"
|
||||
Style="{DynamicResource SettingGroupBox}">
|
||||
|
|
@ -720,7 +720,7 @@
|
|||
<ComboBox
|
||||
x:Name="SelectScreen"
|
||||
MinWidth="160"
|
||||
Margin="0,0,18,0"
|
||||
Margin="0,0,18,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
ItemsSource="{Binding ScreenNumbers}"
|
||||
|
|
@ -2543,7 +2543,7 @@
|
|||
TickFrequency="1"
|
||||
Value="{Binding SoundEffectVolume, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||

|
||||
</TextBlock>
|
||||
</ItemsControl>
|
||||
|
|
@ -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" />
|
||||
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||

|
||||
|
|
@ -2684,8 +2683,7 @@
|
|||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
HorizontalContentAlignment="Right"
|
||||
Loaded="OnPreviewHotkeyControlLoaded"
|
||||
LostFocus="OnPreviewHotkeyControlFocusLost"
|
||||
Hotkey="{Binding Settings.PreviewHotkey}"
|
||||
ValidateKeyGesture="True" />
|
||||
<TextBlock Style="{StaticResource Glyph}">
|
||||

|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue