feat(设置): 添加实验性选项页面并优化图标显示

添加新的实验性选项页面,将高级设置中的实验性功能移至该页面
优化设置页面中图标的显示,支持自定义字体
为外部协议调用和避免全屏助手添加设置项
默认启用避免全屏助手功能
This commit is contained in:
PrefacedCorg
2026-04-24 19:16:48 +08:00
parent 5266368f79
commit b9651240df
20 changed files with 439 additions and 339 deletions
@@ -45,7 +45,7 @@
Click="SubPageCard_Click"
Tag="{Binding PageTag}">
<ui:SettingsCard.HeaderIcon>
<ui:FontIcon Glyph="{Binding IconGlyph}" />
<ui:FontIcon Glyph="{Binding IconGlyph}" FontFamily="{Binding IconFontFamily}" />
</ui:SettingsCard.HeaderIcon>
</ui:SettingsCard>
</DataTemplate>
@@ -1,6 +1,9 @@
using iNKORE.UI.WPF.Modern.Common.IconKeys;
using iNKORE.UI.WPF.Modern.Controls;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using SWC = System.Windows.Controls;
namespace Ink_Canvas.Windows.SettingsViews.Pages
@@ -11,6 +14,7 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
public string Description { get; set; }
public string PageTag { get; set; }
public string IconGlyph { get; set; }
public FontFamily IconFontFamily { get; set; }
}
public partial class BasicPage : SWC.Page
@@ -53,7 +57,7 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
string childTag = childItem.Tag as string;
if (!string.IsNullOrEmpty(childTag))
{
string glyph = ExtractIconGlyph(childItem);
(string glyph, FontFamily fontFamily) = ExtractIconInfo(childItem);
string description = SWC.ToolTipService.GetToolTip(childItem) as string
?? $"点击跳转到{childItem.Content}";
@@ -62,7 +66,8 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
Header = childItem.Content?.ToString() ?? "",
Description = description,
PageTag = childTag,
IconGlyph = glyph
IconGlyph = glyph,
IconFontFamily = fontFamily
});
}
}
@@ -73,15 +78,39 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
}
}
private string ExtractIconGlyph(NavigationViewItem navItem)
private (string glyph, FontFamily fontFamily) ExtractIconInfo(NavigationViewItem navItem)
{
if (navItem.Icon is FontIcon fontIcon)
return fontIcon.Glyph ?? "\uE713";
{
string glyph = fontIcon.Glyph ?? "\uE713";
FontFamily fontFamily = fontIcon.FontFamily ?? new FontFamily("Segoe Fluent Icons");
if (fontIcon.Icon != null)
{
string iconStr = fontIcon.Icon.ToString();
if (iconStr.Contains("_20_"))
{
string key24 = iconStr.Replace("_20_", "_24_");
var field = typeof(FluentSystemIcons).GetField(key24, BindingFlags.Public | BindingFlags.Static);
if (field != null)
{
var value = field.GetValue(null);
if (value is FontIconData data24)
{
glyph = data24.Glyph ?? glyph;
fontFamily = data24.FontFamily ?? fontFamily;
}
}
}
}
return (glyph, fontFamily);
}
if (navItem.Icon is SymbolIcon symbolIcon)
return char.ConvertFromUtf32((int)symbolIcon.Symbol);
return (char.ConvertFromUtf32((int)symbolIcon.Symbol), new FontFamily("Segoe Fluent Icons"));
return "\uE713";
return ("\uE713", new FontFamily("Segoe Fluent Icons"));
}
private void SubPageCard_Click(object sender, RoutedEventArgs e)
@@ -0,0 +1,74 @@
<ui:Page x:Class="Ink_Canvas.Windows.SettingsViews.Pages.ExperimentalPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ink_Canvas.Windows.SettingsViews.Pages"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
xmlns:i18n="clr-namespace:Ink_Canvas.MarkupExtensions"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:controls="clr-namespace:Ink_Canvas.Controls;assembly=InkCanvas.Controls"
mc:Ignorable="d"
Title="实验性选项">
<ScrollViewer PanningMode="VerticalFirst">
<Grid Margin="59,0,59,0">
<FrameworkElement.Resources>
<sys:Double x:Key="SettingsCardSpacing">4</sys:Double>
<Style x:Key="SettingsSectionHeaderTextBlockStyle"
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
TargetType="TextBlock">
<Style.Setters>
<Setter Property="Margin" Value="1,30,0,6" />
</Style.Setters>
</Style>
</FrameworkElement.Resources>
<Grid>
<ikw:SimpleStackPanel MaxWidth="1000"
HorizontalAlignment="Stretch"
Spacing="{StaticResource SettingsCardSpacing}">
<controls:LabeledSettingsCard x:Name="CardFullScreenHelper"
Header="{i18n:I18n Key=Advanced_FullScreenHelper}"
Description="{i18n:I18n Key=Advanced_FullScreenHelperHint}"
Icon="{x:Static ui:SegoeFluentIcons.FullScreen}"
SwitchName="ToggleSwitchFullScreenHelper"
Toggled="ToggleSwitchFullScreenHelper_Toggled" />
<controls:LabeledSettingsCard x:Name="CardEdgeGestureUtil"
Header="{i18n:I18n Key=Advanced_EdgeGestureUtil}"
Description="{i18n:I18n Key=Advanced_EdgeGestureUtilHint_Part1}"
Icon="{x:Static ui:SegoeFluentIcons.AlignLeft}"
SwitchName="ToggleSwitchEdgeGestureUtil"
Toggled="ToggleSwitchEdgeGestureUtil_Toggled" />
<controls:LabeledSettingsCard x:Name="CardForceFullScreen"
Header="{i18n:I18n Key=Advanced_ForceFullScreen}"
Description="{i18n:I18n Key=Advanced_ForceFullScreenHint}"
Icon="{x:Static ui:SegoeFluentIcons.Video}"
SwitchName="ToggleSwitchForceFullScreen"
Toggled="ToggleSwitchForceFullScreen_Toggled" />
<controls:LabeledSettingsCard x:Name="CardDPIChangeDetection"
Header="{i18n:I18n Key=Advanced_DPIChangeDetection}"
Description="{i18n:I18n Key=Advanced_DPIChangeDetectionHint}"
Icon="{x:Static ui:SegoeFluentIcons.View}"
SwitchName="ToggleSwitchDPIChangeDetection"
Toggled="ToggleSwitchDPIChangeDetection_Toggled" />
<controls:LabeledSettingsCard x:Name="CardResolutionChangeDetection"
Header="{i18n:I18n Key=Advanced_ResolutionChangeDetection}"
Description="{i18n:I18n Key=Advanced_ResolutionChangeDetectionHint}"
Icon="{x:Static ui:SegoeFluentIcons.Accept}"
SwitchName="ToggleSwitchResolutionChangeDetection"
Toggled="ToggleSwitchResolutionChangeDetection_Toggled" />
<Rectangle Height="48" />
</ikw:SimpleStackPanel>
</Grid>
</Grid>
</ScrollViewer>
</ui:Page>
@@ -0,0 +1,135 @@
using Ink_Canvas.Helpers;
using Ink_Canvas.Windows.SettingsViews.Helpers;
using OSVersionExtension;
using System;
using System.Diagnostics;
using System.Windows;
namespace Ink_Canvas.Windows.SettingsViews.Pages
{
public partial class ExperimentalPage : iNKORE.UI.WPF.Modern.Controls.Page
{
private bool _isLoaded = false;
public ExperimentalPage()
{
InitializeComponent();
Loaded += ExperimentalPage_Loaded;
}
private void ExperimentalPage_Loaded(object sender, RoutedEventArgs e)
{
LoadSettings();
_isLoaded = true;
}
private void LoadSettings()
{
_isLoaded = false;
try
{
var settings = SettingsManager.Settings;
if (settings.Advanced != null)
{
CardFullScreenHelper.IsOn = settings.Advanced.IsEnableFullScreenHelper;
CardEdgeGestureUtil.IsOn = settings.Advanced.IsEnableEdgeGestureUtil;
CardForceFullScreen.IsOn = settings.Advanced.IsEnableForceFullScreen;
CardDPIChangeDetection.IsOn = settings.Advanced.IsEnableDPIChangeDetection;
CardResolutionChangeDetection.IsOn = settings.Advanced.IsEnableResolutionChangeDetection;
}
}
catch (Exception ex)
{
Debug.WriteLine($"加载实验性选项时出错: {ex.Message}");
}
_isLoaded = true;
}
private void ToggleSwitchFullScreenHelper_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
SettingsManager.Settings.Advanced.IsEnableFullScreenHelper = CardFullScreenHelper.IsOn;
SettingsManager.SaveSettingsToFile();
}
catch (Exception ex)
{
Debug.WriteLine($"设置全屏助手时出错: {ex.Message}");
}
}
private void ToggleSwitchEdgeGestureUtil_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
SettingsManager.Settings.Advanced.IsEnableEdgeGestureUtil = CardEdgeGestureUtil.IsOn;
SettingsManager.SaveSettingsToFile();
if (OSVersion.GetOperatingSystem() >= OSVersionExtension.OperatingSystem.Windows10)
{
var window = Application.Current.MainWindow;
if (window != null)
{
var handle = new System.Windows.Interop.WindowInteropHelper(window).Handle;
EdgeGestureUtil.DisableEdgeGestures(handle, CardEdgeGestureUtil.IsOn);
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"设置边缘手势时出错: {ex.Message}");
}
}
private void ToggleSwitchForceFullScreen_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
SettingsManager.Settings.Advanced.IsEnableForceFullScreen = CardForceFullScreen.IsOn;
SettingsManager.SaveSettingsToFile();
}
catch (Exception ex)
{
Debug.WriteLine($"设置强制全屏时出错: {ex.Message}");
}
}
private void ToggleSwitchDPIChangeDetection_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
SettingsManager.Settings.Advanced.IsEnableDPIChangeDetection = CardDPIChangeDetection.IsOn;
SettingsManager.SaveSettingsToFile();
}
catch (Exception ex)
{
Debug.WriteLine($"设置DPI变化检测时出错: {ex.Message}");
}
}
private void ToggleSwitchResolutionChangeDetection_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
SettingsManager.Settings.Advanced.IsEnableResolutionChangeDetection = CardResolutionChangeDetection.IsOn;
SettingsManager.SaveSettingsToFile();
}
catch (Exception ex)
{
Debug.WriteLine($"设置分辨率变化检测时出错: {ex.Message}");
}
}
}
}
@@ -45,7 +45,7 @@
Click="QuickNavCard_Click"
Tag="{Binding PageTag}">
<ui:SettingsCard.HeaderIcon>
<ui:FontIcon Glyph="{Binding IconGlyph}" />
<ui:FontIcon Glyph="{Binding IconGlyph}" FontFamily="{Binding IconFontFamily}" />
</ui:SettingsCard.HeaderIcon>
</ui:SettingsCard>
</DataTemplate>
@@ -1,6 +1,7 @@
using iNKORE.UI.WPF.Modern.Common.IconKeys;
using iNKORE.UI.WPF.Modern.Controls;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@@ -13,6 +14,7 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
public string Description { get; set; }
public string PageTag { get; set; }
public string IconGlyph { get; set; }
public FontFamily IconFontFamily { get; set; }
}
public partial class HomePage
@@ -54,8 +56,8 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
string tag = navItem.Tag as string;
if (!string.IsNullOrEmpty(tag) && tag != "HomePage")
{
string glyph = ExtractIconGlyph(navItem);
string description = System.Windows.Controls.ToolTipService.GetToolTip(navItem) as string
(string glyph, FontFamily fontFamily) = ExtractIconInfo(navItem);
string description = ToolTipService.GetToolTip(navItem) as string
?? $"点击跳转到{navItem.Content}";
_navItems.Add(new QuickNavItem
@@ -63,26 +65,47 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
Header = navItem.Content?.ToString() ?? "",
Description = description,
PageTag = tag,
IconGlyph = glyph
IconGlyph = glyph,
IconFontFamily = fontFamily
});
}
}
}
}
private string ExtractIconGlyph(NavigationViewItem navItem)
private (string glyph, FontFamily fontFamily) ExtractIconInfo(NavigationViewItem navItem)
{
if (navItem.Icon is FontIcon fontIcon)
{
return fontIcon.Glyph ?? "\uE713";
string glyph = fontIcon.Glyph ?? "\uE713";
FontFamily fontFamily = fontIcon.FontFamily ?? new FontFamily("Segoe Fluent Icons");
if (fontIcon.Icon != null)
{
string iconStr = fontIcon.Icon.ToString();
if (iconStr.Contains("_20_"))
{
string key24 = iconStr.Replace("_20_", "_24_");
var field = typeof(FluentSystemIcons).GetField(key24, BindingFlags.Public | BindingFlags.Static);
if (field != null)
{
var value = field.GetValue(null);
if (value is FontIconData data24)
{
glyph = data24.Glyph ?? glyph;
fontFamily = data24.FontFamily ?? fontFamily;
}
}
}
}
return (glyph, fontFamily);
}
if (navItem.Icon is SymbolIcon symbolIcon)
{
return char.ConvertFromUtf32((int)symbolIcon.Symbol);
}
return (char.ConvertFromUtf32((int)symbolIcon.Symbol), new FontFamily("Segoe Fluent Icons"));
return "\uE713";
return ("\uE713", new FontFamily("Segoe Fluent Icons"));
}
private void QuickNavCard_Click(object sender, RoutedEventArgs e)
@@ -45,7 +45,7 @@
Click="SubPageCard_Click"
Tag="{Binding PageTag}">
<ui:SettingsCard.HeaderIcon>
<ui:FontIcon Glyph="{Binding IconGlyph}" />
<ui:FontIcon Glyph="{Binding IconGlyph}" FontFamily="{Binding IconFontFamily}" />
</ui:SettingsCard.HeaderIcon>
</ui:SettingsCard>
</DataTemplate>
@@ -1,6 +1,9 @@
using iNKORE.UI.WPF.Modern.Common.IconKeys;
using iNKORE.UI.WPF.Modern.Controls;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using SWC = System.Windows.Controls;
namespace Ink_Canvas.Windows.SettingsViews.Pages
@@ -45,7 +48,7 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
string childTag = childItem.Tag as string;
if (!string.IsNullOrEmpty(childTag))
{
string glyph = ExtractIconGlyph(childItem);
(string glyph, FontFamily fontFamily) = ExtractIconInfo(childItem);
string description = SWC.ToolTipService.GetToolTip(childItem) as string
?? $"点击跳转到{childItem.Content}";
@@ -54,7 +57,8 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
Header = childItem.Content?.ToString() ?? "",
Description = description,
PageTag = childTag,
IconGlyph = glyph
IconGlyph = glyph,
IconFontFamily = fontFamily
});
}
}
@@ -65,15 +69,39 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
}
}
private string ExtractIconGlyph(NavigationViewItem navItem)
private (string glyph, FontFamily fontFamily) ExtractIconInfo(NavigationViewItem navItem)
{
if (navItem.Icon is FontIcon fontIcon)
return fontIcon.Glyph ?? "\uE737";
{
string glyph = fontIcon.Glyph ?? "\uE737";
FontFamily fontFamily = fontIcon.FontFamily ?? new FontFamily("Segoe Fluent Icons");
if (fontIcon.Icon != null)
{
string iconStr = fontIcon.Icon.ToString();
if (iconStr.Contains("_20_"))
{
string key24 = iconStr.Replace("_20_", "_24_");
var field = typeof(FluentSystemIcons).GetField(key24, BindingFlags.Public | BindingFlags.Static);
if (field != null)
{
var value = field.GetValue(null);
if (value is FontIconData data24)
{
glyph = data24.Glyph ?? glyph;
fontFamily = data24.FontFamily ?? fontFamily;
}
}
}
}
return (glyph, fontFamily);
}
if (navItem.Icon is SymbolIcon symbolIcon)
return char.ConvertFromUtf32((int)symbolIcon.Symbol);
return (char.ConvertFromUtf32((int)symbolIcon.Symbol), new FontFamily("Segoe Fluent Icons"));
return "\uE737";
return ("\uE737", new FontFamily("Segoe Fluent Icons"));
}
private void SubPageCard_Click(object sender, RoutedEventArgs e)
@@ -50,6 +50,14 @@
SwitchName="ToggleSwitchFoldAtStartup"
Toggled="ToggleSwitchFoldAtStartup_Toggled" />
<!-- 外部协议调用 -->
<controls:LabeledSettingsCard x:Name="CardExternalProtocol"
Header="{i18n:I18n Key=Startup_ExternalProtocol}"
Description="{i18n:I18n Key=Startup_ExternalProtocolHint}"
Icon="{x:Static ui:FluentSystemIcons.Link_20_Regular}"
SwitchName="ToggleSwitchExternalProtocol"
Toggled="ToggleSwitchExternalProtocol_Toggled" />
<!-- 运行模式 -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
Text="{i18n:I18n Key=Settings_ModeDesc_1}" />
@@ -42,6 +42,8 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
{
CardPPTOnlyMode.IsOn = settings.ModeSettings.IsPPTOnlyMode;
}
CardExternalProtocol.IsOn = settings.Advanced.IsEnableUriScheme;
}
catch (Exception ex)
{
@@ -95,6 +97,58 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
}
}
private void ToggleSwitchExternalProtocol_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
bool newState = CardExternalProtocol.IsOn;
bool success = false;
if (newState)
{
if (!UriSchemeHelper.IsUriSchemeRegistered())
{
success = UriSchemeHelper.RegisterUriScheme();
}
else
{
success = true;
}
}
else
{
if (UriSchemeHelper.IsUriSchemeRegistered())
{
success = UriSchemeHelper.UnregisterUriScheme();
}
else
{
success = true;
}
}
if (success)
{
SettingsManager.Settings.Advanced.IsEnableUriScheme = newState;
SettingsManager.SaveSettingsToFile();
}
else
{
_isLoaded = false;
CardExternalProtocol.IsOn = !newState;
_isLoaded = true;
LogHelper.WriteLogToFile("设置外部协议失败,请检查权限或日志", LogHelper.LogType.Error);
}
}
catch (Exception ex)
{
Debug.WriteLine($"设置外部协议时出错: {ex.Message}");
}
}
#endregion
#region
@@ -50,6 +50,13 @@
SwitchName="ToggleSwitchWindowMode"
Toggled="ToggleSwitchWindowMode_Toggled" />
<controls:LabeledSettingsCard x:Name="CardAvoidFullScreen"
Header="{i18n:I18n Key=Advanced_AvoidFullScreenHelper}"
Description="{i18n:I18n Key=Advanced_AvoidFullScreenHelperHint}"
Icon="{x:Static ui:SegoeFluentIcons.Cancel}"
SwitchName="ToggleSwitchAvoidFullScreen"
Toggled="ToggleSwitchAvoidFullScreen_Toggled" />
<ui:SettingsExpander x:Name="ExpanderAlwaysOnTop"
Header="{i18n:I18n Key=Startup_TopMost}"
Description="{i18n:I18n Key=Startup_TopMostHint}"
@@ -40,6 +40,7 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
{
CardNoFocusMode.IsOn = settings.Advanced.IsNoFocusMode;
CardWindowMode.IsOn = settings.Advanced.WindowMode;
CardAvoidFullScreen.IsOn = settings.Advanced.IsEnableAvoidFullScreenHelper;
ToggleSwitchAlwaysOnTop.IsOn = settings.Advanced.IsAlwaysOnTop;
_topMostModeItems.Clear();
@@ -152,6 +153,35 @@ namespace Ink_Canvas.Windows.SettingsViews.Pages
}
}
private void ToggleSwitchAvoidFullScreen_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
try
{
bool newState = CardAvoidFullScreen.IsOn;
SettingsManager.Settings.Advanced.IsEnableAvoidFullScreenHelper = newState;
SettingsManager.SaveSettingsToFile();
var window = Application.Current.MainWindow;
if (window != null)
{
if (newState)
{
AvoidFullScreenHelper.StartAvoidFullScreen(window);
}
else
{
AvoidFullScreenHelper.StopAvoidFullScreen(window);
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"设置避免全屏时出错: {ex.Message}");
}
}
private void ToggleSwitchAlwaysOnTop_Toggled(object sender, RoutedEventArgs e)
{
if (!_isLoaded) return;
@@ -189,6 +189,17 @@
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<!-- 实验性选项 -->
<ui:NavigationViewItem
x:Name="ExperimentalPageItem"
Content="实验性选项"
Tag="ExperimentalPage"
ToolTipService.ToolTip="实验性选项">
<ui:NavigationViewItem.Icon>
<ui:FontIcon Icon="{x:Static ui:FluentSystemIcons.Beaker_20_Regular}" FontSize="20" Margin="-2"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<!-- 画板设置 -->
<ui:NavigationViewItem
x:Name="CanvasPageItem"
@@ -235,6 +246,7 @@
</ui:NavigationView.FooterMenuItems>
<ui:Frame x:Name="rootFrame" Navigated="OnRootFrameNavigated" NavigationUIVisibility="Hidden" />
<!--我要玩原神-->
</ui:NavigationView>
</Grid>
</Window>
@@ -43,6 +43,7 @@ namespace Ink_Canvas.Windows.SettingsViews
{ "MainInterfacePage", typeof(MainInterfacePage) },
{ "WindowPage", typeof(WindowPage) },
{ "UpdatePage", typeof(UpdatePage) },
{ "ExperimentalPage", typeof(ExperimentalPage) },
{ "CanvasPage", typeof(CanvasPage) },
{ "DebugPage", typeof(IconographyPage) },
{ "AboutPage", typeof(AboutPage) },