Browse Source

Fix arrange size with margins.

Fixes #432.
pull/488/head
Steven Kirk 10 years ago
parent
commit
75e13dc02b
  1. 33
      src/Perspex.Layout/Layoutable.cs
  2. 64
      tests/Perspex.Layout.UnitTests/ArrangeTests.cs
  3. 15
      tests/Perspex.Layout.UnitTests/MeasureTests.cs

33
src/Perspex.Layout/Layoutable.cs

@ -521,24 +521,27 @@ namespace Perspex.Layout
{
if (IsVisible)
{
var originX = finalRect.X + Margin.Left;
var originY = finalRect.Y + Margin.Top;
var sizeMinusMargins = new Size(
Math.Max(0, finalRect.Width - Margin.Left - Margin.Right),
Math.Max(0, finalRect.Height - Margin.Top - Margin.Bottom));
var margin = Margin;
var originX = finalRect.X + margin.Left;
var originY = finalRect.Y + margin.Top;
var availableSizeMinusMargins = new Size(
Math.Max(0, finalRect.Width - margin.Left - margin.Right),
Math.Max(0, finalRect.Height - margin.Top - margin.Bottom));
var horizontalAlignment = HorizontalAlignment;
var verticalAlignment = VerticalAlignment;
var size = sizeMinusMargins;
var size = availableSizeMinusMargins;
var scale = GetLayoutScale();
if (horizontalAlignment != HorizontalAlignment.Stretch)
{
size = size.WithWidth(Math.Min(size.Width, DesiredSize.Width));
size = size.WithWidth(Math.Min(size.Width, DesiredSize.Width)
- margin.Left - margin.Right);
}
if (verticalAlignment != VerticalAlignment.Stretch)
{
size = size.WithHeight(Math.Min(size.Height, DesiredSize.Height));
size = size.WithHeight(Math.Min(size.Height, DesiredSize.Height)
- margin.Top - margin.Bottom);
}
size = LayoutHelper.ApplyLayoutConstraints(this, size);
@ -548,9 +551,9 @@ namespace Perspex.Layout
size = new Size(
Math.Ceiling(size.Width * scale) / scale,
Math.Ceiling(size.Height * scale) / scale);
sizeMinusMargins = new Size(
Math.Ceiling(sizeMinusMargins.Width * scale) / scale,
Math.Ceiling(sizeMinusMargins.Height * scale) / scale);
availableSizeMinusMargins = new Size(
Math.Ceiling(availableSizeMinusMargins.Width * scale) / scale,
Math.Ceiling(availableSizeMinusMargins.Height * scale) / scale);
}
size = ArrangeOverride(size).Constrain(size);
@ -559,10 +562,10 @@ namespace Perspex.Layout
{
case HorizontalAlignment.Center:
case HorizontalAlignment.Stretch:
originX += (sizeMinusMargins.Width - size.Width) / 2;
originX += (availableSizeMinusMargins.Width - size.Width) / 2;
break;
case HorizontalAlignment.Right:
originX += sizeMinusMargins.Width - size.Width;
originX += availableSizeMinusMargins.Width - size.Width;
break;
}
@ -570,10 +573,10 @@ namespace Perspex.Layout
{
case VerticalAlignment.Center:
case VerticalAlignment.Stretch:
originY += (sizeMinusMargins.Height - size.Height) / 2;
originY += (availableSizeMinusMargins.Height - size.Height) / 2;
break;
case VerticalAlignment.Bottom:
originY += sizeMinusMargins.Height - size.Height;
originY += availableSizeMinusMargins.Height - size.Height;
break;
}

64
tests/Perspex.Layout.UnitTests/ArrangeTests.cs

@ -8,6 +8,56 @@ namespace Perspex.Layout.UnitTests
{
public class ArrangeTests
{
[Fact]
public void Margin_Should_Be_Subtracted_From_Arrange_FinalSize()
{
var target = new TestControl
{
Width = 100,
Height = 100,
Margin = new Thickness(8),
};
target.Measure(Size.Infinity);
target.Arrange(new Rect(target.DesiredSize));
Assert.Equal(new Size(100, 100), target.ArrangeFinalSize);
}
[Fact]
public void ArrangeOverride_Receives_Desired_Size_When_Centered()
{
var target = new TestControl
{
MeasureResult = new Size(100, 100),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(8),
};
target.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
target.Arrange(new Rect(0, 0, 200, 200));
Assert.Equal(new Size(100, 100), target.ArrangeFinalSize);
}
[Fact]
public void ArrangeOverride_Receives_Available_Size_Minus_Margin_When_Stretched()
{
var target = new TestControl
{
MeasureResult = new Size(100, 100),
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Margin = new Thickness(8),
};
target.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
target.Arrange(new Rect(0, 0, 200, 200));
Assert.Equal(new Size(184, 184), target.ArrangeFinalSize);
}
[Fact]
public void Arrange_With_IsMeasureValid_False_Calls_Measure()
{
@ -32,14 +82,24 @@ namespace Perspex.Layout.UnitTests
Assert.Equal(new Size(120, 120), target.MeasureConstraint);
}
private class TestControl : Border
private class TestControl : Decorator
{
public Size MeasureConstraint { get; private set; }
public Size MeasureResult { get; set; }
public Size ArrangeFinalSize { get; private set; }
protected override Size MeasureOverride(Size constraint)
{
MeasureConstraint = constraint;
return base.MeasureOverride(constraint);
return MeasureResult;
}
protected override Size ArrangeOverride(Size finalSize)
{
ArrangeFinalSize = finalSize;
return base.ArrangeOverride(finalSize);
}
}
}

15
tests/Perspex.Layout.UnitTests/MeasureTests.cs

@ -8,6 +8,21 @@ namespace Perspex.Layout.UnitTests
{
public class MeasureTests
{
[Fact]
public void Margin_Should_Be_Included_In_DesiredSize()
{
var decorator = new Decorator
{
Width = 100,
Height = 100,
Margin = new Thickness(8),
};
decorator.Measure(Size.Infinity);
Assert.Equal(new Size(116, 116), decorator.DesiredSize);
}
[Fact]
public void Invalidating_Child_Should_Not_Invalidate_Parent()
{

Loading…
Cancel
Save