mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-22 09:23:53 +08:00
Refactor WaveSpiritAdorner Color Retrieve
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="AtomUI"/>
|
||||
<InternalsVisibleTo Include="AtomUI.Controls"/>
|
||||
<InternalsVisibleTo Include="AtomUI.Theme"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -59,4 +59,11 @@ public enum ColorNameFormat
|
||||
{
|
||||
HexRgb,
|
||||
HexArgb
|
||||
}
|
||||
|
||||
internal static class AtomUILogArea
|
||||
{
|
||||
public const string Theme = "Theme";
|
||||
public const string Control = "Control";
|
||||
public const string System = "System";
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Theme;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.LogicalTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@@ -28,6 +30,27 @@ public class LineEdit : TextBox
|
||||
|
||||
#endregion
|
||||
|
||||
#region 内部属性定义
|
||||
|
||||
private ControlTokenResourceRegister _controlTokenResourceRegister;
|
||||
private bool _initialized;
|
||||
#endregion
|
||||
|
||||
public LineEdit()
|
||||
{
|
||||
_controlTokenResourceRegister = new ControlTokenResourceRegister(this, LineEditToken.ID);
|
||||
}
|
||||
|
||||
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
if (!_initialized)
|
||||
{
|
||||
_controlTokenResourceRegister.RegisterResources();
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
@@ -115,7 +116,59 @@ internal class WaveSpiritAdorner : Control, IDisposable
|
||||
{
|
||||
_targetControl = targetControl;
|
||||
_targetControl.PropertyChanged += HandleTargetControlChanged;
|
||||
var sharedToken = TokenFinderUtils.FindSharedToken(_targetControl!);
|
||||
var sharedToken = TokenFinderUtils.FindSharedToken(_targetControl!);
|
||||
var themeVariant = TokenFinderUtils.FindThemeVariant(_targetControl);
|
||||
|
||||
CornerRadius? borderRadius = null;
|
||||
// 获取相关值
|
||||
{
|
||||
if (_targetControl.TryGetResource(SharedTokenKey.BorderRadius, themeVariant, out var value))
|
||||
{
|
||||
if (value is CornerRadius cornerRadius)
|
||||
{
|
||||
borderRadius = cornerRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
borderRadius ??= sharedToken.BorderRadius;
|
||||
|
||||
TimeSpan? motionDurationSlow = null;
|
||||
{
|
||||
if (_targetControl.TryGetResource(SharedTokenKey.MotionDurationSlow, themeVariant, out var value))
|
||||
{
|
||||
if (value is TimeSpan timeSpan)
|
||||
{
|
||||
motionDurationSlow = timeSpan;
|
||||
}
|
||||
}
|
||||
}
|
||||
motionDurationSlow ??= sharedToken.MotionDurationSlow;
|
||||
|
||||
double? waveStartOpacity = null;
|
||||
{
|
||||
if (_targetControl.TryGetResource(SharedTokenKey.WaveStartOpacity, themeVariant, out var value))
|
||||
{
|
||||
if (value is double dvalue)
|
||||
{
|
||||
waveStartOpacity = dvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
waveStartOpacity ??= sharedToken.WaveStartOpacity;
|
||||
|
||||
double? waveAnimationRange = null;
|
||||
{
|
||||
if (_targetControl.TryGetResource(SharedTokenKey.WaveAnimationRange, themeVariant, out var value))
|
||||
{
|
||||
if (value is double dvalue)
|
||||
{
|
||||
waveAnimationRange = dvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
waveAnimationRange ??= sharedToken.WaveAnimationRange;
|
||||
|
||||
if (waveType == WaveType.CircleWave)
|
||||
{
|
||||
_wavePainter = new CircleWavePainter();
|
||||
@@ -127,24 +180,34 @@ internal class WaveSpiritAdorner : Control, IDisposable
|
||||
else
|
||||
{
|
||||
var roundWavePainter = new RoundRectWavePainter();
|
||||
roundWavePainter.CornerRadius = sharedToken.BorderRadius;
|
||||
roundWavePainter.CornerRadius = borderRadius.Value;
|
||||
_wavePainter = roundWavePainter;
|
||||
}
|
||||
|
||||
var motionDurationSlow = sharedToken.MotionDurationSlow;
|
||||
|
||||
_wavePainter.SizeEasingCurve = new CubicEaseOut();
|
||||
_wavePainter.OpacityEasingCurve = new CubicEaseOut();
|
||||
_wavePainter.OriginOpacity = Math.Clamp(sharedToken.WaveStartOpacity, 0.0, 1.0);
|
||||
_wavePainter.SizeMotionDuration = motionDurationSlow;
|
||||
_wavePainter.OpacityMotionDuration = motionDurationSlow.Add(TimeSpan.FromMilliseconds(50));
|
||||
_wavePainter.WaveRange = Math.Min(sharedToken.WaveAnimationRange, 8);
|
||||
_wavePainter.OriginOpacity = Math.Clamp(waveStartOpacity.Value, 0.0, 1.0);
|
||||
_wavePainter.SizeMotionDuration = motionDurationSlow.Value;
|
||||
_wavePainter.OpacityMotionDuration = motionDurationSlow.Value.Add(TimeSpan.FromMilliseconds(50));
|
||||
_wavePainter.WaveRange = Math.Min(waveAnimationRange.Value, 8);
|
||||
if (waveColor is not null)
|
||||
{
|
||||
_wavePainter.WaveColor = waveColor.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_wavePainter.WaveColor = sharedToken.ColorPrimary;
|
||||
Color? colorPrimary = null;
|
||||
{
|
||||
if (_targetControl.TryGetResource(SharedTokenKey.ColorPrimary, themeVariant, out var value))
|
||||
{
|
||||
if (value is Color color)
|
||||
{
|
||||
colorPrimary = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
colorPrimary ??= sharedToken.ColorPrimary;
|
||||
_wavePainter.WaveColor = colorPrimary.Value;
|
||||
}
|
||||
|
||||
LayoutUpdated += HandleLayoutUpdated;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using Avalonia.Metadata;
|
||||
|
||||
namespace AtomUI.Theme;
|
||||
|
||||
public class ControlTokenInfoSetter
|
||||
{
|
||||
public bool EnableAlgorithm { get; set; } = false;
|
||||
|
||||
[Content]
|
||||
public List<TokenSetter> Setters { get; set; } = new ();
|
||||
|
||||
public string? Catalog { get; set; }
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ControlTokenResourceRegister
|
||||
private Control _target;
|
||||
private string _tokenId;
|
||||
private string? _resourceCatalog;
|
||||
private IResourceDictionary? _resourceDictionary;
|
||||
private ResourceDictionary? _resourceDictionary;
|
||||
|
||||
public ControlTokenResourceRegister(Control target, string tokenId, string? resourceCatalog = null)
|
||||
{
|
||||
@@ -34,8 +34,9 @@ public class ControlTokenResourceRegister
|
||||
{
|
||||
_resourceDictionary.Add(entry.Key, entry.Value);
|
||||
}
|
||||
|
||||
_target.Resources.MergedDictionaries.Add(_resourceDictionary);
|
||||
|
||||
var themeVariant = TokenFinderUtils.FindThemeVariant(_target);
|
||||
_target.Resources.ThemeDictionaries.Add(themeVariant, _resourceDictionary);
|
||||
}
|
||||
|
||||
private IControlDesignToken? FindControlToken()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AtomUI.Theme.TokenSystem;
|
||||
using Avalonia.Styling;
|
||||
|
||||
namespace AtomUI.Theme;
|
||||
|
||||
@@ -9,4 +10,5 @@ public interface IThemeConfigProvider
|
||||
IControlDesignToken? GetControlToken(string tokenId, string? catalog = null);
|
||||
List<string> Algorithms { get; }
|
||||
bool IsDarkMode { get; }
|
||||
ThemeVariant ThemeVariant { get; }
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public abstract class AbstractControlDesignToken : AbstractDesignToken, IControl
|
||||
}
|
||||
}
|
||||
|
||||
_sharedResourceDeltaDictionary.Add(name, localSharedTokenValue);
|
||||
_sharedResourceDeltaDictionary.Add(new TokenResourceKey(name), localSharedTokenValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Logging;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Theme.TokenSystem;
|
||||
@@ -33,28 +35,33 @@ public abstract class AbstractDesignToken : IDesignToken
|
||||
try
|
||||
{
|
||||
var type = GetType();
|
||||
var tokenProperties =
|
||||
type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
|
||||
foreach (var property in tokenProperties)
|
||||
var tokenPropertyMap =
|
||||
type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
|
||||
.ToDictionary(p => p.Name);
|
||||
foreach (var tokenInfo in tokenConfigInfo)
|
||||
{
|
||||
var tokenName = property.Name;
|
||||
if (tokenConfigInfo.ContainsKey(tokenName))
|
||||
var tokenName = tokenInfo.Key;
|
||||
if (!tokenPropertyMap.ContainsKey(tokenInfo.Key))
|
||||
{
|
||||
var propertyType = property.PropertyType;
|
||||
if (_valueConverters.ContainsKey(propertyType))
|
||||
var logger = Logger.TryGet(LogEventLevel.Warning, AtomUILogArea.Theme);
|
||||
logger?.Log(this, $"Token property: '{tokenInfo.Key}' found in token {type.Name}.'");
|
||||
continue;
|
||||
}
|
||||
var property = tokenPropertyMap[tokenName];
|
||||
var propertyType = property.PropertyType;
|
||||
if (_valueConverters.ContainsKey(propertyType))
|
||||
{
|
||||
property.SetValue(this, _valueConverters[propertyType].Convert(tokenConfigInfo[tokenName]));
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
property.SetValue(this, _valueConverters[propertyType].Convert(tokenConfigInfo[tokenName]));
|
||||
property.SetValue(tokenName, tokenConfigInfo[tokenName]);
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
property.SetValue(tokenName, tokenConfigInfo[tokenName]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Unable to set token property: {tokenName}, maybe value type mismatch.", ex);
|
||||
}
|
||||
throw new InvalidOperationException($"Unable to set token property: {tokenName}, maybe value type mismatch.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,4 +60,28 @@ internal static class TokenFinderUtils
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public static ThemeVariant FindThemeVariant(Control control)
|
||||
{
|
||||
ThemeVariant? themeVariant = null;
|
||||
var current = control;
|
||||
while (current != null)
|
||||
{
|
||||
if (current is IThemeConfigProvider configProvider)
|
||||
{
|
||||
themeVariant = configProvider.ThemeVariant;
|
||||
break;
|
||||
}
|
||||
|
||||
current = (current as IStyleHost).StylingParent as Control;
|
||||
}
|
||||
|
||||
if (themeVariant is null)
|
||||
{
|
||||
var theme = ThemeManager.Current.ActivatedTheme;
|
||||
Debug.Assert(theme != null);
|
||||
themeVariant = theme.ThemeVariant;
|
||||
}
|
||||
return themeVariant;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user