Browse Source

>implement FlowDirection on Popup

pull/7810/head
daniel mayost 5 years ago
parent
commit
780ea035a3
  1. 29
      src/Avalonia.Controls/MenuItem.cs
  2. 2
      src/Avalonia.Controls/Primitives/OverlayPopupHost.cs
  3. 30
      src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs
  4. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  5. 2
      src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

29
src/Avalonia.Controls/MenuItem.cs

@ -411,33 +411,6 @@ namespace Avalonia.Controls
} }
} }
public override void InvalidateFlowDirection()
{
if (_popup != null && Parent is Menu)
{
var popupAnchor = FlowDirection == FlowDirection.LeftToRight ?
PopupAnchor.BottomLeft : PopupAnchor.BottomRight;
var popupGravity = FlowDirection == FlowDirection.LeftToRight ?
PopupGravity.BottomRight : PopupGravity.BottomLeft;
var placement = FlowDirection == FlowDirection.LeftToRight ?
PlacementMode.Right : PlacementMode.Left;
_popup.PlacementAnchor = popupAnchor;
_popup.PlacementGravity = popupGravity;
}
else if (_popup != null)
{
var placement = FlowDirection == FlowDirection.LeftToRight ?
PlacementMode.Right : PlacementMode.Left;
_popup.PlacementMode = placement;
}
base.InvalidateFlowDirection();
}
/// <summary> /// <summary>
/// Called when the <see cref="MenuItem"/> is clicked. /// Called when the <see cref="MenuItem"/> is clicked.
/// </summary> /// </summary>
@ -522,8 +495,6 @@ namespace Avalonia.Controls
_popup.Opened += PopupOpened; _popup.Opened += PopupOpened;
_popup.Closed += PopupClosed; _popup.Closed += PopupClosed;
} }
InvalidateFlowDirection();
} }
protected override AutomationPeer OnCreateAutomationPeer() protected override AutomationPeer OnCreateAutomationPeer()

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

@ -76,7 +76,7 @@ namespace Avalonia.Controls.Primitives
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, constraintAdjustment, rect); gravity, constraintAdjustment, rect, FlowDirection);
UpdatePosition(); UpdatePosition();
} }

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

@ -46,6 +46,7 @@ Copyright © 2019 Nikita Tsukanov
using System; using System;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Avalonia.Media;
namespace Avalonia.Controls.Primitives.PopupPositioning namespace Avalonia.Controls.Primitives.PopupPositioning
{ {
@ -444,7 +445,8 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
TopLevel topLevel, TopLevel topLevel,
IVisual target, PlacementMode placement, Point offset, IVisual target, PlacementMode placement, Point offset,
PopupAnchor anchor, PopupGravity gravity, PopupAnchor anchor, PopupGravity gravity,
PopupPositionerConstraintAdjustment constraintAdjustment, Rect? rect) PopupPositionerConstraintAdjustment constraintAdjustment, Rect? rect,
FlowDirection flowDirection)
{ {
// We need a better way for tracking the last pointer position // We need a better way for tracking the last pointer position
#pragma warning disable CS0618 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete
@ -503,6 +505,32 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
else else
throw new InvalidOperationException("Invalid value for Popup.PlacementMode"); throw new InvalidOperationException("Invalid value for Popup.PlacementMode");
} }
// Invert coordinate system if FlowDirection is RTL
if (flowDirection == FlowDirection.RightToLeft)
{
if ((positionerParameters.Anchor & PopupAnchor.Right) == PopupAnchor.Right)
{
positionerParameters.Anchor ^= PopupAnchor.Right;
positionerParameters.Anchor |= PopupAnchor.Left;
}
else if ((positionerParameters.Anchor & PopupAnchor.Left) == PopupAnchor.Left)
{
positionerParameters.Anchor ^= PopupAnchor.Left;
positionerParameters.Anchor |= PopupAnchor.Right;
}
if ((positionerParameters.Gravity & PopupGravity.Right) == PopupGravity.Right)
{
positionerParameters.Gravity ^= PopupGravity.Right;
positionerParameters.Gravity |= PopupGravity.Left;
}
else if ((positionerParameters.Gravity & PopupGravity.Left) == PopupGravity.Left)
{
positionerParameters.Gravity ^= PopupGravity.Left;
positionerParameters.Gravity |= PopupGravity.Right;
}
}
} }
} }

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

@ -92,7 +92,7 @@ namespace Avalonia.Controls.Primitives
Rect? rect = null) Rect? rect = null)
{ {
_positionerParameters.ConfigurePosition(_parent, target, _positionerParameters.ConfigurePosition(_parent, target,
placement, offset, anchor, gravity, constraintAdjustment, rect); placement, offset, anchor, gravity, constraintAdjustment, rect, FlowDirection);
if (_positionerParameters.Size != default) if (_positionerParameters.Size != default)
UpdatePosition(); UpdatePosition();

2
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

@ -111,6 +111,7 @@
</Border> </Border>
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
WindowManagerAddShadowHint="False" WindowManagerAddShadowHint="False"
PlacementMode="Right"
HorizontalOffset="{DynamicResource MenuFlyoutSubItemPopupHorizontalOffset}" HorizontalOffset="{DynamicResource MenuFlyoutSubItemPopupHorizontalOffset}"
IsLightDismissEnabled="False" IsLightDismissEnabled="False"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"> IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}">
@ -159,7 +160,6 @@
</ContentPresenter> </ContentPresenter>
<Popup Name="PART_Popup" <Popup Name="PART_Popup"
WindowManagerAddShadowHint="False" WindowManagerAddShadowHint="False"
PlacementMode="AnchorAndGravity"
MinWidth="{ReflectionBinding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}" MinWidth="{ReflectionBinding Bounds.Width, RelativeSource={RelativeSource TemplatedParent}}"
IsLightDismissEnabled="True" IsLightDismissEnabled="True"
IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}" IsOpen="{TemplateBinding IsSubMenuOpen, Mode=TwoWay}"

Loading…
Cancel
Save