// ----------------------------------------------------------------------- // // Copyright 2015 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Controls { using Perspex.Collections; /// /// Base class for controls which decorate a single child control. /// public class Decorator : Control, IVisual, ILogical { /// /// Defines the property. /// public static readonly PerspexProperty ChildProperty = PerspexProperty.Register(nameof(Child)); /// /// Defines the property. /// public static readonly PerspexProperty PaddingProperty = PerspexProperty.Register(nameof(Padding)); private PerspexSingleItemList logicalChild = new PerspexSingleItemList(); /// /// Initializes static members of the class. /// static Decorator() { ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); } /// /// Gets or sets the decorated control. /// public Control Child { get { return this.GetValue(ChildProperty); } set { this.SetValue(ChildProperty, value); } } /// /// Gets or sets the padding to place around the control. /// public Thickness Padding { get { return this.GetValue(PaddingProperty); } set { this.SetValue(PaddingProperty, value); } } /// /// Gets the logical children of the control. /// IPerspexReadOnlyList ILogical.LogicalChildren { get { return this.logicalChild; } } /// protected override Size MeasureOverride(Size availableSize) { var content = this.Child; var padding = this.Padding; if (content != null) { content.Measure(availableSize.Deflate(padding)); return content.DesiredSize.Inflate(padding); } else { return new Size(padding.Left + padding.Right, padding.Bottom + padding.Top); } } /// protected override Size ArrangeOverride(Size finalSize) { Control content = this.Child; if (content != null) { content.Arrange(new Rect(finalSize).Deflate(this.Padding)); } return finalSize; } /// /// Called when the property changes. /// /// The event args. private void ChildChanged(PerspexPropertyChangedEventArgs e) { var oldChild = (Control)e.OldValue; var newChild = (Control)e.NewValue; if (oldChild != null) { ((ISetLogicalParent)oldChild).SetParent(null); this.RemoveVisualChild(oldChild); } if (newChild != null) { this.AddVisualChild(newChild); ((ISetLogicalParent)newChild).SetParent(this); } this.logicalChild.SingleItem = newChild; } } }