From 19570abec07d20b42a2a90bd6511431fdd097376 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 18 Apr 2020 14:25:48 +0200 Subject: [PATCH] Fix calculating min/max layout size. Code ported from WPF. --- src/Avalonia.Layout/LayoutHelper.cs | 50 +++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Layout/LayoutHelper.cs b/src/Avalonia.Layout/LayoutHelper.cs index af7d8ee52e..2b61de00a7 100644 --- a/src/Avalonia.Layout/LayoutHelper.cs +++ b/src/Avalonia.Layout/LayoutHelper.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Utilities; using Avalonia.VisualTree; namespace Avalonia.Layout @@ -19,16 +20,11 @@ namespace Avalonia.Layout /// The control's size. public static Size ApplyLayoutConstraints(ILayoutable control, Size constraints) { - var controlWidth = control.Width; - var controlHeight = control.Height; - - double width = (controlWidth > 0) ? controlWidth : constraints.Width; - double height = (controlHeight > 0) ? controlHeight : constraints.Height; - width = Math.Min(width, control.MaxWidth); - width = Math.Max(width, control.MinWidth); - height = Math.Min(height, control.MaxHeight); - height = Math.Max(height, control.MinHeight); - return new Size(width, height); + var minmax = new MinMax(control); + + return new Size( + MathUtilities.Clamp(constraints.Width, minmax.MinWidth, minmax.MaxWidth), + MathUtilities.Clamp(constraints.Height, minmax.MinHeight, minmax.MaxHeight)); } public static Size MeasureChild(ILayoutable control, Size availableSize, Thickness padding, @@ -85,5 +81,39 @@ namespace Avalonia.Layout InnerInvalidateMeasure(control); } + + /// + /// Calculates the min and max height for a control. Ported from WPF. + /// + private readonly struct MinMax + { + public MinMax(ILayoutable e) + { + MaxHeight = e.MaxHeight; + MinHeight = e.MinHeight; + double l = e.Height; + + double height = (double.IsNaN(l) ? double.PositiveInfinity : l); + MaxHeight = Math.Max(Math.Min(height, MaxHeight), MinHeight); + + height = (double.IsNaN(l) ? 0 : l); + MinHeight = Math.Max(Math.Min(MaxHeight, height), MinHeight); + + MaxWidth = e.MaxWidth; + MinWidth = e.MinWidth; + l = e.Width; + + double width = (double.IsNaN(l) ? double.PositiveInfinity : l); + MaxWidth = Math.Max(Math.Min(width, MaxWidth), MinWidth); + + width = (double.IsNaN(l) ? 0 : l); + MinWidth = Math.Max(Math.Min(MaxWidth, width), MinWidth); + } + + public double MinWidth { get; } + public double MaxWidth { get; } + public double MinHeight { get; } + public double MaxHeight { get; } + } } }