// -----------------------------------------------------------------------
//
// 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);
}
}
}
}
}