From b0f97939c3e147904417a23bd192ff6e570ec578 Mon Sep 17 00:00:00 2001 From: sdoroff Date: Tue, 17 Oct 2017 02:15:18 -0400 Subject: [PATCH] Fix sizing behavior of Shape class Shapes with Strech set to Fill would fail to size themselves correctly when an infinite available size was passed to messure. This occurs because the transform is calculated before a final size is known. A flag was added that signals ArrangeOverride to calculate the transform for the RenderedGeometry --- src/Avalonia.Controls/Shapes/Shape.cs | 46 +++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/Shapes/Shape.cs b/src/Avalonia.Controls/Shapes/Shape.cs index c03f4dc563..73b89ca4b7 100644 --- a/src/Avalonia.Controls/Shapes/Shape.cs +++ b/src/Avalonia.Controls/Shapes/Shape.cs @@ -29,6 +29,8 @@ namespace Avalonia.Controls.Shapes private Matrix _transform = Matrix.Identity; private Geometry _definingGeometry; private Geometry _renderedGeometry; + bool _calculateTransformOnArrange = false; + static Shape() { @@ -150,13 +152,53 @@ namespace Avalonia.Controls.Shapes this._definingGeometry = null; InvalidateMeasure(); } - + protected override Size MeasureOverride(Size availableSize) + { + bool deferCalculateTransform; + switch (Stretch) + { + case Stretch.Fill: + case Stretch.UniformToFill: + deferCalculateTransform = double.IsInfinity(availableSize.Width) || double.IsInfinity(availableSize.Height); + break; + case Stretch.Uniform: + deferCalculateTransform = double.IsInfinity(availableSize.Width) && double.IsInfinity(availableSize.Height); + break; + case Stretch.None: + default: + deferCalculateTransform = false; + break; + } + + if (deferCalculateTransform) + { + _calculateTransformOnArrange = true; + return DefiningGeometry.Bounds.Size; + } + else + { + _calculateTransformOnArrange = false; + return CalculateShapeSizeAndSetTransform(availableSize); + } + } + + protected override Size ArrangeOverride(Size finalSize) + { + if(_calculateTransformOnArrange) + { + _calculateTransformOnArrange = false; + CalculateShapeSizeAndSetTransform(finalSize); + } + + return finalSize; + } + private Size CalculateShapeSizeAndSetTransform(Size availableSize) { // This should probably use GetRenderBounds(strokeThickness) but then the calculations // will multiply the stroke thickness as well, which isn't correct. var (size, transform) = CalculateSizeAndTransform(availableSize, DefiningGeometry.Bounds, Stretch); - + if (_transform != transform) { _transform = transform;