From d47163353bb99aa746d0e664b85b6be76fc57c0d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 24 Jun 2014 16:32:13 +0200 Subject: [PATCH] Moved alignment into child Control. --- Perspex.UnitTests/StyleTests.cs | 2 +- Perspex/Controls/Border.cs | 18 ++-- Perspex/Controls/ContentControl.cs | 4 +- Perspex/Controls/ContentPresenter.cs | 4 +- Perspex/Controls/Control.cs | 63 +++++++++++-- Perspex/Controls/Decorator.cs | 13 ++- Perspex/Controls/Grid.cs | 4 +- Perspex/Controls/StackPanel.cs | 4 +- Perspex/Controls/TextBlock.cs | 2 +- Perspex/Layout/LayoutHelper.cs | 86 ------------------ Perspex/Shapes/Rectangle.cs | 6 +- Perspex/Shapes/Shape.cs | 2 +- ..._Centers_Content_Horizontally.expected.png | Bin 832 -> 830 bytes ...er_Centers_Content_Vertically.expected.png | Bin 811 -> 811 bytes 14 files changed, 90 insertions(+), 118 deletions(-) diff --git a/Perspex.UnitTests/StyleTests.cs b/Perspex.UnitTests/StyleTests.cs index 0c51bb4552..7662869578 100644 --- a/Perspex.UnitTests/StyleTests.cs +++ b/Perspex.UnitTests/StyleTests.cs @@ -119,7 +119,7 @@ namespace Perspex.UnitTests set { this.SetValue(FooProperty, value); } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { throw new NotImplementedException(); } diff --git a/Perspex/Controls/Border.cs b/Perspex/Controls/Border.cs index a496d4c16c..b2c563df3b 100644 --- a/Perspex/Controls/Border.cs +++ b/Perspex/Controls/Border.cs @@ -42,16 +42,20 @@ namespace Perspex.Controls } } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { - return LayoutHelper.ArrangeDecorator( - this, - this.Content, - finalSize, - this.Padding + new Thickness(this.BorderThickness)); + Control content = this.Content; + + if (content != null) + { + Thickness padding = this.Padding + new Thickness(this.BorderThickness); + content.Arrange(new Rect(finalSize).Deflate(padding)); + } + + return finalSize; } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { return LayoutHelper.MeasureDecorator( this, diff --git a/Perspex/Controls/ContentControl.cs b/Perspex/Controls/ContentControl.cs index 4bc3d9b6aa..5cb7e47087 100644 --- a/Perspex/Controls/ContentControl.cs +++ b/Perspex/Controls/ContentControl.cs @@ -48,7 +48,7 @@ namespace Perspex.Controls } } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; @@ -63,7 +63,7 @@ namespace Perspex.Controls } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { if (this.Visibility != Visibility.Collapsed) { diff --git a/Perspex/Controls/ContentPresenter.cs b/Perspex/Controls/ContentPresenter.cs index 373c024633..4825ae175b 100644 --- a/Perspex/Controls/ContentPresenter.cs +++ b/Perspex/Controls/ContentPresenter.cs @@ -86,7 +86,7 @@ namespace Perspex.Controls } } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; @@ -143,7 +143,7 @@ namespace Perspex.Controls return finalSize; } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { if (this.Visibility != Visibility.Collapsed) { diff --git a/Perspex/Controls/Control.cs b/Perspex/Controls/Control.cs index abcb75ef17..bbdfddfc5a 100644 --- a/Perspex/Controls/Control.cs +++ b/Perspex/Controls/Control.cs @@ -332,17 +332,13 @@ namespace Perspex.Controls public void Arrange(Rect rect) { - Thickness margin = this.Margin; - - ((IVisual)this).Bounds = new Rect( - new Point(rect.Position.X + margin.Left, rect.Position.Y + margin.Top), - this.ArrangeContent(rect.Size.Deflate(margin).Constrain(rect.Size))); + this.ArrangeCore(rect); } public void Measure(Size availableSize) { availableSize = availableSize.Deflate(this.Margin); - this.DesiredSize = this.MeasureContent(availableSize).Constrain(availableSize); + this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize); } public void InvalidateArrange() @@ -365,12 +361,63 @@ namespace Perspex.Controls } } - protected virtual Size ArrangeContent(Size finalSize) + protected virtual void ArrangeCore(Rect finalRect) + { + double originX = finalRect.X + this.Margin.Left; + double originY = finalRect.Y + this.Margin.Top; + double sizeX = Math.Max(0, finalRect.Width - this.Margin.Left - this.Margin.Right); + double sizeY = Math.Max(0, finalRect.Height - this.Margin.Top - this.Margin.Bottom); + + if (this.HorizontalAlignment != HorizontalAlignment.Stretch) + { + sizeX = Math.Min(sizeX, this.DesiredSize.Value.Width); + } + + if (this.VerticalAlignment != VerticalAlignment.Stretch) + { + sizeY = Math.Min(sizeY, this.DesiredSize.Value.Height); + } + + Size taken = this.ArrangeOverride(new Size(sizeX, sizeY)); + + sizeX = Math.Min(taken.Width, sizeX); + sizeY = Math.Min(taken.Height, sizeY); + + switch (this.HorizontalAlignment) + { + case HorizontalAlignment.Center: + originX += (finalRect.Width - sizeX) / 2; + break; + case HorizontalAlignment.Right: + originX += finalRect.Width - sizeX; + break; + } + + switch (this.VerticalAlignment) + { + case VerticalAlignment.Center: + originY += (finalRect.Height - sizeY) / 2; + break; + case VerticalAlignment.Bottom: + originY += finalRect.Height - sizeY; + break; + } + + ((IVisual)this).Bounds = new Rect(originX, originY, sizeX, sizeY); + } + + protected virtual Size ArrangeOverride(Size finalSize) { return finalSize; } - protected virtual Size MeasureContent(Size availableSize) + protected virtual Size MeasureCore(Size availableSize) + { + availableSize = availableSize.Deflate(this.Margin); + return this.MeasureOverride(availableSize); + } + + protected virtual Size MeasureOverride(Size availableSize) { return new Size(); } diff --git a/Perspex/Controls/Decorator.cs b/Perspex/Controls/Decorator.cs index 9e9d77cf71..cd2e648f8e 100644 --- a/Perspex/Controls/Decorator.cs +++ b/Perspex/Controls/Decorator.cs @@ -64,12 +64,19 @@ namespace Perspex.Controls } } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { - return LayoutHelper.ArrangeDecorator(this, this.Content, finalSize, this.Padding); + Control content = this.Content; + + if (content != null) + { + content.Arrange(new Rect(finalSize).Deflate(this.Padding)); + } + + return finalSize; } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { return LayoutHelper.MeasureDecorator(this, this.Content, availableSize, this.Padding); } diff --git a/Perspex/Controls/Grid.cs b/Perspex/Controls/Grid.cs index 57d5c8bfb5..4cc626b139 100644 --- a/Perspex/Controls/Grid.cs +++ b/Perspex/Controls/Grid.cs @@ -88,7 +88,7 @@ namespace Perspex.Controls element.SetValue(RowSpanProperty, value); } - protected override Size MeasureContent(Size constraint) + protected override Size MeasureOverride(Size constraint) { Size totalSize = constraint; int colCount = this.ColumnDefinitions.Count; @@ -379,7 +379,7 @@ namespace Perspex.Controls return new Size(gridSizeX, gridSizeY); } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { int colCount = this.ColumnDefinitions.Count; int rowCount = this.RowDefinitions.Count; diff --git a/Perspex/Controls/StackPanel.cs b/Perspex/Controls/StackPanel.cs index 9a7ab81318..7c84004764 100644 --- a/Perspex/Controls/StackPanel.cs +++ b/Perspex/Controls/StackPanel.cs @@ -38,7 +38,7 @@ namespace Perspex.Controls set { this.SetValue(OrientationProperty, value); } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { if (this.Visibility != Visibility.Collapsed) { @@ -97,7 +97,7 @@ namespace Perspex.Controls return new Size(); } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { double arrangedWidth = finalSize.Width; double arrangedHeight = finalSize.Height; diff --git a/Perspex/Controls/TextBlock.cs b/Perspex/Controls/TextBlock.cs index 180ae42285..7d0e7bdd99 100644 --- a/Perspex/Controls/TextBlock.cs +++ b/Perspex/Controls/TextBlock.cs @@ -67,7 +67,7 @@ namespace Perspex.Controls } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { if (this.Visibility != Visibility.Collapsed) { diff --git a/Perspex/Layout/LayoutHelper.cs b/Perspex/Layout/LayoutHelper.cs index 94b15eceee..8665897b31 100644 --- a/Perspex/Layout/LayoutHelper.cs +++ b/Perspex/Layout/LayoutHelper.cs @@ -47,91 +47,5 @@ namespace Perspex.Layout return new Size(width, height); } - - public static Size ArrangeDecorator( - Control decorator, - Control content, - Size finalSize, - Thickness padding) - { - if (content != null) - { - Rect childRect = AlignChild( - new Rect(finalSize).Deflate(padding), - content.DesiredSize.Value, - content.HorizontalAlignment, - content.VerticalAlignment); - - content.Arrange(childRect); - } - - return finalSize; - } - - public static Rect AlignChild( - Rect parentRect, - Size desiredSize, - HorizontalAlignment horizontalAlignment, - VerticalAlignment verticalAlignment) - { - double x; - double y; - double width; - double height; - - switch (horizontalAlignment) - { - case HorizontalAlignment.Stretch: - width = parentRect.Width; - x = parentRect.X; - break; - - case HorizontalAlignment.Left: - width = desiredSize.Width; - x = parentRect.X; - break; - - case HorizontalAlignment.Center: - width = desiredSize.Width; - x = (parentRect.Width - width) / 2; - break; - - case HorizontalAlignment.Right: - width = desiredSize.Width; - x = parentRect.Right - width; - break; - - default: - throw new InvalidOperationException("Invalid HorizontalAlignment."); - } - - switch (verticalAlignment) - { - case VerticalAlignment.Stretch: - height = parentRect.Height; - y = parentRect.Y; - break; - - case VerticalAlignment.Top: - height = desiredSize.Height; - y = parentRect.Y; - break; - - case VerticalAlignment.Center: - height = desiredSize.Height; - y = (parentRect.Height - height) / 2; - break; - - case VerticalAlignment.Bottom: - height = desiredSize.Height; - y = parentRect.Bottom - height; - break; - - default: - throw new InvalidOperationException("Invalid VerticalAlignment."); - } - - return new Rect(x, y, width, height); - } } } diff --git a/Perspex/Shapes/Rectangle.cs b/Perspex/Shapes/Rectangle.cs index d62809f0fb..c386c14922 100644 --- a/Perspex/Shapes/Rectangle.cs +++ b/Perspex/Shapes/Rectangle.cs @@ -19,15 +19,15 @@ namespace Perspex.Shapes get { return new RectangleGeometry(new Rect(size)); } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { return new Size(this.Width, this.Height); } - protected override Size ArrangeContent(Size finalSize) + protected override Size ArrangeOverride(Size finalSize) { this.size = finalSize; - return base.ArrangeContent(finalSize); + return base.ArrangeOverride(finalSize); } } } diff --git a/Perspex/Shapes/Shape.cs b/Perspex/Shapes/Shape.cs index 068b5e8520..b5d0c8b140 100644 --- a/Perspex/Shapes/Shape.cs +++ b/Perspex/Shapes/Shape.cs @@ -58,7 +58,7 @@ namespace Perspex.Shapes set { this.SetValue(StrokeThicknessProperty, value); } } - protected override Size MeasureContent(Size availableSize) + protected override Size MeasureOverride(Size availableSize) { Rect shapeBounds = this.RenderedGeometry.Bounds; double width = this.Width; diff --git a/TestFiles/Direct2D1/Controls/Border/Border_Centers_Content_Horizontally.expected.png b/TestFiles/Direct2D1/Controls/Border/Border_Centers_Content_Horizontally.expected.png index c893b695e517ce3cb015b4965a9c7ca1c7c229a1..18ecd01c7a707b53da0ef2d890604cd900c6658c 100644 GIT binary patch literal 830 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg>4m3@V@O5Z+ZzXaFFPhBWn?|xYI zX7kH^+nOB&I9M7T1Wt(7N+nl4uoZe}; z`Fx`8^TVZO6SSqxzu(vXoY*rzxkmDF#;-S@CH5a%Q5@6mkay*Gs@>9ag|)M{Dcy=V zF!_JdT3ffd*5+y7EZ01(*>V18-HVC6tTBIQe}66UIsDnjU)I^rj~V`!xo+ZH-!rH9 z&qUq(sYjRQzbZ70>8~}rd;OlH0tZWz!zeL0!{E?oqv_LA+p4GV-TVM%xNb!1@J z*w6hZk(Ggg>6NF8V@O5Z+Z&E~mmL@!E>0`nz@&FP(1P<0^N}X&f@wyREmo|WBp<%< zl2)a^RIjLeWY1sIGC810K#+IkvC;J9scq3ycxxik9&}uPqmaGtGx1&cgTKDO}i|9w%REEl70Wj@}A0?ml1W-PM_Us zvwL2d00&d0^XI_VKNnwLZ^-vb=KbkaYdanvJM>m=GNY} z%*wKN+1s4uD^h*@>|edBUGK;0p8RB)Gw1j9eN6AMI$p~8WbV%$XO3U7ymt;_jO<_W z*H@CS>?}@BliqE5S3WLnv-~digTe~DWM4fKei74 delta 41 wcmZ3@wwi52665A{#u<#01DIGR|7VgAv07@`wl|~d69W)