Преглед на файлове

Merge pull request #9622 from danielmayost/fixes/moveFlowDirection

Move FlowFirection to Visual
Max Katz преди 2 години
родител
ревизия
511d7b5957

+ 90 - 0
src/Avalonia.Base/Visual.cs

@@ -89,6 +89,14 @@ namespace Avalonia
         public static readonly StyledProperty<RelativePoint> RenderTransformOriginProperty =
             AvaloniaProperty.Register<Visual, RelativePoint>(nameof(RenderTransformOrigin), defaultValue: RelativePoint.Center);
 
+        /// <summary>
+        /// Defines the <see cref="FlowDirection"/> property.
+        /// </summary>
+        public static readonly AttachedProperty<FlowDirection> FlowDirectionProperty =
+            AvaloniaProperty.RegisterAttached<Visual, Visual, FlowDirection>(
+                nameof(FlowDirection),
+                inherits: true);
+
         /// <summary>
         /// Defines the <see cref="VisualParent"/> property.
         /// </summary>
@@ -263,6 +271,15 @@ namespace Avalonia
             set { SetValue(RenderTransformOriginProperty, value); }
         }
 
+        /// <summary>
+        /// Gets or sets the text flow direction.
+        /// </summary>
+        public FlowDirection FlowDirection
+        {
+            get => GetValue(FlowDirectionProperty);
+            set => SetValue(FlowDirectionProperty, value);
+        }
+
         /// <summary>
         /// Gets or sets the Z index of the control.
         /// </summary>
@@ -306,6 +323,36 @@ namespace Avalonia
         /// </summary>
         internal Visual? VisualParent => _visualParent;
 
+        /// <summary>
+        /// Gets a value indicating whether control bypass FlowDirecton policies.
+        /// </summary>
+        /// <remarks>
+        /// Related to FlowDirection system and returns false as default, so if 
+        /// <see cref="FlowDirection"/> is RTL then control will get a mirror presentation. 
+        /// For controls that want to avoid this behavior, override this property and return true.
+        /// </remarks>
+        protected virtual bool BypassFlowDirectionPolicies => false;
+
+        /// <summary>
+        /// Gets the value of the attached <see cref="FlowDirectionProperty"/> on a control.
+        /// </summary>
+        /// <param name="visual">The control.</param>
+        /// <returns>The flow direction.</returns>
+        public static FlowDirection GetFlowDirection(Visual visual)
+        {
+            return visual.GetValue(FlowDirectionProperty);
+        }
+
+        /// <summary>
+        /// Sets the value of the attached <see cref="FlowDirectionProperty"/> on a control.
+        /// </summary>
+        /// <param name="visual">The control.</param>
+        /// <param name="value">The property value to set.</param>
+        public static void SetFlowDirection(Visual visual, FlowDirection value)
+        {
+            visual.SetValue(FlowDirectionProperty, value);
+        }
+
         /// <summary>
         /// Invalidates the visual and queues a repaint.
         /// </summary>
@@ -387,6 +434,22 @@ namespace Avalonia
             }
         }
 
+        /// <inheritdoc/>
+        protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+        {
+            base.OnPropertyChanged(change);
+
+            if (change.Property == FlowDirectionProperty)
+            {
+                InvalidateMirrorTransform();
+
+                foreach (var child in VisualChildren)
+                {
+                    child.InvalidateMirrorTransform();
+                }
+            }
+        }
+
         protected override void LogicalChildrenCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
         {
             base.LogicalChildrenCollectionChanged(sender, e);
@@ -682,5 +745,32 @@ namespace Avalonia
                 visual.SetVisualParent(parent);
             }
         }
+
+        /// <summary>
+        /// Computes the <see cref="HasMirrorTransform"/> value according to the 
+        /// <see cref="FlowDirection"/> and <see cref="BypassFlowDirectionPolicies"/>
+        /// </summary>
+        public virtual void InvalidateMirrorTransform()
+        {
+            var flowDirection = this.FlowDirection;
+            var parentFlowDirection = FlowDirection.LeftToRight;
+
+            bool bypassFlowDirectionPolicies = BypassFlowDirectionPolicies;
+            bool parentBypassFlowDirectionPolicies = false;
+
+            var parent = VisualParent;
+            if (parent != null)
+            {
+                parentFlowDirection = parent.FlowDirection;
+                parentBypassFlowDirectionPolicies = parent.BypassFlowDirectionPolicies;
+            }
+
+            bool thisShouldBeMirrored = flowDirection == FlowDirection.RightToLeft && !bypassFlowDirectionPolicies;
+            bool parentShouldBeMirrored = parentFlowDirection == FlowDirection.RightToLeft && !parentBypassFlowDirectionPolicies;
+
+            bool shouldApplyMirrorTransform = thisShouldBeMirrored != parentShouldBeMirrored;
+
+            HasMirrorTransform = shouldApplyMirrorTransform;
+        }
     }
 }

+ 2 - 3
src/Avalonia.Controls/ComboBox.cs

@@ -454,10 +454,9 @@ namespace Avalonia.Controls
         {
             if (SelectionBoxItem is Rectangle rectangle)
             {
-                if ((rectangle.Fill as VisualBrush)?.Visual is Control content)
+                if ((rectangle.Fill as VisualBrush)?.Visual is Visual content)
                 {
-                    var flowDirection = (((Visual)content!).VisualParent as Control)?.FlowDirection ?? 
-                        FlowDirection.LeftToRight;
+                    var flowDirection = content.VisualParent?.FlowDirection ?? FlowDirection.LeftToRight;
                     rectangle.FlowDirection = flowDirection;
                 }
             }

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

@@ -91,13 +91,6 @@ namespace Avalonia.Controls
             RoutedEvent.Register<Control, SizeChangedEventArgs>(
                 nameof(SizeChanged), RoutingStrategies.Direct);
 
-        /// <summary>
-        /// Defines the <see cref="FlowDirection"/> property.
-        /// </summary>
-        public static readonly AttachedProperty<FlowDirection> FlowDirectionProperty =
-            AvaloniaProperty.RegisterAttached<Control, Control, FlowDirection>(
-                nameof(FlowDirection),
-                inherits: true);
 
         // Note the following:
         // _loadedQueue :
@@ -170,15 +163,6 @@ namespace Avalonia.Controls
             get => GetValue(TagProperty);
             set => SetValue(TagProperty, value);
         }
-        
-        /// <summary>
-        /// Gets or sets the text flow direction.
-        /// </summary>
-        public FlowDirection FlowDirection
-        {
-            get => GetValue(FlowDirectionProperty);
-            set => SetValue(FlowDirectionProperty, value);
-        }
 
         /// <summary>
         /// Occurs when the user has completed a context input gesture, such as a right-click.
@@ -229,39 +213,9 @@ namespace Avalonia.Controls
 
         public new Control? Parent => (Control?)base.Parent;
 
-        /// <summary>
-        /// Gets the value of the attached <see cref="FlowDirectionProperty"/> on a control.
-        /// </summary>
-        /// <param name="control">The control.</param>
-        /// <returns>The flow direction.</returns>
-        public static FlowDirection GetFlowDirection(Control control)
-        {
-            return control.GetValue(FlowDirectionProperty);
-        }
-
-        /// <summary>
-        /// Sets the value of the attached <see cref="FlowDirectionProperty"/> on a control.
-        /// </summary>
-        /// <param name="control">The control.</param>
-        /// <param name="value">The property value to set.</param>
-        public static void SetFlowDirection(Control control, FlowDirection value)
-        {
-            control.SetValue(FlowDirectionProperty, value);
-        }
-
         /// <inheritdoc/>
         bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
 
-        /// <summary>
-        /// Gets a value indicating whether control bypass FlowDirecton policies.
-        /// </summary>
-        /// <remarks>
-        /// Related to FlowDirection system and returns false as default, so if 
-        /// <see cref="FlowDirection"/> is RTL then control will get a mirror presentation. 
-        /// For controls that want to avoid this behavior, override this property and return true.
-        /// </remarks>
-        protected virtual bool BypassFlowDirectionPolicies => false;
-
         /// <inheritdoc/>
         void ISetterValue.Initialize(ISetter setter)
         {
@@ -571,45 +525,6 @@ namespace Avalonia.Controls
                     RaiseEvent(sizeChangedEventArgs);
                 }
             }
-            else if (change.Property == FlowDirectionProperty)
-            {
-                InvalidateMirrorTransform();
-
-                foreach (var visual in VisualChildren)
-                {
-                    if (visual is Control child)
-                    {
-                        child.InvalidateMirrorTransform();
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Computes the <see cref="Visual.HasMirrorTransform"/> value according to the 
-        /// <see cref="FlowDirection"/> and <see cref="BypassFlowDirectionPolicies"/>
-        /// </summary>
-        public virtual void InvalidateMirrorTransform()
-        {
-            var flowDirection = this.FlowDirection;
-            var parentFlowDirection = FlowDirection.LeftToRight;
-
-            bool bypassFlowDirectionPolicies = BypassFlowDirectionPolicies;
-            bool parentBypassFlowDirectionPolicies = false;
-
-            var parent = this.VisualParent as Control;
-            if (parent != null)
-            {
-                parentFlowDirection = parent.FlowDirection;
-                parentBypassFlowDirectionPolicies = parent.BypassFlowDirectionPolicies;
-            }
-
-            bool thisShouldBeMirrored = flowDirection == FlowDirection.RightToLeft && !bypassFlowDirectionPolicies;
-            bool parentShouldBeMirrored = parentFlowDirection == FlowDirection.RightToLeft && !parentBypassFlowDirectionPolicies;
-
-            bool shouldApplyMirrorTransform = thisShouldBeMirrored != parentShouldBeMirrored;
-
-            HasMirrorTransform = shouldApplyMirrorTransform;
         }
     }
 }

+ 0 - 6
src/Avalonia.Controls/TopLevel.cs

@@ -357,12 +357,6 @@ namespace Avalonia.Controls
         /// </summary>
         protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager(this);
 
-        public override void InvalidateMirrorTransform()
-        {
-        }
-        
-        protected override bool BypassFlowDirectionPolicies => true;
-        
         /// <summary>
         /// Handles a paint notification from <see cref="ITopLevelImpl.Resized"/>.
         /// </summary>

+ 16 - 11
tests/Avalonia.Controls.UnitTests/FlowDirectionTests.cs → tests/Avalonia.Base.UnitTests/FlowDirectionTests.cs

@@ -8,7 +8,7 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void HasMirrorTransform_Should_Be_True()
         {
-            var target = new Control
+            var target = new Visual
             {
                 FlowDirection = FlowDirection.RightToLeft,
             };
@@ -19,31 +19,36 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void HasMirrorTransform_Of_LTR_Children_Should_Be_True_For_RTL_Parent()
         {
-            Control child;
-            var target = new Decorator
+            var child = new Visual()
+            {
+                FlowDirection = FlowDirection.LeftToRight,
+            };
+
+            var target = new Visual
             {
                 FlowDirection = FlowDirection.RightToLeft,
-                Child = child = new Control()
             };
+            target.VisualChildren.Add(child);
 
-            child.FlowDirection = FlowDirection.LeftToRight;
+            child.InvalidateMirrorTransform();
 
             Assert.True(target.HasMirrorTransform);
             Assert.True(child.HasMirrorTransform);  
         }
 
         [Fact]
-        public void HasMirrorTransform_Of_Children_Is_Updated_After_Parent_Changeed()
+        public void HasMirrorTransform_Of_Children_Is_Updated_After_Parent_Changed()
         {
-            Control child;
+            var child = new Visual()
+            {
+                FlowDirection = FlowDirection.LeftToRight,
+            };
+
             var target = new Decorator
             {
                 FlowDirection = FlowDirection.LeftToRight,
-                Child = child = new Control()
-                {
-                    FlowDirection = FlowDirection.LeftToRight,
-                }
             };
+            target.VisualChildren.Add(child);
 
             Assert.False(target.HasMirrorTransform);
             Assert.False(child.HasMirrorTransform);