Browse Source

Base case works

wojciech krysiak 7 years ago
parent
commit
5741d0ef14
1 changed files with 82 additions and 54 deletions
  1. 82 54
      src/Avalonia.Controls/Grid.cs

+ 82 - 54
src/Avalonia.Controls/Grid.cs

@@ -60,6 +60,7 @@ namespace Avalonia.Controls
 
             private class MeasurementCache
             {
+
                 public MeasurementCache(Grid grid)
                 {
                     Grid = grid;
@@ -67,19 +68,20 @@ namespace Avalonia.Controls
                                  .Concat(grid.ColumnDefinitions)
                                  .Select(d => new MeasurementResult(d))
                                  .ToList();
+
+                    grid.RowDefinitions.
+
                 }
 
                 public void UpdateMeasureResult(GridLayout.MeasureResult rowResult, GridLayout.MeasureResult columnResult)
                 {
-                    RowResult = rowResult;
-                    ColumnResult = columnResult;
                     MeasurementState = MeasurementState.Cached;
-                    for (int i = 0; i < rowResult.LengthList.Count; i++)
+                    for (int i = 0; i < Grid.RowDefinitions.Count; i++)
                     {
                         Results[i].MeasuredResult = rowResult.LengthList[i];
                     }
 
-                    for (int i = 0; i < columnResult.LengthList.Count; i++)
+                    for (int i = 0; i < Grid.ColumnDefinitions.Count; i++)
                     {
                         Results[i + rowResult.LengthList.Count].MeasuredResult = columnResult.LengthList[i];
                     }
@@ -92,8 +94,6 @@ namespace Avalonia.Controls
                 }
 
                 public Grid Grid { get; }
-                public GridLayout.MeasureResult RowResult { get; private set; }
-                public GridLayout.MeasureResult ColumnResult { get; private set; }
                 public MeasurementState MeasurementState { get; private set; }
 
                 public List<MeasurementResult> Results { get; }
@@ -103,9 +103,9 @@ namespace Avalonia.Controls
 
             private class MeasurementResult
             {
-                public MeasurementResult(DefinitionBase @base)
+                public MeasurementResult(DefinitionBase definition)
                 {
-                    Definition = @base;
+                    Definition = definition;
                     MeasuredResult = double.NaN;
                 }
 
@@ -113,22 +113,16 @@ namespace Avalonia.Controls
                 public double MeasuredResult { get; set; }
             }
 
-            private enum ScopeType
-            {
-                Auto,
-                Fixed
-            }
-
             private class Group
             {
                 public bool IsFixed { get; set; }
 
-                public List<MeasurementResult> Results { get; }
+                public List<MeasurementResult> Results { get; } = new List<MeasurementResult>();
 
                 public double CalculatedLength { get; }
             }
 
-            private Dictionary<string, Group> _groups = new Dictionary<string, Group>();
+            private readonly Dictionary<string, Group> _groups = new Dictionary<string, Group>();
 
 
             public SharedSizeScopeHost(Control scope)
@@ -158,57 +152,79 @@ namespace Avalonia.Controls
                 cache.UpdateMeasureResult(rowResult, columnResult);
             }
 
-            internal (GridLayout.MeasureResult, GridLayout.MeasureResult) HandleArrange(Grid grid, GridLayout.MeasureResult rowResult, GridLayout.MeasureResult columnResult)
+            private double Gather(IEnumerable<MeasurementResult> measurements)
             {
-                var rowConventions = rowResult.LeanLengthList.ToList();
-                var rowLengths = rowResult.LengthList.ToList();
-                var rowDesiredLength = 0.0;
-                for (int i = 0; i < grid.RowDefinitions.Count; i++)
+                var result = 0.0d;
+
+                bool onlyFixed = false;
+
+                foreach (var measurement in measurements)
                 {
-                    var definition = grid.RowDefinitions[i];
-                    if (string.IsNullOrEmpty(definition.SharedSizeGroup))
+                    if (measurement.Definition is ColumnDefinition column)
                     {
-                        rowDesiredLength += rowResult.LengthList[i];
-                        continue;
+                        if (!onlyFixed && column.Width.IsAbsolute)
+                        {
+                            onlyFixed = true;
+                            result = measurement.MeasuredResult;
+                        }
+                        else if (onlyFixed == column.Width.IsAbsolute)
+                            result = Math.Max(result, measurement.MeasuredResult);
+
+                        result = Math.Max(result, column.MinWidth);
                     }
+                    if (measurement.Definition is RowDefinition row)
+                    {
+                        if (!onlyFixed && row.Height.IsAbsolute)
+                        {
+                            onlyFixed = true;
+                            result = measurement.MeasuredResult;
+                        }
+                        else if (onlyFixed == row.Height.IsAbsolute)
+                            result = Math.Max(result, measurement.MeasuredResult);
+
+                        result = Math.Max(result, row.MinHeight);
+                    }
+                }
 
-                    var group = _groups[definition.SharedSizeGroup];
-
-                    var length = group.Results.Max(g => g.MeasuredResult);
-                    rowConventions[i] = new GridLayout.LengthConvention(
-                        new GridLength(length),
-                        rowResult.LeanLengthList[i].MinLength,
-                        rowResult.LeanLengthList[i].MaxLength
-                        );
-                    rowLengths[i] = length;
-                    rowDesiredLength += length;
+                return result;
+            }
 
-                }
 
-                var columnConventions = columnResult.LeanLengthList.ToList();
-                var columnLengths = columnResult.LengthList.ToList();
-                var columnDesiredLength = 0.0;
-                for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
+            (List<GridLayout.LengthConvention>, List<double>, double) Arrange(IReadOnlyList<DefinitionBase> definitions, GridLayout.MeasureResult measureResult)
+            {
+                var conventions = measureResult.LeanLengthList.ToList();
+                var lengths = measureResult.LengthList.ToList();
+                var desiredLength = 0.0;
+                for (int i = 0; i < definitions.Count; i++)
                 {
-                    var definition = grid.ColumnDefinitions[i];
+                    var definition = definitions[i];
                     if (string.IsNullOrEmpty(definition.SharedSizeGroup))
                     {
-                        columnDesiredLength += rowResult.LengthList[i];
+                        desiredLength += measureResult.LengthList[i];
                         continue;
                     }
 
                     var group = _groups[definition.SharedSizeGroup];
 
-                    var length = group.Results.Max(g => g.MeasuredResult);
-                    columnConventions[i] = new GridLayout.LengthConvention(
+                    var length = Gather(group.Results);
+
+                    conventions[i] = new GridLayout.LengthConvention(
                         new GridLength(length),
-                        columnResult.LeanLengthList[i].MinLength,
-                        columnResult.LeanLengthList[i].MaxLength
-                        );
-                    columnLengths[i] = length;
-                    columnDesiredLength += length;
+                        measureResult.LeanLengthList[i].MinLength,
+                        measureResult.LeanLengthList[i].MaxLength
+                    );
+                    lengths[i] = length;
+                    desiredLength += length;
                 }
 
+                return (conventions, lengths, desiredLength);
+            }
+
+            internal (GridLayout.MeasureResult, GridLayout.MeasureResult) HandleArrange(Grid grid, GridLayout.MeasureResult rowResult, GridLayout.MeasureResult columnResult)
+            {
+                var (rowConventions, rowLengths, rowDesiredLength) = Arrange(grid.RowDefinitions, rowResult);
+                var (columnConventions, columnLengths, columnDesiredLength) = Arrange(grid.ColumnDefinitions, columnResult);
+
                 return (
                     new GridLayout.MeasureResult(
                         rowResult.ContainerLength,
@@ -231,6 +247,8 @@ namespace Avalonia.Controls
                 foreach (var result in cache.Results)
                 {
                     var scopeName = result.Definition.SharedSizeGroup;
+                    if (string.IsNullOrEmpty(scopeName))
+                        continue;
                     if (!_groups.TryGetValue(scopeName, out var group))
                         _groups.Add(scopeName, group = new Group());
 
@@ -250,6 +268,8 @@ namespace Avalonia.Controls
                 foreach (var result in cache.Results)
                 {
                     var scopeName = result.Definition.SharedSizeGroup;
+                    if (string.IsNullOrEmpty(scopeName))
+                        continue;
                     Debug.Assert(_groups.TryGetValue(scopeName, out var group));
 
                     group.Results.Remove(result);
@@ -346,14 +366,14 @@ namespace Avalonia.Controls
             if ((bool)arg2.NewValue)
             {
                 Debug.Assert(source.GetValue(s_sharedSizeScopeHostProperty) == null);
-                source.SetValue(IsSharedSizeScopeProperty, new SharedSizeScopeHost(source));
+                source.SetValue(s_sharedSizeScopeHostProperty, new SharedSizeScopeHost(source));
             }
             else
             {
                 var host = source.GetValue(s_sharedSizeScopeHostProperty) as SharedSizeScopeHost;
                 Debug.Assert(host != null);
                 host.Dispose();
-                source.SetValue(IsSharedSizeScopeProperty, null);
+                source.SetValue(s_sharedSizeScopeHostProperty, null);
             }
         }
 
@@ -626,11 +646,19 @@ namespace Avalonia.Controls
             var columnLayout = _columnLayoutCache;
             var rowLayout = _rowLayoutCache;
 
-            var (rowCache, columnCache) = _sharedSizeHost?.HandleArrange(this, _rowMeasureCache, _columnMeasureCache) ?? (_rowMeasureCache, _columnMeasureCache);
+            var (rowCache, columnCache) =
+                _sharedSizeHost?.HandleArrange(this, _rowMeasureCache, _columnMeasureCache) ??
+                (_rowMeasureCache, _columnMeasureCache);
+
+            if (_sharedSizeHost != null)
+            {
+                rowCache = rowLayout.Measure(finalSize.Width, rowCache.LeanLengthList);
+                columnCache = columnLayout.Measure(finalSize.Width, columnCache.LeanLengthList);
+            }
 
             // Calculate for arrange result.
-            var columnResult = columnLayout.Arrange(finalSize.Width, rowCache);
-            var rowResult = rowLayout.Arrange(finalSize.Height, columnCache);
+            var columnResult = columnLayout.Arrange(finalSize.Width, columnCache);
+            var rowResult = rowLayout.Arrange(finalSize.Height, rowCache);
             // Arrange the children.
             foreach (var child in Children.OfType<Control>())
             {