ThemeProvider.razor.cs
using System;
using System.Collections.Generic;
using BetterUI.Extensions;
namespace BetterUI;
/// <summary>
/// A panel that manages the global theme.
/// </summary>
/// <remarks>
/// Use this panel to set the theme of your UI.
/// </remarks>
public sealed partial class ThemeProvider : Panel
{
/// <summary>
/// The current theme.
/// </summary>
public Theme Theme { get; private set; }
/// <summary>
/// The mode of theme injection.
/// </summary>
/// <remarks>
/// Theme injection is the process of automatically passing the theme to all children
/// of this panel. This enum specifies the mode of theme injection.
/// </remarks>
public ThemeInjectionMode InjectionMode { get; set; } = ThemeInjectionMode.Manual;
/// <inheritdoc />
protected override void OnAfterTreeRender( bool firstTime )
{
EnsureThemeUpdated();
}
private void EnsureThemeUpdated()
{
switch ( InjectionMode )
{
case ThemeInjectionMode.Direct:
IterateChildren( Children );
break;
case ThemeInjectionMode.Descendents:
IterateChildren( Descendants );
break;
}
}
private void IterateChildren( IEnumerable<Panel> panels )
{
foreach ( var child in panels )
ApplyThemeToPanel( child );
}
private void ApplyThemeToPanel( Panel panel )
{
var type = TypeLibrary.GetType( panel.GetType() );
var attr = type.GetAttribute<InjectThemeAttribute>();
if ( attr is null ) return;
panel.BindClass( "light", () => Theme is Theme.Light );
panel.BindClass( "dark", () => Theme is Theme.Dark );
}
/// <summary>
/// Sets the theme.
/// </summary>
/// <param name="theme">The new theme.</param>
public void SetTheme( Theme theme )
{
Theme = theme;
Scene.RunSceneEvent<IThemeEvent>( x => x.OnThemeChanged( theme ) );
}
/// <summary>
/// Switches the theme to the opposite one.
/// </summary>
public void SwitchTheme() => SetTheme( Theme is Theme.Light ? Theme.Dark : Theme.Light );
/// <inheritdoc />
protected override int BuildHash() => HashCode.Combine( Theme, InjectionMode );
}