From 1e52b9933abbc577cebf798d2ddf110388697c4b Mon Sep 17 00:00:00 2001 From: Orbmu2k Date: Mon, 23 Mar 2026 19:56:18 +0100 Subject: [PATCH] refactored thememanager --- .../Common/Helper/UserSettings.cs | 2 + .../Services/ThemeManager.cs | 205 +++++++++--------- .../UI/Styles/Applications.xaml | 4 +- .../UI/Themes/DarkTheme.xaml | 1 + .../UI/Themes/LightTheme.xaml | 4 +- .../UI/Themes/SlateLightTheme.xaml | 3 +- .../UI/ViewModels/MainViewModel.cs | 1 + 7 files changed, 112 insertions(+), 108 deletions(-) diff --git a/nvidiaProfileInspector/Common/Helper/UserSettings.cs b/nvidiaProfileInspector/Common/Helper/UserSettings.cs index e022dc6..e0227a3 100644 --- a/nvidiaProfileInspector/Common/Helper/UserSettings.cs +++ b/nvidiaProfileInspector/Common/Helper/UserSettings.cs @@ -30,6 +30,8 @@ namespace nvidiaProfileInspector.Common.Helper public List FavoriteSettingIds { get; set; } = new List(); +public string Theme { get; set; } = "DarkTheme.xaml"; + private static string GetSettingsFilename() { var fiPortalbleSettings = new FileInfo("settings.xml"); diff --git a/nvidiaProfileInspector/Services/ThemeManager.cs b/nvidiaProfileInspector/Services/ThemeManager.cs index 0003d84..4ba4eff 100644 --- a/nvidiaProfileInspector/Services/ThemeManager.cs +++ b/nvidiaProfileInspector/Services/ThemeManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows; @@ -6,143 +7,49 @@ using nvidiaProfileInspector.Common.Helper; namespace nvidiaProfileInspector.Services { - /// - /// Manages application themes including loading, saving, and switching themes. - /// public class ThemeManager { private const string DarkTheme = "DarkTheme.xaml"; - private const string LightTheme = "LightTheme.xaml"; private const string SlateLightTheme = "SlateLightTheme.xaml"; - private static readonly string[] ValidThemes = { DarkTheme, LightTheme, SlateLightTheme }; + private static readonly string[] ValidThemes = { + DarkTheme, + SlateLightTheme + }; - /// - /// Gets the current theme name. - /// public string CurrentTheme { get; private set; } - /// - /// Initializes a new instance of the ThemeManager class. - /// public ThemeManager() { LoadSavedTheme(); } - /// - /// Loads the saved theme from user settings or defaults to DarkTheme. - /// public void LoadSavedTheme() { try { var settings = UserSettings.LoadSettings(); - var themeName = settings.Theme ?? DarkTheme; - - // Ensure themeName has .xaml extension - if (!themeName.EndsWith(".xaml")) - themeName = DarkTheme; - - // Validate theme - if (!ValidThemes.Contains(themeName)) - themeName = DarkTheme; - - CurrentTheme = themeName; - ApplyTheme(themeName); + ApplyAndPersistTheme(NormalizeThemeName(settings.Theme), savePreference: false); } catch { - // Default to dark theme on error - CurrentTheme = DarkTheme; - ApplyTheme(DarkTheme); + ApplyAndPersistTheme(DarkTheme, savePreference: false); } } - /// - /// Toggles to the next theme in the sequence: Dark -> Light -> SlateLight -> Dark. - /// public void ToggleTheme() { try { - var app = Application.Current; - if (app == null) return; - - var mergedDicts = app.Resources.MergedDictionaries; - var existingTheme = mergedDicts.FirstOrDefault(d => - d.Source != null && (d.Source.OriginalString.Contains(DarkTheme) || - d.Source.OriginalString.Contains(LightTheme) || - d.Source.OriginalString.Contains(SlateLightTheme))); - - string newSource; - if (existingTheme != null) - { - if (existingTheme.Source.OriginalString.Contains(DarkTheme)) - newSource = LightTheme; - else if (existingTheme.Source.OriginalString.Contains(LightTheme)) - newSource = SlateLightTheme; - else if (existingTheme.Source.OriginalString.Contains(SlateLightTheme)) - newSource = DarkTheme; - else - newSource = DarkTheme; // fallback - - // Update the theme dictionary - mergedDicts.Remove(existingTheme); - mergedDicts.Add(new ResourceDictionary { Source = new Uri($"/UI/Themes/{newSource}", UriKind.Relative) }); - } - else - { - // No theme found, apply dark theme - newSource = DarkTheme; - ApplyTheme(newSource); - } - - // Save the new theme preference - CurrentTheme = newSource; - SaveThemePreference(newSource); + var currentTheme = GetCurrentAppliedThemeName(); + ApplyAndPersistTheme(GetNextThemeName(currentTheme), savePreference: true); } catch (Exception ex) { - // Log error but don't crash System.Diagnostics.Debug.WriteLine($"Error toggling theme: {ex.Message}"); } } - /// - /// Applies the specified theme to the application resources. - /// - /// The name of the theme to apply. - private void ApplyTheme(string themeName) - { - try - { - var app = Application.Current; - if (app == null) return; - - var mergedDicts = app.Resources.MergedDictionaries; - var themeDict = mergedDicts.FirstOrDefault(d => - d.Source != null && (d.Source.OriginalString.Contains("DarkTheme.xaml") || - d.Source.OriginalString.Contains("LightTheme.xaml") || - d.Source.OriginalString.Contains("SlateLightTheme.xaml"))); - - if (themeDict != null) - { - string newSource = $"/UI/Themes/{themeName}"; - mergedDicts.Remove(themeDict); - mergedDicts.Add(new ResourceDictionary { Source = new Uri(newSource, UriKind.Relative) }); - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"Error applying theme: {ex.Message}"); - } - } - - /// - /// Saves the theme preference to user settings. - /// - /// The name of the theme to save. private void SaveThemePreference(string themeName) { try @@ -156,5 +63,97 @@ namespace nvidiaProfileInspector.Services System.Diagnostics.Debug.WriteLine($"Error saving theme preference: {ex.Message}"); } } + + private static ResourceDictionary GetThemeDictionary(IList mergedDicts) + { + return mergedDicts.FirstOrDefault(d => GetThemeName(d.Source) != null); + } + + private static string GetCurrentAppliedThemeName() + { + var app = Application.Current; + if (app == null) + return null; + + return GetThemeName(GetThemeDictionary(app.Resources.MergedDictionaries)?.Source); + } + + private static string GetThemeName(Uri source) + { + if (source == null) + return null; + + var themeName = Path.GetFileName(source.OriginalString); + return ValidThemes.FirstOrDefault(validTheme => + string.Equals(validTheme, themeName, StringComparison.OrdinalIgnoreCase)); + } + + private static string NormalizeThemeName(string themeName) + { + if (string.IsNullOrWhiteSpace(themeName)) + return DarkTheme; + + if (!themeName.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)) + return DarkTheme; + + return ValidThemes.FirstOrDefault(validTheme => + string.Equals(validTheme, themeName, StringComparison.OrdinalIgnoreCase)) + ?? DarkTheme; + } + + private static string GetNextThemeName(string currentTheme) + { + if (ValidThemes.Length == 0) + return DarkTheme; + + if (string.IsNullOrWhiteSpace(currentTheme)) + return ValidThemes[0]; + + var currentThemeIndex = Array.FindIndex( + ValidThemes, + theme => string.Equals(theme, currentTheme, StringComparison.OrdinalIgnoreCase)); + + if (currentThemeIndex < 0) + return ValidThemes[0]; + + var nextThemeIndex = (currentThemeIndex + 1) % ValidThemes.Length; + return ValidThemes[nextThemeIndex]; + } + + private void ApplyAndPersistTheme(string themeName, bool savePreference) + { + var app = Application.Current; + if (app == null) + return; + + var normalizedThemeName = NormalizeThemeName(themeName); + var mergedDicts = app.Resources.MergedDictionaries; + var themeDict = GetThemeDictionary(mergedDicts); + + ReplaceThemeDictionary(mergedDicts, themeDict, normalizedThemeName); + + CurrentTheme = normalizedThemeName; + + if (savePreference) + SaveThemePreference(normalizedThemeName); + } + + private static void ReplaceThemeDictionary(IList mergedDicts, ResourceDictionary existingTheme, string themeName) + { + var newThemeDictionary = new ResourceDictionary + { + Source = new Uri($"/UI/Themes/{themeName}", UriKind.Relative) + }; + + if (existingTheme == null) + { + mergedDicts.Add(newThemeDictionary); + return; + } + + var index = mergedDicts.IndexOf(existingTheme); + mergedDicts.RemoveAt(index); + mergedDicts.Insert(index, newThemeDictionary); + } } -} \ No newline at end of file +} diff --git a/nvidiaProfileInspector/UI/Styles/Applications.xaml b/nvidiaProfileInspector/UI/Styles/Applications.xaml index 43b3c79..687ff2b 100644 --- a/nvidiaProfileInspector/UI/Styles/Applications.xaml +++ b/nvidiaProfileInspector/UI/Styles/Applications.xaml @@ -50,9 +50,9 @@ - + - + diff --git a/nvidiaProfileInspector/UI/Themes/DarkTheme.xaml b/nvidiaProfileInspector/UI/Themes/DarkTheme.xaml index 995f5a5..1a17b43 100644 --- a/nvidiaProfileInspector/UI/Themes/DarkTheme.xaml +++ b/nvidiaProfileInspector/UI/Themes/DarkTheme.xaml @@ -66,6 +66,7 @@ + diff --git a/nvidiaProfileInspector/UI/Themes/LightTheme.xaml b/nvidiaProfileInspector/UI/Themes/LightTheme.xaml index df3ec41..cf94fa0 100644 --- a/nvidiaProfileInspector/UI/Themes/LightTheme.xaml +++ b/nvidiaProfileInspector/UI/Themes/LightTheme.xaml @@ -56,7 +56,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/nvidiaProfileInspector/UI/Themes/SlateLightTheme.xaml b/nvidiaProfileInspector/UI/Themes/SlateLightTheme.xaml index d5124fe..a6d8aa9 100644 --- a/nvidiaProfileInspector/UI/Themes/SlateLightTheme.xaml +++ b/nvidiaProfileInspector/UI/Themes/SlateLightTheme.xaml @@ -10,7 +10,7 @@ #E8EAED - #76B900 + #66A900 #8AD400 #659F00 @@ -76,6 +76,7 @@ + diff --git a/nvidiaProfileInspector/UI/ViewModels/MainViewModel.cs b/nvidiaProfileInspector/UI/ViewModels/MainViewModel.cs index bcf1631..aab41f8 100644 --- a/nvidiaProfileInspector/UI/ViewModels/MainViewModel.cs +++ b/nvidiaProfileInspector/UI/ViewModels/MainViewModel.cs @@ -956,6 +956,7 @@ using System.Windows.Input; { var themeManager = App.Bootstrapper.Resolve(); themeManager.ToggleTheme(); + RefreshCurrentProfile(); } }