Main window layout orientation setting

pull/5382/head
2dust 2024-07-19 20:31:07 +08:00
parent 5c070e2ca8
commit ad1a1f8015
11 changed files with 158 additions and 35 deletions

View File

@ -0,0 +1,9 @@
namespace v2rayN.Enums
{
public enum EGirdOrientation
{
Horizontal,
Vertical,
Tab,
}
}

View File

@ -116,6 +116,7 @@ namespace v2rayN
public static readonly List<string> SpeedPingTestUrls = new() {
@"https://www.google.com/generate_204",
@"https://www.gstatic.com/generate_204",
@"https://www.apple.com/library/test/success.html",
@"http://www.msftconnecttest.com/connecttest.txt",
};

View File

@ -119,6 +119,7 @@ namespace v2rayN.Models
public double mainHeight { get; set; }
public double mainGirdHeight1 { get; set; }
public double mainGirdHeight2 { get; set; }
public EGirdOrientation mainGirdOrientation { get; set; }
public bool colorModeDark { get; set; }
public bool followSystemTheme { get; set; }
public string? colorPrimaryName { get; set; }

View File

@ -2878,6 +2878,15 @@ namespace v2rayN.Resx {
}
}
/// <summary>
/// 查找类似 Main layout orientation(Require restart) 的本地化字符串。
/// </summary>
public static string TbSettingsMainGirdOrientation {
get {
return ResourceManager.GetString("TbSettingsMainGirdOrientation", resourceCulture);
}
}
/// <summary>
/// 查找类似 sing-box Mux Protocol 的本地化字符串。
/// </summary>

View File

@ -1249,4 +1249,7 @@
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>Multi-server set to active</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Main layout orientation(Require restart)</value>
</data>
</root>

View File

@ -1246,4 +1246,7 @@
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>多服务器设为活动(多选)</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>主界面布局方向(需重启)</value>
</data>
</root>

View File

@ -74,6 +74,7 @@ namespace v2rayN.ViewModels
[Reactive] public string SpeedPingTestUrl { get; set; }
[Reactive] public bool EnableHWA { get; set; }
[Reactive] public string SubConvertUrl { get; set; }
[Reactive] public int MainGirdOrientation { get; set; }
#endregion UI
@ -171,6 +172,7 @@ namespace v2rayN.ViewModels
SpeedPingTestUrl = _config.speedTestItem.speedPingTestUrl;
EnableHWA = _config.guiItem.enableHWA;
SubConvertUrl = _config.constItem.subConvertUrl;
MainGirdOrientation = (int)_config.uiItem.mainGirdOrientation;
#endregion UI
@ -333,6 +335,7 @@ namespace v2rayN.ViewModels
_config.speedTestItem.speedPingTestUrl = SpeedPingTestUrl;
_config.guiItem.enableHWA = EnableHWA;
_config.constItem.subConvertUrl = SubConvertUrl;
_config.uiItem.mainGirdOrientation = (EGirdOrientation)MainGirdOrientation;
//systemProxy
_config.systemProxyExceptions = systemProxyExceptions;

View File

@ -466,28 +466,50 @@
</DockPanel>
</materialDesign:ColorZone>
<Grid x:Name="gridMain">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ContentControl x:Name="tabProfiles" Grid.Column="0" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<TabControl
x:Name="tabMain"
Grid.Column="2"
HorizontalContentAlignment="Left">
<TabItem x:Name="tabMsgView" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
<materialDesign:Snackbar
x:Name="MainSnackbar"
Grid.Column="0"
Grid.ColumnSpan="3"
MessageQueue="{materialDesign:MessageQueue}" />
<Grid>
<Grid x:Name="gridMain" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ContentControl x:Name="tabProfiles" Grid.Column="0" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<TabControl
x:Name="tabMain"
Grid.Column="2"
HorizontalContentAlignment="Left">
<TabItem x:Name="tabMsgView" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
</Grid>
<Grid x:Name="gridMain1" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="10" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<ContentControl x:Name="tabProfiles1" Grid.Row="0" />
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" />
<TabControl
x:Name="tabMain1"
Grid.Row="2"
HorizontalContentAlignment="Left">
<TabItem x:Name="tabMsgView1" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies1" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections1" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
</Grid>
<Grid x:Name="gridMain2" Visibility="Collapsed">
<TabControl x:Name="tabMain2" HorizontalContentAlignment="Left">
<TabItem x:Name="tabProfiles2" Header="{x:Static resx:ResUI.menuServers}" />
<TabItem x:Name="tabMsgView2" Header="{x:Static resx:ResUI.MsgInformationTitle}" />
<TabItem x:Name="tabClashProxies2" Header="{x:Static resx:ResUI.TbProxies}" />
<TabItem x:Name="tabClashConnections2" Header="{x:Static resx:ResUI.TbConnections}" />
</TabControl>
</Grid>
<materialDesign:Snackbar x:Name="MainSnackbar" MessageQueue="{materialDesign:MessageQueue}" />
</Grid>
</DockPanel>
<tb:TaskbarIcon

View File

@ -137,9 +137,28 @@ namespace v2rayN.Views
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.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.Visibility).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
{
gridMain.Visibility = Visibility.Visible;
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections.Visibility).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain.SelectedIndex).DisposeWith(disposables);
}
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
{
gridMain1.Visibility = Visibility.Visible;
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies1.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections1.Visibility).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain1.SelectedIndex).DisposeWith(disposables);
}
else
{
gridMain2.Visibility = Visibility.Visible;
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashProxies2.Visibility).DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.ShowClashUI, v => v.tabClashConnections2.Visibility).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TabMainSelectedIndex, v => v.tabMain2.SelectedIndex).DisposeWith(disposables);
}
});
var IsAdministrator = Utils.IsAdministrator();
@ -152,10 +171,27 @@ namespace v2rayN.Views
MainFormHandler.Instance.RegisterSystemColorSet(_config, this, (bool bl) => { ViewModel?.ModifyTheme(bl); });
tabProfiles.Content ??= new ProfilesView();
tabMsgView.Content ??= new MsgView();
tabClashProxies.Content ??= new ClashProxiesView();
tabClashConnections.Content ??= new ClashConnectionsView();
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
{
tabProfiles.Content ??= new ProfilesView();
tabMsgView.Content ??= new MsgView();
tabClashProxies.Content ??= new ClashProxiesView();
tabClashConnections.Content ??= new ClashConnectionsView();
}
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
{
tabProfiles1.Content ??= new ProfilesView();
tabMsgView1.Content ??= new MsgView();
tabClashProxies1.Content ??= new ClashProxiesView();
tabClashConnections1.Content ??= new ClashConnectionsView();
}
else
{
tabProfiles2.Content ??= new ProfilesView();
tabMsgView2.Content ??= new MsgView();
tabClashProxies2.Content ??= new ClashProxiesView();
tabClashConnections2.Content ??= new ClashConnectionsView();
}
RestoreUI();
AddHelpMenuItem();
@ -248,8 +284,16 @@ namespace v2rayN.Views
if (Height > maxHeight) Height = maxHeight;
if (_config.uiItem.mainGirdHeight1 > 0 && _config.uiItem.mainGirdHeight2 > 0)
{
gridMain.ColumnDefinitions[0].Width = new GridLength(_config.uiItem.mainGirdHeight1, GridUnitType.Star);
gridMain.ColumnDefinitions[2].Width = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
{
gridMain.ColumnDefinitions[0].Width = new GridLength(_config.uiItem.mainGirdHeight1, GridUnitType.Star);
gridMain.ColumnDefinitions[2].Width = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);
}
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
{
gridMain1.RowDefinitions[0].Height = new GridLength(_config.uiItem.mainGirdHeight1, GridUnitType.Star);
gridMain1.RowDefinitions[2].Height = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);
}
}
}
@ -258,8 +302,16 @@ namespace v2rayN.Views
_config.uiItem.mainWidth = Utils.ToInt(this.Width);
_config.uiItem.mainHeight = Utils.ToInt(this.Height);
_config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.ColumnDefinitions[0].ActualWidth + 0.1);
_config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.ColumnDefinitions[2].ActualWidth + 0.1);
if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Horizontal)
{
_config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.ColumnDefinitions[0].ActualWidth + 0.1);
_config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.ColumnDefinitions[2].ActualWidth + 0.1);
}
else if (_config.uiItem.mainGirdOrientation == EGirdOrientation.Vertical)
{
_config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain1.RowDefinitions[0].ActualHeight + 0.1);
_config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain1.RowDefinitions[2].ActualHeight + 0.1);
}
}
private void AddHelpMenuItem()

View File

@ -528,6 +528,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -830,6 +831,21 @@
materialDesign:HintAssist.Hint="Convert Url"
IsEditable="True"
Style="{StaticResource DefComboBox}" />
<TextBlock
Grid.Row="21"
Grid.Column="0"
Margin="{StaticResource SettingItemMargin}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbSettingsMainGirdOrientation}" />
<ComboBox
x:Name="cmbMainGirdOrientation"
Grid.Row="21"
Grid.Column="1"
Width="300"
Margin="{StaticResource SettingItemMargin}"
Style="{StaticResource DefComboBox}" />
</Grid>
</ScrollViewer>
</TabItem>

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Media;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.ViewModels;
@ -18,8 +19,6 @@ namespace v2rayN.Views
{
InitializeComponent();
this.Owner = Application.Current.MainWindow;
_config = LazyConfig.Instance.GetConfig();
var lstFonts = GetFonts(Utils.GetFontsPath());
@ -90,6 +89,10 @@ namespace v2rayN.Views
{
cmbSubConvertUrl.Items.Add(it);
});
foreach (EGirdOrientation it in Enum.GetValues(typeof(EGirdOrientation)))
{
cmbMainGirdOrientation.Items.Add(it.ToString());
}
lstFonts.ForEach(it => { cmbcurrentFontFamily.Items.Add(it); });
cmbcurrentFontFamily.Items.Add(string.Empty);
@ -145,6 +148,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.SpeedPingTestUrl, v => v.cmbSpeedPingTestUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.MainGirdOrientation, v => v.cmbMainGirdOrientation.SelectedIndex).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables);