Browse Source

>implement FlowDirection on Popup

daniel mayost 3 năm trước cách đây
mục cha
commit
780ea035a3

+ 0 - 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>
         /// Called when the <see cref="MenuItem"/> is clicked.
         /// </summary>
@@ -522,8 +495,6 @@ namespace Avalonia.Controls
                 _popup.Opened += PopupOpened;
                 _popup.Closed += PopupClosed;
             }
-
-            InvalidateFlowDirection();
         }
 
         protected override AutomationPeer OnCreateAutomationPeer()

+ 1 - 1
src/Avalonia.Controls/Primitives/OverlayPopupHost.cs

@@ -76,7 +76,7 @@ namespace Avalonia.Controls.Primitives
             Rect? rect = null)
         {
             _positionerParameters.ConfigurePosition((TopLevel)_overlayLayer.GetVisualRoot()!, target, placement, offset, anchor,
-                gravity, constraintAdjustment, rect);
+                gravity, constraintAdjustment, rect, FlowDirection);
             UpdatePosition();
         }
 

+ 29 - 1
src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs

@@ -46,6 +46,7 @@ Copyright © 2019 Nikita Tsukanov
 
 using System;
 using Avalonia.VisualTree;
+using Avalonia.Media;
 
 namespace Avalonia.Controls.Primitives.PopupPositioning
 {
@@ -444,7 +445,8 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             TopLevel topLevel,
             IVisual target, PlacementMode placement, Point offset,
             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
 #pragma warning disable CS0618 // Type or member is obsolete
@@ -503,6 +505,32 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
                 else
                     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;
+                }
+            }
         }
     }
 

+ 1 - 1
src/Avalonia.Controls/Primitives/PopupRoot.cs

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

+ 1 - 1
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

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