Compare commits

..

No commits in common. "6079e76be5f9b8944068e5afe6cf07a2d81bdc6b" and "dbd3ca44c2dca8e11848b629376caa38cb708391" have entirely different histories.

7 changed files with 113 additions and 158 deletions

View file

@ -158,7 +158,6 @@ namespace ServiceLib.Handler
Length = "100-200", Length = "100-200",
Interval = "10-20" Interval = "10-20"
}; };
config.GlobalHotkeys ??= new();
if (config.SystemProxyItem.SystemProxyExceptions.IsNullOrEmpty()) if (config.SystemProxyItem.SystemProxyExceptions.IsNullOrEmpty())
{ {

View file

@ -1,67 +0,0 @@
using System.Reactive;
using System.Text;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{
public class GlobalHotkeySettingViewModel : MyReactiveObject
{
private readonly List<KeyEventItem> _globalHotkeys;
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public GlobalHotkeySettingViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
{
_config = AppHandler.Instance.Config;
_updateView = updateView;
_globalHotkeys = JsonUtils.DeepCopy(_config.GlobalHotkeys);
SaveCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SaveSettingAsync();
});
}
public KeyEventItem GetKeyEventItem(EGlobalHotkey eg)
{
var item = _globalHotkeys.FirstOrDefault((it) => it.EGlobalHotkey == eg);
if (item != null)
{
return item;
}
item = new()
{
EGlobalHotkey = eg,
Control = false,
Alt = false,
Shift = false,
KeyCode = null
};
_globalHotkeys.Add(item);
return item;
}
public void ResetKeyEventItem()
{
_globalHotkeys.Clear();
}
private async Task SaveSettingAsync()
{
_config.GlobalHotkeys = _globalHotkeys;
if (await ConfigHandler.SaveConfig(_config) == 0)
{
_updateView?.Invoke(EViewAction.CloseWindow, null);
}
else
{
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
}
}
}
}

View file

@ -6,7 +6,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuAddCustomServer}" Title="v2rayN"
Width="700" Width="700"
Height="500" Height="500"
x:DataType="vms:AddServer2ViewModel" x:DataType="vms:AddServer2ViewModel"
@ -15,8 +15,8 @@
mc:Ignorable="d"> mc:Ignorable="d">
<DockPanel Margin="{StaticResource Margin8}"> <DockPanel Margin="{StaticResource Margin8}">
<StackPanel <StackPanel
Margin="{StaticResource Margin4}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Margin="{StaticResource Margin4}"
DockPanel.Dock="Bottom" DockPanel.Dock="Bottom"
Orientation="Horizontal"> Orientation="Horizontal">
<Button <Button
@ -45,8 +45,8 @@
<TextBlock <TextBlock
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbRemarks}" /> Text="{x:Static resx:ResUI.TbRemarks}" />
<TextBox <TextBox
@ -54,24 +54,24 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" /> VerticalAlignment="Center"
Margin="{StaticResource Margin4}" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbAddress}" /> Text="{x:Static resx:ResUI.TbAddress}" />
<TextBox <TextBox
x:Name="txtAddress" x:Name="txtAddress"
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Width="400" Width="400"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
IsReadOnly="True" /> IsReadOnly="True" />
<StackPanel <StackPanel
Grid.Row="2" Grid.Row="2"
@ -91,23 +91,23 @@
<TextBlock <TextBlock
Grid.Row="3" Grid.Row="3"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbCoreType}" /> Text="{x:Static resx:ResUI.TbCoreType}" />
<ComboBox <ComboBox
x:Name="cmbCoreType" x:Name="cmbCoreType"
Grid.Row="3" Grid.Row="3"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
Margin="{StaticResource Margin4}"
MaxDropDownHeight="1000" /> MaxDropDownHeight="1000" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbDisplayLog}" /> Text="{x:Static resx:ResUI.TbDisplayLog}" />
<StackPanel <StackPanel
Grid.Row="4" Grid.Row="4"
@ -116,27 +116,27 @@
Orientation="Horizontal"> Orientation="Horizontal">
<ToggleSwitch <ToggleSwitch
x:Name="togDisplayLog" x:Name="togDisplayLog"
Margin="{StaticResource Margin4}" HorizontalAlignment="Left"
HorizontalAlignment="Left" /> Margin="{StaticResource Margin4}" />
<TextBlock <TextBlock
Margin="{StaticResource MarginLr8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource MarginLr8}"
Text="{x:Static resx:ResUI.TipDisplayLog}" /> Text="{x:Static resx:ResUI.TipDisplayLog}" />
</StackPanel> </StackPanel>
<TextBlock <TextBlock
Grid.Row="5" Grid.Row="5"
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbPreSocksPort}" /> Text="{x:Static resx:ResUI.TbPreSocksPort}" />
<TextBox <TextBox
x:Name="txtPreSocksPort" x:Name="txtPreSocksPort"
Grid.Row="5" Grid.Row="5"
Grid.Column="1" Grid.Column="1"
Width="200" Width="200"
Margin="{StaticResource Margin4}" HorizontalAlignment="Left"
HorizontalAlignment="Left" /> Margin="{StaticResource Margin4}" />
<StackPanel <StackPanel
Grid.Row="6" Grid.Row="6"
Grid.Column="1" Grid.Column="1"
@ -149,8 +149,8 @@
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
Width="500" Width="500"
Margin="{StaticResource MarginLr8}"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="{StaticResource MarginLr8}"
Text="{x:Static resx:ResUI.CustomServerTips}" Text="{x:Static resx:ResUI.CustomServerTips}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</StackPanel> </StackPanel>

View file

@ -29,6 +29,10 @@ namespace v2rayN.Handler
private void Init() private void Init()
{ {
_hotkeyTriggerDic.Clear(); _hotkeyTriggerDic.Clear();
if (AppHandler.Instance.Config.GlobalHotkeys == null)
{
return;
}
foreach (var item in AppHandler.Instance.Config.GlobalHotkeys) foreach (var item in AppHandler.Instance.Config.GlobalHotkeys)
{ {
if (item.KeyCode != null && (Key)item.KeyCode != Key.None) if (item.KeyCode != null && (Key)item.KeyCode != Key.None)

View file

@ -1,4 +1,4 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.AddServer2Window" x:Class="v2rayN.Views.AddServer2Window"
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"
@ -8,7 +8,7 @@
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuAddCustomServer}" Title="v2rayN"
Width="700" Width="700"
Height="500" Height="500"
x:TypeArguments="vms:AddServer2ViewModel" x:TypeArguments="vms:AddServer2ViewModel"
@ -198,4 +198,4 @@
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</DockPanel> </DockPanel>
</reactiveui:ReactiveWindow> </reactiveui:ReactiveWindow>

View file

@ -8,10 +8,10 @@
xmlns:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuGlobalHotkeySetting}" Title="{x:Static resx:ResUI.menuSetting}"
Width="700" Width="700"
Height="500" Height="500"
x:TypeArguments="vms:GlobalHotkeySettingViewModel" x:TypeArguments="vms:SubEditViewModel"
ShowInTaskbar="False" ShowInTaskbar="False"
Style="{StaticResource WindowGlobal}" Style="{StaticResource WindowGlobal}"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
@ -91,6 +91,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
Style="{StaticResource MyOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
@ -108,6 +109,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
Style="{StaticResource MyOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
@ -125,6 +127,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
Style="{StaticResource MyOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="4" Grid.Row="4"
@ -141,6 +144,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
Style="{StaticResource MyOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
<TextBlock <TextBlock
Grid.Row="5" Grid.Row="5"
@ -157,6 +161,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
AcceptsReturn="True" AcceptsReturn="True"
IsReadOnly="True" IsReadOnly="True"
PreviewKeyDown="TxtGlobalHotkey_PreviewKeyDown"
Style="{StaticResource MyOutlinedTextBox}" /> Style="{StaticResource MyOutlinedTextBox}" />
</Grid> </Grid>

View file

@ -1,80 +1,62 @@
using System.Reactive.Disposables;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using ReactiveUI;
using v2rayN.Handler; using v2rayN.Handler;
namespace v2rayN.Views namespace v2rayN.Views
{ {
public partial class GlobalHotkeySettingWindow public partial class GlobalHotkeySettingWindow
{ {
private readonly List<object> _textBoxKeyEventItem = new(); private static Config? _config;
private Dictionary<object, KeyEventItem> _textBoxKeyEventItem = new();
public GlobalHotkeySettingWindow() public GlobalHotkeySettingWindow()
{ {
InitializeComponent(); InitializeComponent();
this.Owner = Application.Current.MainWindow; this.Owner = Application.Current.MainWindow;
_config = AppHandler.Instance.Config;
ViewModel = new GlobalHotkeySettingViewModel(UpdateViewHandler); _config.GlobalHotkeys ??= new();
btnReset.Click += btnReset_Click; btnReset.Click += btnReset_Click;
btnSave.Click += btnSave_ClickAsync;
txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
txtGlobalHotkey2.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
txtGlobalHotkey3.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
txtGlobalHotkey4.KeyDown += TxtGlobalHotkey_PreviewKeyDown;
HotkeyHandler.Instance.IsPause = true; HotkeyHandler.Instance.IsPause = true;
this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false; this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false;
WindowsUtils.SetDarkBorder(this, _config.UiItem.CurrentTheme);
InitData();
}
this.WhenActivated(disposables => private void InitData()
{
_textBoxKeyEventItem = new()
{ {
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); { txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.ShowForm) },
}); { txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyClear) },
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.CurrentTheme); { txtGlobalHotkey2,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxySet) },
{ txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyUnchanged)},
{ txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.GlobalHotkeys,EGlobalHotkey.SystemProxyPac)}
};
Init();
BindingData(); BindingData();
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
{
switch (action)
{
case EViewAction.CloseWindow:
this.DialogResult = true;
break;
}
return await Task.FromResult(true);
}
private void Init()
{
_textBoxKeyEventItem.Add(txtGlobalHotkey0);
_textBoxKeyEventItem.Add(txtGlobalHotkey1);
_textBoxKeyEventItem.Add(txtGlobalHotkey2);
_textBoxKeyEventItem.Add(txtGlobalHotkey3);
_textBoxKeyEventItem.Add(txtGlobalHotkey4);
for (var index = 0; index < _textBoxKeyEventItem.Count; index++)
{
var sender = _textBoxKeyEventItem[index];
if (sender is not TextBox txtBox)
{
continue;
}
txtBox.Tag = (EGlobalHotkey)index;
txtBox.PreviewKeyDown += TxtGlobalHotkey_PreviewKeyDown;
}
}
private void TxtGlobalHotkey_PreviewKeyDown(object? sender, KeyEventArgs e) private void TxtGlobalHotkey_PreviewKeyDown(object? sender, KeyEventArgs e)
{ {
e.Handled = true; e.Handled = true;
if (sender is not TextBox txtBox) if (sender is null)
{ {
return; return;
} }
var item = ViewModel?.GetKeyEventItem((EGlobalHotkey)txtBox.Tag); var item = _textBoxKeyEventItem[sender];
var modifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift, Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin }; var modifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift, Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin };
item.KeyCode = (int)(e.Key == Key.System ? (modifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (modifierKeys.Contains(e.Key) ? Key.None : e.Key)); item.KeyCode = (int)(e.Key == Key.System ? (modifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (modifierKeys.Contains(e.Key) ? Key.None : e.Key));
@ -82,50 +64,38 @@ namespace v2rayN.Views
item.Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control; item.Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
item.Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; item.Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
txtBox.Text = KeyEventItemToString(item); (sender as TextBox)!.Text = KeyEventItemToString(item);
} }
private void BindingData() private KeyEventItem GetKeyEventItemByEGlobalHotkey(List<KeyEventItem> lstKey, EGlobalHotkey eg)
{ {
foreach (var sender in _textBoxKeyEventItem) return JsonUtils.DeepCopy(lstKey.Find((it) => it.EGlobalHotkey == eg) ?? new()
{ {
if (sender is not TextBox txtBox) EGlobalHotkey = eg,
{ Control = false,
continue; Alt = false,
} Shift = false,
KeyCode = null
var item = ViewModel?.GetKeyEventItem((EGlobalHotkey)txtBox.Tag); });
txtBox.Text = KeyEventItemToString(item);
}
} }
private void btnReset_Click(object sender, RoutedEventArgs e) private string KeyEventItemToString(KeyEventItem item)
{ {
ViewModel?.ResetKeyEventItem();
BindingData();
}
private string KeyEventItemToString(KeyEventItem? item)
{
if (item == null)
{
return string.Empty;
}
var res = new StringBuilder(); var res = new StringBuilder();
if (item.Control) if (item.Control)
{ {
res.Append($"{ModifierKeys.Control} +"); res.Append($"{ModifierKeys.Control}+");
} }
if (item.Shift) if (item.Shift)
{ {
res.Append($"{ModifierKeys.Shift} +"); res.Append($"{ModifierKeys.Shift}+");
} }
if (item.Alt) if (item.Alt)
{ {
res.Append($"{ModifierKeys.Alt} +"); res.Append($"{ModifierKeys.Alt}+");
} }
if (item.KeyCode != null && (Key)item.KeyCode != Key.None) if (item.KeyCode != null && (Key)item.KeyCode != Key.None)
@ -135,5 +105,49 @@ namespace v2rayN.Views
return res.ToString(); return res.ToString();
} }
private void BindingData()
{
foreach (var item in _textBoxKeyEventItem)
{
if (item.Value.KeyCode != null && (Key)item.Value.KeyCode != Key.None)
{
(item.Key as TextBox)!.Text = KeyEventItemToString(item.Value);
}
else
{
(item.Key as TextBox)!.Text = string.Empty;
}
}
}
private async void btnSave_ClickAsync(object sender, RoutedEventArgs e)
{
_config.GlobalHotkeys = _textBoxKeyEventItem.Values.ToList();
if (await ConfigHandler.SaveConfig(_config) == 0)
{
HotkeyHandler.Instance.ReLoad();
this.DialogResult = true;
}
else
{
UI.Show(ResUI.OperationFailed);
}
}
private void btnReset_Click(object sender, RoutedEventArgs e)
{
foreach (var k in _textBoxKeyEventItem.Keys)
{
var item = _textBoxKeyEventItem[k];
item.Alt = false;
item.Control = false;
item.Shift = false;
item.KeyCode = (int)Key.None;
}
BindingData();
}
} }
} }