diff --git a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
index 9d4abec549..373386e259 100644
--- a/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
+++ b/src/Avalonia.Controls/Flyouts/FlyoutBase.cs
@@ -29,8 +29,8 @@ namespace Avalonia.Controls.Primitives
///
/// Defines the property
///
- public static readonly StyledProperty PlacementProperty =
- AvaloniaProperty.Register(nameof(Placement));
+ public static readonly StyledProperty PlacementProperty =
+ AvaloniaProperty.Register(nameof(Placement));
///
/// Defines the property
@@ -87,7 +87,7 @@ namespace Avalonia.Controls.Primitives
///
/// Gets or sets the desired placement
///
- public FlyoutPlacementMode Placement
+ public PlacementMode Placement
{
get => GetValue(PlacementProperty);
set => SetValue(PlacementProperty, value);
@@ -452,93 +452,11 @@ namespace Avalonia.Controls.Primitives
}
else
{
- Popup.PlacementMode = PlacementMode.AnchorAndGravity;
+ Popup.PlacementMode = Placement;
Popup.PlacementConstraintAdjustment =
PopupPositioning.PopupPositionerConstraintAdjustment.SlideX |
PopupPositioning.PopupPositionerConstraintAdjustment.SlideY;
}
-
- var trgtBnds = Target?.Bounds ?? default;
-
- switch (Placement)
- {
- case FlyoutPlacementMode.Top: //Above & centered
- Popup.PlacementRect = new Rect(0, 0, trgtBnds.Width - 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.Top;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Top;
- break;
-
- case FlyoutPlacementMode.TopEdgeAlignedLeft:
- Popup.PlacementRect = new Rect(0, 0, 0, 0);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.TopRight;
- break;
-
- case FlyoutPlacementMode.TopEdgeAlignedRight:
- Popup.PlacementRect = new Rect(trgtBnds.Width - 1, 0, 10, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.TopLeft;
- break;
-
- case FlyoutPlacementMode.RightEdgeAlignedTop:
- Popup.PlacementRect = new Rect(trgtBnds.Width - 1, 0, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.BottomRight;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Right;
- break;
-
- case FlyoutPlacementMode.Right: //Right & centered
- Popup.PlacementRect = new Rect(trgtBnds.Width - 1, 0, 1, trgtBnds.Height);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.Right;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Right;
- break;
-
- case FlyoutPlacementMode.RightEdgeAlignedBottom:
- Popup.PlacementRect = new Rect(trgtBnds.Width - 1, trgtBnds.Height - 1, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.TopRight;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Right;
- break;
-
- case FlyoutPlacementMode.Bottom: //Below & centered
- Popup.PlacementRect = new Rect(0, trgtBnds.Height - 1, trgtBnds.Width, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.Bottom;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Bottom;
- break;
-
- case FlyoutPlacementMode.BottomEdgeAlignedLeft:
- Popup.PlacementRect = new Rect(0, trgtBnds.Height - 1, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.BottomRight;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Bottom;
- break;
-
- case FlyoutPlacementMode.BottomEdgeAlignedRight:
- Popup.PlacementRect = new Rect(trgtBnds.Width - 1, trgtBnds.Height - 1, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.BottomLeft;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Bottom;
- break;
-
- case FlyoutPlacementMode.LeftEdgeAlignedTop:
- Popup.PlacementRect = new Rect(0, 0, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.BottomLeft;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Left;
- break;
-
- case FlyoutPlacementMode.Left: //Left & centered
- Popup.PlacementRect = new Rect(0, 0, 1, trgtBnds.Height);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.Left;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.Left;
- break;
-
- case FlyoutPlacementMode.LeftEdgeAlignedBottom:
- Popup.PlacementRect = new Rect(0, trgtBnds.Height - 1, 1, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.TopLeft;
- Popup.PlacementAnchor = PopupPositioning.PopupAnchor.BottomLeft;
- break;
-
- //includes Auto (not sure what determines that)...
- default:
- //This is just FlyoutPlacementMode.Top behavior (above & centered)
- Popup.PlacementRect = new Rect(-sz.Width / 2, 0, sz.Width, 1);
- Popup.PlacementGravity = PopupPositioning.PopupGravity.Top;
- break;
- }
}
private static void OnContextFlyoutPropertyChanged(AvaloniaPropertyChangedEventArgs args)
diff --git a/src/Avalonia.Controls/Flyouts/FlyoutPlacementMode.cs b/src/Avalonia.Controls/Flyouts/FlyoutPlacementMode.cs
deleted file mode 100644
index 2e77de3b3b..0000000000
--- a/src/Avalonia.Controls/Flyouts/FlyoutPlacementMode.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-namespace Avalonia.Controls
-{
- public enum FlyoutPlacementMode
- {
- ///
- /// Preferred location is above the target element
- ///
- Top = 0,
-
- ///
- /// Preferred location is below the target element
- ///
- Bottom = 1,
-
- ///
- /// Preferred location is to the left of the target element
- ///
- Left = 2,
-
- ///
- /// Preferred location is to the right of the target element
- ///
- Right = 3,
-
- //TODO
- //
- // Preferred location is centered on the screen
- //
- //Full = 4,
-
- ///
- /// Preferred location is above the target element, with the left edge of the flyout
- /// aligned with the left edge of the target element
- ///
- TopEdgeAlignedLeft = 5,
-
- ///
- /// Preferred location is above the target element, with the right edge of flyout aligned with right edge of the target element.
- ///
- TopEdgeAlignedRight = 6,
-
- ///
- /// Preferred location is below the target element, with the left edge of flyout aligned with left edge of the target element.
- ///
- BottomEdgeAlignedLeft = 7,
-
- ///
- /// Preferred location is below the target element, with the right edge of flyout aligned with right edge of the target element.
- ///
- BottomEdgeAlignedRight = 8,
-
- ///
- /// Preferred location is to the left of the target element, with the top edge of flyout aligned with top edge of the target element.
- ///
- LeftEdgeAlignedTop = 9,
-
- ///
- /// Preferred location is to the left of the target element, with the bottom edge of flyout aligned with bottom edge of the target element.
- ///
- LeftEdgeAlignedBottom = 10,
-
- ///
- /// Preferred location is to the right of the target element, with the top edge of flyout aligned with top edge of the target element.
- ///
- RightEdgeAlignedTop = 11,
-
- ///
- /// Preferred location is to the right of the target element, with the bottom edge of flyout aligned with bottom edge of the target element.
- ///
- RightEdgeAlignedBottom = 12,
-
- ///
- /// Preferred location is determined automatically.
- ///
- Auto = 13
- }
-}
diff --git a/src/Avalonia.Controls/PlacementMode.cs b/src/Avalonia.Controls/PlacementMode.cs
index 68a4b9eecb..fa4f029cf3 100644
--- a/src/Avalonia.Controls/PlacementMode.cs
+++ b/src/Avalonia.Controls/PlacementMode.cs
@@ -13,28 +13,69 @@ namespace Avalonia.Controls
Pointer,
///
- /// The popup is placed at the bottom left of its target.
+ /// Preferred location is below the target element.
///
Bottom,
///
- /// The popup is placed at the top right of its target.
+ /// Preferred location is to the right of the target element.
///
Right,
///
- /// The popup is placed at the top left of its target.
+ /// Preferred location is to the left of the target element.
///
Left,
///
- /// The popup is placed at the top left of its target.
+ /// Preferred location is above the target element.
///
Top,
+
+ ///
+ /// The popup is placed according to and rules.
+ ///
+ AnchorAndGravity,
///
- /// The popup is placed according to anchor and gravity rules
+ /// Preferred location is above the target element, with the left edge of the popup
+ /// aligned with the left edge of the target element.
+ ///
+ TopEdgeAlignedLeft,
+
+ ///
+ /// Preferred location is above the target element, with the right edge of popup aligned with right edge of the target element.
+ ///
+ TopEdgeAlignedRight,
+
+ ///
+ /// Preferred location is below the target element, with the left edge of popup aligned with left edge of the target element.
+ ///
+ BottomEdgeAlignedLeft,
+
+ ///
+ /// Preferred location is below the target element, with the right edge of popup aligned with right edge of the target element.
+ ///
+ BottomEdgeAlignedRight,
+
+ ///
+ /// Preferred location is to the left of the target element, with the top edge of popup aligned with top edge of the target element.
+ ///
+ LeftEdgeAlignedTop,
+
+ ///
+ /// Preferred location is to the left of the target element, with the bottom edge of popup aligned with bottom edge of the target element.
+ ///
+ LeftEdgeAlignedBottom,
+
+ ///
+ /// Preferred location is to the right of the target element, with the top edge of popup aligned with top edge of the target element.
+ ///
+ RightEdgeAlignedTop,
+
+ ///
+ /// Preferred location is to the right of the target element, with the bottom edge of popup aligned with bottom edge of the target element.
///
- AnchorAndGravity
+ RightEdgeAlignedBottom
}
}
diff --git a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs
index 2e70947457..0bb596d778 100644
--- a/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs
+++ b/src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs
@@ -480,33 +480,26 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
var anchorRect = rect ?? bounds;
positionerParameters.AnchorRectangle = anchorRect.Intersect(bounds).TransformToAABB(matrix.Value);
- if (placement == PlacementMode.Right)
+ var parameters = placement switch
{
- positionerParameters.Anchor = PopupAnchor.TopRight;
- positionerParameters.Gravity = PopupGravity.BottomRight;
- }
- else if (placement == PlacementMode.Bottom)
- {
- positionerParameters.Anchor = PopupAnchor.BottomLeft;
- positionerParameters.Gravity = PopupGravity.BottomRight;
- }
- else if (placement == PlacementMode.Left)
- {
- positionerParameters.Anchor = PopupAnchor.TopLeft;
- positionerParameters.Gravity = PopupGravity.BottomLeft;
- }
- else if (placement == PlacementMode.Top)
- {
- positionerParameters.Anchor = PopupAnchor.TopLeft;
- positionerParameters.Gravity = PopupGravity.TopRight;
- }
- else if (placement == PlacementMode.AnchorAndGravity)
- {
- positionerParameters.Anchor = anchor;
- positionerParameters.Gravity = gravity;
- }
- else
- throw new InvalidOperationException("Invalid value for Popup.PlacementMode");
+ PlacementMode.Bottom => (PopupAnchor.Bottom, PopupGravity.Bottom),
+ PlacementMode.Right => (PopupAnchor.Right, PopupGravity.Right),
+ PlacementMode.Left => (PopupAnchor.Left, PopupGravity.Left),
+ PlacementMode.Top => (PopupAnchor.Top, PopupGravity.Top),
+ PlacementMode.AnchorAndGravity => (anchor, gravity),
+ PlacementMode.TopEdgeAlignedRight => (PopupAnchor.TopRight, PopupGravity.TopLeft),
+ PlacementMode.TopEdgeAlignedLeft => (PopupAnchor.TopLeft, PopupGravity.TopRight),
+ PlacementMode.BottomEdgeAlignedLeft => (PopupAnchor.BottomLeft, PopupGravity.BottomRight),
+ PlacementMode.BottomEdgeAlignedRight => (PopupAnchor.BottomRight, PopupGravity.BottomLeft),
+ PlacementMode.LeftEdgeAlignedTop => (PopupAnchor.TopLeft, PopupGravity.BottomLeft),
+ PlacementMode.LeftEdgeAlignedBottom => (PopupAnchor.BottomLeft, PopupGravity.TopLeft),
+ PlacementMode.RightEdgeAlignedTop => (PopupAnchor.TopRight, PopupGravity.BottomRight),
+ PlacementMode.RightEdgeAlignedBottom => (PopupAnchor.BottomRight, PopupGravity.TopRight),
+ _ => throw new ArgumentOutOfRangeException(nameof(placement), placement,
+ "Invalid value for Popup.PlacementMode")
+ };
+ positionerParameters.Anchor = parameters.Item1;
+ positionerParameters.Gravity = parameters.Item2;
}
// Invert coordinate system if FlowDirection is RTL