// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Controls.Primitives { using System; using Collections; using Perspex.Controls.Presenters; using Perspex.Interactivity; using Perspex.Media; using Perspex.Platform; using Perspex.VisualTree; using Splat; /// /// The root window of a . /// public class PopupRoot : TopLevel, IInteractive, IHostedVisualTreeRoot { private IDisposable presenterSubscription; /// /// Initializes static members of the class. /// static PopupRoot() { BackgroundProperty.OverrideDefaultValue(typeof(PopupRoot), Brushes.White); } /// /// Initializes a new instance of the class. /// public PopupRoot() : this(null) { } /// /// Initializes a new instance of the class. /// /// /// The dependency resolver to use. If null the default dependency resolver will be used. /// public PopupRoot(IDependencyResolver dependencyResolver) : base(Locator.Current.GetService(), dependencyResolver) { this.GetObservable(ParentProperty).Subscribe(x => this.InheritanceParent = (PerspexObject)x); } /// /// Gets the platform-specific window implementation. /// public new IPopupImpl PlatformImpl { get { return (IPopupImpl)base.PlatformImpl; } } /// /// Gets the parent control in the event route. /// /// /// Popup events are passed to their parent window. This facilitates this. /// IInteractive IInteractive.InteractiveParent { get { return this.Parent; } } /// /// Gets the control that is hosting the popup root. /// IVisual IHostedVisualTreeRoot.Host { get { return this.Parent; } } /// /// Sets the position of the popup in screen coordinates. /// /// The position. public void SetPosition(Point p) { this.PlatformImpl.SetPosition(p); } /// /// Hides the popup. /// public void Hide() { this.PlatformImpl.Hide(); this.IsVisible = false; } /// /// Shows the popup. /// public void Show() { this.PlatformImpl.Show(); this.LayoutManager?.ExecuteLayoutPass(); this.IsVisible = true; } /// protected override void OnTemplateApplied() { base.OnTemplateApplied(); if (this.Parent.TemplatedParent != null) { if (this.presenterSubscription != null) { this.presenterSubscription.Dispose(); this.presenterSubscription = null; } var presenter = this.Presenter; if (presenter != null) { presenter.GetObservable(ContentPresenter.ChildProperty) .Subscribe(this.SetTemplatedParentAndApplyChildTemplates); } } } private void SetTemplatedParentAndApplyChildTemplates(IControl control) { var templatedParent = this.Parent.TemplatedParent; if (control.TemplatedParent == null) { control.SetValue(TemplatedParentProperty, templatedParent); } control.ApplyTemplate(); if (!(control is IPresenter && control.TemplatedParent == templatedParent)) { foreach (IControl child in control.GetVisualChildren()) { this.SetTemplatedParentAndApplyChildTemplates(child); } } } } }