Add ThemeVariantCalculatorFactory

This commit is contained in:
qinware
2025-08-08 17:09:07 +08:00
parent 87e8475f5b
commit aa6f521423
6 changed files with 55 additions and 32 deletions
+2
View File
@@ -1,5 +1,6 @@
using System.Globalization;
using AtomUI.Theme.Language;
using AtomUI.Theme.Styling;
using Avalonia;
namespace AtomUI.Theme;
@@ -23,4 +24,5 @@ public interface IThemeManagerBuilder
void WithDefaultTheme(string themeId);
void WithDefaultCultureInfo(CultureInfo cultureInfo);
void WithDefaultLanguageVariant(LanguageVariant languageVariant);
void WithThemeVariantCalculatorFactory(IThemeVariantCalculatorFactory factory);
}
@@ -0,0 +1,6 @@
namespace AtomUI.Theme.Styling;
public interface IThemeVariantCalculatorFactory
{
IThemeVariantCalculator Create(ThemeAlgorithm algorithm, IThemeVariantCalculator? baseAlgorithm);
}
+5 -26
View File
@@ -47,8 +47,9 @@ internal class Theme : AvaloniaObject, ITheme
private bool _isBuiltIn;
private bool _isPrimary;
private IList<ThemeAlgorithm> _algorithms;
private ThemeManager _themeManager;
public Theme(string id, string defFilePath, ISet<ThemeAlgorithm> requestAlgorithms, bool isBuiltIn = false)
public Theme(ThemeManager themeManager, string id, string defFilePath, ISet<ThemeAlgorithm> requestAlgorithms, bool isBuiltIn = false)
{
_id = id;
_isBuiltIn = isBuiltIn;
@@ -71,6 +72,7 @@ internal class Theme : AvaloniaObject, ITheme
}
_themeVariant = BuildThemeVariant(id, _algorithms);
_themeManager = themeManager;
}
public List<string> ThemeResourceKeys => ResourceDictionary.Keys.Select(s => s.ToString()!).ToList();
@@ -122,7 +124,7 @@ internal class Theme : AvaloniaObject, ITheme
IThemeVariantCalculator? calculator = null;
foreach (var algorithmId in algorithms)
{
calculator = CreateThemeVariantCalculator(algorithmId, baseCalculator);
calculator = _themeManager.CreateThemeVariantCalculator(algorithmId, baseCalculator);
baseCalculator = calculator;
}
@@ -217,7 +219,7 @@ internal class Theme : AvaloniaObject, ITheme
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy)
.Select(p => p.Name).ToHashSet();
.Select(p => p.Name).ToHashSet();
foreach (var entry in controlTokenConfigInfo.Tokens)
{
if (!tokenProperties.Contains(entry.Key))
@@ -244,29 +246,6 @@ internal class Theme : AvaloniaObject, ITheme
return algorithms;
}
internal static IThemeVariantCalculator CreateThemeVariantCalculator(ThemeAlgorithm algorithm, IThemeVariantCalculator? baseAlgorithm)
{
IThemeVariantCalculator calculator;
if (algorithm == DefaultThemeVariantCalculator.Algorithm)
{
calculator = new DefaultThemeVariantCalculator();
}
else if (algorithm == DarkThemeVariantCalculator.Algorithm)
{
calculator = new DarkThemeVariantCalculator(baseAlgorithm!);
}
else if (algorithm == CompactThemeVariantCalculator.Algorithm)
{
calculator = new CompactThemeVariantCalculator(baseAlgorithm!);
}
else
{
throw new ThemeLoadException($"Algorithm: {algorithm} is not supported.");
}
return calculator;
}
protected void CollectControlTokens()
{
ControlTokens.Clear();
+1 -1
View File
@@ -140,7 +140,7 @@ public class ThemeConfigProvider : Control, IThemeConfigProvider
IThemeVariantCalculator? calculator = null;
foreach (var algorithm in algorithms)
{
calculator = AtomUITheme.CreateThemeVariantCalculator(algorithm, baseCalculator);
calculator = ThemeManager.Current.CreateThemeVariantCalculator(algorithm, baseCalculator);
baseCalculator = calculator;
}
+31 -4
View File
@@ -1,5 +1,6 @@
using System.Diagnostics;
using AtomUI.Theme.Language;
using AtomUI.Theme.Styling;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Platform;
@@ -37,7 +38,8 @@ internal class ThemeManager : Styles, IThemeManager
public string DefaultThemeId { get; set; }
internal List<Type> ControlTokenTypes { get; set; }
internal IThemeVariantCalculatorFactory? ThemeVariantCalculatorFactory { get; set; }
public event EventHandler<ThemeOperateEventArgs>? ThemeCreated;
public event EventHandler<ThemeOperateEventArgs>? ThemeAboutToLoad;
public event EventHandler<ThemeOperateEventArgs>? ThemeLoaded;
@@ -61,8 +63,8 @@ internal class ThemeManager : Styles, IThemeManager
internal ThemeManager()
{
_themePool = new Dictionary<ThemeVariant, Theme>();
_customThemeDirs = new List<string>();
_themePool = new Dictionary<ThemeVariant, Theme>();
_customThemeDirs = new List<string>();
var appName = Application.Current?.Name ?? DEFAULT_APP_NAME;
_builtInThemeDirs = [Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), appName),
THEME_DIR)];
@@ -284,7 +286,7 @@ internal class ThemeManager : Styles, IThemeManager
var themeId = Path.GetFileNameWithoutExtension(filePath);
foreach (var algorithms in algorithmsCombination)
{
var theme = new Theme(themeId, filePath, algorithms ,isBuiltIn);
var theme = new Theme(this, themeId, filePath, algorithms ,isBuiltIn);
var themeVariant = theme.ThemeVariant;
if (themes.ContainsKey(themeVariant))
{
@@ -362,6 +364,31 @@ internal class ThemeManager : Styles, IThemeManager
Resources.MergedDictionaries.Add(languageResource);
}
}
internal IThemeVariantCalculator CreateThemeVariantCalculator(ThemeAlgorithm algorithm, IThemeVariantCalculator? baseCalculator)
{
if (ThemeVariantCalculatorFactory != null)
{
return ThemeVariantCalculatorFactory.Create(algorithm, baseCalculator);
}
if (algorithm == ThemeAlgorithm.Default)
{
return new DefaultThemeVariantCalculator();
}
if (algorithm == ThemeAlgorithm.Dark)
{
Debug.Assert(baseCalculator is not null);
return new DarkThemeVariantCalculator(baseCalculator);
}
if (algorithm == ThemeAlgorithm.Compact)
{
Debug.Assert(baseCalculator is not null);
return new CompactThemeVariantCalculator(baseCalculator);
}
throw new ArgumentOutOfRangeException(nameof(algorithm), $"Unsupported theme variant algorithm: {algorithm}");
}
}
public class ThemeOperateEventArgs : EventArgs
+10 -1
View File
@@ -1,5 +1,6 @@
using System.Globalization;
using AtomUI.Theme.Language;
using AtomUI.Theme.Styling;
using Avalonia;
namespace AtomUI.Theme;
@@ -12,6 +13,8 @@ internal class ThemeManagerBuilder : IThemeManagerBuilder
public IList<IControlThemesProvider> ControlThemesProviders { get; }
public IList<LanguageProvider> LanguageProviders { get; }
public IList<EventHandler> InitializedHandlers { get; }
public IThemeVariantCalculatorFactory? ThemeVariantCalculatorFactory { get; internal set; }
public LanguageVariant LanguageVariant { get; private set; }
public string ThemeId { get; private set; }
@@ -101,7 +104,8 @@ internal class ThemeManagerBuilder : IThemeManagerBuilder
internal ThemeManager Build()
{
var themeManager = new ThemeManager();
themeManager.DefaultThemeId = ThemeId;
themeManager.DefaultThemeId = ThemeId;
themeManager.ThemeVariantCalculatorFactory = ThemeVariantCalculatorFactory;
foreach (var controlThemesProvider in ControlThemesProviders)
{
themeManager.RegisterControlThemesProvider(controlThemesProvider);
@@ -129,4 +133,9 @@ internal class ThemeManagerBuilder : IThemeManagerBuilder
return themeManager;
}
public void WithThemeVariantCalculatorFactory(IThemeVariantCalculatorFactory factory)
{
ThemeVariantCalculatorFactory = factory;
}
}