mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
165 lines
5.0 KiB
C#
165 lines
5.0 KiB
C#
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",
|
|
"MacOS9",
|
|
"DOS",
|
|
"Amiga",
|
|
"CDE"
|
|
};
|
|
|
|
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("ColorPalette") != 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)
|
|
{
|
|
string themeFile = themeName switch
|
|
{
|
|
"Windows311" => "ms-appx:///Styles/Win311ColorPalette.xaml",
|
|
"MacOS9" => "ms-appx:///Styles/MacOS9ColorPalette.xaml",
|
|
"DOS" => "ms-appx:///Styles/DOSColorPalette.xaml",
|
|
"Amiga" => "ms-appx:///Styles/AmigaColorPalette.xaml",
|
|
"CDE" => "ms-appx:///Styles/CDEColorPalette.xaml",
|
|
_ => null
|
|
};
|
|
|
|
if(themeFile != null)
|
|
{
|
|
var newDictionary = new ResourceDictionary
|
|
{
|
|
Source = new Uri(themeFile)
|
|
};
|
|
|
|
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
|
|
}
|
|
}
|
|
} |