From 887e3f76d2a2b4a3973237fa93bf958b065ece26 Mon Sep 17 00:00:00 2001 From: ww-rm Date: Fri, 3 Oct 2025 19:38:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A8=8B=E5=BA=8F=E7=9A=AE?= =?UTF-8?q?=E8=82=A4=E9=A6=96=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SpineViewer/App.xaml.cs | 29 ++++++ SpineViewer/Models/PreferenceModel.cs | 3 + SpineViewer/Resources/AppResource.cs | 97 ++++++++++++++++++- SpineViewer/Resources/Strings/en.xaml | 1 + SpineViewer/Resources/Strings/ja.xaml | 1 + SpineViewer/Resources/Strings/zh.xaml | 1 + .../MainWindow/PreferenceViewModel.cs | 10 ++ SpineViewer/Views/MainWindow.xaml | 1 + SpineViewer/Views/PreferenceDialog.xaml | 13 ++- 9 files changed, 154 insertions(+), 2 deletions(-) diff --git a/SpineViewer/App.xaml.cs b/SpineViewer/App.xaml.cs index b9eb044..5411bf8 100644 --- a/SpineViewer/App.xaml.cs +++ b/SpineViewer/App.xaml.cs @@ -349,6 +349,28 @@ namespace SpineViewer } } private AppLanguage _language = AppLanguage.ZH; + + public AppSkin Skin + { + get => _skin; + set + { + var uri = $"Resources/Skins/{value.ToString().ToLower()}.xaml"; + try + { + Resources.MergedDictionaries.Add(new() { Source = new(uri, UriKind.Relative) }); + Resources.MergedDictionaries.Add(new() { Source = new("Resources/Theme.xaml", UriKind.Relative) }); + _skin = value; + } + catch (Exception ex) + { + _logger.Error("Failed to switch skin to {0}, {1}", value, ex.Message); + _logger.Trace(ex.ToString()); + } + } + } + private AppSkin _skin = AppSkin.Light; + } public enum AppLanguage @@ -357,4 +379,11 @@ namespace SpineViewer EN, JA } + + public enum AppSkin + { + Light, + Dark, + Violet, + } } diff --git a/SpineViewer/Models/PreferenceModel.cs b/SpineViewer/Models/PreferenceModel.cs index 2ae88ec..4ae94d6 100644 --- a/SpineViewer/Models/PreferenceModel.cs +++ b/SpineViewer/Models/PreferenceModel.cs @@ -86,6 +86,9 @@ namespace SpineViewer.Models [ObservableProperty] private AppLanguage _appLanguage; + [ObservableProperty] + private AppSkin _appSkin; + [ObservableProperty] private bool _renderSelectedOnly; diff --git a/SpineViewer/Resources/AppResource.cs b/SpineViewer/Resources/AppResource.cs index aa6926b..7fdcf4f 100644 --- a/SpineViewer/Resources/AppResource.cs +++ b/SpineViewer/Resources/AppResource.cs @@ -12,7 +12,102 @@ namespace SpineViewer.Resources /// public static class AppResource { - public static T Get(string key) => (T)App.Current.FindResource(key); + private static T Get(string key) => (T)App.Current.FindResource(key); + + #region Colors + + public static Color Color_LightPrimary => Get("LightPrimaryColor"); + public static Color Color_Primary => Get("PrimaryColor"); + public static Color Color_DarkPrimary => Get("DarkPrimaryColor"); + + public static Color Color_LightDanger => Get("LightDangerColor"); + public static Color Color_Danger => Get("DangerColor"); + public static Color Color_DarkDanger => Get("DarkDangerColor"); + + public static Color Color_LightWarning => Get("LightWarningColor"); + public static Color Color_Warning => Get("WarningColor"); + public static Color Color_DarkWarning => Get("DarkWarningColor"); + + public static Color Color_LightInfo => Get("LightInfoColor"); + public static Color Color_Info => Get("InfoColor"); + public static Color Color_DarkInfo => Get("DarkInfoColor"); + + public static Color Color_LightSuccess => Get("LightSuccessColor"); + public static Color Color_Success => Get("SuccessColor"); + public static Color Color_DarkSuccess => Get("DarkSuccessColor"); + + public static Color Color_PrimaryText => Get("PrimaryTextColor"); + public static Color Color_SecondaryText => Get("SecondaryTextColor"); + public static Color Color_ThirdlyText => Get("ThirdlyTextColor"); + public static Color Color_ReverseText => Get("ReverseTextColor"); + public static Color Color_TextIcon => Get("TextIconColor"); + + public static Color Color_Border => Get("BorderColor"); + public static Color Color_SecondaryBorder => Get("SecondaryBorderColor"); + public static Color Color_Background => Get("BackgroundColor"); + public static Color Color_Region => Get("RegionColor"); + public static Color Color_SecondaryRegion => Get("SecondaryRegionColor"); + public static Color Color_ThirdlyRegion => Get("ThirdlyRegionColor"); + public static Color Color_Title => Get("TitleColor"); + public static Color Color_SecondaryTitle => Get("SecondaryTitleColor"); + + public static Color Color_Default => Get("DefaultColor"); + public static Color Color_DarkDefault => Get("DarkDefaultColor"); + + public static Color Color_Accent => Get("AccentColor"); + public static Color Color_DarkAccent => Get("DarkAccentColor"); + + public static Color Color_DarkMask => Get("DarkMaskColor"); + public static Color Color_DarkOpacity => Get("DarkOpacityColor"); + + #endregion + + #region Brushes + + public static SolidColorBrush Brush_LightPrimary => Get("LightPrimaryBrush"); + public static LinearGradientBrush Brush_Primary => Get("PrimaryBrush"); + public static SolidColorBrush Brush_DarkPrimary => Get("DarkPrimaryBrush"); + + public static SolidColorBrush Brush_PrimaryText => Get("PrimaryTextBrush"); + public static SolidColorBrush Brush_SecondaryText => Get("SecondaryTextBrush"); + public static SolidColorBrush Brush_ThirdlyText => Get("ThirdlyTextBrush"); + public static SolidColorBrush Brush_ReverseText => Get("ReverseTextBrush"); + public static SolidColorBrush Brush_TextIcon => Get("TextIconBrush"); + + public static SolidColorBrush Brush_Border => Get("BorderBrush"); + public static SolidColorBrush Brush_SecondaryBorder => Get("SecondaryBorderBrush"); + public static SolidColorBrush Brush_Background => Get("BackgroundBrush"); + public static SolidColorBrush Brush_Region => Get("RegionBrush"); + public static SolidColorBrush Brush_SecondaryRegion => Get("SecondaryRegionBrush"); + public static SolidColorBrush Brush_ThirdlyRegion => Get("ThirdlyRegionBrush"); + public static LinearGradientBrush Brush_Title => Get("TitleBrush"); + + public static SolidColorBrush Brush_Default => Get("DefaultBrush"); + public static SolidColorBrush Brush_DarkDefault => Get("DarkDefaultBrush"); + + public static SolidColorBrush Brush_LightDanger => Get("LightDangerBrush"); + public static LinearGradientBrush Brush_Danger => Get("DangerBrush"); + public static SolidColorBrush Brush_DarkDanger => Get("DarkDangerBrush"); + + public static SolidColorBrush Brush_LightWarning => Get("LightWarningBrush"); + public static LinearGradientBrush Brush_Warning => Get("WarningBrush"); + public static SolidColorBrush Brush_DarkWarning => Get("DarkWarningBrush"); + + public static SolidColorBrush Brush_LightInfo => Get("LightInfoBrush"); + public static LinearGradientBrush Brush_Info => Get("InfoBrush"); + public static SolidColorBrush Brush_DarkInfo => Get("DarkInfoBrush"); + + public static SolidColorBrush Brush_LightSuccess => Get("LightSuccessBrush"); + public static LinearGradientBrush Brush_Success => Get("SuccessBrush"); + public static SolidColorBrush Brush_DarkSuccess => Get("DarkSuccessBrush"); + + public static SolidColorBrush Brush_Accent => Get("AccentBrush"); + public static SolidColorBrush Brush_DarkAccent => Get("DarkAccentBrush"); + + public static SolidColorBrush Brush_DarkMask => Get("DarkMaskBrush"); + public static SolidColorBrush Brush_DarkOpacity => Get("DarkOpacityBrush"); + + #endregion #region Strings diff --git a/SpineViewer/Resources/Strings/en.xaml b/SpineViewer/Resources/Strings/en.xaml index 0ddc1af..386cf0d 100644 --- a/SpineViewer/Resources/Strings/en.xaml +++ b/SpineViewer/Resources/Strings/en.xaml @@ -244,6 +244,7 @@ Application Options Language + Skin Minimize to tray when closing Auto Start Auto-load Workspace File on Startup diff --git a/SpineViewer/Resources/Strings/ja.xaml b/SpineViewer/Resources/Strings/ja.xaml index 39ce6bc..8dff2b9 100644 --- a/SpineViewer/Resources/Strings/ja.xaml +++ b/SpineViewer/Resources/Strings/ja.xaml @@ -244,6 +244,7 @@ アプリケーションプション 言語 + スキン 閉じるときにトレイに最小化する 自動起動 起動時にワークスペースファイルを自動読み込み diff --git a/SpineViewer/Resources/Strings/zh.xaml b/SpineViewer/Resources/Strings/zh.xaml index 9eef84f..d99a38b 100644 --- a/SpineViewer/Resources/Strings/zh.xaml +++ b/SpineViewer/Resources/Strings/zh.xaml @@ -244,6 +244,7 @@ 应用程序选项 语言 + 皮肤 关闭时最小化至托盘图标 开机自启 自启动加载工作区文件 diff --git a/SpineViewer/ViewModels/MainWindow/PreferenceViewModel.cs b/SpineViewer/ViewModels/MainWindow/PreferenceViewModel.cs index b2f5530..41d42a8 100644 --- a/SpineViewer/ViewModels/MainWindow/PreferenceViewModel.cs +++ b/SpineViewer/ViewModels/MainWindow/PreferenceViewModel.cs @@ -109,6 +109,7 @@ namespace SpineViewer.ViewModels.MainWindow DebugClippings = DebugClippings, AppLanguage = AppLanguage, + AppSkin = AppSkin, RenderSelectedOnly = RenderSelectedOnly, HitTestLevel = HitTestLevel, LogHitSlots = LogHitSlots, @@ -140,6 +141,7 @@ namespace SpineViewer.ViewModels.MainWindow DebugClippings = value.DebugClippings; AppLanguage = value.AppLanguage; + AppSkin = value.AppSkin; RenderSelectedOnly = value.RenderSelectedOnly; HitTestLevel = value.HitTestLevel; LogHitSlots = value.LogHitSlots; @@ -253,6 +255,8 @@ namespace SpineViewer.ViewModels.MainWindow public static ImmutableArray AppLanguageOptions { get; } = Enum.GetValues().ToImmutableArray(); + public static ImmutableArray AppSkinOptions { get; } = Enum.GetValues().ToImmutableArray(); + public static ImmutableArray HitTestLevelOptions { get; } = Enum.GetValues().ToImmutableArray(); public AppLanguage AppLanguage @@ -261,6 +265,12 @@ namespace SpineViewer.ViewModels.MainWindow set => SetProperty(((App)App.Current).Language, value, v => ((App)App.Current).Language = v); } + public AppSkin AppSkin + { + get => ((App)App.Current).Skin; + set => SetProperty(((App)App.Current).Skin, value, v => ((App)App.Current).Skin = v); + } + public bool RenderSelectedOnly { get => _vmMain.SFMLRendererViewModel.RenderSelectedOnly; diff --git a/SpineViewer/Views/MainWindow.xaml b/SpineViewer/Views/MainWindow.xaml index 656894b..2999035 100644 --- a/SpineViewer/Views/MainWindow.xaml +++ b/SpineViewer/Views/MainWindow.xaml @@ -11,6 +11,7 @@ mc:Ignorable="d" x:Name="_mainWindow" Title="{Binding Title}" + Background="{DynamicResource RegionBrush}" Width="1500" Height="800" WindowStartupLocation="CenterScreen" diff --git a/SpineViewer/Views/PreferenceDialog.xaml b/SpineViewer/Views/PreferenceDialog.xaml index 9853e40..03a75c5 100644 --- a/SpineViewer/Views/PreferenceDialog.xaml +++ b/SpineViewer/Views/PreferenceDialog.xaml @@ -208,7 +208,18 @@ SelectedItem="{Binding AppLanguage}" ItemsSource="{x:Static vm:PreferenceViewModel.AppLanguageOptions}"/> - + + + + + + + +