mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 00:54:26 +08:00
0.1.6
mica
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
<None Include="Localization\*.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
84
LanMontainDesktop/Localization/en-US.json
Normal file
84
LanMontainDesktop/Localization/en-US.json
Normal 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"
|
||||
}
|
||||
84
LanMontainDesktop/Localization/zh-CN.json
Normal file
84
LanMontainDesktop/Localization/zh-CN.json
Normal 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}px(1: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": "平铺"
|
||||
}
|
||||
@@ -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; } =
|
||||
|
||||
@@ -6,5 +6,6 @@ public enum TaskbarContext
|
||||
SettingsWallpaper,
|
||||
SettingsGrid,
|
||||
SettingsColor,
|
||||
SettingsStatusBar
|
||||
SettingsStatusBar,
|
||||
SettingsRegion
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
65
LanMontainDesktop/Services/LocalizationService.cs
Normal file
65
LanMontainDesktop/Services/LocalizationService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
143
LanMontainDesktop/Views/MainWindow.Localization.cs
Normal file
143
LanMontainDesktop/Views/MainWindow.Localization.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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="回到Windows">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="8">
|
||||
<fi:SymbolIcon Classes="icon-m"
|
||||
Symbol="Window"
|
||||
IconVariant="Regular"
|
||||
/>
|
||||
<TextBlock Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="回到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="设置">
|
||||
<fi:SymbolIcon Classes="icon-l"
|
||||
Symbol="Settings"
|
||||
BorderThickness="0"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Click="OnMinimizeClick"
|
||||
ToolTip.Tip="回到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="回到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="设置">
|
||||
<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="返回桌面" />
|
||||
</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="设置" />
|
||||
<Button Grid.Column="1"
|
||||
Padding="14,8"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Click="OnCloseSettingsClick"
|
||||
Content="返回桌面" />
|
||||
</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="设置选项" />
|
||||
<ListBox x:Name="SettingsNavListBox"
|
||||
SelectionChanged="OnSettingsNavSelectionChanged">
|
||||
<ListBoxItem Content="壁纸" />
|
||||
<ListBoxItem Content="网格" />
|
||||
<ListBoxItem Content="颜色" />
|
||||
<ListBoxItem Content="状态栏" />
|
||||
<ListBoxItem x:Name="SettingsNavWallpaperItem" Content="壁纸" />
|
||||
<ListBoxItem x:Name="SettingsNavGridItem" Content="网格" />
|
||||
<ListBoxItem x:Name="SettingsNavColorItem" Content="颜色" />
|
||||
<ListBoxItem x:Name="SettingsNavStatusBarItem" Content="状态栏" />
|
||||
<ListBoxItem x:Name="SettingsNavRegionItem" Content="地区" />
|
||||
</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="壁纸" />
|
||||
<TextBlock Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
<TextBlock x:Name="WallpaperPanelDescriptionTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="选择图片后可立即设为应用窗口壁纸。" />
|
||||
|
||||
<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="回到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="回到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="当前壁纸" />
|
||||
<TextBlock x:Name="WallpaperPathTextBlock"
|
||||
@@ -423,7 +426,8 @@
|
||||
Foreground="{DynamicResource AdaptiveTextAccentBrush}"
|
||||
Text="未选择壁纸" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
<TextBlock x:Name="WallpaperPlacementLabelTextBlock"
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="显示方式" />
|
||||
@@ -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="浏览图片" />
|
||||
<Button Padding="12,6"
|
||||
<Button x:Name="ClearWallpaperButton"
|
||||
Padding="12,6"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Click="OnClearWallpaperClick"
|
||||
Content="恢复纯色" />
|
||||
@@ -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="日夜模式" />
|
||||
<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="时间组件">
|
||||
<ui:SettingsExpander x:Name="StatusBarClockSettingsExpander"
|
||||
Header="时间组件">
|
||||
<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="在顶部状态栏显示时钟。" />
|
||||
</Grid>
|
||||
</ui:SettingsExpander>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel x:Name="RegionSettingsPanel"
|
||||
IsVisible="False"
|
||||
Spacing="14">
|
||||
<TextBlock x:Name="RegionPanelTitleTextBlock"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="地区" />
|
||||
<TextBlock x:Name="RegionPanelDescriptionTextBlock"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="选择语言,立即应用到设置与主要界面。" />
|
||||
|
||||
<ui:SettingsExpander x:Name="LanguageSettingsExpander"
|
||||
Header="语言">
|
||||
<Grid ColumnDefinitions="Auto,*"
|
||||
ColumnSpacing="12">
|
||||
<TextBlock x:Name="LanguageLabelTextBlock"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="语言" />
|
||||
<ComboBox x:Name="LanguageComboBox"
|
||||
Grid.Column="1"
|
||||
Width="220"
|
||||
SelectionChanged="OnLanguageSelectionChanged">
|
||||
<ComboBoxItem x:Name="LanguageChineseItem" Tag="zh-CN" Content="中文" />
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user