Skip to content

Commit

Permalink
Merge pull request #13839 from Youssef1313/measure-override
Browse files Browse the repository at this point in the history
fix: Match FrameworkElement.[Measure|Arrange]Override with Windows
  • Loading branch information
jeromelaban authored Oct 12, 2023
2 parents 150557a + 74fd140 commit 26b9e38
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GtkMediaPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ private void UpdateVideoSizeAllocate(double playerHeight, double playerWidth, ui

protected override Size ArrangeOverride(Size finalSize)
{
var result = base.ArrangeOverride(finalSize);
var result = ArrangeFirstChild(finalSize);
UpdateVideoStretch();

return result;
Expand Down
2 changes: 2 additions & 0 deletions src/Uno.UI/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme")]
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme.v1")]
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme.v2")]
[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.Skia.Gtk")]
[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.WebAssembly")]

[assembly: AssemblyMetadata("IsTrimmable", "True")]

Expand Down
7 changes: 7 additions & 0 deletions src/Uno.UI/Controls/NativeFramePresenter.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Uno.Extensions;
using Uno.UI.Helpers;
using Uno.Foundation.Logging;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
Expand Down Expand Up @@ -87,6 +88,12 @@ public NativeFramePresenter()
NavigationController.NavigationBarHidden = true;
}

protected override Size MeasureOverride(Size availableSize)
=> MeasureFirstChild(availableSize);

protected override Size ArrangeOverride(Size finalSize)
=> ArrangeFirstChild(finalSize);

internal protected override void OnTemplatedParentChanged(DependencyPropertyChangedEventArgs e)
{
base.OnTemplatedParentChanged(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using AppKit;
using Foundation;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

Expand Down Expand Up @@ -90,5 +91,11 @@ private void OnItemActivated(MenuFlyoutItem flyoutItem)
{
flyoutItem.InvokeClick();
}

protected override Size MeasureOverride(Size availableSize)
=> MeasureFirstChild(availableSize);

protected override Size ArrangeOverride(Size finalSize)
=> ArrangeFirstChild(finalSize);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ protected override Size MeasureOverride(Size availableSize)
}
else
{
return base.MeasureOverride(availableSize);
return MeasureFirstChild(availableSize);
}
}

protected override Size ArrangeOverride(Size finalSize) => ArrangeFirstChild(finalSize);
}
}
15 changes: 11 additions & 4 deletions src/Uno.UI/UI/Xaml/Controls/Border/Border.Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,19 @@ protected override Size MeasureOverride(Size availableSize)
var padding = Padding;
var borderThickness = BorderThickness;

var measuredSize = base.MeasureOverride(
new Size(
Size measuredSize;
if (Child is { } child)
{
var childSize = new Size(
availableSize.Width - padding.Left - padding.Right - borderThickness.Left - borderThickness.Right,
availableSize.Height - padding.Top - padding.Bottom - borderThickness.Top - borderThickness.Bottom
)
);
);
measuredSize = MeasureElement(child, childSize);
}
else
{
measuredSize = default;
}

return new Size(
measuredSize.Width + padding.Left + padding.Right + borderThickness.Left + borderThickness.Right,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ protected override Size MeasureOverride(Size size)
var padding = Padding;
var borderThickness = BorderThickness;

var measuredSize = base.MeasureOverride(
var measuredSize = MeasureFirstChild(
new Size(
size.Width - padding.Left - padding.Right - borderThickness.Left - borderThickness.Right,
size.Height - padding.Top - padding.Bottom - borderThickness.Top - borderThickness.Bottom
Expand Down
6 changes: 6 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Control/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,12 @@ private protected override void OnLoaded()

}

protected override Size MeasureOverride(Size availableSize)
=> MeasureFirstChild(availableSize);

protected override Size ArrangeOverride(Size finalSize)
=> ArrangeFirstChild(finalSize);

/// <summary>
/// Loads the relevant control template so that its parts can be referenced.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Controls/Image/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ protected override Size ArrangeOverride(Size finalSize)
}
#endif

return base.ArrangeOverride(finalSize);
return ArrangeFirstChild(finalSize);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Controls/Image/Image.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ protected override Size ArrangeOverride(Size finalSize)
else
{
_imageSprite.Size = default;
return base.ArrangeOverride(finalSize);
return ArrangeFirstChild(finalSize);
}
}

Expand Down
10 changes: 0 additions & 10 deletions src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ private protected virtual void OnChildAdded(IFrameworkElement element)
UpdateTransitions(element);
}

// In WinUI, the base Panel doesn't measure or arrange anything. This is likely due
// to FrameworkElement.<Measure|Arrange>Override itself not doing anything. In Uno,
// FrameworkElement.<Measure|Arrange>Override have a default implementation that assumes
// a single child and measures/arranges it. This is helpful as most elements have one or no
// children. However, since derived types of Panel can add their own Children, we need to make
// sure our internal FrameworkElement.<Measure|Arrange>Override isn't used by user-defined
// subclasses of Panel.
protected override Size MeasureOverride(Size availableSize) => new Size(0, 0);
protected override Size ArrangeOverride(Size finalSize) => finalSize;

private void UpdateTransitions(IFrameworkElement element)
{
if (_transitionHelper == null)
Expand Down
3 changes: 3 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ internal void Select(int start, int length)

protected override Size MeasureOverride(Size availableSize) => MeasureView(availableSize);

protected override Size ArrangeOverride(Size finalSize)
=> ArrangeFirstChild(finalSize);

internal void SetPasswordRevealState(PasswordRevealState revealState)
{
if (IsMultiline)
Expand Down
7 changes: 7 additions & 0 deletions src/Uno.UI/UI/Xaml/ElementStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Uno.Foundation.Logging;
using Uno.UI;
using Uno.UI.DataBinding;
using Windows.Foundation;

#if __ANDROID__
using View = Android.Views.View;
Expand Down Expand Up @@ -140,6 +141,12 @@ private static void OnLoadChanged(DependencyObject dependencyObject, DependencyP
/// </summary>
public Func<View> ContentBuilder { get; set; }

protected override Size MeasureOverride(Size availableSize)
=> MeasureFirstChild(availableSize);

protected override Size ArrangeOverride(Size finalSize)
=> ArrangeFirstChild(finalSize);

protected override void OnVisibilityChanged(Visibility oldValue, Visibility newValue)
{
base.OnVisibilityChanged(oldValue, newValue);
Expand Down
36 changes: 19 additions & 17 deletions src/Uno.UI/UI/Xaml/FrameworkElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ public bool IsParsing
/// <returns>The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects or based on other considerations such as a fixed container size.</returns>
protected virtual Size MeasureOverride(Size availableSize)
{
var child = this.FindFirstChild();
return child != null ? MeasureElement(child, availableSize) : new Size(0, 0);
return default;
}

/// <summary>
Expand All @@ -283,21 +282,7 @@ protected virtual Size MeasureOverride(Size availableSize)
/// <returns>The actual size that is used after the element is arranged in layout.</returns>
protected virtual Size ArrangeOverride(Size finalSize)
{
var child = this.FindFirstChild();

if (child != null)
{
#if UNO_REFERENCE_API
child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
#else
ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height));
#endif
return finalSize;
}
else
{
return finalSize;
}
return finalSize;
}

/// <summary>
Expand Down Expand Up @@ -756,6 +741,23 @@ internal virtual void OnLayoutUpdated()

private protected virtual Thickness GetBorderThickness() => Thickness.Empty;

private protected Size MeasureFirstChild(Size availableSize)
{
var child = this.FindFirstChild();
return child != null ? MeasureElement(child, availableSize) : new Size(0, 0);
}

private protected Size ArrangeFirstChild(Size finalSize)
{
var child = this.FindFirstChild();
if (child != null)
{
ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height));
}

return finalSize;
}

#if XAMARIN
private static FrameworkElement FindPhaseEnabledRoot(ContentControl content)
{
Expand Down

0 comments on commit 26b9e38

Please sign in to comment.