From bd6e7c214fa222df57102ebf6eac6deeef915104 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 14 May 2023 16:43:40 +0300 Subject: [PATCH 1/4] fix!: Change `Measure`/`Arrange` to not be virtual --- src/Uno.UI/UI/Xaml/FrameworkElement.cs | 44 ------------------ src/Uno.UI/UI/Xaml/FrameworkElement.net.cs | 20 --------- src/Uno.UI/UI/Xaml/UIElement.cs | 52 +++++++++++++++++++++- src/Uno.UI/UI/Xaml/UIElement.net.cs | 20 +++++++++ 4 files changed, 70 insertions(+), 66 deletions(-) diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.cs index 38aac51ad124..1f3347d62783 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkElement.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkElement.cs @@ -268,50 +268,6 @@ protected virtual Size ArrangeOverride(Size finalSize) } } -#if !UNO_REFERENCE_API - /// - /// Updates the DesiredSize of a UIElement. Typically, objects that implement custom layout for their - /// layout children call this method from their own MeasureOverride implementations to form a recursive layout update. - /// - /// - /// The available space that a parent can allocate to a child object. A child object can request a larger - /// space than what is available; the provided size might be accommodated if scrolling or other resize behavior is - /// possible in that particular container. - /// - /// The measured size. - /// - /// Under Uno.UI, this method should not be called during the normal layouting phase. Instead, use the - /// methods, which handles native view properly. - /// - public override void Measure(Size availableSize) - { - if (double.IsNaN(availableSize.Width) || double.IsNaN(availableSize.Height)) - { - throw new InvalidOperationException($"Cannot measure [{GetType()}] with NaN"); - } - - _layouter.Measure(availableSize); -#if IS_UNIT_TESTS - OnMeasurePartial(availableSize); -#endif - } - - /// - /// Positions child objects and determines a size for a UIElement. Parent objects that implement custom layout - /// for their child elements should call this method from their layout override implementations to form a recursive layout update. - /// - /// The final size that the parent computes for the child in layout, provided as a value. - public override void Arrange(Rect finalRect) - { - _layouter.Arrange(finalRect); - _layouter.ArrangeChild(this, finalRect); - } -#endif - -#if IS_UNIT_TESTS - partial void OnMeasurePartial(Size slotSize); -#endif - /// /// Measures an native element, in the same way would do. /// diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.net.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.net.cs index 744402494e4d..b2fe08805737 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkElement.net.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkElement.net.cs @@ -83,26 +83,6 @@ protected internal override void OnInvalidateMeasure() base.OnInvalidateMeasure(); } - partial void OnMeasurePartial(Size slotSize) - { - MeasureCallCount++; - AvailableMeasureSize = slotSize; - - if (DesiredSizeSelector != null) - { - var desiredSize = DesiredSizeSelector(slotSize); - - LayoutInformation.SetDesiredSize(this, desiredSize); - RequestedDesiredSize = desiredSize; - } - else if (RequestedDesiredSize != null) - { - var desiredSize = RequestedDesiredSize.Value; - - LayoutInformation.SetDesiredSize(this, desiredSize); - } - } - internal void InternalArrange(Rect frame) { _layouter.Arrange(frame); diff --git a/src/Uno.UI/UI/Xaml/UIElement.cs b/src/Uno.UI/UI/Xaml/UIElement.cs index 8e8d995ce884..ee2cf39720d1 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.cs @@ -883,12 +883,60 @@ internal static string SetDependencyPropertyValueInternal(DependencyObject owner internal Rect? ClippedFrame; #endif - public virtual void Measure(Size availableSize) + /// + /// Updates the DesiredSize of a UIElement. Typically, objects that implement custom layout for their + /// layout children call this method from their own MeasureOverride implementations to form a recursive layout update. + /// + /// + /// The available space that a parent can allocate to a child object. A child object can request a larger + /// space than what is available; the provided size might be accommodated if scrolling or other resize behavior is + /// possible in that particular container. + /// + /// The measured size. + /// + /// Under Uno.UI, this method should not be called during the normal layouting phase. Instead, use the + /// methods, which handles native view properly. + /// + public void Measure(Size availableSize) { +#if !UNO_REFERENCE_API + if (this is not FrameworkElement fwe) + { + return; + } + + if (double.IsNaN(availableSize.Width) || double.IsNaN(availableSize.Height)) + { + throw new InvalidOperationException($"Cannot measure [{GetType()}] with NaN"); + } + + ((ILayouterElement)fwe).Layouter.Measure(availableSize); +#if IS_UNIT_TESTS + OnMeasurePartial(availableSize); +#endif +#endif } - public virtual void Arrange(Rect finalRect) +#if IS_UNIT_TESTS + partial void OnMeasurePartial(Size slotSize); +#endif + + /// + /// Positions child objects and determines a size for a UIElement. Parent objects that implement custom layout + /// for their child elements should call this method from their layout override implementations to form a recursive layout update. + /// + /// The final size that the parent computes for the child in layout, provided as a value. + public void Arrange(Rect finalRect) { +#if !UNO_REFERENCE_API + if (this is not FrameworkElement fwe) + { + return; + } + + ((ILayouterElement)fwe).Layouter.Arrange(finalRect); + ((ILayouterElement)fwe).Layouter.ArrangeChild(fwe, finalRect); +#endif } public void InvalidateMeasure() diff --git a/src/Uno.UI/UI/Xaml/UIElement.net.cs b/src/Uno.UI/UI/Xaml/UIElement.net.cs index 239e1b838bad..ff9ba323ba0a 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.net.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.net.cs @@ -60,5 +60,25 @@ internal void AddChild(UIElement child, int? index = null) { child.SetParent(this); } + + partial void OnMeasurePartial(Size slotSize) + { + MeasureCallCount++; + AvailableMeasureSize = slotSize; + + if (DesiredSizeSelector != null) + { + var desiredSize = DesiredSizeSelector(slotSize); + + LayoutInformation.SetDesiredSize(this, desiredSize); + RequestedDesiredSize = desiredSize; + } + else if (RequestedDesiredSize != null) + { + var desiredSize = RequestedDesiredSize.Value; + + LayoutInformation.SetDesiredSize(this, desiredSize); + } + } } } From 9b76521add91711a7133d2821b00ea5718fe10fc Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 14 May 2023 19:24:48 +0300 Subject: [PATCH 2/4] chore: Add missing using --- src/Uno.UI/UI/Xaml/UIElement.net.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Uno.UI/UI/Xaml/UIElement.net.cs b/src/Uno.UI/UI/Xaml/UIElement.net.cs index ff9ba323ba0a..1bc070cdecc3 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.net.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.net.cs @@ -4,6 +4,7 @@ using Uno; using Uno.Extensions; using Windows.Foundation; +using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; From 5412031daa227e834aeba41c35f107974841fdfd Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 14 May 2023 19:26:02 +0300 Subject: [PATCH 3/4] chore: Update PackageDiffIgnore.xml --- build/PackageDiffIgnore.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/PackageDiffIgnore.xml b/build/PackageDiffIgnore.xml index d6474cde6b13..67c6e2ecf2ab 100644 --- a/build/PackageDiffIgnore.xml +++ b/build/PackageDiffIgnore.xml @@ -1257,7 +1257,8 @@ - + + From ae2168f2f95f3768a7bbc68880c4d3e7e43094f4 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 15 May 2023 20:31:34 +0300 Subject: [PATCH 4/4] chore: Address review comment --- src/Uno.UI/UI/Xaml/UIElement.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Uno.UI/UI/Xaml/UIElement.cs b/src/Uno.UI/UI/Xaml/UIElement.cs index ee2cf39720d1..b58853310f67 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.cs @@ -934,8 +934,9 @@ public void Arrange(Rect finalRect) return; } - ((ILayouterElement)fwe).Layouter.Arrange(finalRect); - ((ILayouterElement)fwe).Layouter.ArrangeChild(fwe, finalRect); + var layouter = ((ILayouterElement)fwe).Layouter; + layouter.Arrange(finalRect); + layouter.ArrangeChild(fwe, finalRect); #endif }