| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- using System;
- using System.Collections.Generic;
- using Avalonia.Animation;
- using Avalonia.Controls;
- using Avalonia.Metadata;
- using Avalonia.PropertyStore;
- using Avalonia.Styling.Activators;
- namespace Avalonia.Styling
- {
- /// <summary>
- /// Base class for <see cref="Style"/> and <see cref="ControlTheme"/>.
- /// </summary>
- public abstract class StyleBase : AvaloniaObject, IStyle, IResourceProvider
- {
- private IResourceHost? _owner;
- private StyleChildren? _children;
- private IResourceDictionary? _resources;
- private List<ISetter>? _setters;
- private List<IAnimation>? _animations;
- private StyleInstance? _sharedInstance;
- public IList<IStyle> Children => _children ??= new(this);
- public IResourceHost? Owner
- {
- get => _owner;
- private set
- {
- if (_owner != value)
- {
- _owner = value;
- OwnerChanged?.Invoke(this, EventArgs.Empty);
- }
- }
- }
- public IStyle? Parent { get; private set; }
- public IResourceDictionary Resources
- {
- get => _resources ?? (Resources = new ResourceDictionary());
- set
- {
- value = value ?? throw new ArgumentNullException(nameof(value));
- var hadResources = _resources?.HasResources ?? false;
- _resources = value;
- if (Owner is object)
- {
- _resources.AddOwner(Owner);
- if (hadResources || _resources.HasResources)
- {
- Owner.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
- }
- }
- }
- }
- public IList<ISetter> Setters => _setters ??= new List<ISetter>();
- public IList<IAnimation> Animations => _animations ??= new List<IAnimation>();
- bool IResourceNode.HasResources => _resources?.Count > 0;
- IReadOnlyList<IStyle> IStyle.Children => (IReadOnlyList<IStyle>?)_children ?? Array.Empty<IStyle>();
- internal bool HasChildren => _children?.Count > 0;
- internal bool HasSettersOrAnimations => _setters?.Count > 0 || _animations?.Count > 0;
- public void Add(ISetter setter) => Setters.Add(setter);
- public void Add(IStyle style) => Children.Add(style);
- public event EventHandler? OwnerChanged;
- public bool TryGetResource(object key, out object? result)
- {
- if (_resources is not null && _resources.TryGetResource(key, out result))
- return true;
- if (_children is not null)
- {
- for (var i = 0; i < _children.Count; ++i)
- {
- if (_children[i].TryGetResource(key, out result))
- return true;
- }
- }
- result= null;
- return false;
- }
- internal abstract SelectorMatchResult TryAttach(IStyleable target, object? host);
- internal ValueFrame Attach(IStyleable target, IStyleActivator? activator)
- {
- if (target is not AvaloniaObject ao)
- throw new InvalidOperationException("Styles can only be applied to AvaloniaObjects.");
- StyleInstance instance;
- if (_sharedInstance is not null)
- {
- instance = _sharedInstance;
- }
- else
- {
- var canShareInstance = activator is null;
- instance = new StyleInstance(this, activator);
- if (_setters is not null)
- {
- foreach (var setter in _setters)
- {
- var setterInstance = setter.Instance(instance, target);
- instance.Add(setterInstance);
- canShareInstance &= setterInstance == setter;
- }
- }
- if (_animations is not null)
- instance.Add(_animations);
- if (canShareInstance)
- {
- instance.MakeShared();
- _sharedInstance = instance;
- }
- }
- ao.GetValueStore().AddFrame(instance);
- instance.ApplyAnimations(ao);
- return instance;
- }
- internal virtual void SetParent(StyleBase? parent) => Parent = parent;
- void IResourceProvider.AddOwner(IResourceHost owner)
- {
- owner = owner ?? throw new ArgumentNullException(nameof(owner));
- if (Owner != null)
- {
- throw new InvalidOperationException("The Style already has a parent.");
- }
- Owner = owner;
- _resources?.AddOwner(owner);
- }
- void IResourceProvider.RemoveOwner(IResourceHost owner)
- {
- owner = owner ?? throw new ArgumentNullException(nameof(owner));
- if (Owner == owner)
- {
- Owner = null;
- _resources?.RemoveOwner(owner);
- }
- }
- }
- }
|