mirror of https://github.com/2dust/v2rayN
Add clash display in the main interface
parent
e3c2a4b8da
commit
e963f9e349
|
@ -10,7 +10,6 @@ namespace v2rayN.Handler
|
||||||
|
|
||||||
private Dictionary<String, ProxiesItem> _proxies;
|
private Dictionary<String, ProxiesItem> _proxies;
|
||||||
public Dictionary<string, object> ProfileContent { get; set; }
|
public Dictionary<string, object> ProfileContent { get; set; }
|
||||||
public bool ShowInTaskbar { get; set; } = true;
|
|
||||||
|
|
||||||
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
|
public void SetProxies(Dictionary<String, ProxiesItem> proxies)
|
||||||
{
|
{
|
||||||
|
|
|
@ -216,11 +216,12 @@ namespace v2rayN.Models
|
||||||
public class ClashUIItem
|
public class ClashUIItem
|
||||||
{
|
{
|
||||||
public ERuleMode ruleMode { get; set; }
|
public ERuleMode ruleMode { get; set; }
|
||||||
|
public bool showInTaskbar { get; set; }
|
||||||
public int proxiesSorting { get; set; }
|
public int proxiesSorting { get; set; }
|
||||||
public bool proxiesAutoRefresh { get; set; }
|
public bool proxiesAutoRefresh { get; set; }
|
||||||
public int AutoDelayTestInterval { get; set; } = 10;
|
public int proxiesAutoDelayTestInterval { get; set; } = 10;
|
||||||
public int connectionsSorting { get; set; }
|
public int connectionsSorting { get; set; }
|
||||||
public bool connectionsAutoRefresh { get; set; }
|
public bool connectionsAutoRefresh { get; set; }
|
||||||
|
public int connectionsRefreshInterval { get; set; } = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,11 +36,8 @@ namespace v2rayN.ViewModels
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool AutoRefresh { get; set; }
|
public bool AutoRefresh { get; set; }
|
||||||
|
|
||||||
private int AutoRefreshInterval;
|
|
||||||
|
|
||||||
public ClashConnectionsViewModel()
|
public ClashConnectionsViewModel()
|
||||||
{
|
{
|
||||||
AutoRefreshInterval = 10;
|
|
||||||
SortingSelected = _config.clashUIItem.connectionsSorting;
|
SortingSelected = _config.clashUIItem.connectionsSorting;
|
||||||
AutoRefresh = _config.clashUIItem.connectionsAutoRefresh;
|
AutoRefresh = _config.clashUIItem.connectionsAutoRefresh;
|
||||||
|
|
||||||
|
@ -87,15 +84,26 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
Observable.Interval(TimeSpan.FromSeconds(AutoRefreshInterval))
|
var lastTime = DateTime.Now;
|
||||||
.Subscribe(x =>
|
|
||||||
{
|
Observable.Interval(TimeSpan.FromSeconds(10))
|
||||||
if (!(AutoRefresh && ClashApiHandler.Instance.ShowInTaskbar))
|
.Subscribe(x =>
|
||||||
{
|
{
|
||||||
return;
|
if (!(AutoRefresh && _config.clashUIItem.showInTaskbar))
|
||||||
}
|
{
|
||||||
GetClashConnections();
|
return;
|
||||||
});
|
}
|
||||||
|
var dtNow = DateTime.Now;
|
||||||
|
if (_config.clashUIItem.connectionsRefreshInterval > 0)
|
||||||
|
{
|
||||||
|
if ((dtNow - lastTime).Minutes % _config.clashUIItem.connectionsRefreshInterval == 0)
|
||||||
|
{
|
||||||
|
GetClashConnections();
|
||||||
|
lastTime = dtNow;
|
||||||
|
}
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetClashConnections()
|
private void GetClashConnections()
|
||||||
|
|
|
@ -434,8 +434,8 @@ namespace v2rayN.ViewModels
|
||||||
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result);
|
var dicResult = JsonUtils.Deserialize<Dictionary<string, object>>(result);
|
||||||
if (dicResult != null && dicResult.ContainsKey("delay"))
|
if (dicResult != null && dicResult.ContainsKey("delay"))
|
||||||
{
|
{
|
||||||
detail.delay = Convert.ToInt32(dicResult["delay"]);
|
detail.delay = Convert.ToInt32(dicResult["delay"].ToString());
|
||||||
detail.delayName = $"{dicResult["delay"]}ms";
|
detail.delayName = $"{detail.delay}ms";
|
||||||
}
|
}
|
||||||
else if (dicResult != null && dicResult.ContainsKey("message"))
|
else if (dicResult != null && dicResult.ContainsKey("message"))
|
||||||
{
|
{
|
||||||
|
@ -459,27 +459,26 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
public void DelayTestTask()
|
public void DelayTestTask()
|
||||||
{
|
{
|
||||||
var autoDelayTestTime = DateTime.Now;
|
var lastTime = DateTime.Now;
|
||||||
|
|
||||||
Observable.Interval(TimeSpan.FromSeconds(60))
|
Observable.Interval(TimeSpan.FromSeconds(60))
|
||||||
.Subscribe(x =>
|
.Subscribe(x =>
|
||||||
{
|
{
|
||||||
if (!(AutoRefresh && ClashApiHandler.Instance.ShowInTaskbar))
|
if (!(AutoRefresh && _config.clashUIItem.showInTaskbar))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var dtNow = DateTime.Now;
|
var dtNow = DateTime.Now;
|
||||||
|
if (_config.clashUIItem.proxiesAutoDelayTestInterval > 0)
|
||||||
if (_config.clashUIItem.AutoDelayTestInterval > 0)
|
|
||||||
{
|
{
|
||||||
if ((dtNow - autoDelayTestTime).Minutes % _config.clashUIItem.AutoDelayTestInterval == 0)
|
if ((dtNow - lastTime).Minutes % _config.clashUIItem.proxiesAutoDelayTestInterval == 0)
|
||||||
{
|
{
|
||||||
ProxiesDelayTest();
|
ProxiesDelayTest();
|
||||||
autoDelayTestTime = dtNow;
|
lastTime = dtNow;
|
||||||
}
|
}
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion task
|
#endregion task
|
||||||
|
|
|
@ -243,6 +243,9 @@ namespace v2rayN.ViewModels
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string CurrentLanguage { get; set; }
|
public string CurrentLanguage { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool ShowCalshUI { get; set; }
|
||||||
|
|
||||||
#endregion UI
|
#endregion UI
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
@ -569,6 +572,7 @@ namespace v2rayN.ViewModels
|
||||||
AutoHideStartup();
|
AutoHideStartup();
|
||||||
|
|
||||||
_showInTaskbar = true;
|
_showInTaskbar = true;
|
||||||
|
_config.clashUIItem.showInTaskbar = _showInTaskbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
|
@ -1509,7 +1513,12 @@ namespace v2rayN.ViewModels
|
||||||
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
Application.Current?.Dispatcher.Invoke((Action)(() =>
|
||||||
{
|
{
|
||||||
BlReloadEnabled = true;
|
BlReloadEnabled = true;
|
||||||
|
ShowCalshUI = (_config.runningCoreType is ECoreType.clash or ECoreType.clash_meta or ECoreType.mihomo);
|
||||||
|
if (ShowCalshUI) {
|
||||||
|
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1680,6 +1689,7 @@ namespace v2rayN.ViewModels
|
||||||
//Utile.RegWriteValue(Global.MyRegPath, Utile.WindowHwndKey, Convert.ToString((long)windowHandle));
|
//Utile.RegWriteValue(Global.MyRegPath, Utile.WindowHwndKey, Convert.ToString((long)windowHandle));
|
||||||
}
|
}
|
||||||
_showInTaskbar = bl;
|
_showInTaskbar = bl;
|
||||||
|
_config.clashUIItem.showInTaskbar = _showInTaskbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreUI()
|
private void RestoreUI()
|
||||||
|
|
|
@ -13,19 +13,7 @@
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:TypeArguments="vms:ClashConnectionsViewModel"
|
x:TypeArguments="vms:ClashConnectionsViewModel"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="8">
|
<DockPanel>
|
||||||
<StackPanel
|
|
||||||
Margin="8,0,8,8"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock Style="{StaticResource ModuleTitle}" Text="{x:Static resx:ResUI.TbConnections}" />
|
|
||||||
<materialDesign:Chip
|
|
||||||
x:Name="chipCount"
|
|
||||||
Height="20"
|
|
||||||
IsEnabled="False"
|
|
||||||
Style="{StaticResource ListItemChip}" />
|
|
||||||
</StackPanel>
|
|
||||||
<ToolBarTray Margin="0,8,0,8" DockPanel.Dock="Top">
|
<ToolBarTray Margin="0,8,0,8" DockPanel.Dock="Top">
|
||||||
<ToolBar ClipToBounds="True" Style="{StaticResource MaterialDesignToolBar}">
|
<ToolBar ClipToBounds="True" Style="{StaticResource MaterialDesignToolBar}">
|
||||||
<Button Width="1" Visibility="Hidden">
|
<Button Width="1" Visibility="Hidden">
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
this.OneWayBind(ViewModel, vm => vm.ConnectionItems, v => v.lstConnections.ItemsSource).DisposeWith(disposables);
|
this.OneWayBind(ViewModel, vm => vm.ConnectionItems, v => v.lstConnections.ItemsSource).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstConnections.SelectedItem).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstConnections.SelectedItem).DisposeWith(disposables);
|
||||||
this.OneWayBind(ViewModel, vm => vm.ConnectionItems.Count, v => v.chipCount.Content).DisposeWith(disposables);
|
|
||||||
|
|
||||||
this.BindCommand(ViewModel, vm => vm.ConnectionCloseCmd, v => v.menuConnectionClose).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ConnectionCloseCmd, v => v.menuConnectionClose).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.ConnectionCloseAllCmd, v => v.menuConnectionCloseAll).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.ConnectionCloseAllCmd, v => v.menuConnectionCloseAll).DisposeWith(disposables);
|
||||||
|
|
|
@ -20,13 +20,7 @@
|
||||||
<converters:DelayColorConverter x:Key="DelayColorConverter" />
|
<converters:DelayColorConverter x:Key="DelayColorConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<DockPanel Margin="8">
|
<DockPanel>
|
||||||
<TextBlock
|
|
||||||
Margin="8,0,8,8"
|
|
||||||
DockPanel.Dock="Top"
|
|
||||||
Style="{StaticResource ModuleTitle}"
|
|
||||||
Text="{x:Static resx:ResUI.TbProxies}" />
|
|
||||||
|
|
||||||
<ToolBarTray DockPanel.Dock="Top">
|
<ToolBarTray DockPanel.Dock="Top">
|
||||||
<ToolBar
|
<ToolBar
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
|
|
@ -437,6 +437,14 @@
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgServerTitle}"
|
||||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||||
Style="{StaticResource DefTextBox}" />
|
Style="{StaticResource DefTextBox}" />
|
||||||
|
<Button
|
||||||
|
x:Name="btnShowCalshUI"
|
||||||
|
Width="30"
|
||||||
|
Height="30"
|
||||||
|
Margin="20,0"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}">
|
||||||
|
<materialDesign:PackIcon VerticalAlignment="Center" Kind="EyeOutline" />
|
||||||
|
</Button>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
<materialDesign:ColorZone
|
<materialDesign:ColorZone
|
||||||
|
@ -524,237 +532,240 @@
|
||||||
<RowDefinition Height="10" />
|
<RowDefinition Height="10" />
|
||||||
<RowDefinition Height="1*" />
|
<RowDefinition Height="1*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<DataGrid
|
<DockPanel Grid.Row="0">
|
||||||
x:Name="lstProfiles"
|
<ContentControl x:Name="tabClashUI" DockPanel.Dock="Right" />
|
||||||
Grid.Row="0"
|
<DataGrid
|
||||||
materialDesign:DataGridAssist.CellPadding="2,2"
|
x:Name="lstProfiles"
|
||||||
AutoGenerateColumns="False"
|
materialDesign:DataGridAssist.CellPadding="2,2"
|
||||||
BorderThickness="1"
|
AutoGenerateColumns="False"
|
||||||
CanUserAddRows="False"
|
BorderThickness="1"
|
||||||
CanUserResizeRows="False"
|
CanUserAddRows="False"
|
||||||
CanUserSortColumns="False"
|
CanUserResizeRows="False"
|
||||||
EnableRowVirtualization="True"
|
CanUserSortColumns="False"
|
||||||
Focusable="True"
|
EnableRowVirtualization="True"
|
||||||
GridLinesVisibility="All"
|
Focusable="True"
|
||||||
HeadersVisibility="All"
|
GridLinesVisibility="All"
|
||||||
IsReadOnly="True"
|
HeadersVisibility="All"
|
||||||
RowHeaderWidth="40"
|
IsReadOnly="True"
|
||||||
Style="{StaticResource DefDataGrid}">
|
RowHeaderWidth="40"
|
||||||
<DataGrid.InputBindings>
|
Style="{StaticResource DefDataGrid}">
|
||||||
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Ctrl+C" />
|
<DataGrid.InputBindings>
|
||||||
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Ctrl+V" />
|
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Ctrl+C" />
|
||||||
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Delete" />
|
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Ctrl+V" />
|
||||||
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Enter" />
|
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Delete" />
|
||||||
</DataGrid.InputBindings>
|
<KeyBinding Command="ApplicationCommands.NotACommand" Gesture="Enter" />
|
||||||
<DataGrid.ContextMenu>
|
</DataGrid.InputBindings>
|
||||||
<ContextMenu Style="{StaticResource DefContextMenu}">
|
<DataGrid.ContextMenu>
|
||||||
<MenuItem
|
<ContextMenu Style="{StaticResource DefContextMenu}">
|
||||||
x:Name="menuEditServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuEditServer"
|
||||||
Header="{x:Static resx:ResUI.menuEditServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuEditServer}" />
|
||||||
x:Name="menuSetDefaultServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuSetDefaultServer"
|
||||||
Header="{x:Static resx:ResUI.menuSetDefaultServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuSetDefaultServer}" />
|
||||||
x:Name="menuRemoveServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuRemoveServer"
|
||||||
Header="{x:Static resx:ResUI.menuRemoveServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuRemoveServer}" />
|
||||||
x:Name="menuRemoveDuplicateServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuRemoveDuplicateServer"
|
||||||
Header="{x:Static resx:ResUI.menuRemoveDuplicateServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuRemoveDuplicateServer}" />
|
||||||
x:Name="menuCopyServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuCopyServer"
|
||||||
Header="{x:Static resx:ResUI.menuCopyServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuCopyServer}" />
|
||||||
x:Name="menuShareServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuShareServer"
|
||||||
Header="{x:Static resx:ResUI.menuShareServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<Separator />
|
Header="{x:Static resx:ResUI.menuShareServer}" />
|
||||||
<MenuItem
|
<Separator />
|
||||||
x:Name="menuMixedTestServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuMixedTestServer"
|
||||||
Header="{x:Static resx:ResUI.menuMixedTestServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuMixedTestServer}" />
|
||||||
x:Name="menuTcpingServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuTcpingServer"
|
||||||
Header="{x:Static resx:ResUI.menuTcpingServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuTcpingServer}" />
|
||||||
x:Name="menuRealPingServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuRealPingServer"
|
||||||
Header="{x:Static resx:ResUI.menuRealPingServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuRealPingServer}" />
|
||||||
x:Name="menuSpeedServer"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuSpeedServer"
|
||||||
Header="{x:Static resx:ResUI.menuSpeedServer}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem
|
Header="{x:Static resx:ResUI.menuSpeedServer}" />
|
||||||
x:Name="menuSortServerResult"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuSortServerResult"
|
||||||
Header="{x:Static resx:ResUI.menuSortServerResult}" />
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<Separator />
|
Header="{x:Static resx:ResUI.menuSortServerResult}" />
|
||||||
<MenuItem
|
<Separator />
|
||||||
x:Name="menuMoveToGroup"
|
<MenuItem
|
||||||
Height="{StaticResource MenuItemHeight}"
|
x:Name="menuMoveToGroup"
|
||||||
Header="{x:Static resx:ResUI.menuMoveToGroup}">
|
Height="{StaticResource MenuItemHeight}"
|
||||||
<MenuItem Height="Auto">
|
Header="{x:Static resx:ResUI.menuMoveToGroup}">
|
||||||
<MenuItem.Header>
|
<MenuItem Height="Auto">
|
||||||
<DockPanel>
|
<MenuItem.Header>
|
||||||
<ComboBox
|
<DockPanel>
|
||||||
x:Name="cmbMoveToGroup"
|
<ComboBox
|
||||||
Width="200"
|
x:Name="cmbMoveToGroup"
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSubscription}"
|
Width="200"
|
||||||
DisplayMemberPath="remarks"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSubscription}"
|
||||||
FontSize="{DynamicResource StdFontSize}"
|
DisplayMemberPath="remarks"
|
||||||
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
FontSize="{DynamicResource StdFontSize}"
|
||||||
</DockPanel>
|
Style="{StaticResource MaterialDesignFilledComboBox}" />
|
||||||
</MenuItem.Header>
|
</DockPanel>
|
||||||
|
</MenuItem.Header>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem Header="{x:Static resx:ResUI.menuMoveTo}">
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuMoveTop"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuMoveTop}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuMoveUp"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuMoveUp}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuMoveDown"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuMoveDown}" />
|
||||||
|
<MenuItem
|
||||||
|
x:Name="menuMoveBottom"
|
||||||
|
Height="{StaticResource MenuItemHeight}"
|
||||||
|
Header="{x:Static resx:ResUI.menuMoveBottom}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{x:Static resx:ResUI.menuMoveTo}">
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMoveTop"
|
x:Name="menuSelectAll"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuMoveTop}" />
|
Click="menuSelectAll_Click"
|
||||||
|
Header="{x:Static resx:ResUI.menuSelectAll}" />
|
||||||
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMoveUp"
|
x:Name="menuExport2ClientConfig"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuMoveUp}" />
|
Header="{x:Static resx:ResUI.menuExport2ClientConfig}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMoveDown"
|
x:Name="menuExport2ShareUrl"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuMoveDown}" />
|
Header="{x:Static resx:ResUI.menuExport2ShareUrl}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
x:Name="menuMoveBottom"
|
x:Name="menuExport2SubContent"
|
||||||
Height="{StaticResource MenuItemHeight}"
|
Height="{StaticResource MenuItemHeight}"
|
||||||
Header="{x:Static resx:ResUI.menuMoveBottom}" />
|
Header="{x:Static resx:ResUI.menuExport2SubContent}" />
|
||||||
</MenuItem>
|
</ContextMenu>
|
||||||
<MenuItem
|
</DataGrid.ContextMenu>
|
||||||
x:Name="menuSelectAll"
|
<DataGrid.Resources>
|
||||||
Height="{StaticResource MenuItemHeight}"
|
<Style BasedOn="{StaticResource MaterialDesignDataGridRow}" TargetType="DataGridRow">
|
||||||
Click="menuSelectAll_Click"
|
<EventSetter Event="MouseDoubleClick" Handler="LstProfiles_MouseDoubleClick" />
|
||||||
Header="{x:Static resx:ResUI.menuSelectAll}" />
|
</Style>
|
||||||
<Separator />
|
<Style BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}" TargetType="DataGridColumnHeader">
|
||||||
<MenuItem
|
<EventSetter Event="Click" Handler="LstProfiles_ColumnHeader_Click" />
|
||||||
x:Name="menuExport2ClientConfig"
|
</Style>
|
||||||
Height="{StaticResource MenuItemHeight}"
|
|
||||||
Header="{x:Static resx:ResUI.menuExport2ClientConfig}" />
|
|
||||||
<MenuItem
|
|
||||||
x:Name="menuExport2ShareUrl"
|
|
||||||
Height="{StaticResource MenuItemHeight}"
|
|
||||||
Header="{x:Static resx:ResUI.menuExport2ShareUrl}" />
|
|
||||||
<MenuItem
|
|
||||||
x:Name="menuExport2SubContent"
|
|
||||||
Height="{StaticResource MenuItemHeight}"
|
|
||||||
Header="{x:Static resx:ResUI.menuExport2SubContent}" />
|
|
||||||
</ContextMenu>
|
|
||||||
</DataGrid.ContextMenu>
|
|
||||||
<DataGrid.Resources>
|
|
||||||
<Style BasedOn="{StaticResource MaterialDesignDataGridRow}" TargetType="DataGridRow">
|
|
||||||
<EventSetter Event="MouseDoubleClick" Handler="LstProfiles_MouseDoubleClick" />
|
|
||||||
</Style>
|
|
||||||
<Style BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}" TargetType="DataGridColumnHeader">
|
|
||||||
<EventSetter Event="Click" Handler="LstProfiles_ColumnHeader_Click" />
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell">
|
<Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding isActive}" Value="True">
|
<DataTrigger Binding="{Binding isActive}" Value="True">
|
||||||
<Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
|
<Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
|
||||||
<Setter Property="Foreground" Value="Black" />
|
<Setter Property="Foreground" Value="Black" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGrid.Resources>
|
</DataGrid.Resources>
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
|
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="80"
|
Width="80"
|
||||||
Binding="{Binding configType}"
|
Binding="{Binding configType}"
|
||||||
ExName="configType"
|
ExName="configType"
|
||||||
Header="{x:Static resx:ResUI.LvServiceType}" />
|
Header="{x:Static resx:ResUI.LvServiceType}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="150"
|
Width="150"
|
||||||
Binding="{Binding remarks}"
|
Binding="{Binding remarks}"
|
||||||
ExName="remarks"
|
ExName="remarks"
|
||||||
Header="{x:Static resx:ResUI.LvRemarks}" />
|
Header="{x:Static resx:ResUI.LvRemarks}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="120"
|
Width="120"
|
||||||
Binding="{Binding address}"
|
Binding="{Binding address}"
|
||||||
ExName="address"
|
ExName="address"
|
||||||
Header="{x:Static resx:ResUI.LvAddress}" />
|
Header="{x:Static resx:ResUI.LvAddress}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="60"
|
Width="60"
|
||||||
Binding="{Binding port}"
|
Binding="{Binding port}"
|
||||||
ExName="port"
|
ExName="port"
|
||||||
Header="{x:Static resx:ResUI.LvPort}" />
|
Header="{x:Static resx:ResUI.LvPort}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="100"
|
Width="100"
|
||||||
Binding="{Binding network}"
|
Binding="{Binding network}"
|
||||||
ExName="network"
|
ExName="network"
|
||||||
Header="{x:Static resx:ResUI.LvTransportProtocol}" />
|
Header="{x:Static resx:ResUI.LvTransportProtocol}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="100"
|
Width="100"
|
||||||
Binding="{Binding streamSecurity}"
|
Binding="{Binding streamSecurity}"
|
||||||
ExName="streamSecurity"
|
ExName="streamSecurity"
|
||||||
Header="{x:Static resx:ResUI.LvTLS}" />
|
Header="{x:Static resx:ResUI.LvTLS}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="100"
|
Width="100"
|
||||||
Binding="{Binding subRemarks}"
|
Binding="{Binding subRemarks}"
|
||||||
ExName="subRemarks"
|
ExName="subRemarks"
|
||||||
Header="{x:Static resx:ResUI.LvSubscription}" />
|
Header="{x:Static resx:ResUI.LvSubscription}" />
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="100"
|
Width="100"
|
||||||
Binding="{Binding delayVal}"
|
Binding="{Binding delayVal}"
|
||||||
ExName="delayVal"
|
ExName="delayVal"
|
||||||
Header="{x:Static resx:ResUI.LvTestDelay}">
|
Header="{x:Static resx:ResUI.LvTestDelay}">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="{x:Type TextBlock}">
|
<Style TargetType="{x:Type TextBlock}">
|
||||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||||
<Setter Property="Foreground" Value="{Binding delay, Converter={StaticResource DelayColorConverter}}" />
|
<Setter Property="Foreground" Value="{Binding delay, Converter={StaticResource DelayColorConverter}}" />
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
</base:MyDGTextColumn>
|
</base:MyDGTextColumn>
|
||||||
<base:MyDGTextColumn
|
<base:MyDGTextColumn
|
||||||
Width="100"
|
Width="100"
|
||||||
Binding="{Binding speedVal}"
|
Binding="{Binding speedVal}"
|
||||||
ExName="speedVal"
|
ExName="speedVal"
|
||||||
Header="{x:Static resx:ResUI.LvTestSpeed}">
|
Header="{x:Static resx:ResUI.LvTestSpeed}">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="{x:Type TextBlock}">
|
<Style TargetType="{x:Type TextBlock}">
|
||||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
</base:MyDGTextColumn>
|
</base:MyDGTextColumn>
|
||||||
|
|
||||||
|
<base:MyDGTextColumn
|
||||||
|
x:Name="colTodayUp"
|
||||||
|
Width="100"
|
||||||
|
Binding="{Binding todayUp}"
|
||||||
|
ExName="todayUp"
|
||||||
|
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" />
|
||||||
|
<base:MyDGTextColumn
|
||||||
|
x:Name="colTodayDown"
|
||||||
|
Width="100"
|
||||||
|
Binding="{Binding todayDown}"
|
||||||
|
ExName="todayDown"
|
||||||
|
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" />
|
||||||
|
<base:MyDGTextColumn
|
||||||
|
x:Name="colTotalUp"
|
||||||
|
Width="100"
|
||||||
|
Binding="{Binding totalUp}"
|
||||||
|
ExName="totalUp"
|
||||||
|
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" />
|
||||||
|
<base:MyDGTextColumn
|
||||||
|
x:Name="colTotalDown"
|
||||||
|
Width="100"
|
||||||
|
Binding="{Binding totalDown}"
|
||||||
|
ExName="totalDown"
|
||||||
|
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" />
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
<base:MyDGTextColumn
|
|
||||||
x:Name="colTodayUp"
|
|
||||||
Width="100"
|
|
||||||
Binding="{Binding todayUp}"
|
|
||||||
ExName="todayUp"
|
|
||||||
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" />
|
|
||||||
<base:MyDGTextColumn
|
|
||||||
x:Name="colTodayDown"
|
|
||||||
Width="100"
|
|
||||||
Binding="{Binding todayDown}"
|
|
||||||
ExName="todayDown"
|
|
||||||
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" />
|
|
||||||
<base:MyDGTextColumn
|
|
||||||
x:Name="colTotalUp"
|
|
||||||
Width="100"
|
|
||||||
Binding="{Binding totalUp}"
|
|
||||||
ExName="totalUp"
|
|
||||||
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" />
|
|
||||||
<base:MyDGTextColumn
|
|
||||||
x:Name="colTotalDown"
|
|
||||||
Width="100"
|
|
||||||
Binding="{Binding totalDown}"
|
|
||||||
ExName="totalDown"
|
|
||||||
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" />
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" />
|
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" />
|
||||||
<local:MsgView Grid.Row="2" />
|
<local:MsgView Grid.Row="2" />
|
||||||
<materialDesign:Snackbar
|
<materialDesign:Snackbar
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace v2rayN.Views
|
||||||
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
|
||||||
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;
|
||||||
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;
|
||||||
|
btnShowCalshUI.Click += BtnShowCalshUI_Click;
|
||||||
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;
|
||||||
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
|
||||||
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
|
lstProfiles.LoadingRow += LstProfiles_LoadingRow;
|
||||||
|
@ -205,6 +206,8 @@ namespace v2rayN.Views
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);
|
||||||
|
this.OneWayBind(ViewModel, vm => vm.ShowCalshUI, v => v.btnShowCalshUI.Visibility).DisposeWith(disposables);
|
||||||
|
this.OneWayBind(ViewModel, vm => vm.ShowCalshUI, v => v.tabClashUI.Visibility).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|
||||||
RestoreUI();
|
RestoreUI();
|
||||||
|
@ -455,6 +458,27 @@ namespace v2rayN.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool blShowClashUI = false;
|
||||||
|
|
||||||
|
private void BtnShowCalshUI_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (blShowClashUI)
|
||||||
|
{
|
||||||
|
tabClashUI.Visibility = Visibility.Hidden;
|
||||||
|
tabClashUI.Width = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tabClashUI.Visibility = Visibility.Visible;
|
||||||
|
if (tabClashUI.Content is null)
|
||||||
|
{
|
||||||
|
tabClashUI.Content = new ClashProxiesView();
|
||||||
|
}
|
||||||
|
tabClashUI.Width = this.ActualWidth * 5 / 6;
|
||||||
|
}
|
||||||
|
blShowClashUI = !blShowClashUI;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Event
|
#endregion Event
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|
Loading…
Reference in New Issue