From a39de875aa00ab18fdd2db74121b7071c9ee2a8b Mon Sep 17 00:00:00 2001 From: AndrejBunjac Date: Mon, 18 Apr 2022 17:34:31 +0200 Subject: [PATCH] Added invalidation to LayoutThickness property in Border and ContentPresenter and implemented minor review fixes. --- src/Avalonia.Controls/Border.cs | 38 +++++++++++++++---- .../Presenters/ContentPresenter.cs | 29 ++++++++++---- src/Avalonia.Layout/Layoutable.cs | 2 +- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/Avalonia.Controls/Border.cs b/src/Avalonia.Controls/Border.cs index ce64570dc8..53de95ac41 100644 --- a/src/Avalonia.Controls/Border.cs +++ b/src/Avalonia.Controls/Border.cs @@ -1,8 +1,10 @@ +using System; using Avalonia.Collections; using Avalonia.Controls.Shapes; using Avalonia.Controls.Utils; using Avalonia.Layout; using Avalonia.Media; +using Avalonia.Utilities; using Avalonia.VisualTree; namespace Avalonia.Controls @@ -88,6 +90,18 @@ namespace Avalonia.Controls AffectsMeasure(BorderThicknessProperty); } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + switch (change.Property.Name) + { + case nameof(UseLayoutRounding): + case nameof(BorderThickness): + _layoutThickness = null; + break; + } + } + /// /// Gets or sets a brush with which to paint the background. /// @@ -169,29 +183,39 @@ namespace Avalonia.Controls set => SetValue(BoxShadowProperty, value); } - private Thickness _layoutThickness = default; + private Thickness? _layoutThickness; + private double _scale; private Thickness LayoutThickness { get { - if (_layoutThickness == default) + VerifyScale(); + + if (_layoutThickness == null) { var borderThickness = BorderThickness; if (UseLayoutRounding) - { - var scale = LayoutHelper.GetLayoutScale(this); - borderThickness = LayoutHelper.RoundLayoutThickness(BorderThickness, scale, scale); - } + borderThickness = LayoutHelper.RoundLayoutThickness(BorderThickness, _scale, _scale); _layoutThickness = borderThickness; } - return _layoutThickness; + return _layoutThickness.Value; } } + private void VerifyScale() + { + var currentScale = LayoutHelper.GetLayoutScale(this); + if (MathUtilities.AreClose(currentScale, _scale)) + return; + + _scale = currentScale; + _layoutThickness = null; + } + /// /// Renders the control. /// diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index bbb772a4ce..ae08b4a452 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -8,6 +8,7 @@ using Avalonia.Layout; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Metadata; +using Avalonia.Utilities; namespace Avalonia.Controls.Presenters { @@ -249,6 +250,10 @@ namespace Avalonia.Controls.Presenters case nameof(TemplatedParent): TemplatedParentChanged(change); break; + case nameof(UseLayoutRounding): + case nameof(BorderThickness): + _layoutThickness = null; + break; } } @@ -329,29 +334,39 @@ namespace Avalonia.Controls.Presenters InvalidateMeasure(); } - private Thickness _layoutThickness = default; + private Thickness? _layoutThickness; + private double _scale; private Thickness LayoutThickness { get { - if (_layoutThickness == default) + VerifyScale(); + + if (_layoutThickness == null) { var borderThickness = BorderThickness; if (UseLayoutRounding) - { - var scale = LayoutHelper.GetLayoutScale(this); - borderThickness = LayoutHelper.RoundLayoutThickness(BorderThickness, scale, scale); - } + borderThickness = LayoutHelper.RoundLayoutThickness(BorderThickness, _scale, _scale); _layoutThickness = borderThickness; } - return _layoutThickness; + return _layoutThickness.Value; } } + private void VerifyScale() + { + var currentScale = LayoutHelper.GetLayoutScale(this); + if (MathUtilities.AreClose(currentScale, _scale)) + return; + + _scale = currentScale; + _layoutThickness = null; + } + /// public override void Render(DrawingContext context) { diff --git a/src/Avalonia.Layout/Layoutable.cs b/src/Avalonia.Layout/Layoutable.cs index 23a76f6ee2..df7aa937a0 100644 --- a/src/Avalonia.Layout/Layoutable.cs +++ b/src/Avalonia.Layout/Layoutable.cs @@ -653,7 +653,7 @@ namespace Avalonia.Layout // Margin has to be treated separately because the layout rounding function is not linear // f(a + b) != f(a) + f(b) // If the margin isn't pre-rounded some sizes will be offset by 1 pixel in certain scales. - if (UseLayoutRounding) + if (useLayoutRounding) { margin = LayoutHelper.RoundLayoutThickness(margin, scale, scale); }