feat: add demo, sync theme from scope.
This commit is contained in:
@@ -3,11 +3,13 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.LogicalTree;
|
||||
using Avalonia.Styling;
|
||||
using Ursa.Common;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public abstract class ThemeSelectorBase: TemplatedControl
|
||||
{
|
||||
private bool _syncFromScope;
|
||||
private Application? _application;
|
||||
private ThemeVariantScope? _scope;
|
||||
|
||||
@@ -33,17 +35,81 @@ public abstract class ThemeSelectorBase: TemplatedControl
|
||||
static ThemeSelectorBase()
|
||||
{
|
||||
SelectedThemeProperty.Changed.AddClassHandler<ThemeSelectorBase, ThemeVariant?>((s, e) => s.OnSelectedThemeChanged(e));
|
||||
TargetScopeProperty.Changed.AddClassHandler<ThemeSelectorBase, ThemeVariantScope?>((s, e) => s.OnTargetScopeChanged(e));
|
||||
}
|
||||
|
||||
private void OnTargetScopeChanged(AvaloniaPropertyChangedEventArgs<ThemeVariantScope?> args)
|
||||
{
|
||||
var target = args.NewValue.Value;
|
||||
if (target is not null)
|
||||
{
|
||||
SyncThemeFromScope(target.ActualThemeVariant);
|
||||
target.ActualThemeVariantChanged += OnScopeThemeChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScopeThemeChanged(object sender, EventArgs e)
|
||||
{
|
||||
_syncFromScope = true;
|
||||
if (this.TargetScope is { } target)
|
||||
{
|
||||
SyncThemeFromScope(target.ActualThemeVariant);
|
||||
}
|
||||
else if (this._scope is { } scope)
|
||||
{
|
||||
SyncThemeFromScope(scope.ActualThemeVariant);
|
||||
}
|
||||
else if (_application is { } app)
|
||||
{
|
||||
SyncThemeFromScope(app.ActualThemeVariant);
|
||||
}
|
||||
_syncFromScope = false;
|
||||
}
|
||||
|
||||
protected internal virtual void SyncThemeFromScope(ThemeVariant? theme)
|
||||
{
|
||||
this.SelectedTheme = theme;
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
_application = Application.Current;
|
||||
if (_application is not null)
|
||||
{
|
||||
_application.ActualThemeVariantChanged += OnScopeThemeChanged;
|
||||
SyncThemeFromScope(_application.ActualThemeVariant);
|
||||
}
|
||||
_scope = this.GetLogicalAncestors().FirstOrDefault(a => a is ThemeVariantScope) as ThemeVariantScope;
|
||||
if (_scope is not null)
|
||||
{
|
||||
_scope.ActualThemeVariantChanged += OnScopeThemeChanged;
|
||||
SyncThemeFromScope(_scope.ActualThemeVariant);
|
||||
}
|
||||
|
||||
if (TargetScope is not null)
|
||||
{
|
||||
SyncThemeFromScope(TargetScope.ActualThemeVariant);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
if (_application is not null)
|
||||
{
|
||||
_application.ActualThemeVariantChanged -= OnScopeThemeChanged;
|
||||
}
|
||||
|
||||
if (_scope is not null)
|
||||
{
|
||||
_scope.ActualThemeVariantChanged -= OnScopeThemeChanged;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedThemeChanged(AvaloniaPropertyChangedEventArgs<ThemeVariant?> args)
|
||||
{
|
||||
if (_syncFromScope) return;
|
||||
ThemeVariant? newTheme = args.NewValue.Value;
|
||||
if (newTheme is null) return;
|
||||
if (TargetScope is not null)
|
||||
|
||||
Reference in New Issue
Block a user