Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: Change Measure/Arrange to not be virtual #12294

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build/PackageDiffIgnore.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,8 @@
<Member fullName="System.Void Windows.UI.Xaml.Media.Animation.Timeline.Dispose()" reason="Api alignments" />

<Member fullName="System.Void Windows.UI.Xaml.Window.set_Visible(System.Boolean value)" reason="Does not exist in UWP and WinUI" />

<Member fullName="System.Void Windows.UI.Xaml.UIElement.Arrange(Windows.Foundation.Rect finalRect)" reason="Api alignments" />
<Member fullName="System.Void Windows.UI.Xaml.UIElement.Measure(Windows.Foundation.Size availableSize)" reason="Api alignments" />
<Member fullName="System.Object Uno.UI.Svg.GlobalStaticResources.FindResource(System.String name)" reason="API Alignment" />
<Member fullName="System.Void Windows.Devices.Sensors.SimpleOrientationSensor.OnAccuracyChanged(Android.Hardware.Sensor sensor, Android.Hardware.SensorStatus accuracy)" reason="Api alignments" />
<Member fullName="System.Void Windows.Devices.Sensors.SimpleOrientationSensor.OnSensorChanged(Android.Hardware.SensorEvent e)" reason="Api alignments" />
Expand Down
44 changes: 0 additions & 44 deletions src/Uno.UI/UI/Xaml/FrameworkElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,50 +268,6 @@ protected virtual Size ArrangeOverride(Size finalSize)
}
}

#if !UNO_REFERENCE_API
/// <summary>
/// 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.
/// </summary>
/// <param name="availableSize">
/// 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.
/// </param>
/// <returns>The measured size.</returns>
/// <remarks>
/// Under Uno.UI, this method should not be called during the normal layouting phase. Instead, use the
/// <see cref="MeasureElement(View, Size)"/> methods, which handles native view properly.
/// </remarks>
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
}

/// <summary>
/// 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.
/// </summary>
/// <param name="finalRect">The final size that the parent computes for the child in layout, provided as a <see cref="Windows.Foundation.Rect"/> value.</param>
public override void Arrange(Rect finalRect)
{
_layouter.Arrange(finalRect);
_layouter.ArrangeChild(this, finalRect);
}
#endif

#if IS_UNIT_TESTS
partial void OnMeasurePartial(Size slotSize);
#endif

/// <summary>
/// Measures an native element, in the same way <see cref="Measure"/> would do.
/// </summary>
Expand Down
20 changes: 0 additions & 20 deletions src/Uno.UI/UI/Xaml/FrameworkElement.net.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
52 changes: 50 additions & 2 deletions src/Uno.UI/UI/Xaml/UIElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -883,12 +883,60 @@ internal static string SetDependencyPropertyValueInternal(DependencyObject owner
internal Rect? ClippedFrame;
#endif

public virtual void Measure(Size availableSize)
/// <summary>
/// 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.
/// </summary>
/// <param name="availableSize">
/// 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.
/// </param>
/// <returns>The measured size.</returns>
/// <remarks>
/// Under Uno.UI, this method should not be called during the normal layouting phase. Instead, use the
/// <see cref="MeasureElement(View, Size)"/> methods, which handles native view properly.
/// </remarks>
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

/// <summary>
/// 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.
/// </summary>
/// <param name="finalRect">The final size that the parent computes for the child in layout, provided as a <see cref="Windows.Foundation.Rect"/> value.</param>
public void Arrange(Rect finalRect)
{
#if !UNO_REFERENCE_API
if (this is not FrameworkElement fwe)
{
return;
}

((ILayouterElement)fwe).Layouter.Arrange(finalRect);
Youssef1313 marked this conversation as resolved.
Show resolved Hide resolved
((ILayouterElement)fwe).Layouter.ArrangeChild(fwe, finalRect);
#endif
}

public void InvalidateMeasure()
Expand Down
21 changes: 21 additions & 0 deletions src/Uno.UI/UI/Xaml/UIElement.net.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -60,5 +61,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);
}
}
}
}