Browse Source

Added PlacementConstraintAdjustment property.

To `Popup` and `ContextMenu`. Set default value to be `FlipX | FlipY` to try to match WPF's defaults.
pull/3970/head
Steven Kirk 6 years ago
parent
commit
3780d1e8b5
  1. 18
      src/Avalonia.Controls/ContextMenu.cs
  2. 1
      src/Avalonia.Controls/Primitives/IPopupHost.cs
  3. 3
      src/Avalonia.Controls/Primitives/OverlayPopupHost.cs
  4. 19
      src/Avalonia.Controls/Primitives/Popup.cs
  5. 5
      src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs
  6. 3
      src/Avalonia.Controls/Primitives/PopupRoot.cs

18
src/Avalonia.Controls/ContextMenu.cs

@ -20,7 +20,6 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public class ContextMenu : MenuBase, ISetterValue public class ContextMenu : MenuBase, ISetterValue
{ {
/// <summary> /// <summary>
/// Defines the <see cref="HorizontalOffset"/> property. /// Defines the <see cref="HorizontalOffset"/> property.
/// </summary> /// </summary>
@ -39,6 +38,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<PopupAnchor> PlacementAnchorProperty = public static readonly StyledProperty<PopupAnchor> PlacementAnchorProperty =
Popup.PlacementAnchorProperty.AddOwner<ContextMenu>(); Popup.PlacementAnchorProperty.AddOwner<ContextMenu>();
/// <summary>
/// Defines the <see cref="PlacementConstraintAdjustment"/> property.
/// </summary>
public static readonly StyledProperty<PopupPositionerConstraintAdjustment> PlacementConstraintAdjustmentProperty =
Popup.PlacementConstraintAdjustmentProperty.AddOwner<ContextMenu>();
/// <summary> /// <summary>
/// Defines the <see cref="PlacementGravity"/> property. /// Defines the <see cref="PlacementGravity"/> property.
/// </summary> /// </summary>
@ -124,6 +129,16 @@ namespace Avalonia.Controls
set { SetValue(PlacementAnchorProperty, value); } set { SetValue(PlacementAnchorProperty, value); }
} }
/// <summary>
/// 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.
/// </summary>
public PopupPositionerConstraintAdjustment PlacementConstraintAdjustment
{
get { return GetValue(PlacementConstraintAdjustmentProperty); }
set { SetValue(PlacementConstraintAdjustmentProperty, value); }
}
/// <summary> /// <summary>
/// Gets or sets a value which defines in what direction the context menu should open /// Gets or sets a value which defines in what direction the context menu should open
/// when <see cref="PlacementMode"/> is <see cref="PlacementMode.AnchorAndGravity"/>. /// when <see cref="PlacementMode"/> is <see cref="PlacementMode.AnchorAndGravity"/>.
@ -245,6 +260,7 @@ namespace Avalonia.Controls
HorizontalOffset = HorizontalOffset, HorizontalOffset = HorizontalOffset,
VerticalOffset = VerticalOffset, VerticalOffset = VerticalOffset,
PlacementAnchor = PlacementAnchor, PlacementAnchor = PlacementAnchor,
PlacementConstraintAdjustment = PlacementConstraintAdjustment,
PlacementGravity = PlacementGravity, PlacementGravity = PlacementGravity,
PlacementMode = PlacementMode, PlacementMode = PlacementMode,
PlacementRect = PlacementRect, PlacementRect = PlacementRect,

1
src/Avalonia.Controls/Primitives/IPopupHost.cs

@ -52,6 +52,7 @@ namespace Avalonia.Controls.Primitives
void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, void ConfigurePosition(IVisual target, PlacementMode placement, Point offset,
PopupAnchor anchor = PopupAnchor.None, PopupAnchor anchor = PopupAnchor.None,
PopupGravity gravity = PopupGravity.None, PopupGravity gravity = PopupGravity.None,
PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All,
Rect? rect = null); Rect? rect = null);
/// <summary> /// <summary>

3
src/Avalonia.Controls/Primitives/OverlayPopupHost.cs

@ -72,10 +72,11 @@ namespace Avalonia.Controls.Primitives
public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset,
PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None, PopupAnchor anchor = PopupAnchor.None, PopupGravity gravity = PopupGravity.None,
PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All,
Rect? rect = null) Rect? rect = null)
{ {
_positionerParameters.ConfigurePosition((TopLevel)_overlayLayer.GetVisualRoot(), target, placement, offset, anchor, _positionerParameters.ConfigurePosition((TopLevel)_overlayLayer.GetVisualRoot(), target, placement, offset, anchor,
gravity, rect); gravity, constraintAdjustment, rect);
UpdatePosition(); UpdatePosition();
} }

19
src/Avalonia.Controls/Primitives/Popup.cs

@ -44,6 +44,14 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<PopupAnchor> PlacementAnchorProperty = public static readonly StyledProperty<PopupAnchor> PlacementAnchorProperty =
AvaloniaProperty.Register<Popup, PopupAnchor>(nameof(PlacementAnchor)); AvaloniaProperty.Register<Popup, PopupAnchor>(nameof(PlacementAnchor));
/// <summary>
/// Defines the <see cref="PlacementConstraintAdjustment"/> property.
/// </summary>
public static readonly StyledProperty<PopupPositionerConstraintAdjustment> PlacementConstraintAdjustmentProperty =
AvaloniaProperty.Register<Popup, PopupPositionerConstraintAdjustment>(
nameof(PlacementConstraintAdjustment),
PopupPositionerConstraintAdjustment.FlipX | PopupPositionerConstraintAdjustment.FlipY);
/// <summary> /// <summary>
/// Defines the <see cref="PlacementGravity"/> property. /// Defines the <see cref="PlacementGravity"/> property.
/// </summary> /// </summary>
@ -174,6 +182,16 @@ namespace Avalonia.Controls.Primitives
set { SetValue(PlacementAnchorProperty, value); } set { SetValue(PlacementAnchorProperty, value); }
} }
/// <summary>
/// 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.
/// </summary>
public PopupPositionerConstraintAdjustment PlacementConstraintAdjustment
{
get { return GetValue(PlacementConstraintAdjustmentProperty); }
set { SetValue(PlacementConstraintAdjustmentProperty, value); }
}
/// <summary> /// <summary>
/// Gets or sets a value which defines in what direction the popup should open /// Gets or sets a value which defines in what direction the popup should open
/// when <see cref="PlacementMode"/> is <see cref="PlacementMode.AnchorAndGravity"/>. /// when <see cref="PlacementMode"/> is <see cref="PlacementMode.AnchorAndGravity"/>.
@ -320,6 +338,7 @@ namespace Avalonia.Controls.Primitives
new Point(HorizontalOffset, VerticalOffset), new Point(HorizontalOffset, VerticalOffset),
PlacementAnchor, PlacementAnchor,
PlacementGravity, PlacementGravity,
PlacementConstraintAdjustment,
PlacementRect); PlacementRect);
DeferCleanup(SubscribeToEventHandler<IPopupHost, EventHandler<TemplateAppliedEventArgs>>(popupHost, RootTemplateApplied, DeferCleanup(SubscribeToEventHandler<IPopupHost, EventHandler<TemplateAppliedEventArgs>>(popupHost, RootTemplateApplied,

5
src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs

@ -428,13 +428,14 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
public static void ConfigurePosition(ref this PopupPositionerParameters positionerParameters, public static void ConfigurePosition(ref this PopupPositionerParameters positionerParameters,
TopLevel topLevel, TopLevel topLevel,
IVisual target, PlacementMode placement, Point offset, 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 // We need a better way for tracking the last pointer position
var pointer = topLevel.PointToClient(topLevel.PlatformImpl.MouseDevice.Position); var pointer = topLevel.PointToClient(topLevel.PlatformImpl.MouseDevice.Position);
positionerParameters.Offset = offset; positionerParameters.Offset = offset;
positionerParameters.ConstraintAdjustment = PopupPositionerConstraintAdjustment.All; positionerParameters.ConstraintAdjustment = constraintAdjustment;
if (placement == PlacementMode.Pointer) if (placement == PlacementMode.Pointer)
{ {
positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1)); positionerParameters.AnchorRectangle = new Rect(pointer, new Size(1, 1));

3
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -84,10 +84,11 @@ namespace Avalonia.Controls.Primitives
public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset, public void ConfigurePosition(IVisual target, PlacementMode placement, Point offset,
PopupAnchor anchor = PopupAnchor.None, PopupAnchor anchor = PopupAnchor.None,
PopupGravity gravity = PopupGravity.None, PopupGravity gravity = PopupGravity.None,
PopupPositionerConstraintAdjustment constraintAdjustment = PopupPositionerConstraintAdjustment.All,
Rect? rect = null) Rect? rect = null)
{ {
_positionerParameters.ConfigurePosition(_parent, target, _positionerParameters.ConfigurePosition(_parent, target,
placement, offset, anchor, gravity, rect); placement, offset, anchor, gravity, constraintAdjustment, rect);
if (_positionerParameters.Size != default) if (_positionerParameters.Size != default)
UpdatePosition(); UpdatePosition();

Loading…
Cancel
Save