Browse Source

Base case works

pull/1945/head
wojciech krysiak 8 years ago
committed by Wojciech Krysiak
parent
commit
5741d0ef14
  1. 136
      src/Avalonia.Controls/Grid.cs

136
src/Avalonia.Controls/Grid.cs

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

Loading…
Cancel
Save