Remove old HotkeyControl, rename HotkeyControl2 to HotkeyControl

This commit is contained in:
Yusyuriv 2024-04-23 09:04:37 +06:00
parent a3b13ef6ac
commit 03c74590f5
No known key found for this signature in database
GPG key ID: A91C52E6F73148E0
9 changed files with 138 additions and 592 deletions

View file

@ -97,7 +97,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="14" FontSize="14"
Text="{DynamicResource hotkey}" /> Text="{DynamicResource hotkey}" />
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
x:Name="HotkeyControl" x:Name="HotkeyControl"
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"

View file

@ -3,170 +3,75 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 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" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Button
<Popup Width="Auto"
x:Name="popup" FontSize="13"
AllowDrop="True" FontWeight="Bold"
AllowsTransparency="True" Foreground="{DynamicResource Color01B}"
IsOpen="{Binding IsKeyboardFocused, ElementName=tbHotkey, Mode=OneWay}" Click="GetNewHotkey">
Placement="Top" <Button.Template>
PlacementTarget="{Binding ElementName=tbHotkey}" <ControlTemplate TargetType="Button">
PopupAnimation="Fade" <Border
StaysOpen="True" x:Name="ButtonBorder"
VerticalOffset="-5"> Padding="5,0,5,0"
<Border Background="{DynamicResource ButtonBackgroundColor}"
Width="140" BorderBrush="{DynamicResource ButtonInsideBorder}"
Height="30" BorderThickness="1"
Background="{DynamicResource Color01B}" CornerRadius="5">
BorderBrush="{DynamicResource Color21B}" <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
BorderThickness="1" </Border>
CornerRadius="4"> <ControlTemplate.Triggers>
<TextBlock <MultiTrigger>
x:Name="tbMsg" <MultiTrigger.Conditions>
Margin="0,0,0,0" <Condition Property="IsMouseOver" Value="True" />
HorizontalAlignment="Center" <Condition Property="IsPressed" Value="True" />
VerticalAlignment="Center" </MultiTrigger.Conditions>
FontSize="13" <Setter TargetName="ButtonBorder" Property="Background"
FontWeight="SemiBold" Value="{DynamicResource ButtonMousePressed}" />
Foreground="{Binding MessageColor}" <Setter TargetName="ButtonBorder" Property="BorderBrush"
Text="{Binding Message}" Value="{DynamicResource ButtonMousePressedInsideBorder}" />
Visibility="{Binding MessageVisibility}" /> </MultiTrigger>
</Border> <MultiTrigger>
</Popup> <MultiTrigger.Conditions>
<Grid> <Condition Property="IsMouseOver" Value="True" />
<Grid.ColumnDefinitions> </MultiTrigger.Conditions>
<ColumnDefinition /> <Setter TargetName="ButtonBorder" Property="Background"
<ColumnDefinition /> Value="{DynamicResource ButtonMouseOver}" />
</Grid.ColumnDefinitions> </MultiTrigger>
<Border <MultiTrigger>
x:Name="MenuBorder" <MultiTrigger.Conditions>
Grid.Column="0" <Condition Property="IsPressed" Value="True" />
Margin="0,0,5,0" </MultiTrigger.Conditions>
Padding="5,0,5,0" <Setter TargetName="ButtonBorder" Property="Background"
Background="{DynamicResource Color12B}" Value="{DynamicResource ButtonMousePressed}" />
BorderBrush="{DynamicResource ButtonInsideBorder}" <Setter TargetName="ButtonBorder" Property="BorderBrush"
BorderThickness="1" Value="{DynamicResource CustomContextHover}" />
CornerRadius="5"> </MultiTrigger>
<Border.Style> </ControlTemplate.Triggers>
<Style TargetType="{x:Type Border}"> </ControlTemplate>
<Setter Property="Visibility" Value="Collapsed" /> </Button.Template>
<Style.Triggers> <Button.Content>
<DataTrigger Binding="{Binding ElementName=HotkeyBtn, Path=IsChecked}" Value="True"> <ItemsControl x:Name="HotkeyList">
<Setter Property="Visibility" Value="Visible" /> <ItemsControl.ItemsPanel>
</DataTrigger> <ItemsPanelTemplate>
<DataTrigger Binding="{Binding ElementName=HotkeyBtn, Path=IsChecked}" Value="False"> <StackPanel Orientation="Horizontal" />
<Setter Property="Visibility" Value="Collapsed" /> </ItemsPanelTemplate>
</DataTrigger> </ItemsControl.ItemsPanel>
</Style.Triggers> <ItemsControl.ItemTemplate>
</Style> <DataTemplate>
</Border.Style>
<StackPanel Orientation="Horizontal">
<Button Margin="2" Click="ResetButton_OnClick">
<Button.Content>
<ui:FontIcon FontSize="13" Glyph="&#xe72c;" />
</Button.Content>
</Button>
<Button Margin="2" Click="DeleteBtn_OnClick">
<Button.Content>
<ui:FontIcon FontSize="13" Glyph="&#xe74d;" />
</Button.Content>
</Button>
<Button
Margin="2"
Click="StopRecordingBtn_Click"
Foreground="red">
<Button.Content>
<ui:FontIcon FontSize="13" Glyph="&#xe7c8;" />
</Button.Content>
</Button>
</StackPanel>
</Border>
<RadioButton
x:Name="HotkeyBtn"
Grid.Column="1"
Width="Auto"
Checked="HotkeyBtn_OnChecked"
FontSize="13"
FontWeight="Bold"
Foreground="{DynamicResource Color01B}"
GroupName="HotkeyReg"
KeyboardNavigation.TabNavigation="Continue"
PreviewKeyDown="OnPreviewKeyDown"
Style="{StaticResource {x:Type ToggleButton}}">
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Border <Border
x:Name="ButtonBorder" Margin="2,5,2,5"
Padding="5,0,5,0" Padding="10,5,10,5"
Background="{DynamicResource ButtonBackgroundColor}" Background="{DynamicResource AccentButtonBackground}"
BorderBrush="{DynamicResource ButtonInsideBorder}"
BorderThickness="1" BorderThickness="1"
CornerRadius="5"> CornerRadius="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> <TextBlock Text="{Binding}" />
</Border> </Border>
<ControlTemplate.Triggers> </DataTemplate>
<MultiTrigger> </ItemsControl.ItemTemplate>
<MultiTrigger.Conditions> </ItemsControl>
<Condition Property="IsMouseOver" Value="True" /> </Button.Content>
<Condition Property="IsChecked" Value="True" /> </Button>
<Condition Property="IsPressed" Value="True" /> </UserControl>
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource ButtonMousePressedInsideBorder}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsChecked" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMouseOver}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource CustomContextHover}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="IsChecked" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background" Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{DynamicResource CustomContextHover}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</RadioButton.Template>
<ToggleButton.Content>
<ItemsControl x:Name="HotkeyList">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Margin="2,5,2,5"
Padding="10,5,10,5"
Background="{DynamicResource AccentButtonBackground}"
BorderThickness="1"
CornerRadius="5">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ToggleButton.Content>
</RadioButton>
</Grid>
</Grid>
</UserControl>

View file

@ -1,30 +1,38 @@
using System; #nullable enable
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.Threading.Tasks;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media;
using Flow.Launcher.Core.Resource; 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 JetBrains.Annotations;
#nullable enable
namespace Flow.Launcher namespace Flow.Launcher
{ {
public partial class HotkeyControl : INotifyPropertyChanged public partial class HotkeyControl
{ {
public string WindowTitle {
get { return (string)GetValue(WindowTitleProperty); }
set { SetValue(WindowTitleProperty, value); }
}
public static readonly DependencyProperty WindowTitleProperty = DependencyProperty.Register(
nameof(WindowTitle),
typeof(string),
typeof(HotkeyControl),
new PropertyMetadata(string.Empty)
);
/// <summary> /// <summary>
/// Designed for Preview Hotkey and KeyGesture. /// Designed for Preview Hotkey and KeyGesture.
/// </summary> /// </summary>
public static readonly DependencyProperty ValidateKeyGestureProperty = DependencyProperty.Register( public static readonly DependencyProperty ValidateKeyGestureProperty = DependencyProperty.Register(
nameof(ValidateKeyGesture), typeof(bool), typeof(HotkeyControl), nameof(ValidateKeyGesture),
new PropertyMetadata(default(bool))); typeof(bool),
typeof(HotkeyControl),
new PropertyMetadata(default(bool))
);
public bool ValidateKeyGesture public bool ValidateKeyGesture
{ {
@ -33,7 +41,11 @@ namespace Flow.Launcher
} }
public static readonly DependencyProperty DefaultHotkeyProperty = DependencyProperty.Register( public static readonly DependencyProperty DefaultHotkeyProperty = DependencyProperty.Register(
nameof(DefaultHotkey), typeof(string), typeof(HotkeyControl), new PropertyMetadata(default(string))); nameof(DefaultHotkey),
typeof(string),
typeof(HotkeyControl),
new PropertyMetadata(default(string))
);
public string DefaultHotkey public string DefaultHotkey
{ {
@ -54,7 +66,11 @@ namespace Flow.Launcher
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
{ {
@ -64,8 +80,11 @@ namespace Flow.Launcher
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register( public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey), typeof(string), typeof(HotkeyControl), nameof(Hotkey),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHotkeyChanged)); typeof(string),
typeof(HotkeyControl),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHotkeyChanged)
);
public string Hotkey public string Hotkey
{ {
@ -81,148 +100,50 @@ namespace Flow.Launcher
SetKeysToDisplay(CurrentHotkey); SetKeysToDisplay(CurrentHotkey);
} }
/*------------------ New Logic Structure Part------------------------*/
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if (HotkeyBtn.IsChecked != true)
return;
e.Handled = true;
//when alt is pressed, the real key should be e.SystemKey
Key key = e.Key == Key.System ? e.SystemKey : e.Key;
SpecialKeyState specialKeyState = GlobalHotkey.CheckModifiers();
var hotkeyModel = new HotkeyModel(
specialKeyState.AltPressed,
specialKeyState.ShiftPressed,
specialKeyState.WinPressed,
specialKeyState.CtrlPressed,
key);
CurrentHotkey = hotkeyModel;
SetKeysToDisplay(CurrentHotkey);
}
// public new bool IsFocused => tbHotkey.IsFocused;
private void tbHotkey_LostFocus(object sender, RoutedEventArgs e)
{
// tbHotkey.Text = CurrentHotkey?.ToString() ?? "";
// tbHotkey.Select(tbHotkey.Text.Length, 0);
}
private void tbHotkey_GotFocus(object sender, RoutedEventArgs e)
{
ResetMessage();
}
private void ResetMessage()
{
tbMsg.Text = InternationalizationManager.Instance.GetTranslation("flowlauncherPressHotkey");
tbMsg.SetResourceReference(TextBox.ForegroundProperty, "Color05B");
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
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);
public string? Message { get; set; } public string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
public bool MessageVisibility { get; set; }
public SolidColorBrush? MessageColor { get; set; }
public ObservableCollection<string> KeysToDisplay { get; set; } = new();
public bool CurrentHotkeyAvailable { get; private set; }
private void SetMessage(string messageKey, bool error)
{
Message = InternationalizationManager.Instance.GetTranslation(messageKey);
MessageColor = error ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red);
MessageVisibility = true;
}
private string EmptyHotkeyKey = "none";
public string EmptyHotkey => InternationalizationManager.Instance.GetTranslation(EmptyHotkeyKey);
private const string KeySeparator = " + ";
public ObservableCollection<string> KeysToDisplay { get; set; } = new ObservableCollection<string>();
public bool IsEmpty => KeysToDisplay.Count == 0 || (KeysToDisplay.Count == 1 && KeysToDisplay[0] == EmptyHotkey);
public HotkeyModel CurrentHotkey { get; private set; } = new(false, false, false, false, Key.None); public HotkeyModel CurrentHotkey { get; private set; } = new(false, false, false, false, Key.None);
public void StartRecording() public void GetNewHotkey(object sender, RoutedEventArgs e)
{ {
if (!HotkeyBtn.IsChecked ?? false) OpenHotkeyDialog();
{ }
return;
}
private async Task OpenHotkeyDialog()
{
if (!string.IsNullOrEmpty(Hotkey)) if (!string.IsNullOrEmpty(Hotkey))
{ {
HotKeyMapper.RemoveHotkey(Hotkey); HotKeyMapper.RemoveHotkey(Hotkey);
} }
/* 1. Key Recording Start */
/* 2. Key Display area clear
* 3. Key Display when typing*/
}
private void StopRecording() var dialog = new HotkeyControlDialog(Hotkey, DefaultHotkey, WindowTitle);
{ await dialog.ShowAsync();
try switch (dialog.ResultType)
{ {
var converter = new KeyGestureConverter(); case HotkeyControlDialog.EResultType.Cancel:
_ = (KeyGesture)converter.ConvertFromString(CurrentHotkey.ToString())!; SetHotkey(Hotkey);
return;
case HotkeyControlDialog.EResultType.Save:
SetHotkey(dialog.ResultValue);
break;
case HotkeyControlDialog.EResultType.Delete:
Delete();
break;
} }
catch (Exception e) when (e is NotSupportedException or InvalidEnumArgumentException)
{
SetMessage("Hotkey Invalid", true);
CurrentHotkey = new HotkeyModel(Hotkey);
SetKeysToDisplay(CurrentHotkey);
return;
}
HotkeyBtn.IsChecked = false;
SetHotkey(CurrentHotkey, true);
}
private void ResetToDefault()
{
if (!string.IsNullOrEmpty(Hotkey))
HotKeyMapper.RemoveHotkey(Hotkey);
Hotkey = DefaultHotkey;
CurrentHotkey = new HotkeyModel(Hotkey);
SetKeysToDisplay(CurrentHotkey);
SetHotkey(CurrentHotkey);
HotkeyBtn.IsChecked = false;
} }
private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true) private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
{ {
// tbHotkey.Text = keyModel.ToString();
// tbHotkey.Select(tbHotkey.Text.Length, 0);
if (triggerValidate) if (triggerValidate)
{ {
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture); bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
if (!hotkeyAvailable) if (!hotkeyAvailable)
{ {
@ -246,7 +167,6 @@ namespace Flow.Launcher
HotKeyMapper.RemoveHotkey(Hotkey); HotKeyMapper.RemoveHotkey(Hotkey);
Hotkey = ""; Hotkey = "";
SetKeysToDisplay(new HotkeyModel(false, false, false, false, Key.None)); SetKeysToDisplay(new HotkeyModel(false, false, false, false, Key.None));
HotkeyBtn.IsChecked = false;
} }
private void SetKeysToDisplay(HotkeyModel? hotkey) private void SetKeysToDisplay(HotkeyModel? hotkey)
@ -269,14 +189,5 @@ namespace Flow.Launcher
{ {
SetHotkey(new HotkeyModel(keyStr), triggerValidate); SetHotkey(new HotkeyModel(keyStr), triggerValidate);
} }
private void HotkeyBtn_OnChecked(object sender, RoutedEventArgs e) => StartRecording();
private void ResetButton_OnClick(object sender, RoutedEventArgs e) => ResetToDefault();
private void DeleteBtn_OnClick(object sender, RoutedEventArgs e) => Delete();
private void StopRecordingBtn_Click(object sender, RoutedEventArgs e) => StopRecording();
} }
} }

View file

@ -1,77 +0,0 @@
<UserControl
x:Class="Flow.Launcher.HotkeyControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Button
Width="Auto"
FontSize="13"
FontWeight="Bold"
Foreground="{DynamicResource Color01B}"
Click="GetNewHotkey">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border
x:Name="ButtonBorder"
Padding="5,0,5,0"
Background="{DynamicResource ButtonBackgroundColor}"
BorderBrush="{DynamicResource ButtonInsideBorder}"
BorderThickness="1"
CornerRadius="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsPressed" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush"
Value="{DynamicResource ButtonMousePressedInsideBorder}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMouseOver}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ButtonBorder" Property="Background"
Value="{DynamicResource ButtonMousePressed}" />
<Setter TargetName="ButtonBorder" Property="BorderBrush"
Value="{DynamicResource CustomContextHover}" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<Button.Content>
<ItemsControl x:Name="HotkeyList">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Margin="2,5,2,5"
Padding="10,5,10,5"
Background="{DynamicResource AccentButtonBackground}"
BorderThickness="1"
CornerRadius="5">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Button.Content>
</Button>
</UserControl>

View file

@ -1,193 +0,0 @@
#nullable enable
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure.Hotkey;
namespace Flow.Launcher
{
public partial class HotkeyControl2
{
public string WindowTitle {
get { return (string)GetValue(WindowTitleProperty); }
set { SetValue(WindowTitleProperty, value); }
}
public static readonly DependencyProperty WindowTitleProperty = DependencyProperty.Register(
nameof(WindowTitle),
typeof(string),
typeof(HotkeyControl2),
new PropertyMetadata(string.Empty)
);
/// <summary>
/// Designed for Preview Hotkey and KeyGesture.
/// </summary>
public static readonly DependencyProperty ValidateKeyGestureProperty = DependencyProperty.Register(
nameof(ValidateKeyGesture),
typeof(bool),
typeof(HotkeyControl2),
new PropertyMetadata(default(bool))
);
public bool ValidateKeyGesture
{
get { return (bool)GetValue(ValidateKeyGestureProperty); }
set { SetValue(ValidateKeyGestureProperty, value); }
}
public static readonly DependencyProperty DefaultHotkeyProperty = DependencyProperty.Register(
nameof(DefaultHotkey),
typeof(string),
typeof(HotkeyControl2),
new PropertyMetadata(default(string))
);
public string DefaultHotkey
{
get { return (string)GetValue(DefaultHotkeyProperty); }
set { SetValue(DefaultHotkeyProperty, value); }
}
private static void OnHotkeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not HotkeyControl2 hotkeyControl)
{
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(HotkeyControl2),
new PropertyMetadata(default(ICommand))
);
public ICommand? ChangeHotkey
{
get { return (ICommand)GetValue(ChangeHotkeyProperty); }
set { SetValue(ChangeHotkeyProperty, value); }
}
public static readonly DependencyProperty HotkeyProperty = DependencyProperty.Register(
nameof(Hotkey),
typeof(string),
typeof(HotkeyControl2),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnHotkeyChanged)
);
public string Hotkey
{
get { return (string)GetValue(HotkeyProperty); }
set { SetValue(HotkeyProperty, value); }
}
public HotkeyControl2()
{
InitializeComponent();
HotkeyList.ItemsSource = KeysToDisplay;
SetKeysToDisplay(CurrentHotkey);
}
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
public string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
public ObservableCollection<string> KeysToDisplay { get; set; } = new();
public HotkeyModel CurrentHotkey { get; private set; } = new(false, false, false, false, Key.None);
public void GetNewHotkey(object sender, RoutedEventArgs e)
{
OpenHotkeyDialog();
}
private async Task OpenHotkeyDialog()
{
if (!string.IsNullOrEmpty(Hotkey))
{
HotKeyMapper.RemoveHotkey(Hotkey);
}
var dialog = new HotkeyControl2Dialog(Hotkey, DefaultHotkey, WindowTitle);
await dialog.ShowAsync();
switch (dialog.ResultType)
{
case HotkeyControl2Dialog.EResultType.Cancel:
SetHotkey(Hotkey);
return;
case HotkeyControl2Dialog.EResultType.Save:
SetHotkey(dialog.ResultValue);
break;
case HotkeyControl2Dialog.EResultType.Delete:
Delete();
break;
}
}
private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
{
if (triggerValidate)
{
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
if (!hotkeyAvailable)
{
return;
}
Hotkey = keyModel.ToString();
SetKeysToDisplay(CurrentHotkey);
ChangeHotkey?.Execute(keyModel);
}
else
{
Hotkey = keyModel.ToString();
ChangeHotkey?.Execute(keyModel);
}
}
public void Delete()
{
if (!string.IsNullOrEmpty(Hotkey))
HotKeyMapper.RemoveHotkey(Hotkey);
Hotkey = "";
SetKeysToDisplay(new HotkeyModel(false, false, false, false, Key.None));
}
private void SetKeysToDisplay(HotkeyModel? hotkey)
{
KeysToDisplay.Clear();
if (hotkey == null || hotkey == default(HotkeyModel))
{
KeysToDisplay.Add(EmptyHotkey);
return;
}
foreach (var key in hotkey.Value.EnumerateDisplayKeys()!)
{
KeysToDisplay.Add(key);
}
}
public void SetHotkey(string? keyStr, bool triggerValidate = true)
{
SetHotkey(new HotkeyModel(keyStr), triggerValidate);
}
}
}

View file

@ -1,5 +1,5 @@
<ui:ContentDialog <ui:ContentDialog
x:Class="Flow.Launcher.HotkeyControl2Dialog" x:Class="Flow.Launcher.HotkeyControlDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:ui="http://schemas.modernwpf.com/2019"

View file

@ -9,7 +9,7 @@ using ModernWpf.Controls;
namespace Flow.Launcher; namespace Flow.Launcher;
public partial class HotkeyControl2Dialog : ContentDialog public partial class HotkeyControlDialog : ContentDialog
{ {
private string DefaultHotkey { get; } private string DefaultHotkey { get; }
public string WindowTitle { get; } public string WindowTitle { get; }
@ -27,7 +27,7 @@ public partial class HotkeyControl2Dialog : ContentDialog
public string ResultValue { get; private set; } = string.Empty; public string ResultValue { get; private set; } = string.Empty;
public static string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none"); public static string EmptyHotkey => InternationalizationManager.Instance.GetTranslation("none");
public HotkeyControl2Dialog(string hotkey, string defaultHotkey, string windowTitle = "") public HotkeyControlDialog(string hotkey, string defaultHotkey, string windowTitle = "")
{ {
WindowTitle = windowTitle switch WindowTitle = windowTitle switch
{ {

View file

@ -110,7 +110,7 @@
FontSize="14" FontSize="14"
FontWeight="SemiBold" FontWeight="SemiBold"
Text="{DynamicResource flowlauncherHotkey}" /> Text="{DynamicResource flowlauncherHotkey}" />
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
Margin="0,8,0,0" Margin="0,8,0,0"
ChangeHotkey="{Binding SetTogglingHotkeyCommand}" ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space" DefaultHotkey="Alt+Space"

View file

@ -2641,7 +2641,7 @@
Title="{DynamicResource flowlauncherHotkey}" Title="{DynamicResource flowlauncherHotkey}"
Icon="&#xeda7;" Icon="&#xeda7;"
Sub="{DynamicResource flowlauncherHotkeyToolTip}"> Sub="{DynamicResource flowlauncherHotkeyToolTip}">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
ChangeHotkey="{Binding SetTogglingHotkeyCommand}" ChangeHotkey="{Binding SetTogglingHotkeyCommand}"
DefaultHotkey="Alt+Space" DefaultHotkey="Alt+Space"
Hotkey="{Binding Settings.Hotkey}" Hotkey="{Binding Settings.Hotkey}"
@ -2655,7 +2655,7 @@
Title="{DynamicResource previewHotkey}" Title="{DynamicResource previewHotkey}"
Icon="&#xe8a1;" Icon="&#xe8a1;"
Sub="{DynamicResource previewHotkeyToolTip}"> Sub="{DynamicResource previewHotkeyToolTip}">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="F1" DefaultHotkey="F1"
Hotkey="{Binding Settings.PreviewHotkey}" Hotkey="{Binding Settings.PreviewHotkey}"
ValidateKeyGesture="False" ValidateKeyGesture="False"
@ -2755,7 +2755,7 @@
Title="{DynamicResource OpenContextMenuHotkey}" Title="{DynamicResource OpenContextMenuHotkey}"
Icon="&#xede3;" Icon="&#xede3;"
Type="Inside"> Type="Inside">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+I" DefaultHotkey="Ctrl+I"
Hotkey="{Binding Settings.OpenContextMenuHotkey}" Hotkey="{Binding Settings.OpenContextMenuHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2771,7 +2771,7 @@
Title="{DynamicResource SettingWindowHotkey}" Title="{DynamicResource SettingWindowHotkey}"
Icon="&#xe713;" Icon="&#xe713;"
Type="Inside"> Type="Inside">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+I" DefaultHotkey="Ctrl+I"
Hotkey="{Binding Settings.SettingWindowHotkey}" Hotkey="{Binding Settings.SettingWindowHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2793,7 +2793,7 @@
Title="{DynamicResource SelectNextPageHotkey}" Title="{DynamicResource SelectNextPageHotkey}"
Icon="&#xf0ad;" Icon="&#xf0ad;"
Type="Inside"> Type="Inside">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="" DefaultHotkey=""
Hotkey="{Binding Settings.SelectNextPageHotkey}" Hotkey="{Binding Settings.SelectNextPageHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2802,7 +2802,7 @@
Title="{DynamicResource SelectPrevPageHotkey}" Title="{DynamicResource SelectPrevPageHotkey}"
Icon="&#xf0ae;" Icon="&#xf0ae;"
Type="Inside"> Type="Inside">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="" DefaultHotkey=""
Hotkey="{Binding Settings.SelectPrevPageHotkey}" Hotkey="{Binding Settings.SelectPrevPageHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2836,7 +2836,7 @@
Icon="&#xe893;" Icon="&#xe893;"
Sub="{DynamicResource autoCompleteHotkeyToolTip}"> Sub="{DynamicResource autoCompleteHotkeyToolTip}">
<cc:ExCard.SideContent> <cc:ExCard.SideContent>
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="Ctrl+Tab" DefaultHotkey="Ctrl+Tab"
Hotkey="{Binding Settings.AutoCompleteHotkey}" Hotkey="{Binding Settings.AutoCompleteHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2845,7 +2845,7 @@
Title="{DynamicResource autoCompleteHotkey}" Title="{DynamicResource autoCompleteHotkey}"
Sub="{DynamicResource AdditionalHotkeyToolTip}" Sub="{DynamicResource AdditionalHotkeyToolTip}"
Type="InsideFit"> Type="InsideFit">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="" DefaultHotkey=""
Hotkey="{Binding Settings.AutoCompleteHotkey2}" Hotkey="{Binding Settings.AutoCompleteHotkey2}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2858,7 +2858,7 @@
Margin="0,4,0,0" Margin="0,4,0,0"
Icon="&#xe74b;"> Icon="&#xe74b;">
<cc:ExCard.SideContent> <cc:ExCard.SideContent>
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="Tab" DefaultHotkey="Tab"
Hotkey="{Binding Settings.SelectNextItemHotkey}" Hotkey="{Binding Settings.SelectNextItemHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2867,7 +2867,7 @@
Title="{DynamicResource SelectNextItemHotkey}" Title="{DynamicResource SelectNextItemHotkey}"
Sub="{DynamicResource AdditionalHotkeyToolTip}" Sub="{DynamicResource AdditionalHotkeyToolTip}"
Type="InsideFit"> Type="InsideFit">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="" DefaultHotkey=""
Hotkey="{Binding Settings.SelectNextItemHotkey2}" Hotkey="{Binding Settings.SelectNextItemHotkey2}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2879,7 +2879,7 @@
Margin="0,4,0,0" Margin="0,4,0,0"
Icon="&#xe74a;"> Icon="&#xe74a;">
<cc:ExCard.SideContent> <cc:ExCard.SideContent>
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="Shift+Tab" DefaultHotkey="Shift+Tab"
Hotkey="{Binding Settings.SelectPrevItemHotkey}" Hotkey="{Binding Settings.SelectPrevItemHotkey}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />
@ -2888,7 +2888,7 @@
Title="{DynamicResource SelectPrevItemHotkey}" Title="{DynamicResource SelectPrevItemHotkey}"
Sub="{DynamicResource AdditionalHotkeyToolTip}" Sub="{DynamicResource AdditionalHotkeyToolTip}"
Type="InsideFit"> Type="InsideFit">
<flowlauncher:HotkeyControl2 <flowlauncher:HotkeyControl
DefaultHotkey="" DefaultHotkey=""
Hotkey="{Binding Settings.SelectPrevItemHotkey2}" Hotkey="{Binding Settings.SelectPrevItemHotkey2}"
ValidateKeyGesture="False" /> ValidateKeyGesture="False" />