diff --git a/src/Avalonia.Controls/ContextMenu.cs b/src/Avalonia.Controls/ContextMenu.cs index 456af7bdde..5929dd39d4 100644 --- a/src/Avalonia.Controls/ContextMenu.cs +++ b/src/Avalonia.Controls/ContextMenu.cs @@ -20,7 +20,6 @@ namespace Avalonia.Controls /// public class ContextMenu : MenuBase, ISetterValue { - /// /// Defines the property. /// @@ -39,6 +38,12 @@ namespace Avalonia.Controls public static readonly StyledProperty PlacementAnchorProperty = Popup.PlacementAnchorProperty.AddOwner(); + /// + /// Defines the property. + /// + public static readonly StyledProperty PlacementConstraintAdjustmentProperty = + Popup.PlacementConstraintAdjustmentProperty.AddOwner(); + /// /// Defines the property. /// @@ -124,6 +129,16 @@ namespace Avalonia.Controls set { SetValue(PlacementAnchorProperty, value); } } + /// + /// Gets or sets a value describing how the context menu position will be adjusted if the + /// unadjusted position would result in the context menu being partly constrained. + /// + public PopupPositionerConstraintAdjustment PlacementConstraintAdjustment + { + get { return GetValue(PlacementConstraintAdjustmentProperty); } + set { SetValue(PlacementConstraintAdjustmentProperty, value); } + } + /// /// Gets or sets a value which defines in what direction the context menu should open /// when is . @@ -245,6 +260,7 @@ namespace Avalonia.Controls HorizontalOffset = HorizontalOffset, VerticalOffset = VerticalOffset, PlacementAnchor = PlacementAnchor, + PlacementConstraintAdjustment = PlacementConstraintAdjustment, PlacementGravity = PlacementGravity, PlacementMode = PlacementMode, PlacementRect = PlacementRect, diff --git a/src/Avalonia.Controls/Primitives/IPopupHost.cs b/src/Avalonia.Controls/Primitives/IPopupHost.cs index 18fb45fd5a..e424bf683d 100644 --- a/src/Avalonia.Controls/Primitives/IPopupHost.cs +++ b/src/Avalonia.Controls/Primitives/IPopupHost.cs @@ -52,6 +52,7 @@ namespace Avalonia.Controls.Primitives void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, + PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, Rect? rect = null); /// diff --git a/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs b/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs index 9584585d87..20ada95773 100644 --- a/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs +++ b/src/Avalonia.Controls/Primitives/OverlayPopupHost.cs @@ -72,10 +72,11 @@ namespace Avalonia.Controls.Primitives public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, + PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, Rect? rect = null) { _positionerParameters.ConfigurePosition((TopLevel)_overlayLayer.GetVisualRoot(), target, placement, offset, anchor, - gravity, rect); + gravity, constraintAdjustment, rect); UpdatePosition(); } diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index dcc59cc76d..f3ccc89b2a 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -41,6 +41,14 @@ namespace Avalonia.Controls.Primitives public static readonly StyledProperty PlacementAnchorProperty = AvaloniaProperty.Register(nameof(PlacementAnchor)); + /// + /// Defines the property. + /// + public static readonly StyledProperty PlacementConstraintAdjustmentProperty = + AvaloniaProperty.Register( + nameof(PlacementConstraintAdjustment), + PopupPositionerConstraintAdjustment.FlipX | PopupPositionerConstraintAdjustment.FlipY); + /// /// Defines the property. /// @@ -165,6 +173,16 @@ namespace Avalonia.Controls.Primitives set { SetValue(PlacementAnchorProperty, value); } } + /// + /// Gets or sets a value describing how the popup position will be adjusted if the + /// unadjusted position would result in the popup being partly constrained. + /// + public PopupPositionerConstraintAdjustment PlacementConstraintAdjustment + { + get { return GetValue(PlacementConstraintAdjustmentProperty); } + set { SetValue(PlacementConstraintAdjustmentProperty, value); } + } + /// /// Gets or sets a value which defines in what direction the popup should open /// when is . @@ -311,6 +329,7 @@ namespace Avalonia.Controls.Primitives new Point(HorizontalOffset, VerticalOffset), PlacementAnchor, PlacementGravity, + PlacementConstraintAdjustment, PlacementRect); DeferCleanup(SubscribeToEventHandler>(popupHost, RootTemplateApplied, diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs index 54b7f7a1c6..7771823014 100644 --- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs +++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs @@ -428,13 +428,14 @@ namespace Avalonia.Controls.Primitives.PopupPositioning public static void ConfigurePosition(ref this PopupPositionerParameters positionerParameters, TopLevel topLevel, IVisual target, PlacementMode placement, Point offset, - PopupAnchor anchor, PopupGravity gravity, Rect? rect) + PopupAnchor anchor, PopupGravity gravity, + PopupPositionerConstraintAdjustment constraintAdjustment, Rect? rect) { // We need a better way for tracking the last pointer position var pointer = topLevel.PointToClient(topLevel.PlatformImpl.MouseDevice.Position); positionerParameters.Offset = offset; - positionerParameters.ConstraintAdjustment = PopupPositionerConstraintAdjustment.All; + positionerParameters.ConstraintAdjustment = constraintAdjustment; if (placement == PlacementMode.Pointer) { positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1)); diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs index 66d7012168..6c0de7a1dd 100644 --- a/src/Avalonia.Controls/Primitives/PopupRoot.cs +++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs @@ -84,10 +84,11 @@ namespace Avalonia.Controls.Primitives public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, + PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All, Rect? rect = null) { _positionerParameters.ConfigurePosition(_parent, target, - placement, offset, anchor, gravity, rect); + placement, offset, anchor, gravity, constraintAdjustment, rect); if (_positionerParameters.Size != default) UpdatePosition();