daniel mayost 3 роки тому
батько
коміт
3eddf5cac4

+ 8 - 0
samples/ControlCatalog/MainView.xaml

@@ -187,6 +187,14 @@
                 <WindowTransparencyLevel>Mica</WindowTransparencyLevel>
               </ComboBox.Items>
             </ComboBox>
+            <ComboBox x:Name="FlowDirection"
+                      HorizontalAlignment="Stretch"
+                      SelectedIndex="0">
+              <ComboBox.Items>
+                <FlowDirection>LeftToRight</FlowDirection>
+                <FlowDirection>RightToLeft</FlowDirection>
+              </ComboBox.Items>
+            </ComboBox>
             <ComboBox HorizontalAlignment="Stretch"
                       Items="{Binding WindowStates}"
                       SelectedItem="{Binding WindowState}" />

+ 9 - 0
samples/ControlCatalog/MainView.xaml.cs

@@ -76,6 +76,15 @@ namespace ControlCatalog
                 }
             };
 
+            var flowDirections = this.Find<ComboBox>("FlowDirection");
+            flowDirections.SelectionChanged += (sender, e) =>
+            {
+                if (flowDirections.SelectedItem is FlowDirection flowDirection)
+                {
+                    this.FlowDirection = flowDirection;
+                }
+            };
+
             var decorations = this.Find<ComboBox>("Decorations");
             decorations.SelectionChanged += (sender, e) =>
             {

+ 74 - 0
src/Avalonia.Controls/Control.cs

@@ -309,5 +309,79 @@ namespace Avalonia.Controls
                 }
             }
         }
+
+        static Control()
+        {
+            AffectsArrange<Control>(FlowDirectionProperty);
+        }
+
+        private bool _mirrorApplied;
+
+        protected virtual bool ShouldBeMirroredIfRightToLeft()
+        {
+            if (Parent is Control parent)
+            {
+                return parent.ShouldBeMirroredIfRightToLeft();
+            }
+            else
+            {
+                return true;
+            }
+        }
+
+        protected override void ArrangeCore(Rect finalRect)
+        {
+            base.ArrangeCore(finalRect);
+
+            FlowDirection parentFD = FlowDirection.LeftToRight;
+            FlowDirection thisFD = FlowDirection;
+            bool shouldBeMirroredIfRightToLeft = ShouldBeMirroredIfRightToLeft();
+
+            if (Parent is Control control)
+            {
+                parentFD = control.FlowDirection;
+            }
+            
+            bool shouldMirror;
+            if (shouldBeMirroredIfRightToLeft)
+            {
+                shouldMirror = ShuoldApplyMirrorTransform(parentFD, thisFD);
+                if (this is PopupRoot && thisFD == FlowDirection.RightToLeft)
+                {
+                    shouldMirror = true;
+                }
+            }
+            else
+            {
+                shouldMirror = ShuoldApplyMirrorTransform(parentFD, FlowDirection.LeftToRight);
+            }
+
+            if (shouldMirror)
+            {
+                ApplyMirrorTransform();
+            }
+            else
+            {
+                //RenderTransform = null;
+            }
+        }
+
+        private void ApplyMirrorTransform()
+        {
+            if (_mirrorApplied)
+            {
+                return;
+            }
+
+            var transform = new MatrixTransform(new Avalonia.Matrix(-1, 0, 0, 1, 0.0, 0.0));
+            RenderTransform = transform;
+            _mirrorApplied = true;
+        }
+
+        internal static bool ShuoldApplyMirrorTransform(FlowDirection parentFD, FlowDirection thisFD)
+        {
+            return ((parentFD == FlowDirection.LeftToRight && thisFD == FlowDirection.RightToLeft) ||
+                    (parentFD == FlowDirection.RightToLeft && thisFD == FlowDirection.LeftToRight));
+        }
     }
 }

+ 2 - 0
src/Avalonia.Controls/TextBlock.cs

@@ -612,5 +612,7 @@ namespace Avalonia.Controls
         {
             InvalidateTextLayout();
         }
+
+        protected override bool ShouldBeMirroredIfRightToLeft() => false;
     }
 }

+ 2 - 0
src/Avalonia.Controls/TextBox.cs

@@ -1504,5 +1504,7 @@ namespace Avalonia.Controls
                 }
             }
         }
+
+        protected override bool ShouldBeMirroredIfRightToLeft() => false;
     }
 }