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
{
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>())
{

Loading…
Cancel
Save