From 04cb90fb3aade4edf00a313ef1a5236afdb4d2c3 Mon Sep 17 00:00:00 2001 From: chinboy Date: Tue, 21 Apr 2026 14:03:54 +0800 Subject: [PATCH] perf(AddOnDecoratedBox): batch layout recalculations with dirty flags to avoid redundant computations on single property change --- .../AddOnDecoratedBox/AddOnDecoratedBox.cs | 104 ++++++++++++------ 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/src/AtomUI.Desktop.Controls/Primitives/AddOnDecoratedBox/AddOnDecoratedBox.cs b/src/AtomUI.Desktop.Controls/Primitives/AddOnDecoratedBox/AddOnDecoratedBox.cs index 2199e1fd1..15e5d44b2 100644 --- a/src/AtomUI.Desktop.Controls/Primitives/AddOnDecoratedBox/AddOnDecoratedBox.cs +++ b/src/AtomUI.Desktop.Controls/Primitives/AddOnDecoratedBox/AddOnDecoratedBox.cs @@ -11,6 +11,7 @@ using Avalonia.Interactivity; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Metadata; +using Avalonia.Threading; using Avalonia.VisualTree; namespace AtomUI.Desktop.Controls; @@ -295,6 +296,10 @@ internal class AddOnDecoratedBox : ContentControl, private protected Control? _rightAddOn; private ContentPresenter? _contentLeftAddOn; private ContentPresenter? _contentRightAddOn; + private bool _borderInfoDirty; + private bool _cornerRadiusDirty; + private bool _borderThicknessDirty; + private bool _layoutUpdatePosted; internal Border? ContentFrame; @@ -332,46 +337,75 @@ internal class AddOnDecoratedBox : ContentControl, UpdatePseudoClasses(); } - if (this.IsAttachedToVisualTree()) + if (change.Property == StyleVariantProperty || + change.Property == BorderThicknessProperty) { - if (change.Property == StyleVariantProperty) - { - ConfigureInnerBoxBorderThickness(); - } + _borderThicknessDirty = true; + } - if (change.Property == LeftAddOnProperty || - change.Property == RightAddOnProperty || - change.Property == CornerRadiusProperty || - change.Property == StyleVariantProperty || - change.Property == CompactSpaceItemPositionProperty || - change.Property == CompactSpaceOrientationProperty) - { - ConfigureInnerBoxCornerRadius(); - } + if (change.Property == LeftAddOnProperty || + change.Property == RightAddOnProperty || + change.Property == CornerRadiusProperty || + change.Property == StyleVariantProperty || + change.Property == CompactSpaceItemPositionProperty || + change.Property == CompactSpaceOrientationProperty) + { + _cornerRadiusDirty = true; + } - if (change.Property == BorderThicknessProperty) - { - ConfigureInnerBoxBorderThickness(); - } + if (change.Property == CornerRadiusProperty || + change.Property == BorderThicknessProperty || + change.Property == StyleVariantProperty || + change.Property == CompactSpaceItemPositionProperty || + change.Property == CompactSpaceOrientationProperty) + { + _borderInfoDirty = true; + } - if (change.Property == CornerRadiusProperty || - change.Property == BorderThicknessProperty || - change.Property == StyleVariantProperty || - change.Property == CompactSpaceItemPositionProperty || - change.Property == CompactSpaceOrientationProperty) - { - ConfigureAddOnBorderInfo(); - } + if (change.Property == StatusProperty || + change.Property == IsEnabledProperty || + change.Property == ContentLeftAddOnProperty || + change.Property == ContentRightAddOnProperty || + change.Property == AddOnStatusForegroundProperty || + change.Property == AddOnStatusIconBrushProperty) + { + UpdateIconStatusColors(); + } - if (change.Property == StatusProperty || - change.Property == IsEnabledProperty || - change.Property == ContentLeftAddOnProperty || - change.Property == ContentRightAddOnProperty || - change.Property == AddOnStatusForegroundProperty || - change.Property == AddOnStatusIconBrushProperty) - { - UpdateIconStatusColors(); - } + ScheduleLayoutUpdate(); + } + + private void ScheduleLayoutUpdate() + { + if (_layoutUpdatePosted) + { + return; + } + if (!_borderInfoDirty && !_cornerRadiusDirty && !_borderThicknessDirty) + { + return; + } + _layoutUpdatePosted = true; + Dispatcher.UIThread.Post(ApplyDirtyLayoutUpdates, DispatcherPriority.Render); + } + + private void ApplyDirtyLayoutUpdates() + { + _layoutUpdatePosted = false; + if (_cornerRadiusDirty) + { + ConfigureInnerBoxCornerRadius(); + _cornerRadiusDirty = false; + } + if (_borderInfoDirty) + { + ConfigureAddOnBorderInfo(); + _borderInfoDirty = false; + } + if (_borderThicknessDirty) + { + ConfigureInnerBoxBorderThickness(); + _borderThicknessDirty = false; } }