From b2a868dd3a15631b428aa5251c7b5334b503ed22 Mon Sep 17 00:00:00 2001 From: walterlv Date: Sun, 6 May 2018 09:35:36 +0800 Subject: [PATCH] Finish the AggregateAdditionalConventionsForStars method algorithm. --- src/Avalonia.Controls/Utils/GridLayout.cs | 40 ++++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Avalonia.Controls/Utils/GridLayout.cs b/src/Avalonia.Controls/Utils/GridLayout.cs index 53ca7b13c5..da2bf42f6d 100644 --- a/src/Avalonia.Controls/Utils/GridLayout.cs +++ b/src/Avalonia.Controls/Utils/GridLayout.cs @@ -367,21 +367,37 @@ namespace Avalonia.Controls.Utils private double AggregateAdditionalConventionsForStars( IReadOnlyList conventions) { - // Note: The comment in this method is just a draft. - // +-----------------------------------------------------------+ - // | * | P | * | P | P | * | P | * | * | - // +-----------------------------------------------------------+ - // |<- x ->| |<- z ->| - // |<- y ->| - // conveniences 是上面看到的那个列表,所有能够确定的 A、P 和 * 都已经转换成了 P;剩下的 * 只有 Max 是没确定的。 - // _additionalConventions 是上面的 x、y、z…… 集合,只有最小值是可用的。 - // 需要返回所有标记为 * 的方格的累加和的最小值。 + // 1. Determine all one-span column's desired widths or row's desired heights. + // 2. Order the multi-span conventions by its last index + // (Notice that the sorting data source is much smaller than the original children source.) + // 3. Determin each multi-span last index by calculating the maximun desired size. // Before we determine the behavior of this method, we just aggregate the one-span * columns. - var lookup = _additionalConventions + + var fixedLength = conventions.Where(x => x.Length.IsAbsolute).Sum(x => x.Length.Value); + + // Prepare a lengthList variable indicating the fixed length of each column/row. + var lengthList = conventions.Select(x => x.Length.IsAbsolute ? x.Length.Value : 0.0).ToList(); + foreach (var group in _additionalConventions .Where(x => x.Span == 1 && conventions[x.Index].Length.IsStar) - .ToLookup(x => x.Index); - return lookup.Select(group => group.Max(x => x.Min)).Sum(); + .ToLookup(x => x.Index)) + { + lengthList[group.Key] = Math.Max(lengthList[group.Key], group.Max(x => x.Min)); + } + + // Now the lengthList is fixed by every one-span columns/rows. + // Then we should determine the multi-span column's/row's length. + foreach (var group in _additionalConventions + .Where(x => x.Span > 1) + .ToLookup(x => x.Index + x.Span - 1) + // Order the multi-span columns/rows by last index. + .OrderBy(x => x.Key)) + { + var length = group.Max(x => x.Min - Enumerable.Range(x.Index, x.Span - 1).Sum(r => lengthList[r])); + lengthList[group.Key] = Math.Max(lengthList[group.Key], length > 0 ? length : 0); + } + + return lengthList.Sum() - fixedLength; } ///