mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Add theming and a Windows 3.11 inspired theme.
This commit is contained in:
148
Marechai.App/Services/ColorThemeService.cs
Normal file
148
Marechai.App/Services/ColorThemeService.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Uno.Extensions.Toolkit;
|
||||
|
||||
namespace Marechai.App.Services;
|
||||
|
||||
public interface IColorThemeService
|
||||
{
|
||||
string CurrentColorTheme { get; }
|
||||
IReadOnlyList<string> AvailableColorThemes { get; }
|
||||
void ApplyColorTheme(string themeName);
|
||||
void SetThemeService(IThemeService themeService);
|
||||
void ReapplyCurrentTheme();
|
||||
}
|
||||
|
||||
public class ColorThemeService : IColorThemeService
|
||||
{
|
||||
private const string COLOR_THEME_KEY = "ColorTheme";
|
||||
private const string DEFAULT_THEME = "Default";
|
||||
private IThemeService _themeService;
|
||||
|
||||
public ColorThemeService()
|
||||
{
|
||||
LoadSavedTheme();
|
||||
}
|
||||
|
||||
public string CurrentColorTheme { get; private set; } = DEFAULT_THEME;
|
||||
|
||||
public IReadOnlyList<string> AvailableColorThemes => new List<string>
|
||||
{
|
||||
DEFAULT_THEME,
|
||||
"Windows311"
|
||||
};
|
||||
|
||||
public void SetThemeService(IThemeService themeService)
|
||||
{
|
||||
_themeService = themeService;
|
||||
|
||||
// Reapply the current theme now that we have the theme service
|
||||
if(CurrentColorTheme != DEFAULT_THEME) ReapplyCurrentTheme();
|
||||
}
|
||||
|
||||
public void ReapplyCurrentTheme()
|
||||
{
|
||||
// Force refresh of the current theme
|
||||
ApplyColorTheme(CurrentColorTheme);
|
||||
}
|
||||
|
||||
public void ApplyColorTheme(string themeName)
|
||||
{
|
||||
if(!AvailableColorThemes.Contains(themeName)) return;
|
||||
|
||||
CurrentColorTheme = themeName;
|
||||
|
||||
// Save preference
|
||||
try
|
||||
{
|
||||
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
|
||||
localSettings.Values[COLOR_THEME_KEY] = themeName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail
|
||||
}
|
||||
|
||||
// Apply the theme by rebuilding merged dictionaries
|
||||
Application app = Application.Current;
|
||||
|
||||
if(app?.Resources == null) return;
|
||||
|
||||
// Store the existing merged dictionaries (except color overrides)
|
||||
var existingDictionaries = app.Resources.MergedDictionaries
|
||||
.Where(d => d.Source?.OriginalString?.Contains("ColorPaletteOverride") != true)
|
||||
.ToList();
|
||||
|
||||
// Clear all merged dictionaries
|
||||
app.Resources.MergedDictionaries.Clear();
|
||||
|
||||
// Re-add the existing dictionaries
|
||||
foreach(ResourceDictionary dict in existingDictionaries) app.Resources.MergedDictionaries.Add(dict);
|
||||
|
||||
// Add the new color theme if not default
|
||||
if(themeName != DEFAULT_THEME)
|
||||
{
|
||||
var newDictionary = new ResourceDictionary
|
||||
{
|
||||
Source = new Uri("ms-appx:///Styles/ColorPaletteOverride.xaml")
|
||||
};
|
||||
|
||||
app.Resources.MergedDictionaries.Add(newDictionary);
|
||||
}
|
||||
|
||||
// Force UI refresh by toggling the theme temporarily
|
||||
ForceThemeRefresh();
|
||||
}
|
||||
|
||||
private void LoadSavedTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
|
||||
|
||||
if(localSettings.Values.ContainsKey(COLOR_THEME_KEY))
|
||||
{
|
||||
var savedTheme = localSettings.Values[COLOR_THEME_KEY] as string;
|
||||
|
||||
if(!string.IsNullOrEmpty(savedTheme) && AvailableColorThemes.Contains(savedTheme))
|
||||
{
|
||||
CurrentColorTheme = savedTheme;
|
||||
ApplyColorTheme(CurrentColorTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If loading fails, use default theme
|
||||
}
|
||||
}
|
||||
|
||||
private async void ForceThemeRefresh()
|
||||
{
|
||||
if(_themeService == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
// Get current theme
|
||||
AppTheme currentTheme = _themeService.Theme;
|
||||
|
||||
// Toggle to opposite theme briefly
|
||||
AppTheme tempTheme = currentTheme == AppTheme.Light ? AppTheme.Dark : AppTheme.Light;
|
||||
await _themeService.SetThemeAsync(tempTheme);
|
||||
|
||||
// Small delay to ensure the change is applied
|
||||
await Task.Delay(50);
|
||||
|
||||
// Switch back to original theme
|
||||
await _themeService.SetThemeAsync(currentTheme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Silently fail
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user