Browse Source

When the available length is not enough, clip the measure list.

pull/1517/head
walterlv 8 years ago
parent
commit
fc73d7cc37
  1. 12
      src/Avalonia.Controls/Grid.cs
  2. 32
      src/Avalonia.Controls/Utils/GridLayout.cs
  3. 15
      tests/Avalonia.Controls.UnitTests/GridLayoutTests.cs

12
src/Avalonia.Controls/Grid.cs

@ -211,10 +211,8 @@ namespace Avalonia.Controls
{
var (column, columnSpan) = safeColumns[child];
var (row, rowSpan) = safeRows[child];
var width = Enumerable.Range(column, columnSpan)
.Select(x => columnResult.LengthList[x].Length.Value).Sum();
var height = Enumerable.Range(row, rowSpan)
.Select(x => rowResult.LengthList[x].Length.Value).Sum();
var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum();
var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum();
MeasureOnce(child, new Size(width, height));
}
@ -256,10 +254,8 @@ namespace Avalonia.Controls
{
var (column, columnSpan) = safeColumns[child];
var (row, rowSpan) = safeRows[child];
var width = Enumerable.Range(column, columnSpan)
.Select(x => columnResult.LengthList[x].Length.Value).Sum();
var height = Enumerable.Range(row, rowSpan)
.Select(x => rowResult.LengthList[x].Length.Value).Sum();
var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum();
var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum();
child.Arrange(new Rect(0, 0, width, height));
}

32
src/Avalonia.Controls/Utils/GridLayout.cs

@ -176,9 +176,11 @@ namespace Avalonia.Controls.Utils
// M6/6. Expand all the left stars. These stars have no conventions or only have max value so they can be expanded from zero to constrant.
var dynamicConvention = ExpandStars(conventions, containerLength);
Clip(dynamicConvention, containerLength);
// Stores the measure result.
return new MeasureResult(containerLength, desiredLength, greedyDesiredLength, conventions, dynamicConvention);
// Stores the measuring result.
return new MeasureResult(containerLength, desiredLength, greedyDesiredLength,
conventions, dynamicConvention);
}
public ArrangeResult Arrange(double finalLength, MeasureResult measure)
@ -201,7 +203,7 @@ namespace Avalonia.Controls.Utils
}
[Pure]
private static List<LengthConvention> ExpandStars(IEnumerable<LengthConvention> conventions, double constraint)
private static List<double> ExpandStars(IEnumerable<LengthConvention> conventions, double constraint)
{
// Initial.
var dynamicConvention = conventions.Select(x => x.Clone()).ToList();
@ -244,7 +246,25 @@ namespace Avalonia.Controls.Utils
Debug.Assert(dynamicConvention.All(x => x.Length.IsAbsolute));
return dynamicConvention;
return dynamicConvention.Select(x => x.Length.Value).ToList();
}
private static void Clip(IList<double> lengthList, double constraint)
{
var measureLength = 0.0;
for (var i = 0; i < lengthList.Count; i++)
{
var length = lengthList[i];
if (constraint - measureLength > length)
{
measureLength += length;
}
else
{
lengthList[i] = constraint - measureLength;
measureLength = constraint;
}
}
}
internal class LengthConvention : ICloneable
@ -299,13 +319,13 @@ namespace Avalonia.Controls.Utils
internal class MeasureResult
{
internal MeasureResult(double containerLength, double desiredLength, double greedyDesiredLength,
IReadOnlyList<LengthConvention> leanConventions, IReadOnlyList<LengthConvention> expandedConventions)
IReadOnlyList<LengthConvention> leanConventions, IReadOnlyList<double> expandedConventions)
{
ContainerLength = containerLength;
DesiredLength = desiredLength;
GreedyDesiredLength = greedyDesiredLength;
LeanLengthList = leanConventions;
LengthList = expandedConventions.Select(x => x.Length.Value).ToList();
LengthList = expandedConventions;
}
public double ContainerLength { get; }

15
tests/Avalonia.Controls.UnitTests/GridLayoutTests.cs

@ -9,6 +9,8 @@ namespace Avalonia.Controls.UnitTests
{
[Theory]
[InlineData("100, 200, 300", 800d, 600d, new[] { 100d, 200d, 300d })]
[InlineData("100, 200, 300", 600d, 600d, new[] { 100d, 200d, 300d })]
[InlineData("100, 200, 300", 400d, 400d, new[] { 100d, 200d, 100d })]
public void MeasureArrange_AllPixelLength_Correct(string length, double containerLength,
double expectedDesiredLength, IList<double> expectedLengthList)
{
@ -55,19 +57,6 @@ namespace Avalonia.Controls.UnitTests
TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList);
}
[Fact]
public void MeasureArrange_AllPixelLengthButNotEnough_Correct()
{
// Arrange
var layout = new GridLayout(new RowDefinitions("100,200,300"));
// Measure - Action & Assert
var measure = layout.Measure(400);
Assert.Equal(new[] { 100d, 200d, 300d }, measure.LengthList);
// Arrange - Action & Assert
}
[SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local")]
private static void TestRowDefinitionsOnly(string length, double containerLength,
double expectedDesiredLength, IList<double> expectedLengthList)

Loading…
Cancel
Save