mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
Refactor settings window UI and theming
Improve theming and layout for the Settings window and related services. - MaterialSurfaceService: add special material parameters for SettingsWindowBackground (lower alpha, no blur) and avoid hot-switching real backdrops for non-settings windows. - GlassEffectService: add AdaptiveSettingsWindowTintBrush + ResolveSettingsWindowTintAlpha to provide optional content tinting tied to system material mode. - SettingsWindowService: refactor theme application into ApplyThemeVariantAndResources, ensure settings window material is applied at show/activate times, and tidy theme/resource application flow. - SettingsWindow.axaml / .axaml.cs: restructure title bar (separate Grid.Row=0 border) and FANavigationView host, add pane-footer toggle button for :minimal layout, use dynamic corner radius resource, and update toggle/visibility/icon logic and responsive layout code. - SettingsPages: remove some IconText usages and adjust margins; use DesignCornerRadiusLg for update card corner radius. - Add NuGet.Config to set local globalPackagesFolder and ignore .nuget/packages in .gitignore. These changes aim to improve visuals, avoid backdrop overdraw, and make the settings window behavior consistent across themes and layouts.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,6 +6,9 @@
|
|||||||
# dotenv files
|
# dotenv files
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# Local NuGet global packages (NuGet.Config globalPackagesFolder)
|
||||||
|
.nuget/packages/
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
|
|||||||
@@ -353,6 +353,26 @@ internal sealed class MaterialSurfaceService : IMaterialSurfaceService
|
|||||||
MaterialSurfaceRole role,
|
MaterialSurfaceRole role,
|
||||||
bool isNightMode)
|
bool isNightMode)
|
||||||
{
|
{
|
||||||
|
// Settings 根层(如 RootGrid)叠在 Transparent + Mica/Acrylic 上:过高 alpha 会完全盖住系统 backdrop。
|
||||||
|
// 保持非 None 下较低 alpha;None 仍用不透明白底等价。BlurRadius=0(由 DWM 提供模糊)。
|
||||||
|
if (role == MaterialSurfaceRole.SettingsWindowBackground)
|
||||||
|
{
|
||||||
|
return materialMode switch
|
||||||
|
{
|
||||||
|
ThemeAppearanceValues.MaterialAcrylic => (
|
||||||
|
0.20,
|
||||||
|
0.14,
|
||||||
|
isNightMode ? (byte)0x8E : (byte)0x96,
|
||||||
|
0),
|
||||||
|
ThemeAppearanceValues.MaterialMica => (
|
||||||
|
0.14,
|
||||||
|
0.08,
|
||||||
|
isNightMode ? (byte)0x9E : (byte)0xA6,
|
||||||
|
0),
|
||||||
|
_ => (0.08, 0.05, (byte)0xFF, 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var isOverlay = role is MaterialSurfaceRole.DockBackground or MaterialSurfaceRole.StatusBarBackground or MaterialSurfaceRole.OverlayPanel;
|
var isOverlay = role is MaterialSurfaceRole.DockBackground or MaterialSurfaceRole.StatusBarBackground or MaterialSurfaceRole.OverlayPanel;
|
||||||
return materialMode switch
|
return materialMode switch
|
||||||
{
|
{
|
||||||
@@ -491,7 +511,8 @@ internal sealed class AppearanceThemeService : IAppearanceThemeService, IDisposa
|
|||||||
|
|
||||||
// Avoid hot-switching real backdrops on already-visible windows. This has been
|
// Avoid hot-switching real backdrops on already-visible windows. This has been
|
||||||
// a stability hotspot when users flip theme source/material at runtime.
|
// a stability hotspot when users flip theme source/material at runtime.
|
||||||
if (window.IsVisible)
|
// SettingsWindowBackground 是唯一需要材质与资源同步热切换的宿主角色;其它窗口仍保持「仅创建时」应用以降低风险。
|
||||||
|
if (window.IsVisible && role != MaterialSurfaceRole.SettingsWindowBackground)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,15 @@ public static class GlassEffectService
|
|||||||
resources["AdaptiveWindowBackgroundBrush"] = new SolidColorBrush(windowSurface.BackgroundColor);
|
resources["AdaptiveWindowBackgroundBrush"] = new SolidColorBrush(windowSurface.BackgroundColor);
|
||||||
resources["AdaptiveWindowBorderBrush"] = new SolidColorBrush(windowSurface.BorderColor);
|
resources["AdaptiveWindowBorderBrush"] = new SolidColorBrush(windowSurface.BorderColor);
|
||||||
resources["AdaptiveSettingsWindowBackgroundBrush"] = new SolidColorBrush(settingsWindowSurface.BackgroundColor);
|
resources["AdaptiveSettingsWindowBackgroundBrush"] = new SolidColorBrush(settingsWindowSurface.BackgroundColor);
|
||||||
|
// 可选:叠在内容区上的可读性 tint(半透明);不改变 AdaptiveSettingsWindowBackgroundBrush 的语义权重,供 P1 绑定内容层。
|
||||||
|
var settingsTintBase = settingsWindowSurface.BackgroundColor;
|
||||||
|
var settingsTintAlpha = ResolveSettingsWindowTintAlpha(context);
|
||||||
|
resources["AdaptiveSettingsWindowTintBrush"] = new SolidColorBrush(
|
||||||
|
Color.FromArgb(
|
||||||
|
settingsTintAlpha,
|
||||||
|
settingsTintBase.R,
|
||||||
|
settingsTintBase.G,
|
||||||
|
settingsTintBase.B));
|
||||||
resources["AdaptiveSettingsWindowBorderBrush"] = new SolidColorBrush(settingsWindowSurface.BorderColor);
|
resources["AdaptiveSettingsWindowBorderBrush"] = new SolidColorBrush(settingsWindowSurface.BorderColor);
|
||||||
resources["AdaptiveDockBackgroundBrush"] = new SolidColorBrush(dockSurface.BackgroundColor);
|
resources["AdaptiveDockBackgroundBrush"] = new SolidColorBrush(dockSurface.BackgroundColor);
|
||||||
resources["AdaptiveDockBorderBrush"] = new SolidColorBrush(dockSurface.BorderColor);
|
resources["AdaptiveDockBorderBrush"] = new SolidColorBrush(dockSurface.BorderColor);
|
||||||
@@ -100,4 +109,16 @@ public static class GlassEffectService
|
|||||||
resources["AdaptiveDesktopComponentHostOpacity"] = desktopComponentSurface.Opacity;
|
resources["AdaptiveDesktopComponentHostOpacity"] = desktopComponentSurface.Opacity;
|
||||||
resources["AdaptiveStatusBarComponentHostOpacity"] = statusBarComponentSurface.Opacity;
|
resources["AdaptiveStatusBarComponentHostOpacity"] = statusBarComponentSurface.Opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>可选内容叠层 alpha,与设置窗表面色相一致;None 为 0 避免重复染色。</summary>
|
||||||
|
private static byte ResolveSettingsWindowTintAlpha(ThemeColorContext context)
|
||||||
|
{
|
||||||
|
var mode = ThemeAppearanceValues.NormalizeSystemMaterialMode(context.SystemMaterialMode);
|
||||||
|
return mode switch
|
||||||
|
{
|
||||||
|
ThemeAppearanceValues.MaterialAcrylic => context.IsNightMode ? (byte)0x58 : (byte)0x4C,
|
||||||
|
ThemeAppearanceValues.MaterialMica => context.IsNightMode ? (byte)0x50 : (byte)0x44,
|
||||||
|
_ => (byte)0x00
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ internal sealed class SettingsWindowService : ISettingsWindowService
|
|||||||
_window ??= CreateWindow();
|
_window ??= CreateWindow();
|
||||||
var appearanceSnapshot = _appearanceThemeService.GetCurrent();
|
var appearanceSnapshot = _appearanceThemeService.GetCurrent();
|
||||||
_window.ApplyChromeMode(appearanceSnapshot.UseSystemChrome);
|
_window.ApplyChromeMode(appearanceSnapshot.UseSystemChrome);
|
||||||
ApplyTheme(_window);
|
ApplyThemeVariantAndResources(_window);
|
||||||
|
|
||||||
var targetPageId = request.PageId ?? _window.ViewModel.CurrentPageId;
|
var targetPageId = request.PageId ?? _window.ViewModel.CurrentPageId;
|
||||||
_window.ReloadPages(targetPageId);
|
_window.ReloadPages(targetPageId);
|
||||||
@@ -79,6 +79,7 @@ internal sealed class SettingsWindowService : ISettingsWindowService
|
|||||||
if (!_window.IsVisible)
|
if (!_window.IsVisible)
|
||||||
{
|
{
|
||||||
CenterWindow(_window, request);
|
CenterWindow(_window, request);
|
||||||
|
_appearanceThemeService.ApplyWindowMaterial(_window, MaterialSurfaceRole.SettingsWindowBackground);
|
||||||
_window.Show();
|
_window.Show();
|
||||||
NotifyStateChanged();
|
NotifyStateChanged();
|
||||||
CenterWindowLater(_window, request);
|
CenterWindowLater(_window, request);
|
||||||
@@ -90,6 +91,7 @@ internal sealed class SettingsWindowService : ISettingsWindowService
|
|||||||
_window.WindowState = WindowState.Normal;
|
_window.WindowState = WindowState.Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_appearanceThemeService.ApplyWindowMaterial(_window, MaterialSurfaceRole.SettingsWindowBackground);
|
||||||
_window.Activate();
|
_window.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +115,6 @@ internal sealed class SettingsWindowService : ISettingsWindowService
|
|||||||
_pageRegistry,
|
_pageRegistry,
|
||||||
_hostApplicationLifecycle,
|
_hostApplicationLifecycle,
|
||||||
useSystemChrome);
|
useSystemChrome);
|
||||||
ApplyTheme(window);
|
|
||||||
window.ShowInTaskbar = true;
|
window.ShowInTaskbar = true;
|
||||||
window.Closed += (_, _) =>
|
window.Closed += (_, _) =>
|
||||||
{
|
{
|
||||||
@@ -285,13 +286,23 @@ internal sealed class SettingsWindowService : ISettingsWindowService
|
|||||||
}, DispatcherPriority.Background);
|
}, DispatcherPriority.Background);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyTheme(SettingsWindow window)
|
private static void ApplyThemeVariantAndResources(SettingsWindow window, IAppearanceThemeService appearanceThemeService)
|
||||||
{
|
{
|
||||||
var appearanceSnapshot = _appearanceThemeService.GetCurrent();
|
var appearanceSnapshot = appearanceThemeService.GetCurrent();
|
||||||
window.RequestedThemeVariant = appearanceSnapshot.IsNightMode
|
window.RequestedThemeVariant = appearanceSnapshot.IsNightMode
|
||||||
? ThemeVariant.Dark
|
? ThemeVariant.Dark
|
||||||
: ThemeVariant.Light;
|
: ThemeVariant.Light;
|
||||||
_appearanceThemeService.ApplyThemeResources(window.Resources);
|
appearanceThemeService.ApplyThemeResources(window.Resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyThemeVariantAndResources(SettingsWindow window)
|
||||||
|
{
|
||||||
|
ApplyThemeVariantAndResources(window, _appearanceThemeService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyTheme(SettingsWindow window)
|
||||||
|
{
|
||||||
|
ApplyThemeVariantAndResources(window, _appearanceThemeService);
|
||||||
_appearanceThemeService.ApplyWindowMaterial(window, MaterialSurfaceRole.SettingsWindowBackground);
|
_appearanceThemeService.ApplyWindowMaterial(window, MaterialSurfaceRole.SettingsWindowBackground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:vm="using:LanMountainDesktop.ViewModels"
|
xmlns:vm="using:LanMountainDesktop.ViewModels"
|
||||||
xmlns:controls="using:LanMountainDesktop.Controls"
|
|
||||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||||
xmlns:fi="using:FluentIcons.Avalonia"
|
xmlns:fi="using:FluentIcons.Avalonia"
|
||||||
xmlns:symbol="using:FluentIcons.Common"
|
xmlns:symbol="using:FluentIcons.Common"
|
||||||
@@ -52,10 +51,6 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<controls:IconText Icon="Apps"
|
|
||||||
Text="{Binding AppearanceHeader}"
|
|
||||||
Margin="0,0,0,4" />
|
|
||||||
|
|
||||||
<ui:FASettingsExpander Classes="settings-expander-card"
|
<ui:FASettingsExpander Classes="settings-expander-card"
|
||||||
Header="{Binding AppearanceHeader}"
|
Header="{Binding AppearanceHeader}"
|
||||||
Description="{Binding AppearanceDescription}"
|
Description="{Binding AppearanceDescription}"
|
||||||
@@ -76,11 +71,8 @@
|
|||||||
</ui:FASettingsExpanderItem>
|
</ui:FASettingsExpanderItem>
|
||||||
</ui:FASettingsExpander>
|
</ui:FASettingsExpander>
|
||||||
|
|
||||||
<controls:IconText Icon="Apps"
|
|
||||||
Text="{Binding HiddenHeader}"
|
|
||||||
Margin="0,24,0,4" />
|
|
||||||
|
|
||||||
<ui:FASettingsExpander Classes="settings-expander-card"
|
<ui:FASettingsExpander Classes="settings-expander-card"
|
||||||
|
Margin="0,24,0,14"
|
||||||
Header="{Binding HiddenHeader}"
|
Header="{Binding HiddenHeader}"
|
||||||
Description="{Binding HiddenDescription}"
|
Description="{Binding HiddenDescription}"
|
||||||
IsExpanded="True">
|
IsExpanded="True">
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<Style Selector="Border.update-status-card">
|
<Style Selector="Border.update-status-card">
|
||||||
<Setter Property="Padding" Value="24" />
|
<Setter Property="Padding" Value="24" />
|
||||||
<Setter Property="Margin" Value="0,0,0,18" />
|
<Setter Property="Margin" Value="0,0,0,18" />
|
||||||
<Setter Property="CornerRadius" Value="24" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
|
||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
|||||||
@@ -40,10 +40,108 @@
|
|||||||
Classes="settings-scope"
|
Classes="settings-scope"
|
||||||
Background="{DynamicResource AdaptiveSettingsWindowBackgroundBrush}"
|
Background="{DynamicResource AdaptiveSettingsWindowBackgroundBrush}"
|
||||||
RowDefinitions="Auto,*">
|
RowDefinitions="Auto,*">
|
||||||
<!-- 顶栏布局对齐 SecRandom:左(折叠/品牌/标题)+ 中(透明拖窗区)+ 右(重启 / Windows caption 占位) -->
|
<!-- ClassIsland SettingsWindowNew:声明顺序为先 FANavigationView(Grid.Row=1)再顶栏 Border(Grid.Row=0);Row 仍为 0=标题栏、1=导航宿主,最终叠放不变。 -->
|
||||||
|
|
||||||
|
<ui:FANavigationView x:Name="RootNavigationView"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0"
|
||||||
|
Background="Transparent"
|
||||||
|
PaneDisplayMode="Auto"
|
||||||
|
OpenPaneLength="283"
|
||||||
|
IsSettingsVisible="False"
|
||||||
|
IsBackButtonVisible="False"
|
||||||
|
SelectionChanged="OnNavigationSelectionChanged">
|
||||||
|
<ui:FANavigationView.PaneFooter>
|
||||||
|
<!-- 仅在 :minimal(IsPaneToggleButtonVisible=False)时由代码显示;与模板内 pane-toggle-button 一致,不用顶栏备胎 -->
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Button x:Name="PaneFooterToggleButton"
|
||||||
|
Classes="pane-toggle-button"
|
||||||
|
Margin="0,-8,0,0"
|
||||||
|
MinWidth="40"
|
||||||
|
Width="48"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Click="OnPaneFooterToggleClick">
|
||||||
|
<Grid>
|
||||||
|
<fi:FluentIcon x:Name="PaneFooterToggleButtonIcon"
|
||||||
|
Icon="Navigation"
|
||||||
|
IconVariant="Regular"
|
||||||
|
FontSize="16"
|
||||||
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
|
||||||
|
</Grid>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</ui:FANavigationView.PaneFooter>
|
||||||
|
|
||||||
|
<ui:FANavigationView.Styles>
|
||||||
|
<Style Selector="ui|FANavigationView#RootNavigationView:minimal">
|
||||||
|
<Setter Property="IsPaneToggleButtonVisible" Value="False"/>
|
||||||
|
</Style>
|
||||||
|
</ui:FANavigationView.Styles>
|
||||||
|
|
||||||
|
<ui:FANavigationView.Resources>
|
||||||
|
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
|
||||||
|
<SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" />
|
||||||
|
</ui:FANavigationView.Resources>
|
||||||
|
|
||||||
|
<Grid x:Name="SettingsContentGrid"
|
||||||
|
ColumnDefinitions="*,Auto"
|
||||||
|
ColumnSpacing="20"
|
||||||
|
Margin="12,0,16,16">
|
||||||
|
<Grid Grid.Column="0"
|
||||||
|
RowDefinitions="Auto,*">
|
||||||
|
<Grid x:Name="PageTitleContainer"
|
||||||
|
Grid.Row="0"
|
||||||
|
Classes="page-title-container"
|
||||||
|
IsVisible="{Binding IsPageTitleVisible}">
|
||||||
|
<TextBlock x:Name="PageTitleTextBlock"
|
||||||
|
Classes="page-title-text"
|
||||||
|
Text="{Binding CurrentPageTitle}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ui:FAFrame x:Name="ContentFrame"
|
||||||
|
Grid.Row="1" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Border x:Name="DrawerBorder"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="296"
|
||||||
|
Background="{DynamicResource AdaptiveSurfaceRaisedBrush}"
|
||||||
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||||
|
Padding="20"
|
||||||
|
BoxShadow="0 8 24 #14000000"
|
||||||
|
IsVisible="{Binding IsDrawerOpen}">
|
||||||
|
<Grid RowDefinitions="Auto,*"
|
||||||
|
RowSpacing="16">
|
||||||
|
<Grid ColumnDefinitions="*,Auto">
|
||||||
|
<TextBlock x:Name="DrawerTitleTextBlock"
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Text="{Binding DrawerTitle}" />
|
||||||
|
<Button Grid.Column="1"
|
||||||
|
Width="32"
|
||||||
|
Height="32"
|
||||||
|
Padding="0"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
Click="OnCloseDrawerClick">
|
||||||
|
<fi:FluentIcon Icon="Dismiss"
|
||||||
|
IconVariant="Regular" />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ContentControl x:Name="DrawerContentHost"
|
||||||
|
Grid.Row="1" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</ui:FANavigationView>
|
||||||
|
|
||||||
<Border x:Name="WindowTitleBarHost"
|
<Border x:Name="WindowTitleBarHost"
|
||||||
|
Grid.Row="0"
|
||||||
Height="48"
|
Height="48"
|
||||||
Background="Transparent"
|
Background="{DynamicResource SolidBackgroundFillColorBaseBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveSettingsWindowBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveSettingsWindowBorderBrush}"
|
||||||
BorderThickness="0,0,0,1">
|
BorderThickness="0,0,0,1">
|
||||||
<Grid ColumnDefinitions="Auto,*,Auto"
|
<Grid ColumnDefinitions="Auto,*,Auto"
|
||||||
@@ -53,26 +151,11 @@
|
|||||||
Margin="8,0,8,0"
|
Margin="8,0,8,0"
|
||||||
Spacing="8"
|
Spacing="8"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<Button x:Name="TogglePaneButton"
|
|
||||||
Classes="pane-toggle-button"
|
|
||||||
Margin="-7,-8,-8,-8"
|
|
||||||
MinWidth="40"
|
|
||||||
Width="48"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
IsVisible="{Binding !#RootNavigationView.IsPaneToggleButtonVisible}"
|
|
||||||
Click="OnTogglePaneButtonClick">
|
|
||||||
<Grid>
|
|
||||||
<fi:FluentIcon x:Name="TogglePaneButtonIcon"
|
|
||||||
Icon="Navigation"
|
|
||||||
IconVariant="Regular"
|
|
||||||
FontSize="16" />
|
|
||||||
</Grid>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<fi:FluentIcon x:Name="WindowBrandIcon"
|
<fi:FluentIcon x:Name="WindowBrandIcon"
|
||||||
Margin="0,0,0,0"
|
|
||||||
Icon="Settings"
|
Icon="Settings"
|
||||||
IconVariant="Filled"
|
IconVariant="Filled"
|
||||||
|
FontSize="18"
|
||||||
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
VerticalAlignment="Center" />
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
@@ -81,6 +164,7 @@
|
|||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Margin="8,0,0,0"
|
Margin="8,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
Text="{Binding Title}" />
|
Text="{Binding Title}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -119,80 +203,5 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ui:FANavigationView x:Name="RootNavigationView"
|
|
||||||
Grid.Row="1"
|
|
||||||
Margin="0"
|
|
||||||
Background="Transparent"
|
|
||||||
PaneDisplayMode="Auto"
|
|
||||||
OpenPaneLength="283"
|
|
||||||
IsSettingsVisible="False"
|
|
||||||
IsBackButtonVisible="False"
|
|
||||||
SelectionChanged="OnNavigationSelectionChanged">
|
|
||||||
<ui:FANavigationView.Styles>
|
|
||||||
<Style Selector="ui|FANavigationView#RootNavigationView:minimal">
|
|
||||||
<Setter Property="IsPaneToggleButtonVisible" Value="False"/>
|
|
||||||
</Style>
|
|
||||||
</ui:FANavigationView.Styles>
|
|
||||||
|
|
||||||
<ui:FANavigationView.Resources>
|
|
||||||
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
|
|
||||||
<SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" />
|
|
||||||
</ui:FANavigationView.Resources>
|
|
||||||
|
|
||||||
<Grid x:Name="SettingsContentGrid"
|
|
||||||
ColumnDefinitions="*,Auto"
|
|
||||||
ColumnSpacing="20"
|
|
||||||
Margin="12,0,16,16">
|
|
||||||
<Grid Grid.Column="0"
|
|
||||||
RowDefinitions="Auto,*">
|
|
||||||
<Grid x:Name="PageTitleContainer"
|
|
||||||
Grid.Row="0"
|
|
||||||
Classes="page-title-container"
|
|
||||||
IsVisible="{Binding IsPageTitleVisible}">
|
|
||||||
<TextBlock x:Name="PageTitleTextBlock"
|
|
||||||
Classes="page-title-text"
|
|
||||||
Text="{Binding CurrentPageTitle}" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<ui:FAFrame x:Name="ContentFrame"
|
|
||||||
Grid.Row="1" />
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Border x:Name="DrawerBorder"
|
|
||||||
Grid.Column="1"
|
|
||||||
Width="296"
|
|
||||||
Background="{DynamicResource AdaptiveSurfaceRaisedBrush}"
|
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
|
||||||
BorderThickness="1"
|
|
||||||
CornerRadius="16"
|
|
||||||
Padding="20"
|
|
||||||
BoxShadow="0 8 24 #14000000"
|
|
||||||
IsVisible="{Binding IsDrawerOpen}">
|
|
||||||
<Grid RowDefinitions="Auto,*"
|
|
||||||
RowSpacing="16">
|
|
||||||
<Grid ColumnDefinitions="*,Auto">
|
|
||||||
<TextBlock x:Name="DrawerTitleTextBlock"
|
|
||||||
FontSize="16"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Text="{Binding DrawerTitle}" />
|
|
||||||
<Button Grid.Column="1"
|
|
||||||
Width="32"
|
|
||||||
Height="32"
|
|
||||||
Padding="0"
|
|
||||||
Background="Transparent"
|
|
||||||
BorderThickness="0"
|
|
||||||
Click="OnCloseDrawerClick">
|
|
||||||
<fi:FluentIcon Icon="Dismiss"
|
|
||||||
IconVariant="Regular" />
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<ContentControl x:Name="DrawerContentHost"
|
|
||||||
Grid.Row="1" />
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
</ui:FANavigationView>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</faWindowing:FAAppWindow>
|
</faWindowing:FAAppWindow>
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
SyncPendingRestartState();
|
SyncPendingRestartState();
|
||||||
SyncTitleText();
|
SyncTitleText();
|
||||||
UpdateChromeMetrics();
|
UpdateChromeMetrics();
|
||||||
UpdatePaneToggleIcon();
|
UpdatePaneFooterToggleVisibility();
|
||||||
|
UpdatePaneFooterToggleIcon();
|
||||||
UpdateResponsiveLayout();
|
UpdateResponsiveLayout();
|
||||||
RequestResponsiveLayoutRefresh();
|
RequestResponsiveLayoutRefresh();
|
||||||
}
|
}
|
||||||
@@ -104,6 +105,7 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
CloseDrawer();
|
CloseDrawer();
|
||||||
RebuildNavigationItems();
|
RebuildNavigationItems();
|
||||||
NavigateTo(pageId ?? ViewModel.Pages.FirstOrDefault()?.PageId);
|
NavigateTo(pageId ?? ViewModel.Pages.FirstOrDefault()?.PageId);
|
||||||
|
UpdatePaneFooterToggleVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RebuildAndNavigateToDevPage()
|
public void RebuildAndNavigateToDevPage()
|
||||||
@@ -266,6 +268,7 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
ViewModel.IsPageTitleVisible = !descriptor.HidePageTitle;
|
ViewModel.IsPageTitleVisible = !descriptor.HidePageTitle;
|
||||||
TrySelectNavigationItem(descriptor.PageId);
|
TrySelectNavigationItem(descriptor.PageId);
|
||||||
SyncTitleText();
|
SyncTitleText();
|
||||||
|
UpdatePaneFooterToggleVisibility();
|
||||||
UpdateResponsiveLayout();
|
UpdateResponsiveLayout();
|
||||||
RequestResponsiveLayoutRefresh();
|
RequestResponsiveLayoutRefresh();
|
||||||
if (!string.Equals(previousPageId, descriptor.PageId, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(previousPageId, descriptor.PageId, StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -523,7 +526,7 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTogglePaneButtonClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
private void OnPaneFooterToggleClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_ = sender;
|
_ = sender;
|
||||||
_ = e;
|
_ = e;
|
||||||
@@ -533,7 +536,7 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
RootNavigationView.IsPaneOpen = !RootNavigationView.IsPaneOpen;
|
RootNavigationView.IsPaneOpen = !RootNavigationView.IsPaneOpen;
|
||||||
UpdatePaneToggleIcon();
|
UpdatePaneFooterToggleIcon();
|
||||||
UpdateResponsiveLayout();
|
UpdateResponsiveLayout();
|
||||||
RequestResponsiveLayoutRefresh();
|
RequestResponsiveLayoutRefresh();
|
||||||
}
|
}
|
||||||
@@ -544,13 +547,33 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
|
|
||||||
if (e.Property == FANavigationView.IsPaneOpenProperty ||
|
if (e.Property == FANavigationView.IsPaneOpenProperty ||
|
||||||
e.Property == FANavigationView.OpenPaneLengthProperty ||
|
e.Property == FANavigationView.OpenPaneLengthProperty ||
|
||||||
e.Property == FANavigationView.PaneDisplayModeProperty)
|
e.Property == FANavigationView.PaneDisplayModeProperty ||
|
||||||
|
e.Property == FANavigationView.IsPaneToggleButtonVisibleProperty)
|
||||||
{
|
{
|
||||||
UpdatePaneToggleIcon();
|
if (e.Property == FANavigationView.IsPaneToggleButtonVisibleProperty)
|
||||||
|
{
|
||||||
|
UpdatePaneFooterToggleVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePaneFooterToggleIcon();
|
||||||
RequestResponsiveLayoutRefresh();
|
RequestResponsiveLayoutRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仅在 <c>:minimal</c>(<see cref="FANavigationView.IsPaneToggleButtonVisible"/> 为 false)时显示侧栏底部备胎按钮。
|
||||||
|
/// 根 DataContext 为 ViewModel 时,对 <c>#RootNavigationView</c> 的绑定易失效,故用代码同步可见性。
|
||||||
|
/// </summary>
|
||||||
|
private void UpdatePaneFooterToggleVisibility()
|
||||||
|
{
|
||||||
|
if (PaneFooterToggleButton is null || RootNavigationView is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PaneFooterToggleButton.IsVisible = !RootNavigationView.IsPaneToggleButtonVisible;
|
||||||
|
}
|
||||||
|
|
||||||
private void RequestResponsiveLayoutRefresh()
|
private void RequestResponsiveLayoutRefresh()
|
||||||
{
|
{
|
||||||
if (_isResponsiveRefreshPending)
|
if (_isResponsiveRefreshPending)
|
||||||
@@ -580,14 +603,14 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
: compactPaneWidth;
|
: compactPaneWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePaneToggleIcon()
|
private void UpdatePaneFooterToggleIcon()
|
||||||
{
|
{
|
||||||
if (TogglePaneButtonIcon is null || RootNavigationView is null)
|
if (PaneFooterToggleButtonIcon is null || RootNavigationView is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TogglePaneButtonIcon.Icon = RootNavigationView.IsPaneOpen
|
PaneFooterToggleButtonIcon.Icon = RootNavigationView.IsPaneOpen
|
||||||
? FluentIcons.Common.Icon.LineHorizontal3
|
? FluentIcons.Common.Icon.LineHorizontal3
|
||||||
: FluentIcons.Common.Icon.Navigation;
|
: FluentIcons.Common.Icon.Navigation;
|
||||||
}
|
}
|
||||||
@@ -604,8 +627,6 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (WindowTitleBarHost is null ||
|
if (WindowTitleBarHost is null ||
|
||||||
TogglePaneButton is null ||
|
|
||||||
TogglePaneButtonIcon is null ||
|
|
||||||
WindowBrandIcon is null ||
|
WindowBrandIcon is null ||
|
||||||
WindowTitleTextBlock is null ||
|
WindowTitleTextBlock is null ||
|
||||||
RestartNowButton is null ||
|
RestartNowButton is null ||
|
||||||
@@ -622,8 +643,6 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
var layoutScale = Math.Clamp(Math.Min(width / 1120d, height / 760d), 0.90, 1.18);
|
var layoutScale = Math.Clamp(Math.Min(width / 1120d, height / 760d), 0.90, 1.18);
|
||||||
|
|
||||||
const double titleBarHeight = 48d;
|
const double titleBarHeight = 48d;
|
||||||
var titleBarButtonWidth = Math.Clamp(40d * layoutScale, 36d, 48d);
|
|
||||||
var titleBarButtonHeight = Math.Clamp(32d * layoutScale, 30d, 38d);
|
|
||||||
var titleFontSize = Math.Clamp(12d * layoutScale, 11d, 14d);
|
var titleFontSize = Math.Clamp(12d * layoutScale, 11d, 14d);
|
||||||
var titleBarIconSize = Math.Clamp(16d * layoutScale, 15d, 20d);
|
var titleBarIconSize = Math.Clamp(16d * layoutScale, 15d, 20d);
|
||||||
var drawerTitleFontSize = Math.Clamp(16d * layoutScale, 14d, 20d);
|
var drawerTitleFontSize = Math.Clamp(16d * layoutScale, 14d, 20d);
|
||||||
@@ -634,9 +653,6 @@ public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
|
|||||||
|
|
||||||
WindowTitleBarHost.Height = titleBarHeight;
|
WindowTitleBarHost.Height = titleBarHeight;
|
||||||
|
|
||||||
TogglePaneButton.Width = titleBarButtonWidth;
|
|
||||||
TogglePaneButton.Height = titleBarButtonHeight;
|
|
||||||
TogglePaneButtonIcon.FontSize = titleBarIconSize;
|
|
||||||
WindowBrandIcon.FontSize = titleBarIconSize + 2;
|
WindowBrandIcon.FontSize = titleBarIconSize + 2;
|
||||||
|
|
||||||
WindowTitleTextBlock.FontSize = titleFontSize;
|
WindowTitleTextBlock.FontSize = titleFontSize;
|
||||||
|
|||||||
7
NuGet.Config
Normal file
7
NuGet.Config
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<config>
|
||||||
|
<!-- 相对本文件:包落在仓库目录下,与仓库同盘(本机 D:),避免依赖 C:\Temp\cursor-sandbox-cache 等易损路径 -->
|
||||||
|
<add key="globalPackagesFolder" value=".nuget/packages" />
|
||||||
|
</config>
|
||||||
|
</configuration>
|
||||||
Reference in New Issue
Block a user