diff --git a/src/Perspex.Controls/Presenters/ContentPresenter.cs b/src/Perspex.Controls/Presenters/ContentPresenter.cs index 246db77c46..42f300f763 100644 --- a/src/Perspex.Controls/Presenters/ContentPresenter.cs +++ b/src/Perspex.Controls/Presenters/ContentPresenter.cs @@ -1,9 +1,12 @@ // Copyright (c) The Perspex Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; +using Perspex.Layout; using Perspex.LogicalTree; +using Perspex.Media; namespace Perspex.Controls.Presenters { @@ -12,6 +15,24 @@ namespace Perspex.Controls.Presenters /// public class ContentPresenter : Control, IContentPresenter { + /// + /// Defines the property. + /// + public static readonly StyledProperty BackgroundProperty = + Border.BackgroundProperty.AddOwner(); + + /// + /// Defines the property. + /// + public static readonly PerspexProperty BorderBrushProperty = + Border.BorderBrushProperty.AddOwner(); + + /// + /// Defines the property. + /// + public static readonly StyledProperty BorderThicknessProperty = + Border.BorderThicknessProperty.AddOwner(); + /// /// Defines the property. /// @@ -26,6 +47,30 @@ namespace Perspex.Controls.Presenters public static readonly StyledProperty ContentProperty = ContentControl.ContentProperty.AddOwner(); + /// + /// Defines the property. + /// + public static readonly StyledProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(); + + /// + /// Defines the property. + /// + public static readonly StyledProperty HorizontalContentAlignmentProperty = + ContentControl.HorizontalContentAlignmentProperty.AddOwner(); + + /// + /// Defines the property. + /// + public static readonly StyledProperty VerticalContentAlignmentProperty = + ContentControl.VerticalContentAlignmentProperty.AddOwner(); + + /// + /// Defines the property. + /// + public static readonly StyledProperty PaddingProperty = + Border.PaddingProperty.AddOwner(); + private IControl _child; private bool _createdChild; @@ -38,6 +83,33 @@ namespace Perspex.Controls.Presenters TemplatedParentProperty.Changed.AddClassHandler(x => x.TemplatedParentChanged); } + /// + /// Gets or sets a brush with which to paint the background. + /// + public Brush Background + { + get { return GetValue(BackgroundProperty); } + set { SetValue(BackgroundProperty, value); } + } + + /// + /// Gets or sets a brush with which to paint the border. + /// + public Brush BorderBrush + { + get { return GetValue(BorderBrushProperty); } + set { SetValue(BorderBrushProperty, value); } + } + + /// + /// Gets or sets the thickness of the border. + /// + public double BorderThickness + { + get { return GetValue(BorderThicknessProperty); } + set { SetValue(BorderThicknessProperty, value); } + } + /// /// Gets the control displayed by the presenter. /// @@ -56,6 +128,42 @@ namespace Perspex.Controls.Presenters set { SetValue(ContentProperty, value); } } + /// + /// Gets or sets the radius of the border rounded corners. + /// + public float CornerRadius + { + get { return GetValue(CornerRadiusProperty); } + set { SetValue(CornerRadiusProperty, value); } + } + + /// + /// Gets or sets the horizontal alignment of the content within the control. + /// + public HorizontalAlignment HorizontalContentAlignment + { + get { return GetValue(HorizontalContentAlignmentProperty); } + set { SetValue(HorizontalContentAlignmentProperty, value); } + } + + /// + /// Gets or sets the vertical alignment of the content within the control. + /// + public VerticalAlignment VerticalContentAlignment + { + get { return GetValue(VerticalContentAlignmentProperty); } + set { SetValue(VerticalContentAlignmentProperty, value); } + } + + /// + /// Gets or sets the padding to place around the control. + /// + public Thickness Padding + { + get { return GetValue(PaddingProperty); } + set { SetValue(PaddingProperty, value); } + } + /// public override sealed void ApplyTemplate() { @@ -120,23 +228,93 @@ namespace Perspex.Controls.Presenters } /// - protected override Size MeasureCore(Size availableSize) + public override void Render(DrawingContext context) { - return base.MeasureCore(availableSize); + var background = Background; + var borderBrush = BorderBrush; + var borderThickness = BorderThickness; + var cornerRadius = CornerRadius; + var rect = new Rect(Bounds.Size).Deflate(BorderThickness); + + if (background != null) + { + context.FillRectangle(background, rect, cornerRadius); + } + + if (borderBrush != null && borderThickness > 0) + { + context.DrawRectangle(new Pen(borderBrush, borderThickness), rect, cornerRadius); + } } /// protected override Size MeasureOverride(Size availableSize) { var child = Child; + var padding = Padding + new Thickness(BorderThickness); if (child != null) { - child.Measure(availableSize); - return child.DesiredSize; + child.Measure(availableSize.Deflate(padding)); + return child.DesiredSize.Inflate(padding); + } + else + { + return new Size(padding.Left + padding.Right, padding.Bottom + padding.Top); + } + } + + /// + protected override Size ArrangeOverride(Size finalSize) + { + var child = Child; + + if (child != null) + { + var padding = Padding + new Thickness(BorderThickness); + var sizeMinusPadding = finalSize.Deflate(padding); + var size = sizeMinusPadding; + var horizontalAlignment = HorizontalContentAlignment; + var verticalAlignment = VerticalContentAlignment; + var originX = padding.Left; + var originY = padding.Top; + + if (horizontalAlignment != HorizontalAlignment.Stretch) + { + size = size.WithWidth(child.DesiredSize.Width); + } + + if (verticalAlignment != VerticalAlignment.Stretch) + { + size = size.WithHeight(child.DesiredSize.Height); + } + + switch (horizontalAlignment) + { + case HorizontalAlignment.Stretch: + case HorizontalAlignment.Center: + originX += (sizeMinusPadding.Width - size.Width) / 2; + break; + case HorizontalAlignment.Right: + originX = size.Width - child.DesiredSize.Width; + break; + } + + switch (verticalAlignment) + { + case VerticalAlignment.Stretch: + case VerticalAlignment.Center: + originY += (sizeMinusPadding.Height - size.Height) / 2; + break; + case VerticalAlignment.Bottom: + originY = size.Height - child.DesiredSize.Height; + break; + } + + child.Arrange(new Rect(originX, originY, size.Width, size.Height)); } - return new Size(); + return finalSize; } /// diff --git a/src/Perspex.Layout/Layoutable.cs b/src/Perspex.Layout/Layoutable.cs index 354f279e07..af4ee13853 100644 --- a/src/Perspex.Layout/Layoutable.cs +++ b/src/Perspex.Layout/Layoutable.cs @@ -536,20 +536,22 @@ namespace Perspex.Layout { if (IsVisible) { - double originX = finalRect.X + Margin.Left; - double originY = finalRect.Y + Margin.Top; + 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 horizontalAlignment = HorizontalAlignment; + var verticalAlignment = VerticalAlignment; var size = sizeMinusMargins; var scale = GetLayoutScale(); - if (HorizontalAlignment != HorizontalAlignment.Stretch) + if (horizontalAlignment != HorizontalAlignment.Stretch) { size = size.WithWidth(Math.Min(size.Width, DesiredSize.Width)); } - if (VerticalAlignment != VerticalAlignment.Stretch) + if (verticalAlignment != VerticalAlignment.Stretch) { size = size.WithHeight(Math.Min(size.Height, DesiredSize.Height)); } @@ -568,7 +570,7 @@ namespace Perspex.Layout size = ArrangeOverride(size).Constrain(size); - switch (HorizontalAlignment) + switch (horizontalAlignment) { case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: @@ -579,7 +581,7 @@ namespace Perspex.Layout break; } - switch (VerticalAlignment) + switch (verticalAlignment) { case VerticalAlignment.Center: case VerticalAlignment.Stretch: diff --git a/src/Perspex.Themes.Default/Button.xaml b/src/Perspex.Themes.Default/Button.xaml index baf85381bc..114849b131 100644 --- a/src/Perspex.Themes.Default/Button.xaml +++ b/src/Perspex.Themes.Default/Button.xaml @@ -9,24 +9,22 @@ - - - + - - \ No newline at end of file diff --git a/src/Perspex.Themes.Default/DropDownItem.xaml b/src/Perspex.Themes.Default/DropDownItem.xaml index e2853da9aa..26bbe9959b 100644 --- a/src/Perspex.Themes.Default/DropDownItem.xaml +++ b/src/Perspex.Themes.Default/DropDownItem.xaml @@ -3,21 +3,19 @@ - - - + - - \ No newline at end of file diff --git a/src/Perspex.Themes.Default/ListBoxItem.xaml b/src/Perspex.Themes.Default/ListBoxItem.xaml index 7896e521aa..784731d57b 100644 --- a/src/Perspex.Themes.Default/ListBoxItem.xaml +++ b/src/Perspex.Themes.Default/ListBoxItem.xaml @@ -2,21 +2,19 @@ - - \ No newline at end of file diff --git a/src/Perspex.Themes.Default/PopupRoot.xaml b/src/Perspex.Themes.Default/PopupRoot.xaml index 4f620a25e2..cbd5da2081 100644 --- a/src/Perspex.Themes.Default/PopupRoot.xaml +++ b/src/Perspex.Themes.Default/PopupRoot.xaml @@ -2,11 +2,10 @@ - - - + \ No newline at end of file diff --git a/src/Perspex.Themes.Default/TabStripItem.xaml b/src/Perspex.Themes.Default/TabStripItem.xaml index 3af1f98f82..e32de4613b 100644 --- a/src/Perspex.Themes.Default/TabStripItem.xaml +++ b/src/Perspex.Themes.Default/TabStripItem.xaml @@ -4,13 +4,12 @@ - - - + Padding="{TemplateBinding Padding}"/> diff --git a/src/Perspex.Themes.Default/ToggleButton.xaml b/src/Perspex.Themes.Default/ToggleButton.xaml index 90b80129c6..03354c9b27 100644 --- a/src/Perspex.Themes.Default/ToggleButton.xaml +++ b/src/Perspex.Themes.Default/ToggleButton.xaml @@ -4,33 +4,31 @@ + - - - + - - - \ No newline at end of file diff --git a/src/Perspex.Themes.Default/TreeViewItem.xaml b/src/Perspex.Themes.Default/TreeViewItem.xaml index f5fc37f236..61dc149977 100644 --- a/src/Perspex.Themes.Default/TreeViewItem.xaml +++ b/src/Perspex.Themes.Default/TreeViewItem.xaml @@ -7,16 +7,14 @@ - - - + - - -