mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Change all the logic back to control rather than viewmodel
This commit is contained in:
parent
66125fce2c
commit
c544a7e3af
9 changed files with 311 additions and 338 deletions
|
|
@ -106,7 +106,7 @@
|
|||
Grid.Column="1"
|
||||
Orientation="Horizontal">
|
||||
<flowlauncher:HotkeyControl
|
||||
DataContext="{Binding HotkeyControlViewModel}"
|
||||
x:Name="HotkeyControl"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Height="36"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Flow.Launcher
|
|||
{
|
||||
if (!update)
|
||||
{
|
||||
if (!HotkeyControlViewModel.CurrentHotkeyAvailable)
|
||||
if (!HotkeyControl.CurrentHotkeyAvailable)
|
||||
{
|
||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("hotkeyIsNotUnavailable"));
|
||||
return;
|
||||
|
|
@ -46,7 +46,7 @@ namespace Flow.Launcher
|
|||
|
||||
var pluginHotkey = new CustomPluginHotkey
|
||||
{
|
||||
Hotkey = HotkeyControlViewModel.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
|
||||
Hotkey = HotkeyControl.CurrentHotkey.ToString(), ActionKeyword = tbAction.Text
|
||||
};
|
||||
_settings.CustomPluginHotkeys.Add(pluginHotkey);
|
||||
|
||||
|
|
@ -54,8 +54,8 @@ namespace Flow.Launcher
|
|||
}
|
||||
else
|
||||
{
|
||||
if (updateCustomHotkey.Hotkey != HotkeyControlViewModel.CurrentHotkey.ToString() &&
|
||||
!HotkeyControlViewModel.CurrentHotkeyAvailable)
|
||||
if (updateCustomHotkey.Hotkey != HotkeyControl.CurrentHotkey.ToString() &&
|
||||
!HotkeyControl.CurrentHotkeyAvailable)
|
||||
{
|
||||
MessageBox.Show(InternationalizationManager.Instance.GetTranslation("hotkeyIsNotUnavailable"));
|
||||
return;
|
||||
|
|
@ -63,7 +63,7 @@ namespace Flow.Launcher
|
|||
|
||||
var oldHotkey = updateCustomHotkey.Hotkey;
|
||||
updateCustomHotkey.ActionKeyword = tbAction.Text;
|
||||
updateCustomHotkey.Hotkey = HotkeyControlViewModel.CurrentHotkey.ToString();
|
||||
updateCustomHotkey.Hotkey = HotkeyControl.CurrentHotkey.ToString();
|
||||
//remove origin hotkey
|
||||
HotKeyMapper.RemoveHotkey(oldHotkey);
|
||||
HotKeyMapper.SetCustomQueryHotkey(updateCustomHotkey);
|
||||
|
|
@ -72,7 +72,6 @@ namespace Flow.Launcher
|
|||
Close();
|
||||
}
|
||||
|
||||
public HotkeyControlViewModel HotkeyControlViewModel { get; set; } = new HotkeyControlViewModel();
|
||||
|
||||
public void UpdateItem(CustomPluginHotkey item)
|
||||
{
|
||||
|
|
@ -86,7 +85,7 @@ namespace Flow.Launcher
|
|||
}
|
||||
|
||||
tbAction.Text = updateCustomHotkey.ActionKeyword;
|
||||
_ = HotkeyControlViewModel.SetHotkeyAsync(updateCustomHotkey.Hotkey, false);
|
||||
HotkeyControl.SetHotkey(updateCustomHotkey.Hotkey, false);
|
||||
update = true;
|
||||
lblAdd.Text = InternationalizationManager.Instance.GetTranslation("update");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.modernwpf.com/2019"
|
||||
xmlns:vm="clr-namespace:Flow.Launcher.ViewModel"
|
||||
d:DataContext="{d:DesignInstance vm:HotkeyControlViewModel}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Popup
|
||||
|
|
@ -67,19 +66,19 @@
|
|||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Margin="2" Command="{Binding ResetToDefaultCommand}">
|
||||
<Button Margin="2" Click="ResetButton_OnClick">
|
||||
<Button.Content>
|
||||
<ui:FontIcon FontSize="13" Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button Margin="2" Command="{Binding DeleteCommand}">
|
||||
<Button Margin="2" Click="DeleteBtn_OnClick">
|
||||
<Button.Content>
|
||||
<ui:FontIcon FontSize="13" Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button
|
||||
Margin="2"
|
||||
Command="{Binding StopRecordingCommand}"
|
||||
Click="StopRecordingBtn_Click"
|
||||
Foreground="red">
|
||||
<Button.Content>
|
||||
<ui:FontIcon FontSize="13" Glyph="" />
|
||||
|
|
@ -92,12 +91,12 @@
|
|||
x:Name="HotkeyBtn"
|
||||
Grid.Column="1"
|
||||
Width="Auto"
|
||||
Command="{Binding StartRecordingCommand}"
|
||||
Checked="HotkeyBtn_OnChecked"
|
||||
Unchecked="HotkeyBtn_OnUnchecked"
|
||||
FontSize="13"
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource Color01B}"
|
||||
GroupName="HotkeyReg"
|
||||
IsChecked="{Binding Recording}"
|
||||
KeyboardNavigation.TabNavigation="Continue"
|
||||
PreviewKeyDown="OnPreviewKeyDown"
|
||||
LostFocus="HotkeyBtn_OnLostFocus"
|
||||
|
|
@ -149,7 +148,7 @@
|
|||
</ControlTemplate>
|
||||
</RadioButton.Template>
|
||||
<ToggleButton.Content>
|
||||
<ItemsControl ItemsSource="{Binding Path=KeysToDisplay}">
|
||||
<ItemsControl x:Name="HotkeyList">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
|
|
|
|||
|
|
@ -1,5 +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;
|
||||
|
|
@ -17,31 +20,61 @@ namespace Flow.Launcher
|
|||
{
|
||||
public partial class HotkeyControl : UserControl, INotifyPropertyChanged
|
||||
{
|
||||
// /// <summary>
|
||||
// /// Designed for Preview Hotkey and KeyGesture.
|
||||
// /// </summary>
|
||||
// public static readonly DependencyProperty ValidateKeyGestureProperty = DependencyProperty.Register(
|
||||
// nameof(ValidateKeyGesture), typeof(bool), typeof(HotkeyControlViewModel),
|
||||
// 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(HotkeyControl), new PropertyMetadata(default(string)));
|
||||
//
|
||||
// public string DefaultHotkey
|
||||
// {
|
||||
// get { return (string)GetValue(DefaultHotkeyProperty); }
|
||||
// set { SetValue(DefaultHotkeyProperty, value); }
|
||||
// }
|
||||
/// <summary>
|
||||
/// Designed for Preview Hotkey and KeyGesture.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ValidateKeyGestureProperty = DependencyProperty.Register(
|
||||
nameof(ValidateKeyGesture), typeof(bool), typeof(HotkeyControl),
|
||||
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(HotkeyControl), new PropertyMetadata(default(string)));
|
||||
|
||||
public string DefaultHotkey
|
||||
{
|
||||
get { return (string)GetValue(DefaultHotkeyProperty); }
|
||||
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)
|
||||
{
|
||||
hotkeyControl.SetKeysToDisplay(new HotkeyModel(hotkeyControl.Hotkey));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static readonly DependencyProperty ChangeHotkeyProperty = DependencyProperty.Register(
|
||||
nameof(ChangeHotkey), typeof(ICommand), typeof(HotkeyControl), new PropertyMetadata(default(ICommand)));
|
||||
|
||||
public ICommand ChangeHotkey
|
||||
{
|
||||
get { return (ICommand)GetValue(ChangeHotkeyProperty); }
|
||||
set { SetValue(ChangeHotkeyProperty, value); }
|
||||
}
|
||||
|
||||
public string Hotkey
|
||||
{
|
||||
get { return (string)GetValue(HotkeyProperty); }
|
||||
set { SetValue(HotkeyProperty, value); }
|
||||
}
|
||||
|
||||
public HotkeyControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
HotkeyList.ItemsSource = KeysToDisplay;
|
||||
}
|
||||
|
||||
/*------------------ New Logic Structure Part------------------------*/
|
||||
|
|
@ -64,7 +97,8 @@ namespace Flow.Launcher
|
|||
specialKeyState.CtrlPressed,
|
||||
key);
|
||||
|
||||
((HotkeyControlViewModel)this.DataContext).KeyDown(hotkeyModel);
|
||||
CurrentHotkey = hotkeyModel;
|
||||
SetKeysToDisplay(CurrentHotkey);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -96,7 +130,208 @@ namespace Flow.Launcher
|
|||
|
||||
private void HotkeyBtn_OnLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_ = ((HotkeyControlViewModel)DataContext).RegisterHotkey();
|
||||
HotkeyBtn.IsChecked = false;
|
||||
RegisterHotkey();
|
||||
}
|
||||
|
||||
|
||||
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
|
||||
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
|
||||
|
||||
public string? Message { get; set; }
|
||||
public bool MessageVisibility { get; set; }
|
||||
public SolidColorBrush? MessageColor { get; set; }
|
||||
|
||||
|
||||
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 HotkeyModel CurrentHotkey { get; private set; }
|
||||
|
||||
|
||||
public void StartRecording()
|
||||
{
|
||||
if (!HotkeyBtn.IsChecked ?? false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
{
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
}
|
||||
/* 1. Key Recording Start */
|
||||
/* 2. Key Display area clear
|
||||
* 3. Key Display when typing*/
|
||||
}
|
||||
|
||||
private void StopRecording()
|
||||
{
|
||||
try
|
||||
{
|
||||
var converter = new KeyGestureConverter();
|
||||
var key = (KeyGesture)converter.ConvertFromString(CurrentHotkey.ToString())!;
|
||||
}
|
||||
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()
|
||||
{
|
||||
HotkeyBtn.IsChecked = false;
|
||||
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
Hotkey = DefaultHotkey;
|
||||
CurrentHotkey = new HotkeyModel(Hotkey);
|
||||
|
||||
SetKeysToDisplay(CurrentHotkey);
|
||||
|
||||
SetHotkey(CurrentHotkey);
|
||||
}
|
||||
|
||||
|
||||
private void SetHotkey(HotkeyModel keyModel, bool triggerValidate = true)
|
||||
{
|
||||
// tbHotkey.Text = keyModel.ToString();
|
||||
// tbHotkey.Select(tbHotkey.Text.Length, 0);
|
||||
|
||||
if (triggerValidate)
|
||||
{
|
||||
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
|
||||
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
|
||||
|
||||
if (hotkeyAvailable)
|
||||
{
|
||||
Hotkey = keyModel.ToString();
|
||||
SetKeysToDisplay(CurrentHotkey);
|
||||
ChangeHotkey?.Execute(keyModel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Hotkey = keyModel.ToString();
|
||||
ChangeHotkey?.Execute(keyModel);
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
HotkeyBtn.IsChecked = false;
|
||||
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
Hotkey = "";
|
||||
SetKeysToDisplay(KeysToDisplay, new List<string>());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
container.Add(key);
|
||||
}
|
||||
|
||||
if (!keys.Any())
|
||||
{
|
||||
container.Add(EmptyHotkey);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterHotkey()
|
||||
{
|
||||
SetHotkey(Hotkey, true);
|
||||
}
|
||||
|
||||
public void SetHotkey(string? keyStr, bool triggerValidate = true)
|
||||
{
|
||||
SetHotkey(new HotkeyModel(keyStr), triggerValidate);
|
||||
}
|
||||
|
||||
|
||||
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 DeleteBtn_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
public void StopRecordingBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StopRecording();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@
|
|||
Text="{DynamicResource flowlauncherHotkey}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
x:Name="HotkeyControl"
|
||||
DataContext="{Binding Path=HotkeyControlViewModel}"
|
||||
Width="300"
|
||||
Height="35"
|
||||
Margin="-206,10,0,0"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Navigation;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Flow.Launcher.ViewModel;
|
||||
|
||||
namespace Flow.Launcher.Resources.Pages
|
||||
|
|
@ -17,41 +18,35 @@ namespace Flow.Launcher.Resources.Pages
|
|||
|
||||
private string tbMsgTextOriginal;
|
||||
|
||||
public HotkeyControlViewModel HotkeyControlViewModel { get; set; }= new HotkeyControlViewModel()
|
||||
{
|
||||
ValidateKeyGesture = true
|
||||
};
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.ExtraData is Settings settings)
|
||||
Settings = settings;
|
||||
else
|
||||
throw new ArgumentException("Unexpected Parameter setting.");
|
||||
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
tbMsgTextOriginal = HotkeyControl.tbMsg.Text;
|
||||
tbMsgForegroundColorOriginal = HotkeyControl.tbMsg.Foreground;
|
||||
|
||||
_ = HotkeyControlViewModel.SetHotkeyAsync(Settings.Hotkey, false);
|
||||
HotkeyControl.ChangeHotkey = ChangeHotkeyCommand;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public void ChangeHotkey(HotkeyModel hotkeyModel)
|
||||
{
|
||||
Settings.Hotkey = hotkeyModel.ToString();
|
||||
HotKeyMapper.SetHotkey(hotkeyModel, HotKeyMapper.OnToggleHotkey);
|
||||
}
|
||||
|
||||
private void HotkeyControl_OnGotFocus(object sender, RoutedEventArgs args)
|
||||
{
|
||||
HotKeyMapper.RemoveHotkey(Settings.Hotkey);
|
||||
}
|
||||
|
||||
private void HotkeyControl_OnLostFocus(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (HotkeyControlViewModel.CurrentHotkeyAvailable)
|
||||
{
|
||||
HotKeyMapper.SetHotkey(HotkeyControlViewModel.CurrentHotkey, HotKeyMapper.OnToggleHotkey);
|
||||
Settings.Hotkey = HotkeyControlViewModel.CurrentHotkey.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
HotKeyMapper.SetHotkey(new HotkeyModel(Settings.Hotkey), HotKeyMapper.OnToggleHotkey);
|
||||
}
|
||||
|
||||
HotkeyControl.tbMsg.Text = tbMsgTextOriginal;
|
||||
HotkeyControl.tbMsg.Foreground = tbMsgForegroundColorOriginal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2641,7 +2641,11 @@
|
|||
Title="{DynamicResource flowlauncherHotkey}"
|
||||
Icon=""
|
||||
Sub="{DynamicResource flowlauncherHotkeyToolTip}">
|
||||
<flowlauncher:HotkeyControl DataContext="{Binding ToggleHotkeyViewModel}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
DefaultHotkey="Alt+Space"
|
||||
ValidateKeyGesture="True"
|
||||
Hotkey="{Binding Settings.Hotkey}"
|
||||
ChangeHotkey="{Binding SetTogglingHotkeyCommand}"/>
|
||||
</cc:Card>
|
||||
</StackPanel>
|
||||
|
||||
|
|
@ -2650,7 +2654,10 @@
|
|||
Title="{DynamicResource previewHotkey}"
|
||||
Icon=""
|
||||
Sub="{DynamicResource previewHotkeyToolTip}">
|
||||
<flowlauncher:HotkeyControl DataContext="{Binding PreviewHotkeyViewModel}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
DefaultHotkey="F1"
|
||||
ValidateKeyGesture="False"
|
||||
Hotkey="{Binding Settings.PreviewHotkey}"/>
|
||||
</cc:Card>
|
||||
</StackPanel>
|
||||
|
||||
|
|
@ -2740,16 +2747,25 @@
|
|||
Margin="0,12,0,0"
|
||||
Icon=""
|
||||
Sub="{DynamicResource autoCompleteHotkeyToolTip}">
|
||||
<flowlauncher:HotkeyControl DataContext="{Binding AutoCompleteHotkeyViewModel}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
DefaultHotkey="Ctrl+Tab"
|
||||
ValidateKeyGesture="False"
|
||||
Hotkey="{Binding Settings.AutoCompleteHotkey}"/>
|
||||
</cc:Card>
|
||||
|
||||
<cc:Card Title="{DynamicResource SelectNextItemHotkey}" Icon="">
|
||||
<flowlauncher:HotkeyControl DataContext="{Binding SelectNextItemHotkeyViewModel}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
DefaultHotkey="Tab"
|
||||
ValidateKeyGesture="False"
|
||||
Hotkey="{Binding Settings.Hotkey}"/>
|
||||
</cc:Card>
|
||||
|
||||
|
||||
<cc:Card Title="{DynamicResource SelectPrevItemHotkey}" Icon="">
|
||||
<flowlauncher:HotkeyControl DataContext="{Binding SelectPrevItemHotkeyViewModel}" />
|
||||
<flowlauncher:HotkeyControl
|
||||
DefaultHotkey="Shift+Tab"
|
||||
ValidateKeyGesture="False"
|
||||
Hotkey="{Binding Settings.SelectPrevItemHotkey}"/>
|
||||
</cc:Card>
|
||||
</StackPanel>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,241 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Flow.Launcher.Core.Resource;
|
||||
using Flow.Launcher.Helper;
|
||||
using Flow.Launcher.Infrastructure.Hotkey;
|
||||
using Flow.Launcher.Plugin;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Flow.Launcher.ViewModel
|
||||
{
|
||||
public partial class HotkeyControlViewModel : BaseModel
|
||||
{
|
||||
private static bool CheckHotkeyAvailability(HotkeyModel hotkey, bool validateKeyGesture) =>
|
||||
hotkey.Validate(validateKeyGesture) && HotKeyMapper.CheckAvailability(hotkey);
|
||||
|
||||
public string? Message { get; set; }
|
||||
public bool MessageVisibility { get; set; }
|
||||
public SolidColorBrush? MessageColor { get; set; }
|
||||
|
||||
|
||||
public bool CurrentHotkeyAvailable { get; private set; }
|
||||
|
||||
public string DefaultHotkey { get; init; }
|
||||
|
||||
private void SetMessage(string messageKey, bool error)
|
||||
{
|
||||
Message = InternationalizationManager.Instance.GetTranslation(messageKey);
|
||||
MessageColor = error ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red);
|
||||
MessageVisibility = true;
|
||||
}
|
||||
|
||||
public HotkeyControlViewModel(string hotkey = "",
|
||||
string defaultHotkey = "",
|
||||
bool validateKeyGesture = true,
|
||||
Action<HotkeyModel>? hotkeyDelegate = null)
|
||||
{
|
||||
Hotkey = hotkey;
|
||||
CurrentHotkey = new HotkeyModel(hotkey);
|
||||
DefaultHotkey = defaultHotkey;
|
||||
ValidateKeyGesture = validateKeyGesture;
|
||||
HotkeyDelegate = hotkeyDelegate;
|
||||
|
||||
keysToDisplay = new(() =>
|
||||
{
|
||||
var collection = new ObservableCollection<string>();
|
||||
|
||||
if (string.IsNullOrEmpty(Hotkey))
|
||||
{
|
||||
Hotkey = DefaultHotkey;
|
||||
}
|
||||
|
||||
SetKeysToDisplay(collection, Hotkey?.Split(KeySeparator));
|
||||
return collection;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private string EmptyHotkeyKey = "none";
|
||||
public string EmptyHotkey => InternationalizationManager.Instance.GetTranslation(EmptyHotkeyKey);
|
||||
private const string KeySeparator = " + ";
|
||||
|
||||
private Lazy<ObservableCollection<string>> keysToDisplay;
|
||||
|
||||
public ObservableCollection<string> KeysToDisplay => keysToDisplay.Value;
|
||||
|
||||
|
||||
public HotkeyModel CurrentHotkey { get; private set; }
|
||||
|
||||
public string Hotkey { get; set; }
|
||||
|
||||
|
||||
public bool Recording { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
public async Task StartRecordingAsync()
|
||||
{
|
||||
if (!Recording)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
{
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
}
|
||||
/* 1. Key Recording Start */
|
||||
/* 2. Key Display area clear
|
||||
* 3. Key Display when typing*/
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task StopRecordingAsync()
|
||||
{
|
||||
Recording = false;
|
||||
|
||||
try
|
||||
{
|
||||
var converter = new KeyGestureConverter();
|
||||
var key = (KeyGesture)converter.ConvertFromString(CurrentHotkey.ToString())!;
|
||||
}
|
||||
catch (Exception e) when (e is NotSupportedException or InvalidEnumArgumentException)
|
||||
{
|
||||
SetMessage("Hotkey Invalid", true);
|
||||
CurrentHotkey = new HotkeyModel(Hotkey);
|
||||
SetKeysToDisplay(KeysToDisplay, CurrentHotkey);
|
||||
return;
|
||||
}
|
||||
|
||||
Hotkey = CurrentHotkey.ToString();
|
||||
|
||||
await SetHotkeyAsync(CurrentHotkey, true);
|
||||
}
|
||||
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ResetToDefaultAsync()
|
||||
{
|
||||
Recording = false;
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
Hotkey = DefaultHotkey;
|
||||
CurrentHotkey = new HotkeyModel(Hotkey);
|
||||
|
||||
SetKeysToDisplay(KeysToDisplay, CurrentHotkey);
|
||||
|
||||
await SetHotkeyAsync(Hotkey);
|
||||
}
|
||||
|
||||
public bool ValidateKeyGesture { get; set; }
|
||||
public Action<HotkeyModel>? HotkeyDelegate { get; set; }
|
||||
|
||||
private async Task SetHotkeyAsync(HotkeyModel keyModel, bool triggerValidate = true)
|
||||
{
|
||||
// tbHotkey.Text = keyModel.ToString();
|
||||
// tbHotkey.Select(tbHotkey.Text.Length, 0);
|
||||
|
||||
if (triggerValidate)
|
||||
{
|
||||
bool hotkeyAvailable = CheckHotkeyAvailability(keyModel, ValidateKeyGesture);
|
||||
SetMessage(hotkeyAvailable ? "success" : "hotkeyUnavailable", !hotkeyAvailable);
|
||||
HotkeyDelegate?.Invoke(keyModel);
|
||||
|
||||
if (CurrentHotkeyAvailable)
|
||||
{
|
||||
Hotkey = keyModel.ToString();
|
||||
SetKeysToDisplay(KeysToDisplay, CurrentHotkey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Hotkey = keyModel.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
public async Task DeleteAsync()
|
||||
{
|
||||
Recording = false;
|
||||
if (!string.IsNullOrEmpty(Hotkey))
|
||||
HotKeyMapper.RemoveHotkey(Hotkey);
|
||||
Hotkey = "";
|
||||
SetKeysToDisplay(KeysToDisplay, new List<string>());
|
||||
}
|
||||
|
||||
private void SetKeysToDisplay(ICollection<string> container, 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
container.Add(key);
|
||||
}
|
||||
|
||||
if (!keys.Any())
|
||||
{
|
||||
container.Add(EmptyHotkey);
|
||||
}
|
||||
}
|
||||
|
||||
public Task RegisterHotkey()
|
||||
{
|
||||
return SetHotkeyAsync(Hotkey, true);
|
||||
}
|
||||
|
||||
public Task SetHotkeyAsync(string? keyStr, bool triggerValidate = true)
|
||||
{
|
||||
return SetHotkeyAsync(new HotkeyModel(keyStr), triggerValidate);
|
||||
}
|
||||
|
||||
public void KeyDown(HotkeyModel hotkeyModel)
|
||||
{
|
||||
CurrentHotkey = hotkeyModel;
|
||||
SetKeysToDisplay(KeysToDisplay, CurrentHotkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ using System.Collections.ObjectModel;
|
|||
using CommunityToolkit.Mvvm.Input;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Flow.Launcher.Infrastructure.Hotkey;
|
||||
|
||||
namespace Flow.Launcher.ViewModel
|
||||
{
|
||||
|
|
@ -69,36 +70,12 @@ namespace Flow.Launcher.ViewModel
|
|||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ToggleHotkeyViewModel =
|
||||
new HotkeyControlViewModel(Settings.Hotkey, "Alt + Space", true, hotkey =>
|
||||
{
|
||||
Settings.Hotkey = hotkey.ToString();
|
||||
HotKeyMapper.SetHotkey(hotkey, HotKeyMapper.OnToggleHotkey);
|
||||
});
|
||||
|
||||
PreviewHotkeyViewModel =
|
||||
new HotkeyControlViewModel(Settings.PreviewHotkey, "F1", false, hotkey =>
|
||||
{
|
||||
Settings.PreviewHotkey = hotkey.ToString();
|
||||
});
|
||||
|
||||
AutoCompleteHotkeyViewModel =
|
||||
new HotkeyControlViewModel(Settings.AutoCompleteHotkey, "Ctrl+Tab", false, hotkey =>
|
||||
{
|
||||
Settings.AutoCompleteHotkey = hotkey.ToString();
|
||||
});
|
||||
|
||||
SelectNextItemHotkeyViewModel =
|
||||
new HotkeyControlViewModel(Settings.SelectNextItemHotkey, "Tab", false, hotkey =>
|
||||
{
|
||||
Settings.SelectNextItemHotkey = hotkey.ToString();
|
||||
});
|
||||
SelectPrevItemHotkeyViewModel =
|
||||
new HotkeyControlViewModel(Settings.SelectPrevItemHotkey, "Shift+Tab", false, hotkey =>
|
||||
{
|
||||
Settings.SelectPrevItemHotkey = hotkey.ToString();
|
||||
});
|
||||
[RelayCommand]
|
||||
public void SetTogglingHotkey(HotkeyModel hotkey)
|
||||
{
|
||||
HotKeyMapper.SetHotkey(hotkey, HotKeyMapper.OnToggleHotkey);
|
||||
}
|
||||
|
||||
public Settings Settings { get; set; }
|
||||
|
|
@ -977,12 +954,6 @@ namespace Flow.Launcher.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
public HotkeyControlViewModel ToggleHotkeyViewModel { get; set; }
|
||||
public HotkeyControlViewModel PreviewHotkeyViewModel { get; set; }
|
||||
public HotkeyControlViewModel AutoCompleteHotkeyViewModel { get; set; }
|
||||
public HotkeyControlViewModel SelectNextItemHotkeyViewModel { get; set; }
|
||||
public HotkeyControlViewModel SelectPrevItemHotkeyViewModel { get; set; }
|
||||
|
||||
private static DirectoryInfo GetLogDir(string version = "")
|
||||
{
|
||||
return new DirectoryInfo(Path.Combine(DataLocation.DataDirectory(), Constant.Logs, version));
|
||||
|
|
|
|||
Loading…
Reference in a new issue