Browse Source

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

pull/1517/head
walterlv 9 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 (column, columnSpan) = safeColumns[child];
var (row, rowSpan) = safeRows[child]; var (row, rowSpan) = safeRows[child];
var width = Enumerable.Range(column, columnSpan) var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum();
.Select(x => columnResult.LengthList[x].Length.Value).Sum(); var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum();
var height = Enumerable.Range(row, rowSpan)
.Select(x => rowResult.LengthList[x].Length.Value).Sum();
MeasureOnce(child, new Size(width, height)); MeasureOnce(child, new Size(width, height));
} }
@ -256,10 +254,8 @@ namespace Avalonia.Controls
{ {
var (column, columnSpan) = safeColumns[child]; var (column, columnSpan) = safeColumns[child];
var (row, rowSpan) = safeRows[child]; var (row, rowSpan) = safeRows[child];
var width = Enumerable.Range(column, columnSpan) var width = Enumerable.Range(column, columnSpan).Select(x => columnResult.LengthList[x]).Sum();
.Select(x => columnResult.LengthList[x].Length.Value).Sum(); var height = Enumerable.Range(row, rowSpan).Select(x => rowResult.LengthList[x]).Sum();
var height = Enumerable.Range(row, rowSpan)
.Select(x => rowResult.LengthList[x].Length.Value).Sum();
child.Arrange(new Rect(0, 0, width, height)); 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. // 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); var dynamicConvention = ExpandStars(conventions, containerLength);
Clip(dynamicConvention, containerLength);
// Stores the measure result. // Stores the measuring result.
return new MeasureResult(containerLength, desiredLength, greedyDesiredLength, conventions, dynamicConvention); return new MeasureResult(containerLength, desiredLength, greedyDesiredLength,
conventions, dynamicConvention);
} }
public ArrangeResult Arrange(double finalLength, MeasureResult measure) public ArrangeResult Arrange(double finalLength, MeasureResult measure)
@ -201,7 +203,7 @@ namespace Avalonia.Controls.Utils
} }
[Pure] [Pure]
private static List<LengthConvention> ExpandStars(IEnumerable<LengthConvention> conventions, double constraint) private static List<double> ExpandStars(IEnumerable<LengthConvention> conventions, double constraint)
{ {
// Initial. // Initial.
var dynamicConvention = conventions.Select(x => x.Clone()).ToList(); var dynamicConvention = conventions.Select(x => x.Clone()).ToList();
@ -244,7 +246,25 @@ namespace Avalonia.Controls.Utils
Debug.Assert(dynamicConvention.All(x => x.Length.IsAbsolute)); 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 internal class LengthConvention : ICloneable
@ -299,13 +319,13 @@ namespace Avalonia.Controls.Utils
internal class MeasureResult internal class MeasureResult
{ {
internal MeasureResult(double containerLength, double desiredLength, double greedyDesiredLength, internal MeasureResult(double containerLength, double desiredLength, double greedyDesiredLength,
IReadOnlyList<LengthConvention> leanConventions, IReadOnlyList<LengthConvention> expandedConventions) IReadOnlyList<LengthConvention> leanConventions, IReadOnlyList<double> expandedConventions)
{ {
ContainerLength = containerLength; ContainerLength = containerLength;
DesiredLength = desiredLength; DesiredLength = desiredLength;
GreedyDesiredLength = greedyDesiredLength; GreedyDesiredLength = greedyDesiredLength;
LeanLengthList = leanConventions; LeanLengthList = leanConventions;
LengthList = expandedConventions.Select(x => x.Length.Value).ToList(); LengthList = expandedConventions;
} }
public double ContainerLength { get; } public double ContainerLength { get; }

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

@ -9,6 +9,8 @@ namespace Avalonia.Controls.UnitTests
{ {
[Theory] [Theory]
[InlineData("100, 200, 300", 800d, 600d, new[] { 100d, 200d, 300d })] [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, public void MeasureArrange_AllPixelLength_Correct(string length, double containerLength,
double expectedDesiredLength, IList<double> expectedLengthList) double expectedDesiredLength, IList<double> expectedLengthList)
{ {
@ -55,19 +57,6 @@ namespace Avalonia.Controls.UnitTests
TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); 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")] [SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local")]
private static void TestRowDefinitionsOnly(string length, double containerLength, private static void TestRowDefinitionsOnly(string length, double containerLength,
double expectedDesiredLength, IList<double> expectedLengthList) double expectedDesiredLength, IList<double> expectedLengthList)

Loading…
Cancel
Save