// 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 Perspex.Metadata; namespace Perspex.Controls { /// /// Base class for controls which decorate a single child control. /// public class Decorator : Control { /// /// Defines the property. /// public static readonly StyledProperty ChildProperty = PerspexProperty.Register(nameof(Child)); /// /// Defines the property. /// public static readonly StyledProperty PaddingProperty = PerspexProperty.Register(nameof(Padding)); /// /// Initializes static members of the class. /// static Decorator() { ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); } /// /// Gets or sets the decorated control. /// [Content] public Control Child { get { return GetValue(ChildProperty); } set { SetValue(ChildProperty, value); } } /// /// Gets or sets the padding to place around the control. /// public Thickness Padding { get { return GetValue(PaddingProperty); } set { SetValue(PaddingProperty, value); } } /// protected override Size MeasureOverride(Size availableSize) { var content = Child; var padding = 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 = Child; content?.Arrange(new Rect(finalSize).Deflate(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); LogicalChildren.Clear(); VisualChildren.Remove(oldChild); } if (newChild != null) { ((ISetLogicalParent)newChild).SetParent(this); VisualChildren.Add(newChild); LogicalChildren.Add(newChild); } } } }