diff --git a/Perspex.Controls/Perspex.Controls.csproj b/Perspex.Controls/Perspex.Controls.csproj index 763a0e5c58..5bcb9abb4f 100644 --- a/Perspex.Controls/Perspex.Controls.csproj +++ b/Perspex.Controls/Perspex.Controls.csproj @@ -50,6 +50,7 @@ + diff --git a/Perspex.Controls/PlacementMode.cs b/Perspex.Controls/PlacementMode.cs new file mode 100644 index 0000000000..89e848177a --- /dev/null +++ b/Perspex.Controls/PlacementMode.cs @@ -0,0 +1,14 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Controls +{ + public enum PlacementMode + { + Bottom, + Right, + } +} diff --git a/Perspex.Controls/Popup.cs b/Perspex.Controls/Popup.cs index a54518fb4d..3924bd38ec 100644 --- a/Perspex.Controls/Popup.cs +++ b/Perspex.Controls/Popup.cs @@ -10,6 +10,7 @@ namespace Perspex.Controls using Perspex.Interactivity; using Perspex.Platform; using Perspex.Rendering; + using Perspex.VisualTree; public class Popup : Control { @@ -19,6 +20,9 @@ namespace Perspex.Controls public static readonly PerspexProperty IsOpenProperty = PerspexProperty.Register("IsOpen"); + public static readonly PerspexProperty PlacementModeProperty = + PerspexProperty.Register("PlacementMode", defaultValue: PlacementMode.Bottom); + public static readonly PerspexProperty PlacementTargetProperty = PerspexProperty.Register("PlacementTarget"); @@ -61,6 +65,12 @@ namespace Perspex.Controls set { this.SetValue(IsOpenProperty, value); } } + public PlacementMode PlacementMode + { + get { return this.GetValue(PlacementModeProperty); } + set { this.SetValue(PlacementModeProperty, value); } + } + public Control PlacementTarget { get { return this.GetValue(PlacementTargetProperty); } @@ -130,9 +140,24 @@ namespace Perspex.Controls private Point GetPosition() { - if (this.PlacementTarget != null) + var target = this.PlacementTarget ?? this.GetVisualParent(); + Point point; + + switch (this.PlacementMode) + { + case PlacementMode.Bottom: + point = target.Bounds.BottomLeft; + break; + case PlacementMode.Right: + point = target.Bounds.TopRight; + break; + default: + throw new InvalidOperationException("Invalid value for Popup.PlacementMode"); + } + + if (target != null) { - return this.PlacementTarget.PointToScreen(new Point(0, this.PlacementTarget.Bounds.Size.Height)); + return target.PointToScreen(point); } else { diff --git a/Perspex.Themes.Default/MenuItemStyle.cs b/Perspex.Themes.Default/MenuItemStyle.cs index 6ec245baef..b22cf9d391 100644 --- a/Perspex.Themes.Default/MenuItemStyle.cs +++ b/Perspex.Themes.Default/MenuItemStyle.cs @@ -188,6 +188,7 @@ namespace Perspex.Themes.Default (popup = new Popup { Name = "popup", + PlacementMode = PlacementMode.Right, StaysOpen = true, [!!Popup.IsOpenProperty] = control[!!MenuItem.IsSubMenuOpenProperty], Child = new Border