зеркало из https://github.com/AvaloniaUI/Avalonia.git
ResourceProvider upgrade (#16928)
* Implement AvaloniaObject on ResourceProvider * ColorPaletteResources and ColorPaletteResourcesCollection should inherit ResourceProvider * Use ResourceProvider in tests too * Adjust API diff --------- Co-authored-by: Steven Kirk <grokys@users.noreply.github.com>
This commit is contained in:
Родитель
932f54316b
Коммит
c50e731d8d
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0007</DiagnosticId>
|
||||
<Target>T:Avalonia.Themes.Fluent.ColorPaletteResources</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0008</DiagnosticId>
|
||||
<Target>T:Avalonia.Themes.Fluent.ColorPaletteResources</Target>
|
||||
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
|
||||
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
|
||||
</Suppression>
|
||||
</Suppressions>
|
|
@ -7,7 +7,7 @@ namespace Avalonia.Controls;
|
|||
/// Base implementation for IResourceProvider interface.
|
||||
/// Includes Owner property management.
|
||||
/// </summary>
|
||||
public abstract class ResourceProvider : IResourceProvider
|
||||
public abstract class ResourceProvider : AvaloniaObject, IResourceProvider
|
||||
{
|
||||
private IResourceHost? _owner;
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@ namespace Avalonia.Themes.Fluent;
|
|||
/// <remarks>
|
||||
/// This class can only be used in <see cref="FluentTheme.Palettes"/>.
|
||||
/// </remarks>
|
||||
public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
|
||||
public partial class ColorPaletteResources : ResourceProvider
|
||||
{
|
||||
private readonly Dictionary<string, Color> _colors = new(StringComparer.InvariantCulture);
|
||||
|
||||
public bool HasResources => _hasAccentColor || _colors.Count > 0;
|
||||
public override bool HasResources => _hasAccentColor || _colors.Count > 0;
|
||||
|
||||
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
public override bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
{
|
||||
if (key is string strKey)
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
|
|||
|
||||
return default;
|
||||
}
|
||||
|
||||
|
||||
private void SetColor(string key, Color value)
|
||||
{
|
||||
if (value == default)
|
||||
|
@ -113,6 +113,7 @@ public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
|
|||
_accentColorLight1, _accentColorLight2, _accentColorLight3) =
|
||||
SystemAccentColors.CalculateAccentShades(_accentColor);
|
||||
}
|
||||
RaiseResourcesChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace Avalonia.Themes.Fluent;
|
||||
|
||||
internal class ColorPaletteResourcesCollection : AvaloniaDictionary<ThemeVariant, ColorPaletteResources>, IResourceProvider
|
||||
internal sealed class ColorPaletteResourcesCollection : ResourceProvider, IDictionary<ThemeVariant, ColorPaletteResources>
|
||||
{
|
||||
public ColorPaletteResourcesCollection() : base(2)
|
||||
private readonly AvaloniaDictionary<ThemeVariant, ColorPaletteResources> _inner;
|
||||
|
||||
public ColorPaletteResourcesCollection()
|
||||
{
|
||||
this.ForEachItem(
|
||||
_inner = new AvaloniaDictionary<ThemeVariant, ColorPaletteResources>(2);
|
||||
_inner.ForEachItem(
|
||||
(key, x) =>
|
||||
{
|
||||
if (Owner is not null)
|
||||
{
|
||||
x.PropertyChanged += Palette_PropertyChanged;
|
||||
((IResourceProvider)x).AddOwner(Owner);
|
||||
}
|
||||
|
||||
if (key != ThemeVariant.Dark && key != ThemeVariant.Light)
|
||||
|
@ -27,21 +33,21 @@ internal class ColorPaletteResourcesCollection : AvaloniaDictionary<ThemeVariant
|
|||
{
|
||||
if (Owner is not null)
|
||||
{
|
||||
x.PropertyChanged -= Palette_PropertyChanged;
|
||||
((IResourceProvider)x).RemoveOwner(Owner);
|
||||
}
|
||||
},
|
||||
() => throw new NotSupportedException("Dictionary reset not supported"));
|
||||
}
|
||||
|
||||
public bool HasResources => Count > 0;
|
||||
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
public override bool HasResources => _inner.Count > 0;
|
||||
public override bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
{
|
||||
if (theme == null || theme == ThemeVariant.Default)
|
||||
{
|
||||
theme = ThemeVariant.Light;
|
||||
}
|
||||
|
||||
if (base.TryGetValue(theme, out var themePaletteResources)
|
||||
if (_inner.TryGetValue(theme, out var themePaletteResources)
|
||||
&& themePaletteResources.TryGetResource(key, theme, out value))
|
||||
{
|
||||
return true;
|
||||
|
@ -51,25 +57,94 @@ internal class ColorPaletteResourcesCollection : AvaloniaDictionary<ThemeVariant
|
|||
return false;
|
||||
}
|
||||
|
||||
public IResourceHost? Owner { get; private set; }
|
||||
public event EventHandler? OwnerChanged;
|
||||
public void AddOwner(IResourceHost owner)
|
||||
protected override void OnAddOwner(IResourceHost owner)
|
||||
{
|
||||
Owner = owner;
|
||||
OwnerChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void RemoveOwner(IResourceHost owner)
|
||||
{
|
||||
Owner = null;
|
||||
OwnerChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void Palette_PropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.Property == ColorPaletteResources.AccentProperty)
|
||||
base.OnAddOwner(owner);
|
||||
foreach (var palette in _inner.Values)
|
||||
{
|
||||
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
|
||||
((IResourceProvider)palette).AddOwner(owner);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRemoveOwner(IResourceHost owner)
|
||||
{
|
||||
base.OnRemoveOwner(owner);
|
||||
foreach (var palette in _inner.Values)
|
||||
{
|
||||
((IResourceProvider)palette).RemoveOwner(owner);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<ThemeVariant, ColorPaletteResources>> IEnumerable<KeyValuePair<ThemeVariant, ColorPaletteResources>>.GetEnumerator()
|
||||
{
|
||||
return _inner.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)_inner).GetEnumerator();
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.Add(KeyValuePair<ThemeVariant, ColorPaletteResources> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>)_inner).Add(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.Clear()
|
||||
{
|
||||
_inner.Clear();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.Contains(KeyValuePair<ThemeVariant, ColorPaletteResources> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>)_inner).Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.CopyTo(KeyValuePair<ThemeVariant, ColorPaletteResources>[] array, int arrayIndex)
|
||||
{
|
||||
_inner.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.Remove(KeyValuePair<ThemeVariant, ColorPaletteResources> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>)_inner).Remove(item);
|
||||
}
|
||||
|
||||
int ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.Count => _inner.Count;
|
||||
|
||||
bool ICollection<KeyValuePair<ThemeVariant, ColorPaletteResources>>.IsReadOnly => _inner.IsReadOnly;
|
||||
|
||||
void IDictionary<ThemeVariant, ColorPaletteResources>.Add(ThemeVariant key, ColorPaletteResources value)
|
||||
{
|
||||
_inner.Add(key, value);
|
||||
}
|
||||
|
||||
bool IDictionary<ThemeVariant, ColorPaletteResources>.ContainsKey(ThemeVariant key)
|
||||
{
|
||||
return _inner.ContainsKey(key);
|
||||
}
|
||||
|
||||
bool IDictionary<ThemeVariant, ColorPaletteResources>.Remove(ThemeVariant key)
|
||||
{
|
||||
return _inner.Remove(key);
|
||||
}
|
||||
|
||||
bool IDictionary<ThemeVariant, ColorPaletteResources>.TryGetValue(ThemeVariant key,
|
||||
#if NET6_0_OR_GREATER
|
||||
[MaybeNullWhen(false)]
|
||||
#endif
|
||||
out ColorPaletteResources value)
|
||||
{
|
||||
return _inner.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
ColorPaletteResources IDictionary<ThemeVariant, ColorPaletteResources>.this[ThemeVariant key]
|
||||
{
|
||||
get => _inner[key];
|
||||
set => _inner[key] = value;
|
||||
}
|
||||
|
||||
ICollection<ThemeVariant> IDictionary<ThemeVariant, ColorPaletteResources>.Keys => _inner.Keys;
|
||||
|
||||
ICollection<ColorPaletteResources> IDictionary<ThemeVariant, ColorPaletteResources>.Values => _inner.Values;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Avalonia.Themes.Fluent
|
|||
get => _densityStyle;
|
||||
set => SetAndRaise(DensityStyleProperty, ref _densityStyle, value);
|
||||
}
|
||||
|
||||
|
||||
public IDictionary<ThemeVariant, ColorPaletteResources> Palettes { get; }
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
|
|
|
@ -991,18 +991,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
|
|||
}
|
||||
}
|
||||
|
||||
public class TrackingResourceProvider : IResourceProvider
|
||||
public class TrackingResourceProvider : ResourceProvider
|
||||
{
|
||||
public IResourceHost Owner { get; private set; }
|
||||
public bool HasResources => true;
|
||||
public override bool HasResources => true;
|
||||
public List<object> RequestedResources { get; } = new List<object>();
|
||||
|
||||
public event EventHandler OwnerChanged { add { } remove { } }
|
||||
|
||||
public void AddOwner(IResourceHost owner) => Owner = owner;
|
||||
public void RemoveOwner(IResourceHost owner) => Owner = null;
|
||||
|
||||
public bool TryGetResource(object key, ThemeVariant themeVariant, out object value)
|
||||
public override bool TryGetResource(object key, ThemeVariant themeVariant, out object value)
|
||||
{
|
||||
RequestedResources.Add(key);
|
||||
value = key;
|
||||
|
|
|
@ -127,25 +127,13 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
|
|||
}
|
||||
|
||||
// See https://github.com/AvaloniaUI/Avalonia/issues/11172
|
||||
public class LocaleCollection : IResourceProvider
|
||||
public class LocaleCollection : ResourceProvider
|
||||
{
|
||||
private readonly Dictionary<object, IResourceProvider> _langs = new();
|
||||
|
||||
public override bool HasResources => true;
|
||||
|
||||
public IResourceHost? Owner { get; private set; }
|
||||
|
||||
public bool HasResources => true;
|
||||
|
||||
public event EventHandler? OwnerChanged
|
||||
{
|
||||
add { }
|
||||
remove { }
|
||||
}
|
||||
|
||||
public void AddOwner(IResourceHost owner) => Owner = owner;
|
||||
|
||||
public void RemoveOwner(IResourceHost owner) => Owner = null;
|
||||
|
||||
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
public override bool TryGetResource(object key, ThemeVariant? theme, out object? value)
|
||||
{
|
||||
if (_langs.TryGetValue("English", out var res))
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче