mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-22 00:46:48 +08:00
Refactor LoadingIndicator
This commit is contained in:
@@ -228,18 +228,19 @@ public class Expander : AvaloniaExpander,
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, BorderThicknessProperty,
|
||||
SharedTokenKey.BorderThickness,
|
||||
BindingPriority.Template, new RenderScaleAwareThicknessConfigure(this)));
|
||||
SetupEffectiveBorderThickness();
|
||||
SetupExpanderBorderThickness();
|
||||
SetupDefaultIcon();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
SetupDefaultIcon();
|
||||
base.OnApplyTemplate(e);
|
||||
this.RunThemeTokenBindingActions();
|
||||
_motionActor = e.NameScope.Find<MotionActorControl>(ExpanderTheme.ContentMotionActorPart);
|
||||
_headerDecorator = e.NameScope.Find<Border>(ExpanderTheme.HeaderDecoratorPart);
|
||||
_expandButton = e.NameScope.Find<IconButton>(ExpanderTheme.ExpandButtonPart);
|
||||
SetupEffectiveBorderThickness();
|
||||
SetupExpanderBorderThickness();
|
||||
|
||||
_tempAnimationDisabled = true;
|
||||
HandleExpandedChanged();
|
||||
_tempAnimationDisabled = false;
|
||||
@@ -276,16 +277,12 @@ public class Expander : AvaloniaExpander,
|
||||
|
||||
SetupDefaultIcon();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.IsAttachedToVisualTree())
|
||||
{
|
||||
if (change.Property == IsBorderlessProperty)
|
||||
else if (change.Property == IsBorderlessProperty)
|
||||
{
|
||||
SetupEffectiveBorderThickness();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (change.Property == ExpandIconProperty)
|
||||
{
|
||||
if (change.OldValue is Icon oldIcon)
|
||||
|
||||
@@ -192,17 +192,6 @@ public class FlyoutHost : Control,
|
||||
{
|
||||
base.OnAttachedToLogicalTree(e);
|
||||
_tokenBindingsDisposable = new CompositeDisposable();
|
||||
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, MarginToAnchorProperty, SharedTokenKey.MarginXXS));
|
||||
|
||||
BindUtils.RelayBind(this, AnchorTargetProperty, _flyoutStateHelper, FlyoutStateHelper.AnchorTargetProperty);
|
||||
BindUtils.RelayBind(this, FlyoutProperty, _flyoutStateHelper, FlyoutStateHelper.FlyoutProperty);
|
||||
BindUtils.RelayBind(this, MouseEnterDelayProperty, _flyoutStateHelper,
|
||||
FlyoutStateHelper.MouseEnterDelayProperty);
|
||||
BindUtils.RelayBind(this, MouseLeaveDelayProperty, _flyoutStateHelper,
|
||||
FlyoutStateHelper.MouseLeaveDelayProperty);
|
||||
BindUtils.RelayBind(this, TriggerProperty, _flyoutStateHelper, FlyoutStateHelper.TriggerTypeProperty);
|
||||
SetupFlyoutProperties();
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
|
||||
@@ -214,7 +203,16 @@ public class FlyoutHost : Control,
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
BindUtils.RelayBind(this, AnchorTargetProperty, _flyoutStateHelper, FlyoutStateHelper.AnchorTargetProperty);
|
||||
BindUtils.RelayBind(this, FlyoutProperty, _flyoutStateHelper, FlyoutStateHelper.FlyoutProperty);
|
||||
BindUtils.RelayBind(this, MouseEnterDelayProperty, _flyoutStateHelper,
|
||||
FlyoutStateHelper.MouseEnterDelayProperty);
|
||||
BindUtils.RelayBind(this, MouseLeaveDelayProperty, _flyoutStateHelper,
|
||||
FlyoutStateHelper.MouseLeaveDelayProperty);
|
||||
BindUtils.RelayBind(this, TriggerProperty, _flyoutStateHelper, FlyoutStateHelper.TriggerTypeProperty);
|
||||
SetupFlyoutProperties();
|
||||
_flyoutStateHelper.NotifyAttachedToVisualTree();
|
||||
this.AddTokenBindingDisposable(TokenResourceBinder.CreateTokenBinding(this, MarginToAnchorProperty, SharedTokenKey.MarginXXS));
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
|
||||
@@ -113,12 +113,6 @@ public class TextBox : AvaloniaTextBox,
|
||||
this.RegisterResources();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
SetupEffectiveShowClearButton();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
@@ -130,13 +124,11 @@ public class TextBox : AvaloniaTextBox,
|
||||
{
|
||||
SetupEffectiveShowClearButton();
|
||||
}
|
||||
|
||||
if (change.Property == StatusProperty)
|
||||
else if (change.Property == StatusProperty)
|
||||
{
|
||||
UpdatePseudoClasses();
|
||||
}
|
||||
|
||||
if (change.Property == InnerLeftContentProperty ||
|
||||
else if (change.Property == InnerLeftContentProperty ||
|
||||
change.Property == InnerRightContentProperty)
|
||||
{
|
||||
if (change.OldValue is Control oldControl)
|
||||
@@ -179,4 +171,10 @@ public class TextBox : AvaloniaTextBox,
|
||||
base.OnDetachedFromLogicalTree(e);
|
||||
this.DisposeTokenBindings();
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
SetupEffectiveShowClearButton();
|
||||
}
|
||||
}
|
||||
@@ -70,4 +70,10 @@ public class ListBoxItem : AvaloniaListBoxItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
SetupTransitions();
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ using Avalonia;
|
||||
using Avalonia.Animation;
|
||||
using Avalonia.Animation.Easings;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Transformation;
|
||||
using Avalonia.Styling;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@@ -122,7 +122,7 @@ public class LoadingIndicator : TemplatedControl,
|
||||
get => _indicatorAngle;
|
||||
set => SetAndRaise(IndicatorAngleProperty, ref _indicatorAngle, value);
|
||||
}
|
||||
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => LoadingIndicatorToken.ID;
|
||||
|
||||
@@ -130,8 +130,8 @@ public class LoadingIndicator : TemplatedControl,
|
||||
|
||||
private Animation? _animation;
|
||||
private TextBlock? _loadingText;
|
||||
private Canvas? _mainContainer;
|
||||
private RenderInfo? _renderInfo;
|
||||
private ContentPresenter? _customIndicatorIconPresenter;
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
|
||||
internal const double LARGE_INDICATOR_SIZE = 48;
|
||||
@@ -154,7 +154,7 @@ public class LoadingIndicator : TemplatedControl,
|
||||
{
|
||||
this.RegisterResources();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
@@ -173,60 +173,40 @@ public class LoadingIndicator : TemplatedControl,
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
base.OnPropertyChanged(e);
|
||||
if (this.IsAttachedToVisualTree())
|
||||
if (e.Property == CustomIndicatorIconProperty)
|
||||
{
|
||||
if (e.Property == CustomIndicatorIconProperty)
|
||||
if (e.OldValue is Icon oldIcon)
|
||||
{
|
||||
var oldCustomIcon = e.GetOldValue<Icon?>();
|
||||
if (oldCustomIcon is not null)
|
||||
{
|
||||
_mainContainer?.Children.Remove(oldCustomIcon);
|
||||
}
|
||||
oldIcon.SetTemplatedParent(null);
|
||||
}
|
||||
|
||||
SetupCustomIndicator();
|
||||
if (e.NewValue is Icon newIcon)
|
||||
{
|
||||
newIcon.SetTemplatedParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.Property == IndicatorAngleProperty)
|
||||
{
|
||||
if (CustomIndicatorIcon is not null)
|
||||
{
|
||||
HandleIndicatorAngleChanged();
|
||||
}
|
||||
HandleIndicatorAngleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
HandleTemplateApplied(e.NameScope);
|
||||
}
|
||||
|
||||
private void HandleTemplateApplied(INameScope scope)
|
||||
{
|
||||
_mainContainer = scope.Find<Canvas>(LoadingIndicatorTheme.MainContainerPart);
|
||||
_loadingText = scope.Find<TextBlock>(LoadingIndicatorTheme.LoadingTextPart);
|
||||
|
||||
SetupCustomIndicator();
|
||||
_loadingText = e.NameScope.Find<TextBlock>(LoadingIndicatorTheme.LoadingTextPart);
|
||||
_customIndicatorIconPresenter =
|
||||
e.NameScope.Find<ContentPresenter>(LoadingIndicatorTheme.CustomIndicatorIconPresenterPart);
|
||||
}
|
||||
|
||||
// 只在使用自定义的 Icon 的时候有效
|
||||
private void HandleIndicatorAngleChanged()
|
||||
{
|
||||
if (CustomIndicatorIcon is not null)
|
||||
if (_customIndicatorIconPresenter is not null && _customIndicatorIconPresenter.IsVisible)
|
||||
{
|
||||
var builder = new TransformOperations.Builder(1);
|
||||
builder.AppendRotate(MathUtils.Deg2Rad(IndicatorAngle));
|
||||
CustomIndicatorIcon.RenderTransform = builder.Build();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupCustomIndicator()
|
||||
{
|
||||
if (CustomIndicatorIcon is not null)
|
||||
{
|
||||
CustomIndicatorIcon.SetTemplatedParent(this);
|
||||
_mainContainer?.Children.Insert(0, CustomIndicatorIcon);
|
||||
_customIndicatorIconPresenter.RenderTransform = builder.Build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,11 @@ using AtomUI.Theme;
|
||||
using AtomUI.Theme.Styling;
|
||||
using Avalonia.Animation.Easings;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
|
||||
@@ -15,6 +18,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
{
|
||||
public const string MainContainerPart = "PART_MainContainer";
|
||||
public const string LoadingTextPart = "PART_LoadingText";
|
||||
public const string CustomIndicatorIconPresenterPart = "PART_CustomIndicatorIconPresenter";
|
||||
|
||||
public LoadingIndicatorTheme()
|
||||
: base(typeof(LoadingIndicator))
|
||||
@@ -25,6 +29,17 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
{
|
||||
return new FuncControlTemplate<LoadingIndicator>((indicator, scope) =>
|
||||
{
|
||||
var customIndicatorIconPresenter = new ContentPresenter()
|
||||
{
|
||||
Name = CustomIndicatorIconPresenterPart,
|
||||
};
|
||||
CreateTemplateParentBinding(customIndicatorIconPresenter, ContentPresenter.ContentProperty,
|
||||
LoadingIndicator.CustomIndicatorIconProperty);
|
||||
CreateTemplateParentBinding(customIndicatorIconPresenter, ContentPresenter.IsVisibleProperty,
|
||||
LoadingIndicator.CustomIndicatorIconProperty,
|
||||
BindingMode.Default,
|
||||
ObjectConverters.IsNotNull);
|
||||
customIndicatorIconPresenter.RegisterInNameScope(scope);
|
||||
var loadingText = new TextBlock()
|
||||
{
|
||||
Name = LoadingTextPart,
|
||||
@@ -37,6 +52,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
{
|
||||
Name = MainContainerPart
|
||||
};
|
||||
mainContainer.Children.Add(customIndicatorIconPresenter);
|
||||
mainContainer.Children.Add(loadingText);
|
||||
mainContainer.RegisterInNameScope(scope);
|
||||
return mainContainer;
|
||||
@@ -49,7 +65,8 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
commonStyle.Add(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment.Left);
|
||||
commonStyle.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Top);
|
||||
commonStyle.Add(TemplatedControl.FontSizeProperty, SharedTokenKey.FontSize);
|
||||
commonStyle.Add(LoadingIndicator.MotionEasingCurveProperty, new SetterValueFactory<Easing>(() => new LinearEasing()));
|
||||
commonStyle.Add(LoadingIndicator.MotionEasingCurveProperty,
|
||||
new SetterValueFactory<Easing>(() => new LinearEasing()));
|
||||
commonStyle.Add(LoadingIndicator.MotionDurationProperty, LoadingIndicatorTokenKey.IndicatorDuration);
|
||||
commonStyle.Add(LoadingIndicator.DotBgBrushProperty, SharedTokenKey.ColorPrimary);
|
||||
commonStyle.Add(LoadingIndicator.IndicatorTextMarginProperty, SharedTokenKey.MarginXXS);
|
||||
@@ -63,7 +80,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
|
||||
private void BuildCustomIconStyle()
|
||||
{
|
||||
var customIconStyle = new Style(selector => selector.Nesting().Template().OfType<Icon>());
|
||||
var customIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType<Icon>());
|
||||
customIconStyle.Add(Icon.IconModeProperty, IconMode.Normal);
|
||||
customIconStyle.Add(Layoutable.VerticalAlignmentProperty, VerticalAlignment.Center);
|
||||
customIconStyle.Add(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment.Center);
|
||||
@@ -71,7 +88,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
|
||||
var largeSizeStyle = new Style(selector =>
|
||||
selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Large));
|
||||
var largeIconStyle = new Style(selector => selector.Nesting().Template().OfType<Icon>());
|
||||
var largeIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType<Icon>());
|
||||
largeIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.LARGE_INDICATOR_SIZE);
|
||||
largeIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.LARGE_INDICATOR_SIZE);
|
||||
largeSizeStyle.Add(largeIconStyle);
|
||||
@@ -79,7 +96,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
|
||||
var middleSizeStyle = new Style(selector =>
|
||||
selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Middle));
|
||||
var middleIconStyle = new Style(selector => selector.Nesting().Template().OfType<Icon>());
|
||||
var middleIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType<Icon>());
|
||||
middleIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.MIDDLE_INDICATOR_SIZE);
|
||||
middleIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.MIDDLE_INDICATOR_SIZE);
|
||||
middleSizeStyle.Add(middleIconStyle);
|
||||
@@ -87,7 +104,7 @@ internal class LoadingIndicatorTheme : BaseControlTheme
|
||||
|
||||
var smallSizeStyle = new Style(selector =>
|
||||
selector.Nesting().PropertyEquals(LoadingIndicator.SizeTypeProperty, SizeType.Small));
|
||||
var smallIconStyle = new Style(selector => selector.Nesting().Template().OfType<Icon>());
|
||||
var smallIconStyle = new Style(selector => selector.Nesting().Template().Name(CustomIndicatorIconPresenterPart).Descendant().OfType<Icon>());
|
||||
smallIconStyle.Add(Layoutable.WidthProperty, LoadingIndicator.SMALL_INDICATOR_SIZE);
|
||||
smallIconStyle.Add(Layoutable.HeightProperty, LoadingIndicator.SMALL_INDICATOR_SIZE);
|
||||
smallSizeStyle.Add(smallIconStyle);
|
||||
|
||||
Reference in New Issue
Block a user