mica
This commit is contained in:
lincube
2026-02-28 04:23:28 +08:00
parent b224f07e69
commit 2250071a91
12 changed files with 785 additions and 242 deletions

View File

@@ -11,6 +11,7 @@
<ItemGroup>
<Folder Include="Models\" />
<AvaloniaResource Include="Assets\**" />
<None Include="Localization\*.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,84 @@
{
"app.title": "LanMontainDesktop",
"button.back_to_windows": "Back to Windows",
"tooltip.back_to_windows": "Back to Windows",
"tooltip.open_settings": "Settings",
"settings.title": "Settings",
"settings.back_to_desktop": "Back to Desktop",
"settings.nav_header": "Settings",
"settings.nav.wallpaper": "Wallpaper",
"settings.nav.grid": "Grid",
"settings.nav.color": "Color",
"settings.nav.status_bar": "Status Bar",
"settings.nav.region": "Region",
"settings.wallpaper.title": "Wallpaper",
"settings.wallpaper.description": "Pick an image or video to apply as the app window wallpaper immediately.",
"settings.wallpaper.current_label": "Current Wallpaper",
"settings.wallpaper.placement_label": "Placement",
"settings.wallpaper.pick_button": "Browse Files",
"settings.wallpaper.clear_button": "Reset to Solid Color",
"settings.wallpaper.no_selection": "No wallpaper selected.",
"settings.wallpaper.storage_unavailable": "Storage provider is unavailable.",
"settings.wallpaper.import_failed": "Failed to import wallpaper file.",
"settings.wallpaper.image_applied": "Image wallpaper applied.",
"settings.wallpaper.video_applied": "Video wallpaper applied.",
"settings.wallpaper.unsupported_file": "Selected file type is not supported.",
"settings.wallpaper.apply_failed_format": "Failed to apply wallpaper: {0}",
"settings.wallpaper.mode_format": "Wallpaper mode: {0}.",
"settings.wallpaper.video_mode": "Video wallpaper uses automatic fill mode.",
"settings.wallpaper.cleared": "Background reset to solid color.",
"settings.wallpaper.default_status": "Current background uses solid color.",
"settings.wallpaper.saved_not_found": "Saved wallpaper file was not found. Using solid color background.",
"settings.wallpaper.restored": "Wallpaper restored from saved settings.",
"settings.wallpaper.video_restored": "Video wallpaper restored from saved settings.",
"settings.wallpaper.restore_failed": "Failed to restore saved wallpaper. Using solid color background.",
"settings.wallpaper.video_not_found": "Video wallpaper file not found.",
"settings.wallpaper.video_player_unavailable": "Video player is unavailable.",
"settings.wallpaper.video_play_failed_format": "Failed to play video wallpaper: {0}",
"settings.grid.title": "Grid Layout",
"settings.grid.description": "Every component must occupy at least one cell (minimum 1x1).",
"settings.grid.short_side_label": "Short Side Cells",
"settings.grid.apply_button": "Apply",
"settings.grid.info_format": "Grid: {0} cols x {1} rows | cell {2:F1}px (1:1)",
"settings.color.title": "Color",
"settings.color.description": "Switch day/night mode and choose app accent colors.",
"settings.color.day_night_label": "Day/Night Mode",
"settings.color.day_night_on": "Night",
"settings.color.day_night_off": "Day",
"settings.color.recommended_label": "Recommended Colors",
"settings.color.system_monet_label": "System Monet Colors",
"settings.color.refresh_button": "Refresh",
"settings.color.mode_night": "Night mode enabled",
"settings.color.mode_day": "Day mode enabled",
"settings.color.mode_status_format": "Theme mode: {0}.",
"settings.color.monet_refreshed": "Monet colors refreshed.",
"settings.color.theme_ready_format": "Theme color ready: {0}.",
"settings.color.theme_applied_format": "{0} color applied: {1}.",
"settings.color.theme_updated_wallpaper": "Wallpaper updated. Monet colors refreshed.",
"settings.color.theme_updated_video": "Video wallpaper updated. Theme colors refreshed.",
"settings.color.theme_cleared_wallpaper": "Wallpaper cleared. Monet colors refreshed.",
"settings.status_bar.title": "Status Bar",
"settings.status_bar.description": "Choose which components appear on the top status bar.",
"settings.status_bar.clock_header": "Clock Component",
"settings.status_bar.clock_description": "Display a clock on the top status bar.",
"settings.region.title": "Region",
"settings.region.description": "Choose language and apply immediately to settings and key UI.",
"settings.region.language_header": "Language",
"settings.region.language_label": "Language",
"settings.region.language_zh": "Chinese",
"settings.region.language_en": "English",
"settings.region.applied_format": "Language switched to: {0}",
"settings.footer": "LanMontainDesktop Settings",
"filepicker.title": "Select wallpaper",
"filepicker.image_files": "Image files",
"filepicker.video_files": "Video files",
"common.day": "Day",
"common.night": "Night",
"common.recommended": "Recommended",
"common.monet": "Monet",
"placement.fill": "Fill",
"placement.fit": "Fit",
"placement.stretch": "Stretch",
"placement.center": "Center",
"placement.tile": "Tile"
}

View File

@@ -0,0 +1,84 @@
{
"app.title": "LanMontainDesktop",
"button.back_to_windows": "回到Windows",
"tooltip.back_to_windows": "回到Windows",
"tooltip.open_settings": "设置",
"settings.title": "设置",
"settings.back_to_desktop": "返回桌面",
"settings.nav_header": "设置选项",
"settings.nav.wallpaper": "壁纸",
"settings.nav.grid": "网格",
"settings.nav.color": "颜色",
"settings.nav.status_bar": "状态栏",
"settings.nav.region": "地区",
"settings.wallpaper.title": "壁纸",
"settings.wallpaper.description": "选择图片或视频后可立刻设为应用窗口壁纸。",
"settings.wallpaper.current_label": "当前壁纸",
"settings.wallpaper.placement_label": "显示方式",
"settings.wallpaper.pick_button": "浏览文件",
"settings.wallpaper.clear_button": "恢复纯色",
"settings.wallpaper.no_selection": "未选择壁纸。",
"settings.wallpaper.storage_unavailable": "存储提供器不可用。",
"settings.wallpaper.import_failed": "导入壁纸文件失败。",
"settings.wallpaper.image_applied": "图片壁纸已应用。",
"settings.wallpaper.video_applied": "视频壁纸已应用。",
"settings.wallpaper.unsupported_file": "所选文件类型不受支持。",
"settings.wallpaper.apply_failed_format": "应用壁纸失败:{0}",
"settings.wallpaper.mode_format": "壁纸模式:{0}。",
"settings.wallpaper.video_mode": "视频壁纸使用自动填充模式。",
"settings.wallpaper.cleared": "背景已恢复为纯色。",
"settings.wallpaper.default_status": "当前使用纯色背景。",
"settings.wallpaper.saved_not_found": "未找到已保存的壁纸文件,使用纯色背景。",
"settings.wallpaper.restored": "已恢复保存的壁纸。",
"settings.wallpaper.video_restored": "已恢复保存的视频壁纸。",
"settings.wallpaper.restore_failed": "恢复已保存壁纸失败,使用纯色背景。",
"settings.wallpaper.video_not_found": "未找到视频壁纸文件。",
"settings.wallpaper.video_player_unavailable": "视频播放器不可用。",
"settings.wallpaper.video_play_failed_format": "播放视频壁纸失败:{0}",
"settings.grid.title": "网格布局",
"settings.grid.description": "每个组件至少占用一个格子(最小 1x1。",
"settings.grid.short_side_label": "短边格数",
"settings.grid.apply_button": "应用",
"settings.grid.info_format": "网格:{0} 列 x {1} 行 | 单元格 {2:F1}px1:1",
"settings.color.title": "颜色",
"settings.color.description": "切换日夜模式并选择应用主题色。",
"settings.color.day_night_label": "日夜模式",
"settings.color.day_night_on": "夜间",
"settings.color.day_night_off": "日间",
"settings.color.recommended_label": "推荐色",
"settings.color.system_monet_label": "系统莫奈色",
"settings.color.refresh_button": "刷新",
"settings.color.mode_night": "夜间模式已启用",
"settings.color.mode_day": "日间模式已启用",
"settings.color.mode_status_format": "主题模式:{0}。",
"settings.color.monet_refreshed": "莫奈色已刷新。",
"settings.color.theme_ready_format": "主题色已就绪:{0}。",
"settings.color.theme_applied_format": "{0}主题色已应用:{1}。",
"settings.color.theme_updated_wallpaper": "壁纸更新,莫奈色已刷新。",
"settings.color.theme_updated_video": "视频壁纸更新,主题色已刷新。",
"settings.color.theme_cleared_wallpaper": "壁纸已清除,莫奈色已刷新。",
"settings.status_bar.title": "状态栏",
"settings.status_bar.description": "选择顶部状态栏显示的组件。",
"settings.status_bar.clock_header": "时间组件",
"settings.status_bar.clock_description": "在顶部状态栏显示时钟。",
"settings.region.title": "地区",
"settings.region.description": "选择语言并立即应用到设置与主要界面。",
"settings.region.language_header": "语言",
"settings.region.language_label": "语言",
"settings.region.language_zh": "中文",
"settings.region.language_en": "英文",
"settings.region.applied_format": "语言已切换为:{0}",
"settings.footer": "LanMontainDesktop 设置",
"filepicker.title": "选择壁纸",
"filepicker.image_files": "图片文件",
"filepicker.video_files": "视频文件",
"common.day": "日间",
"common.night": "夜间",
"common.recommended": "推荐",
"common.monet": "莫奈",
"placement.fill": "填充",
"placement.fit": "适应",
"placement.stretch": "拉伸",
"placement.center": "居中",
"placement.tile": "平铺"
}

View File

@@ -16,6 +16,8 @@ public sealed class AppSettingsSnapshot
public int SettingsTabIndex { get; set; } = 0;
public string LanguageCode { get; set; } = "zh-CN";
public List<string> TopStatusComponentIds { get; set; } = [];
public List<string> PinnedTaskbarActions { get; set; } =

View File

@@ -6,5 +6,6 @@ public enum TaskbarContext
SettingsWallpaper,
SettingsGrid,
SettingsColor,
SettingsStatusBar
SettingsStatusBar,
SettingsRegion
}

View File

@@ -15,36 +15,54 @@ public static class GlassEffectService
public static void ApplyGlassResources(IResourceDictionary resources, ThemeColorContext context)
{
var neutralBase = context.IsNightMode ? Color.Parse("#FF0B1220") : Color.Parse("#FFF8FAFC");
var neutralElevated = context.IsNightMode ? Color.Parse("#FF1E293B") : Color.Parse("#FFFFFFFF");
var tintMix = context.IsNightMode ? 0.15 : 0.08;
var panelTone = ColorMath.Blend(neutralElevated, context.AccentColor, tintMix);
var strongTone = ColorMath.Blend(neutralBase, context.AccentColor, context.IsNightMode ? 0.18 : 0.12);
var overlayTone = ColorMath.Blend(neutralBase, context.AccentColor, context.IsNightMode ? 0.25 : 0.15);
resources["AdaptiveButtonBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(panelTone, context.IsNightMode ? (byte)0x66 : (byte)0x80));
resources["AdaptiveButtonBorderBrush"] = new SolidColorBrush(ColorMath.WithAlpha(neutralElevated, 0x1A));
// Mica 材质:不透明,但混合壁纸颜色
// 提取壁纸颜色的透明度0-1用于控制 Mica 效果强度
var wallpaperTintOpacity = 0.15; // 壁纸颜色混合比例
var neutralBase = context.IsNightMode ? Color.Parse("#FF202020") : Color.Parse("#FFF3F3F3");
var neutralElevated = context.IsNightMode ? Color.Parse("#FF2C2C2C") : Color.Parse("#FFFAFAFA");
// Mica 效果:将壁纸颜色混合到中性基色中
var micaBackground = ColorMath.Blend(neutralBase, context.AccentColor, wallpaperTintOpacity);
var micaElevated = ColorMath.Blend(neutralElevated, context.AccentColor, wallpaperTintOpacity * 0.8);
// 按钮颜色
var buttonBackground = context.IsNightMode ?
Color.FromArgb(0x33, micaBackground.R, micaBackground.G, micaBackground.B) :
Color.FromArgb(0x4D, micaBackground.R, micaBackground.G, micaBackground.B);
resources["AdaptiveButtonBackgroundBrush"] = new SolidColorBrush(buttonBackground);
resources["AdaptiveButtonBorderBrush"] = new SolidColorBrush(
Color.FromArgb(0x1A, neutralElevated.R, neutralElevated.G, neutralElevated.B));
resources["AdaptiveButtonHoverBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(ColorMath.Blend(panelTone, context.AccentColor, 0.15), context.IsNightMode ? (byte)0x7A : (byte)0x99));
ColorMath.WithAlpha(buttonBackground, context.IsNightMode ? (byte)0x4D : (byte)0x66));
resources["AdaptiveButtonPressedBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(ColorMath.Blend(panelTone, context.AccentColor, 0.28), context.IsNightMode ? (byte)0x8C : (byte)0xB3));
ColorMath.WithAlpha(buttonBackground, context.IsNightMode ? (byte)0x66 : (byte)0x80));
// 面板颜色 - 使用 Mica 材质
resources["AdaptiveGlassPanelBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(panelTone, context.IsNightMode ? (byte)0x4D : (byte)0x66));
resources["AdaptiveGlassPanelBorderBrush"] = new SolidColorBrush(ColorMath.WithAlpha(neutralElevated, 0x26));
Color.FromArgb(context.IsNightMode ? (byte)0xE6 : (byte)0xF2,
micaBackground.R, micaBackground.G, micaBackground.B));
resources["AdaptiveGlassPanelBorderBrush"] = new SolidColorBrush(
Color.FromArgb(0x1F, neutralElevated.R, neutralElevated.G, neutralElevated.B));
resources["AdaptiveGlassStrongBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(strongTone, context.IsNightMode ? (byte)0x66 : (byte)0x80));
resources["AdaptiveGlassStrongBorderBrush"] = new SolidColorBrush(ColorMath.WithAlpha(neutralElevated, 0x33));
Color.FromArgb(context.IsNightMode ? (byte)0xE6 : (byte)0xF5,
micaElevated.R, micaElevated.G, micaElevated.B));
resources["AdaptiveGlassStrongBorderBrush"] = new SolidColorBrush(
Color.FromArgb(0x29, neutralElevated.R, neutralElevated.G, neutralElevated.B));
resources["AdaptiveGlassOverlayBackgroundBrush"] = new SolidColorBrush(
ColorMath.WithAlpha(overlayTone, context.IsNightMode ? (byte)0x59 : (byte)0x73));
Color.FromArgb(context.IsNightMode ? (byte)0xCC : (byte)0xE6,
micaBackground.R, micaBackground.G, micaBackground.B));
resources["AdaptiveGlassPanelBlurRadius"] = context.IsNightMode ? NightPanelBlurRadius : DayPanelBlurRadius;
resources["AdaptiveGlassStrongBlurRadius"] = context.IsNightMode ? NightStrongBlurRadius : DayStrongBlurRadius;
resources["AdaptiveGlassOverlayBlurRadius"] = context.IsNightMode ? NightOverlayBlurRadius : DayOverlayBlurRadius;
resources["AdaptiveGlassPanelOpacity"] = context.IsNightMode ? 0.85 : 0.80;
resources["AdaptiveGlassStrongOpacity"] = context.IsNightMode ? 0.90 : 0.85;
resources["AdaptiveGlassOverlayOpacity"] = context.IsNightMode ? 0.75 : 0.70;
resources["AdaptiveGlassNoiseOpacity"] = context.IsNightMode ? 0.03 : 0.02;
// 模糊半径Mica 不需要强模糊)
resources["AdaptiveGlassPanelBlurRadius"] = context.IsNightMode ? 20.0 : 30.0;
resources["AdaptiveGlassStrongBlurRadius"] = context.IsNightMode ? 25.0 : 35.0;
resources["AdaptiveGlassOverlayBlurRadius"] = context.IsNightMode ? 30.0 : 40.0;
// 不透明度Mica 材质接近不透明)
resources["AdaptiveGlassPanelOpacity"] = context.IsNightMode ? 0.95 : 0.98;
resources["AdaptiveGlassStrongOpacity"] = context.IsNightMode ? 0.97 : 0.99;
resources["AdaptiveGlassOverlayOpacity"] = context.IsNightMode ? 0.85 : 0.92;
resources["AdaptiveGlassNoiseOpacity"] = context.IsNightMode ? 0.01 : 0.008;
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
namespace LanMontainDesktop.Services;
public sealed class LocalizationService
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
ReadCommentHandling = JsonCommentHandling.Skip,
AllowTrailingCommas = true
};
private readonly Dictionary<string, Dictionary<string, string>> _cache =
new(StringComparer.OrdinalIgnoreCase);
public string NormalizeLanguageCode(string? languageCode)
{
return string.Equals(languageCode, "en-US", StringComparison.OrdinalIgnoreCase)
? "en-US"
: "zh-CN";
}
public string GetString(string languageCode, string key, string fallback)
{
var normalizedLanguage = NormalizeLanguageCode(languageCode);
var table = LoadLanguageTable(normalizedLanguage);
return table.TryGetValue(key, out var value) && !string.IsNullOrWhiteSpace(value)
? value
: fallback;
}
private Dictionary<string, string> LoadLanguageTable(string languageCode)
{
if (_cache.TryGetValue(languageCode, out var table))
{
return table;
}
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
try
{
var filePath = Path.Combine(AppContext.BaseDirectory, "Localization", $"{languageCode}.json");
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
var data = JsonSerializer.Deserialize<Dictionary<string, string>>(json, JsonOptions);
if (data is not null)
{
result = new Dictionary<string, string>(data, StringComparer.OrdinalIgnoreCase);
}
}
}
catch
{
// Keep empty table for resilience.
}
_cache[languageCode] = result;
return result;
}
}

View File

@@ -10,24 +10,27 @@
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="CornerRadius" Value="6" />
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="16,10" />
<Setter Property="Transitions">
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.15" />
<DoubleTransition Property="Opacity" Duration="0:0:0.15" />
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.12" />
<DoubleTransition Property="Opacity" Duration="0:0:0.12" />
<BrushTransition Property="Background" Duration="0:0:0.12" />
</Transitions>
</Setter>
</Style>
<Style Selector="Button:pointerover">
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonHoverBackgroundBrush}" />
<Setter Property="RenderTransform" Value="scale(1.02)" />
<Setter Property="RenderTransform" Value="scale(1.015)" />
</Style>
<Style Selector="Button:pressed">
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonPressedBackgroundBrush}" />
<Setter Property="RenderTransform" Value="scale(0.98)" />
<Setter Property="RenderTransform" Value="scale(0.985)" />
</Style>
<Style Selector="ComboBox">
@@ -68,18 +71,18 @@
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassPanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="12" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassPanelOpacity}" />
<Setter Property="BoxShadow" Value="0 4 20 #1A000000, 0 8 40 #0D000000" />
<Setter Property="BoxShadow" Value="0 1 2 #1A000000" />
</Style>
<Style Selector="Border.glass-strong">
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassStrongBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassStrongBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="16" />
<Setter Property="CornerRadius" Value="12" />
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
<Setter Property="BoxShadow" Value="0 8 30 #26000000, 0 16 60 #14000000" />
<Setter Property="BoxShadow" Value="0 2 4 #26000000" />
</Style>
<Style Selector="Border.glass-overlay">

View File

@@ -0,0 +1,143 @@
using System;
using Avalonia.Controls;
using Avalonia.Interactivity;
namespace LanMontainDesktop.Views;
public partial class MainWindow
{
private void InitializeLocalization(string? languageCode)
{
_languageCode = _localizationService.NormalizeLanguageCode(languageCode);
if (LanguageComboBox is null)
{
return;
}
_suppressLanguageSelectionEvents = true;
LanguageComboBox.SelectedIndex = string.Equals(_languageCode, "en-US", StringComparison.OrdinalIgnoreCase) ? 1 : 0;
_suppressLanguageSelectionEvents = false;
}
private string L(string key, string fallback)
{
return _localizationService.GetString(_languageCode, key, fallback);
}
private string Lf(string key, string fallback, params object[] args)
{
var template = L(key, fallback);
return string.Format(template, args);
}
private string GetLanguageDisplayName(string languageCode)
{
return string.Equals(languageCode, "en-US", StringComparison.OrdinalIgnoreCase)
? L("settings.region.language_en", "English")
: L("settings.region.language_zh", "中文");
}
private string GetLocalizedPlacementDisplayName(WallpaperPlacement placement)
{
return placement switch
{
WallpaperPlacement.Fill => L("placement.fill", "Fill"),
WallpaperPlacement.Fit => L("placement.fit", "Fit"),
WallpaperPlacement.Stretch => L("placement.stretch", "Stretch"),
WallpaperPlacement.Center => L("placement.center", "Center"),
WallpaperPlacement.Tile => L("placement.tile", "Tile"),
_ => L("placement.fill", "Fill")
};
}
private void ApplyLocalization()
{
Title = L("app.title", "LanMontainDesktop");
BackToWindowsTextBlock.Text = L("button.back_to_windows", "Back to Windows");
WallpaperPreviewBackButtonTextBlock.Text = L("button.back_to_windows", "Back to Windows");
ToolTip.SetTip(BackToWindowsButton, L("tooltip.back_to_windows", "Back to Windows"));
SettingsTitleTextBlock.Text = L("settings.title", "Settings");
SettingsNavHeaderTextBlock.Text = L("settings.nav_header", "Settings");
SettingsNavWallpaperItem.Content = L("settings.nav.wallpaper", "Wallpaper");
SettingsNavGridItem.Content = L("settings.nav.grid", "Grid");
SettingsNavColorItem.Content = L("settings.nav.color", "Color");
SettingsNavStatusBarItem.Content = L("settings.nav.status_bar", "Status Bar");
SettingsNavRegionItem.Content = L("settings.nav.region", "Region");
WallpaperPanelTitleTextBlock.Text = L("settings.wallpaper.title", "Wallpaper");
WallpaperPanelDescriptionTextBlock.Text = L("settings.wallpaper.description", "Pick wallpaper.");
WallpaperCurrentLabelTextBlock.Text = L("settings.wallpaper.current_label", "Current Wallpaper");
WallpaperPlacementLabelTextBlock.Text = L("settings.wallpaper.placement_label", "Placement");
PickWallpaperButton.Content = L("settings.wallpaper.pick_button", "Browse Files");
ClearWallpaperButton.Content = L("settings.wallpaper.clear_button", "Reset");
GridPanelTitleTextBlock.Text = L("settings.grid.title", "Grid Layout");
GridPanelDescriptionTextBlock.Text = L("settings.grid.description", "Each component should occupy at least 1x1.");
GridShortSideLabelTextBlock.Text = L("settings.grid.short_side_label", "Short Side Cells");
ApplyGridButton.Content = L("settings.grid.apply_button", "Apply");
ColorPanelTitleTextBlock.Text = L("settings.color.title", "Color");
ColorPanelDescriptionTextBlock.Text = L("settings.color.description", "Theme and accent settings.");
DayNightModeLabelTextBlock.Text = L("settings.color.day_night_label", "Day/Night");
NightModeToggleSwitch.OnContent = L("settings.color.day_night_on", "Night");
NightModeToggleSwitch.OffContent = L("settings.color.day_night_off", "Day");
RecommendedColorsLabelTextBlock.Text = L("settings.color.recommended_label", "Recommended Colors");
SystemMonetColorsLabelTextBlock.Text = L("settings.color.system_monet_label", "System Monet Colors");
RefreshMonetColorsButton.Content = L("settings.color.refresh_button", "Refresh");
StatusBarPanelTitleTextBlock.Text = L("settings.status_bar.title", "Status Bar");
StatusBarPanelDescriptionTextBlock.Text = L("settings.status_bar.description", "Status bar components.");
StatusBarClockSettingsExpander.Header = L("settings.status_bar.clock_header", "Clock");
StatusBarClockDescriptionTextBlock.Text = L("settings.status_bar.clock_description", "Display clock in top status bar.");
RegionPanelTitleTextBlock.Text = L("settings.region.title", "Region");
RegionPanelDescriptionTextBlock.Text = L("settings.region.description", "Select language.");
LanguageSettingsExpander.Header = L("settings.region.language_header", "Language");
LanguageLabelTextBlock.Text = L("settings.region.language_label", "Language");
LanguageChineseItem.Content = L("settings.region.language_zh", "中文");
LanguageEnglishItem.Content = L("settings.region.language_en", "English");
if (WallpaperPlacementComboBox?.ItemCount >= 5)
{
if (WallpaperPlacementComboBox.Items[0] is ComboBoxItem fillItem) fillItem.Content = L("placement.fill", "Fill");
if (WallpaperPlacementComboBox.Items[1] is ComboBoxItem fitItem) fitItem.Content = L("placement.fit", "Fit");
if (WallpaperPlacementComboBox.Items[2] is ComboBoxItem stretchItem) stretchItem.Content = L("placement.stretch", "Stretch");
if (WallpaperPlacementComboBox.Items[3] is ComboBoxItem centerItem) centerItem.Content = L("placement.center", "Center");
if (WallpaperPlacementComboBox.Items[4] is ComboBoxItem tileItem) tileItem.Content = L("placement.tile", "Tile");
}
ThemeModeStatusTextBlock.Text = _isNightMode
? L("settings.color.mode_night", "Night mode enabled")
: L("settings.color.mode_day", "Day mode enabled");
GridInfoTextBlock.Text = Lf(
"settings.grid.info_format",
"Grid: {0} cols x {1} rows | cell {2:F1}px (1:1)",
DesktopGrid.ColumnDefinitions.Count,
DesktopGrid.RowDefinitions.Count,
DesktopGrid.RowDefinitions.Count > 0 ? DesktopGrid.RowDefinitions[0].Height.Value : 0d);
UpdateOpenSettingsActionVisualState();
UpdateWallpaperDisplay();
}
private void OnLanguageSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (_suppressLanguageSelectionEvents || LanguageComboBox?.SelectedItem is not ComboBoxItem item)
{
return;
}
var selectedLanguage = item.Tag as string;
_languageCode = _localizationService.NormalizeLanguageCode(selectedLanguage);
ApplyLocalization();
ThemeColorStatusTextBlock.Text = Lf(
"settings.region.applied_format",
"Language switched to: {0}",
GetLanguageDisplayName(_languageCode));
PersistSettings();
}
}

View File

@@ -24,6 +24,12 @@ public partial class MainWindow
{
private void OnOpenSettingsClick(object? sender, RoutedEventArgs e)
{
if (_isSettingsOpen)
{
CloseSettingsPage();
return;
}
OpenSettingsPage();
}
@@ -45,7 +51,8 @@ public partial class MainWindow
GridSettingsPanel is null ||
WallpaperSettingsPanel is null ||
ColorSettingsPanel is null ||
StatusBarSettingsPanel is null)
StatusBarSettingsPanel is null ||
RegionSettingsPanel is null)
{
return;
}
@@ -55,6 +62,7 @@ public partial class MainWindow
GridSettingsPanel.IsVisible = selectedIndex == 1;
ColorSettingsPanel.IsVisible = selectedIndex == 2;
StatusBarSettingsPanel.IsVisible = selectedIndex == 3;
RegionSettingsPanel.IsVisible = selectedIndex == 4;
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
}
@@ -106,12 +114,12 @@ public partial class MainWindow
private void OnRecommendedColorClick(object? sender, RoutedEventArgs e)
{
ApplyThemeColorFromButton(sender as Button, "Recommended");
ApplyThemeColorFromButton(sender as Button, L("common.recommended", "Recommended"));
}
private void OnMonetColorClick(object? sender, RoutedEventArgs e)
{
ApplyThemeColorFromButton(sender as Button, "Monet");
ApplyThemeColorFromButton(sender as Button, L("common.monet", "Monet"));
}
private void OnRefreshMonetColorsClick(object? sender, RoutedEventArgs e)
@@ -119,7 +127,7 @@ public partial class MainWindow
RefreshColorPalettes();
EnsureSelectedThemeColor();
UpdateThemeColorSelectionState();
ThemeColorStatusTextBlock.Text = "Monet colors refreshed.";
ThemeColorStatusTextBlock.Text = L("settings.color.monet_refreshed", "Monet colors refreshed.");
UpdateAdaptiveTextSystem();
PersistSettings();
}
@@ -128,22 +136,22 @@ public partial class MainWindow
{
if (StorageProvider is null)
{
_wallpaperStatus = "Storage provider is unavailable.";
_wallpaperStatus = L("settings.wallpaper.storage_unavailable", "Storage provider is unavailable.");
UpdateWallpaperDisplay();
return;
}
var options = new FilePickerOpenOptions
{
Title = "Select wallpaper",
Title = L("filepicker.title", "Select wallpaper"),
AllowMultiple = false,
FileTypeFilter =
[
new FilePickerFileType("Image files")
new FilePickerFileType(L("filepicker.image_files", "Image files"))
{
Patterns = ["*.png", "*.jpg", "*.jpeg", "*.bmp", "*.gif", "*.webp"]
},
new FilePickerFileType("Video files")
new FilePickerFileType(L("filepicker.video_files", "Video files"))
{
Patterns = ["*.mp4", "*.mkv", "*.webm", "*.avi", "*.mov", "*.m4v"]
}
@@ -162,7 +170,7 @@ public partial class MainWindow
var importedPath = await ImportWallpaperAssetAsync(file);
if (string.IsNullOrWhiteSpace(importedPath))
{
_wallpaperStatus = "Failed to import wallpaper file.";
_wallpaperStatus = L("settings.wallpaper.import_failed", "Failed to import wallpaper file.");
UpdateWallpaperDisplay();
return;
}
@@ -176,17 +184,17 @@ public partial class MainWindow
_wallpaperBitmap = new Bitmap(importedPath);
_wallpaperVideoPath = null;
_wallpaperMediaType = WallpaperMediaType.Image;
_wallpaperStatus = "Image wallpaper applied.";
_wallpaperStatus = L("settings.wallpaper.image_applied", "Image wallpaper applied.");
break;
case WallpaperMediaType.Video:
_wallpaperBitmap?.Dispose();
_wallpaperBitmap = null;
_wallpaperVideoPath = importedPath;
_wallpaperMediaType = WallpaperMediaType.Video;
_wallpaperStatus = "Video wallpaper applied.";
_wallpaperStatus = L("settings.wallpaper.video_applied", "Video wallpaper applied.");
break;
default:
_wallpaperStatus = "Selected file type is not supported.";
_wallpaperStatus = L("settings.wallpaper.unsupported_file", "Selected file type is not supported.");
UpdateWallpaperDisplay();
return;
}
@@ -197,13 +205,13 @@ public partial class MainWindow
EnsureSelectedThemeColor();
UpdateThemeColorSelectionState();
ThemeColorStatusTextBlock.Text = _wallpaperMediaType == WallpaperMediaType.Video
? "Video wallpaper updated. Theme colors refreshed."
: "Wallpaper updated. Monet colors refreshed.";
? L("settings.color.theme_updated_video", "Video wallpaper updated. Theme colors refreshed.")
: L("settings.color.theme_updated_wallpaper", "Wallpaper updated. Monet colors refreshed.");
PersistSettings();
}
catch (Exception ex)
{
_wallpaperStatus = $"Failed to apply wallpaper: {ex.Message}";
_wallpaperStatus = Lf("settings.wallpaper.apply_failed_format", "Failed to apply wallpaper: {0}", ex.Message);
UpdateWallpaperDisplay();
}
}
@@ -216,13 +224,13 @@ public partial class MainWindow
_wallpaperBitmap?.Dispose();
_wallpaperBitmap = null;
_wallpaperPath = null;
_wallpaperStatus = "Background reset to solid color.";
_wallpaperStatus = L("settings.wallpaper.cleared", "Background reset to solid color.");
ApplyWallpaperBrush();
UpdateWallpaperDisplay();
RefreshColorPalettes();
EnsureSelectedThemeColor();
UpdateThemeColorSelectionState();
ThemeColorStatusTextBlock.Text = "Wallpaper cleared. Monet colors refreshed.";
ThemeColorStatusTextBlock.Text = L("settings.color.theme_cleared_wallpaper", "Wallpaper cleared. Monet colors refreshed.");
PersistSettings();
}
@@ -231,11 +239,14 @@ public partial class MainWindow
ApplyWallpaperBrush();
if (_wallpaperMediaType == WallpaperMediaType.Image && _wallpaperBitmap is not null)
{
_wallpaperStatus = $"Wallpaper mode: {GetPlacementDisplayName(GetSelectedWallpaperPlacement())}.";
_wallpaperStatus = Lf(
"settings.wallpaper.mode_format",
"Wallpaper mode: {0}.",
GetLocalizedPlacementDisplayName(GetSelectedWallpaperPlacement()));
}
else if (_wallpaperMediaType == WallpaperMediaType.Video)
{
_wallpaperStatus = "Video wallpaper mode uses automatic fill.";
_wallpaperStatus = L("settings.wallpaper.video_mode", "Video wallpaper mode uses automatic fill mode.");
}
UpdateWallpaperDisplay();
@@ -278,7 +289,7 @@ public partial class MainWindow
}
WallpaperPathTextBlock.Text = string.IsNullOrWhiteSpace(_wallpaperPath)
? "No wallpaper selected."
? L("settings.wallpaper.no_selection", "No wallpaper selected.")
: Path.GetFileName(_wallpaperPath);
WallpaperStatusTextBlock.Text = _wallpaperStatus;
WallpaperPlacementComboBox.IsEnabled = _wallpaperMediaType != WallpaperMediaType.Video;
@@ -404,13 +415,15 @@ public partial class MainWindow
if (string.IsNullOrWhiteSpace(savedWallpaperPath))
{
_wallpaperStatus = "Current background uses solid color.";
_wallpaperStatus = L("settings.wallpaper.default_status", "Current background uses solid color.");
return;
}
if (!Path.IsPathRooted(savedWallpaperPath) || !File.Exists(savedWallpaperPath))
{
_wallpaperStatus = "Saved wallpaper file was not found. Using solid color background.";
_wallpaperStatus = L(
"settings.wallpaper.saved_not_found",
"Saved wallpaper file was not found. Using solid color background.");
return;
}
@@ -423,22 +436,26 @@ public partial class MainWindow
_wallpaperBitmap = new Bitmap(savedWallpaperPath);
_wallpaperPath = savedWallpaperPath;
_wallpaperMediaType = WallpaperMediaType.Image;
_wallpaperStatus = "Wallpaper restored from saved settings.";
_wallpaperStatus = L("settings.wallpaper.restored", "Wallpaper restored from saved settings.");
break;
case WallpaperMediaType.Video:
_wallpaperVideoPath = savedWallpaperPath;
_wallpaperPath = savedWallpaperPath;
_wallpaperMediaType = WallpaperMediaType.Video;
_wallpaperStatus = "Video wallpaper restored from saved settings.";
_wallpaperStatus = L("settings.wallpaper.video_restored", "Video wallpaper restored from saved settings.");
break;
default:
_wallpaperStatus = "Saved wallpaper type is not supported. Using solid color background.";
_wallpaperStatus = L(
"settings.wallpaper.unsupported_file",
"Saved wallpaper type is not supported. Using solid color background.");
break;
}
}
catch
{
_wallpaperStatus = "Failed to restore saved wallpaper. Using solid color background.";
_wallpaperStatus = L(
"settings.wallpaper.restore_failed",
"Failed to restore saved wallpaper. Using solid color background.");
_wallpaperBitmap?.Dispose();
_wallpaperBitmap = null;
_wallpaperMediaType = WallpaperMediaType.None;
@@ -538,7 +555,7 @@ public partial class MainWindow
{
if (!File.Exists(videoPath))
{
_wallpaperStatus = "Video wallpaper file not found.";
_wallpaperStatus = L("settings.wallpaper.video_not_found", "Video wallpaper file not found.");
StopVideoWallpaper();
return;
}
@@ -552,7 +569,7 @@ public partial class MainWindow
DesktopVideoWallpaperView is null ||
WallpaperPreviewVideoView is null)
{
_wallpaperStatus = "Video player is unavailable.";
_wallpaperStatus = L("settings.wallpaper.video_player_unavailable", "Video player is unavailable.");
StopVideoWallpaper();
return;
}
@@ -570,7 +587,7 @@ public partial class MainWindow
}
catch (Exception ex)
{
_wallpaperStatus = $"Failed to play video wallpaper: {ex.Message}";
_wallpaperStatus = Lf("settings.wallpaper.video_play_failed_format", "Failed to play video wallpaper: {0}", ex.Message);
StopVideoWallpaper();
}
}
@@ -676,16 +693,17 @@ public partial class MainWindow
1 => TaskbarContext.SettingsGrid,
2 => TaskbarContext.SettingsColor,
3 => TaskbarContext.SettingsStatusBar,
4 => TaskbarContext.SettingsRegion,
_ => TaskbarContext.Desktop
};
}
private void ApplyTaskbarActionVisibility(TaskbarContext context)
{
if (BackToWindowsContainer is null ||
OpenSettingsContainer is null ||
WallpaperPreviewBackButtonContainer is null ||
WallpaperPreviewSettingsButtonContainer is null)
if (BackToWindowsButton is null ||
OpenSettingsButton is null ||
WallpaperPreviewBackButtonVisual is null ||
WallpaperPreviewSettingsButtonIcon is null)
{
return;
}
@@ -693,19 +711,29 @@ public partial class MainWindow
var showMinimize = _pinnedTaskbarActions.Contains(TaskbarActionId.MinimizeToWindows);
var showSettings = _pinnedTaskbarActions.Contains(TaskbarActionId.OpenSettings);
BackToWindowsContainer.IsVisible = showMinimize;
OpenSettingsContainer.IsVisible = showSettings;
WallpaperPreviewBackButtonContainer.IsVisible = showMinimize;
WallpaperPreviewSettingsButtonContainer.IsVisible = showSettings;
BackToWindowsButton.IsVisible = showMinimize;
OpenSettingsButton.IsVisible = showSettings;
WallpaperPreviewBackButtonVisual.IsVisible = showMinimize;
WallpaperPreviewSettingsButtonIcon.IsVisible = showSettings;
if (TaskbarFixedActionsHost is not null)
{
TaskbarFixedActionsHost.IsVisible = showMinimize || showSettings;
TaskbarFixedActionsHost.IsVisible = showMinimize;
}
if (TaskbarSettingsActionHost is not null)
{
TaskbarSettingsActionHost.IsVisible = showSettings;
}
if (WallpaperPreviewTaskbarFixedActionsHost is not null)
{
WallpaperPreviewTaskbarFixedActionsHost.IsVisible = showMinimize || showSettings;
WallpaperPreviewTaskbarFixedActionsHost.IsVisible = showMinimize;
}
if (WallpaperPreviewTaskbarSettingsActionHost is not null)
{
WallpaperPreviewTaskbarSettingsActionHost.IsVisible = showSettings;
}
var dynamicActions = ResolveDynamicTaskbarActions(context);
@@ -721,6 +749,30 @@ public partial class MainWindow
{
WallpaperPreviewTaskbarDynamicActionsHost.IsVisible = hasDynamicActions;
}
UpdateOpenSettingsActionVisualState();
}
private void UpdateOpenSettingsActionVisualState()
{
if (OpenSettingsButtonTextBlock is null || OpenSettingsButton is null)
{
return;
}
var showBackToDesktop = _isSettingsOpen;
OpenSettingsButtonTextBlock.IsVisible = showBackToDesktop;
OpenSettingsButtonTextBlock.Text = L("settings.back_to_desktop", "Back to Desktop");
ToolTip.SetTip(
OpenSettingsButton,
showBackToDesktop
? L("settings.back_to_desktop", "Back to Desktop")
: L("tooltip.open_settings", "Settings"));
var effectiveCellSize = _currentDesktopCellSize > 0
? _currentDesktopCellSize
: Math.Max(32, Math.Min(Bounds.Width, Bounds.Height) / Math.Max(1, _targetShortSideCells));
ApplyWidgetSizing(effectiveCellSize);
}
private IReadOnlyList<TaskbarActionItem> ResolveDynamicTaskbarActions(TaskbarContext context)
@@ -804,6 +856,7 @@ public partial class MainWindow
WallpaperPath = _wallpaperPath,
WallpaperPlacement = GetPlacementDisplayName(GetSelectedWallpaperPlacement()),
SettingsTabIndex = Math.Max(0, SettingsNavListBox?.SelectedIndex ?? 0),
LanguageCode = _languageCode,
TopStatusComponentIds = _topStatusComponentIds.ToList(),
PinnedTaskbarActions = _pinnedTaskbarActions.Select(action => action.ToString()).ToList(),
EnableDynamicTaskbarActions = _enableDynamicTaskbarActions,
@@ -863,7 +916,9 @@ public partial class MainWindow
_suppressThemeToggleEvents = true;
NightModeToggleSwitch.IsChecked = enabled;
_suppressThemeToggleEvents = false;
ThemeModeStatusTextBlock.Text = enabled ? "Night mode enabled" : "Day mode enabled";
ThemeModeStatusTextBlock.Text = enabled
? L("settings.color.mode_night", "Night mode enabled")
: L("settings.color.mode_day", "Day mode enabled");
if (refreshPalettes)
{
@@ -872,7 +927,10 @@ public partial class MainWindow
}
UpdateThemeColorSelectionState();
ThemeColorStatusTextBlock.Text = $"Theme mode: {(enabled ? "Night" : "Day")}.";
ThemeColorStatusTextBlock.Text = Lf(
"settings.color.mode_status_format",
"Theme mode: {0}.",
enabled ? L("common.night", "Night") : L("common.day", "Day"));
UpdateAdaptiveTextSystem();
ApplyWallpaperBrush();
PersistSettings();
@@ -960,7 +1018,11 @@ public partial class MainWindow
_selectedThemeColor = color;
UpdateThemeColorSelectionState();
ThemeColorStatusTextBlock.Text = $"{sourceLabel} color applied: {_selectedThemeColor}.";
ThemeColorStatusTextBlock.Text = Lf(
"settings.color.theme_applied_format",
"{0} color applied: {1}.",
sourceLabel,
_selectedThemeColor);
UpdateAdaptiveTextSystem();
PersistSettings();
}
@@ -1131,12 +1193,7 @@ public partial class MainWindow
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
SettingsPage.IsVisible = true;
SettingsPage.Opacity = 0;
if (_settingsContentPanelTransform is not null)
{
_settingsContentPanelTransform.Y = 30;
}
DesktopPage.IsHitTestVisible = false;
UpdateWallpaperPreviewLayout();
Dispatcher.UIThread.Post(() =>
@@ -1147,10 +1204,6 @@ public partial class MainWindow
}
SettingsPage.Opacity = 1;
if (_settingsContentPanelTransform is not null)
{
_settingsContentPanelTransform.Y = 0;
}
}, DispatcherPriority.Background);
}
@@ -1166,13 +1219,7 @@ public partial class MainWindow
ApplyWallpaperBrush();
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
DesktopPage.IsHitTestVisible = true;
SettingsPage.Opacity = 0;
if (_settingsContentPanelTransform is not null)
{
_settingsContentPanelTransform.Y = 30;
}
DispatcherTimer.RunOnce(() =>
{
@@ -1182,6 +1229,6 @@ public partial class MainWindow
}
SettingsPage.IsVisible = false;
}, TimeSpan.FromMilliseconds(SettingsTransitionDurationMs));
}, TimeSpan.FromMilliseconds(200));
}
}

View File

@@ -1,4 +1,4 @@
<Window xmlns="https://github.com/avaloniaui"
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:LanMontainDesktop.ViewModels"
xmlns:ui="using:FluentAvalonia.UI.Controls"
@@ -113,60 +113,38 @@
Margin="4"
CornerRadius="18"
Padding="6">
<Grid ColumnDefinitions="Auto,*"
<Grid ColumnDefinitions="Auto,*,Auto"
ColumnSpacing="8">
<Border x:Name="TaskbarFixedActionsHost"
Grid.Column="0"
Background="Transparent"
BorderThickness="0">
<Grid ColumnDefinitions="Auto,Auto"
<Grid ColumnDefinitions="Auto"
ColumnSpacing="8">
<Border x:Name="BackToWindowsContainer"
<Button x:Name="BackToWindowsButton"
Grid.Column="0"
Padding="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
CornerRadius="12">
<Button x:Name="BackToWindowsButton"
Padding="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnMinimizeClick"
ToolTip.Tip="&#22238;&#21040;Windows">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="8">
<fi:SymbolIcon Classes="icon-m"
Symbol="Window"
IconVariant="Regular"
/>
<TextBlock Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#22238;&#21040;Windows" />
</StackPanel>
</Button>
</Border>
<Border x:Name="OpenSettingsContainer"
Grid.Column="1"
Background="Transparent"
CornerRadius="12">
<Button x:Name="OpenSettingsButton"
Padding="6"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnOpenSettingsClick"
ToolTip.Tip="&#35774;&#32622;">
<fi:SymbolIcon Classes="icon-l"
Symbol="Settings"
BorderThickness="0"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnMinimizeClick"
ToolTip.Tip="&#22238;&#21040;Windows">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="8">
<fi:SymbolIcon Classes="icon-m"
Symbol="Window"
IconVariant="Regular"
/>
</Button>
</Border>
<TextBlock x:Name="BackToWindowsTextBlock"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#22238;&#21040;Windows" />
</StackPanel>
</Button>
</Grid>
</Border>
@@ -179,6 +157,34 @@
Orientation="Horizontal"
Spacing="8" />
</Border>
<Border x:Name="TaskbarSettingsActionHost"
Grid.Column="2"
Background="Transparent"
BorderThickness="0">
<Button x:Name="OpenSettingsButton"
Padding="6"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnOpenSettingsClick"
ToolTip.Tip="&#35774;&#32622;">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="6">
<fi:SymbolIcon Classes="icon-l"
Symbol="Settings"
IconVariant="Regular" />
<TextBlock x:Name="OpenSettingsButtonTextBlock"
IsVisible="False"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#36820;&#22238;&#26700;&#38754;" />
</StackPanel>
</Button>
</Border>
</Grid>
</Border>
</Grid>
@@ -199,11 +205,10 @@
Classes="glass-overlay" />
<Border x:Name="SettingsContentPanel"
Classes="glass-strong"
Margin="24"
Padding="24"
MaxWidth="1240"
CornerRadius="16">
Background="Transparent"
BorderThickness="0"
Margin="0"
Padding="8">
<Border.RenderTransform>
<TranslateTransform Y="30">
<TranslateTransform.Transitions>
@@ -214,19 +219,15 @@
</TranslateTransform>
</Border.RenderTransform>
<Grid RowDefinitions="Auto,*,Auto"
<Grid RowDefinitions="Auto,*"
RowSpacing="16">
<Grid ColumnDefinitions="*,Auto">
<TextBlock VerticalAlignment="Center"
FontSize="30"
FontWeight="Bold"
<Grid ColumnDefinitions="*">
<TextBlock x:Name="SettingsTitleTextBlock"
VerticalAlignment="Center"
FontSize="22"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#35774;&#32622;" />
<Button Grid.Column="1"
Padding="14,8"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnCloseSettingsClick"
Content="&#36820;&#22238;&#26700;&#38754;" />
</Grid>
<Border Grid.Row="1"
@@ -263,16 +264,18 @@
</Border.Styles>
<StackPanel Spacing="10">
<TextBlock FontSize="16"
<TextBlock x:Name="SettingsNavHeaderTextBlock"
FontSize="16"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#35774;&#32622;&#36873;&#39033;" />
<ListBox x:Name="SettingsNavListBox"
SelectionChanged="OnSettingsNavSelectionChanged">
<ListBoxItem Content="&#22721;&#32440;" />
<ListBoxItem Content="&#32593;&#26684;" />
<ListBoxItem Content="&#39068;&#33394;" />
<ListBoxItem Content="&#29366;&#24577;&#26639;" />
<ListBoxItem x:Name="SettingsNavWallpaperItem" Content="&#22721;&#32440;" />
<ListBoxItem x:Name="SettingsNavGridItem" Content="&#32593;&#26684;" />
<ListBoxItem x:Name="SettingsNavColorItem" Content="&#39068;&#33394;" />
<ListBoxItem x:Name="SettingsNavStatusBarItem" Content="&#29366;&#24577;&#26639;" />
<ListBoxItem x:Name="SettingsNavRegionItem" Content="&#22320;&#21306;" />
</ListBox>
</StackPanel>
</Border>
@@ -285,11 +288,13 @@
<StackPanel x:Name="WallpaperSettingsPanel"
IsVisible="True"
Spacing="14">
<TextBlock FontSize="18"
<TextBlock x:Name="WallpaperPanelTitleTextBlock"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#22721;&#32440;" />
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
<TextBlock x:Name="WallpaperPanelDescriptionTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#36873;&#25321;&#22270;&#29255;&#21518;&#21487;&#31435;&#21363;&#35774;&#20026;&#24212;&#29992;&#31383;&#21475;&#22721;&#32440;&#12290;" />
<Border x:Name="WallpaperPreviewHost"
@@ -351,44 +356,31 @@
Margin="3"
CornerRadius="8"
Padding="2">
<Grid ColumnDefinitions="Auto,*"
<Grid ColumnDefinitions="Auto,*,Auto"
ColumnSpacing="3">
<Border x:Name="WallpaperPreviewTaskbarFixedActionsHost"
Grid.Column="0"
Background="Transparent"
BorderThickness="0">
<Grid ColumnDefinitions="Auto,Auto"
<Grid ColumnDefinitions="Auto"
ColumnSpacing="3">
<Border x:Name="WallpaperPreviewBackButtonContainer"
Grid.Column="0"
Background="Transparent"
CornerRadius="6">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="3">
<fi:SymbolIcon Classes="icon-s"
Symbol="Window"
IconVariant="Regular"
/>
<TextBlock x:Name="WallpaperPreviewBackButtonTextBlock"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#22238;&#21040;Windows" />
</StackPanel>
</Border>
<Border x:Name="WallpaperPreviewSettingsButtonContainer"
Grid.Column="1"
Background="Transparent"
CornerRadius="6">
<fi:SymbolIcon x:Name="WallpaperPreviewSettingsButtonIcon"
Classes="icon-s"
Symbol="Settings"
<StackPanel x:Name="WallpaperPreviewBackButtonVisual"
Grid.Column="0"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="3">
<fi:SymbolIcon Classes="icon-s"
Symbol="Window"
IconVariant="Regular"
/>
</Border>
<TextBlock x:Name="WallpaperPreviewBackButtonTextBlock"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Text="&#22238;&#21040;Windows" />
</StackPanel>
</Grid>
</Border>
@@ -401,6 +393,16 @@
Orientation="Horizontal"
Spacing="3" />
</Border>
<Border x:Name="WallpaperPreviewTaskbarSettingsActionHost"
Grid.Column="2"
Background="Transparent"
BorderThickness="0">
<fi:SymbolIcon x:Name="WallpaperPreviewSettingsButtonIcon"
Classes="icon-s"
Symbol="Settings"
IconVariant="Regular" />
</Border>
</Grid>
</Border>
</Grid>
@@ -413,7 +415,8 @@
RowDefinitions="Auto,Auto,Auto"
ColumnSpacing="10"
RowSpacing="10">
<TextBlock VerticalAlignment="Center"
<TextBlock x:Name="WallpaperCurrentLabelTextBlock"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#24403;&#21069;&#22721;&#32440;" />
<TextBlock x:Name="WallpaperPathTextBlock"
@@ -423,7 +426,8 @@
Foreground="{DynamicResource AdaptiveTextAccentBrush}"
Text="&#26410;&#36873;&#25321;&#22721;&#32440;" />
<TextBlock Grid.Row="1"
<TextBlock x:Name="WallpaperPlacementLabelTextBlock"
Grid.Row="1"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#26174;&#31034;&#26041;&#24335;" />
@@ -443,11 +447,13 @@
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="10">
<Button Padding="12,6"
<Button x:Name="PickWallpaperButton"
Padding="12,6"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnPickWallpaperClick"
Content="&#27983;&#35272;&#22270;&#29255;" />
<Button Padding="12,6"
<Button x:Name="ClearWallpaperButton"
Padding="12,6"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Click="OnClearWallpaperClick"
Content="&#24674;&#22797;&#32431;&#33394;" />
@@ -462,18 +468,21 @@
<StackPanel x:Name="GridSettingsPanel"
IsVisible="False"
Spacing="14">
<TextBlock FontSize="18"
<TextBlock x:Name="GridPanelTitleTextBlock"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Grid layout" />
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
<TextBlock x:Name="GridPanelDescriptionTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Every component must occupy at least one cell (minimum 1x1)." />
<Grid ColumnDefinitions="Auto,Auto,Auto"
RowDefinitions="Auto,Auto"
ColumnSpacing="8"
RowSpacing="8">
<TextBlock Grid.Row="0"
<TextBlock x:Name="GridShortSideLabelTextBlock"
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
@@ -486,7 +495,8 @@
Maximum="96"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Value="12" />
<Button Grid.Row="0"
<Button x:Name="ApplyGridButton"
Grid.Row="0"
Grid.Column="2"
Padding="12,6"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
@@ -505,16 +515,19 @@
<StackPanel x:Name="ColorSettingsPanel"
IsVisible="False"
Spacing="14">
<TextBlock FontSize="18"
<TextBlock x:Name="ColorPanelTitleTextBlock"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Color" />
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
<TextBlock x:Name="ColorPanelDescriptionTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Switch day/night mode and pick app accent colors." />
<Grid ColumnDefinitions="Auto,Auto,*"
ColumnSpacing="12">
<TextBlock VerticalAlignment="Center"
<TextBlock x:Name="DayNightModeLabelTextBlock"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#26085;&#22812;&#27169;&#24335;" />
<ToggleSwitch x:Name="NightModeToggleSwitch"
@@ -530,7 +543,8 @@
Text="Night mode enabled" />
</Grid>
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
<TextBlock x:Name="RecommendedColorsLabelTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Recommended Colors" />
<WrapPanel ItemWidth="72"
ItemHeight="56"
@@ -605,10 +619,12 @@
<Grid ColumnDefinitions="*,Auto"
ColumnSpacing="10">
<TextBlock VerticalAlignment="Center"
<TextBlock x:Name="SystemMonetColorsLabelTextBlock"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="System Monet Colors" />
<Button Grid.Column="1"
<Button x:Name="RefreshMonetColorsButton"
Grid.Column="1"
Padding="10,6"
Click="OnRefreshMonetColorsClick"
Content="Refresh" />
@@ -693,14 +709,17 @@
<StackPanel x:Name="StatusBarSettingsPanel"
IsVisible="False"
Spacing="14">
<TextBlock FontSize="18"
<TextBlock x:Name="StatusBarPanelTitleTextBlock"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Status Bar" />
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
<TextBlock x:Name="StatusBarPanelDescriptionTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="Choose which components appear on the top status bar." />
<ui:SettingsExpander Header="&#26102;&#38388;&#32452;&#20214;">
<ui:SettingsExpander x:Name="StatusBarClockSettingsExpander"
Header="&#26102;&#38388;&#32452;&#20214;">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="12">
<ToggleSwitch x:Name="StatusBarClockToggleSwitch"
@@ -709,32 +728,54 @@
OffContent="Off"
Checked="OnStatusBarClockChecked"
Unchecked="OnStatusBarClockUnchecked" />
<TextBlock Grid.Column="1"
<TextBlock x:Name="StatusBarClockDescriptionTextBlock"
Grid.Column="1"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#22312;&#39030;&#37096;&#29366;&#24577;&#26639;&#26174;&#31034;&#26102;&#38047;&#12290;" />
</Grid>
</ui:SettingsExpander>
</StackPanel>
<StackPanel x:Name="RegionSettingsPanel"
IsVisible="False"
Spacing="14">
<TextBlock x:Name="RegionPanelTitleTextBlock"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#22320;&#21306;" />
<TextBlock x:Name="RegionPanelDescriptionTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#36873;&#25321;&#35821;&#35328;&#65292;&#31435;&#21363;&#24212;&#29992;&#21040;&#35774;&#32622;&#19982;&#20027;&#35201;&#30028;&#38754;&#12290;" />
<ui:SettingsExpander x:Name="LanguageSettingsExpander"
Header="&#35821;&#35328;">
<Grid ColumnDefinitions="Auto,*"
ColumnSpacing="12">
<TextBlock x:Name="LanguageLabelTextBlock"
Grid.Column="0"
VerticalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="&#35821;&#35328;" />
<ComboBox x:Name="LanguageComboBox"
Grid.Column="1"
Width="220"
SelectionChanged="OnLanguageSelectionChanged">
<ComboBoxItem x:Name="LanguageChineseItem" Tag="zh-CN" Content="&#20013;&#25991;" />
<ComboBoxItem x:Name="LanguageEnglishItem" Tag="en-US" Content="English" />
</ComboBox>
</Grid>
</ui:SettingsExpander>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
<Border Grid.Row="2"
Classes="glass-panel"
CornerRadius="10"
Padding="8,6">
<TextBlock HorizontalAlignment="Center"
Foreground="{DynamicResource AdaptiveTextMutedBrush}"
Text="LanMontainDesktop Settings" />
</Border>
</Grid>
</Border>
</Grid>
</Grid>
</Window>

View File

@@ -43,6 +43,7 @@ public partial class MainWindow : Window
private const int MinShortSideCells = 6;
private const int MaxShortSideCells = 96;
private const int SettingsTransitionDurationMs = 240;
private const double WallpaperPreviewMaxWidth = 520;
private const double LightBackgroundLuminanceThreshold = 0.57;
private const string ClockStatusComponentId = "Clock";
private const string TaskbarLayoutBottomFullRowMacStyle = "BottomFullRowMacStyle";
@@ -62,6 +63,7 @@ public partial class MainWindow : Window
private readonly record struct GridMetrics(int ColumnCount, int RowCount, double CellSize);
private readonly MonetColorService _monetColorService = new();
private readonly AppSettingsService _appSettingsService = new();
private readonly LocalizationService _localizationService = new();
private readonly FluentAvaloniaTheme? _fluentAvaloniaTheme;
private readonly HashSet<string> _topStatusComponentIds = new(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<TaskbarActionId> _pinnedTaskbarActions = [];
@@ -71,7 +73,9 @@ public partial class MainWindow : Window
private bool _enableDynamicTaskbarActions;
private bool _suppressThemeToggleEvents;
private bool _suppressStatusBarToggleEvents;
private bool _suppressLanguageSelectionEvents;
private bool _suppressSettingsPersistence;
private bool _isUpdatingWallpaperPreviewLayout;
private TranslateTransform? _settingsContentPanelTransform;
private IBrush? _defaultDesktopBackground;
private Bitmap? _wallpaperBitmap;
@@ -87,7 +91,9 @@ public partial class MainWindow : Window
private IReadOnlyList<Color> _recommendedColors = Array.Empty<Color>();
private IReadOnlyList<Color> _monetColors = Array.Empty<Color>();
private Color _selectedThemeColor = Color.Parse("#FF3B82F6");
private double _currentDesktopCellSize;
private string _taskbarLayoutMode = TaskbarLayoutBottomFullRowMacStyle;
private string _languageCode = "zh-CN";
public MainWindow()
{
@@ -109,12 +115,13 @@ public partial class MainWindow : Window
MaxShortSideCells);
GridSizeNumberBox.Value = _targetShortSideCells;
SettingsNavListBox.SelectedIndex = Math.Clamp(snapshot.SettingsTabIndex, 0, 3);
SettingsNavListBox.SelectedIndex = Math.Clamp(snapshot.SettingsTabIndex, 0, 4);
UpdateSettingsTabContent();
WallpaperPlacementComboBox.SelectedIndex = GetPlacementIndexFromSetting(snapshot.WallpaperPlacement);
_defaultDesktopBackground = DesktopWallpaperLayer.Background;
ApplyTaskbarSettings(snapshot);
InitializeLocalization(snapshot.LanguageCode);
TryRestoreWallpaper(snapshot.WallpaperPath);
ApplyWallpaperBrush();
@@ -130,7 +137,8 @@ public partial class MainWindow : Window
_suppressStatusBarToggleEvents = true;
StatusBarClockToggleSwitch.IsChecked = _topStatusComponentIds.Contains(ClockStatusComponentId);
_suppressStatusBarToggleEvents = false;
ThemeColorStatusTextBlock.Text = $"Theme color ready: {_selectedThemeColor}.";
ApplyLocalization();
ThemeColorStatusTextBlock.Text = Lf("settings.color.theme_ready_format", "Theme color ready: {0}.", _selectedThemeColor);
_settingsContentPanelTransform = SettingsContentPanel.RenderTransform as TranslateTransform;
DesktopHost.SizeChanged += OnDesktopHostSizeChanged;
WallpaperPreviewHost.SizeChanged += OnWallpaperPreviewHostSizeChanged;
@@ -208,6 +216,7 @@ public partial class MainWindow : Window
{
return;
}
_currentDesktopCellSize = gridMetrics.CellSize;
DesktopGrid.RowDefinitions.Clear();
DesktopGrid.ColumnDefinitions.Clear();
@@ -240,9 +249,14 @@ public partial class MainWindow : Window
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
ApplyWidgetSizing(gridMetrics.CellSize);
UpdateSettingsViewportInsets(gridMetrics.CellSize);
GridInfoTextBlock.Text =
$"Grid: {gridMetrics.ColumnCount} cols x {gridMetrics.RowCount} rows | cell {gridMetrics.CellSize:F1}px (1:1)";
GridInfoTextBlock.Text = Lf(
"settings.grid.info_format",
"Grid: {0} cols x {1} rows | cell {2:F1}px (1:1)",
gridMetrics.ColumnCount,
gridMetrics.RowCount,
gridMetrics.CellSize);
UpdateWallpaperPreviewLayout();
}
@@ -308,20 +322,46 @@ public partial class MainWindow : Window
BottomTaskbarContainer.CornerRadius = new CornerRadius(Math.Clamp(cellSize * 0.24, 10, 24));
BottomTaskbarContainer.Padding = new Thickness(Math.Clamp(cellSize * 0.08, 2, 10));
BackToWindowsContainer.Margin = new Thickness(0);
BackToWindowsContainer.CornerRadius = new CornerRadius(Math.Clamp(cellSize * 0.16, 6, 16));
BackToWindowsButton.Margin = new Thickness(0);
BackToWindowsButton.Padding = new Thickness(horizontalPadding, verticalPadding);
BackToWindowsButton.FontSize = Math.Clamp(cellSize * 0.22, 8, 22);
BackToWindowsButton.MinHeight = taskbarCell;
BackToWindowsButton.MinWidth = Math.Clamp(cellSize * 2.3, 90, 320);
OpenSettingsContainer.Margin = new Thickness(0);
OpenSettingsContainer.CornerRadius = new CornerRadius(Math.Clamp(cellSize * 0.16, 6, 16));
OpenSettingsContainer.Width = taskbarCell;
OpenSettingsContainer.Height = taskbarCell;
OpenSettingsButton.Width = taskbarCell;
OpenSettingsButton.Margin = new Thickness(0);
OpenSettingsButton.Height = taskbarCell;
OpenSettingsButton.Padding = new Thickness(Math.Clamp(taskbarCell * 0.2, 4, 12));
OpenSettingsButton.MinHeight = taskbarCell;
if (_isSettingsOpen)
{
OpenSettingsButton.Width = double.NaN;
OpenSettingsButton.MinWidth = Math.Clamp(cellSize * 2.3, 120, 340);
OpenSettingsButton.Padding = new Thickness(horizontalPadding, verticalPadding);
}
else
{
OpenSettingsButton.Width = taskbarCell;
OpenSettingsButton.MinWidth = taskbarCell;
OpenSettingsButton.Padding = new Thickness(Math.Clamp(taskbarCell * 0.2, 4, 12));
}
}
private void UpdateSettingsViewportInsets(double cellSize)
{
if (SettingsBackdropOverlay is null || SettingsContentPanel is null)
{
return;
}
var clampedCell = Math.Max(1, cellSize);
var horizontalInset = Math.Clamp(clampedCell * 0.45, 12, 64);
var verticalGap = Math.Clamp(clampedCell * 0.16, 6, 18);
var topInset = clampedCell + verticalGap;
var bottomInset = clampedCell + verticalGap;
var inset = new Thickness(horizontalInset, topInset, horizontalInset, bottomInset);
SettingsBackdropOverlay.Margin = inset;
SettingsContentPanel.Margin = inset;
}
private void UpdateWallpaperPreviewLayout()
@@ -333,6 +373,14 @@ public partial class MainWindow : Window
return;
}
if (_isUpdatingWallpaperPreviewLayout)
{
return;
}
_isUpdatingWallpaperPreviewLayout = true;
try
{
var desktopWidth = Math.Max(1, DesktopHost.Bounds.Width);
var desktopHeight = Math.Max(1, DesktopHost.Bounds.Height);
var aspectRatio = desktopWidth / desktopHeight;
@@ -349,7 +397,7 @@ public partial class MainWindow : Window
availableWidth = Math.Max(1, availableWidth);
availableHeight = Math.Max(1, availableHeight);
var previewWidth = availableWidth;
var previewWidth = Math.Min(availableWidth, WallpaperPreviewMaxWidth);
var previewHeight = previewWidth / aspectRatio;
if (previewHeight > availableHeight)
{
@@ -357,8 +405,16 @@ public partial class MainWindow : Window
previewWidth = previewHeight * aspectRatio;
}
WallpaperPreviewFrame.Width = previewWidth;
WallpaperPreviewFrame.Height = previewHeight;
if (Math.Abs(WallpaperPreviewFrame.Width - previewWidth) > 0.5)
{
WallpaperPreviewFrame.Width = previewWidth;
}
if (Math.Abs(WallpaperPreviewFrame.Height - previewHeight) > 0.5)
{
WallpaperPreviewFrame.Height = previewHeight;
}
WallpaperPreviewClockTextBlock.Text = DateTime.Now.ToString("HH:mm");
var gridMetrics = CalculateGridMetrics(previewWidth, previewHeight, _targetShortSideCells);
@@ -399,6 +455,11 @@ public partial class MainWindow : Window
ApplyTopStatusComponentVisibility();
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
ApplyPreviewWidgetSizing(gridMetrics.CellSize);
}
finally
{
_isUpdatingWallpaperPreviewLayout = false;
}
}
private void ApplyPreviewWidgetSizing(double cellSize)
@@ -412,16 +473,10 @@ public partial class MainWindow : Window
WallpaperPreviewClockTextBlock.FontSize = Math.Clamp(cellSize * 0.30, 6, 18);
WallpaperPreviewBackButtonTextBlock.FontSize = Math.Clamp(cellSize * 0.19, 5, 13);
WallpaperPreviewBackButtonContainer.MinHeight = previewTaskbarCell;
WallpaperPreviewBackButtonContainer.MinWidth = Math.Clamp(cellSize * 2.1, 30, 120);
WallpaperPreviewSettingsButtonContainer.Width = previewTaskbarCell;
WallpaperPreviewSettingsButtonContainer.Height = previewTaskbarCell;
WallpaperPreviewBackButtonVisual.MinHeight = previewTaskbarCell;
WallpaperPreviewBackButtonVisual.MinWidth = Math.Clamp(cellSize * 2.1, 30, 120);
WallpaperPreviewSettingsButtonIcon.Width = Math.Clamp(previewTaskbarCell * 0.42, 6, 14);
WallpaperPreviewSettingsButtonIcon.Height = Math.Clamp(previewTaskbarCell * 0.42, 6, 14);
var cornerRadius = new CornerRadius(Math.Clamp(cellSize * 0.12, 3, 10));
WallpaperPreviewBackButtonContainer.CornerRadius = cornerRadius;
WallpaperPreviewSettingsButtonContainer.CornerRadius = cornerRadius;
}
private void OnMinimizeClick(object? sender, RoutedEventArgs e)
@@ -450,4 +505,3 @@ public partial class MainWindow : Window
});
}
}