Skip to content

Commit

Permalink
fix: Initiate layouting fix. Not yet complete
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 committed Sep 15, 2024
1 parent a32e269 commit 4582818
Show file tree
Hide file tree
Showing 37 changed files with 1,866 additions and 3,656 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2133,13 +2133,7 @@ public void When_One_Fixed_Size_Child_With_Margin_Right_And_Stretch()
#if !WINAPPSDK
private static Size GetUnclippedDesiredSize(UIElement element)
{
#if UNO_REFERENCE_API
return element.m_unclippedDesiredSize;
#else
var layouterElement = (ILayouterElement)element;
var layouter = (Layouter)layouterElement.Layouter;
return layouter._unclippedDesiredSize;
#endif
}
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

namespace Uno.UI.Xaml.Controls;

public partial class NativeRefreshControl : SwipeRefreshLayout, IShadowChildrenProvider, DependencyObject, ILayouterElement
public partial class NativeRefreshControl : SwipeRefreshLayout, IShadowChildrenProvider, DependencyObject
{
// Distance in pixels a touch can wander before we think the user is scrolling
// https://developer.android.com/reference/android/view/ViewConfiguration.html#getScaledTouchSlop()
Expand All @@ -36,7 +36,6 @@ public partial class NativeRefreshControl : SwipeRefreshLayout, IShadowChildrenP

public NativeRefreshControl() : base(ContextHelper.Current)
{
_layouter = new NativeRefreshControlLayouter(this);
}

internal Android.Views.View Content
Expand Down Expand Up @@ -162,93 +161,9 @@ public override bool OnTouchEvent(MotionEvent e)

List<View> IShadowChildrenProvider.ChildrenShadow => Content != null ? new List<View>(1) { Content as View } : _emptyList;

private ILayouter _layouter;

ILayouter ILayouterElement.Layouter => _layouter;
Size ILayouterElement.LastAvailableSize => LayoutInformation.GetAvailableSize(this);
bool ILayouterElement.IsMeasureDirty => true;
bool ILayouterElement.IsFirstMeasureDoneAndManagedElement => false;
bool ILayouterElement.StretchAffectsMeasure => true;
bool ILayouterElement.IsMeasureDirtyPathDisabled => true;

public override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
((ILayouterElement)this).OnMeasureInternal(widthMeasureSpec, heightMeasureSpec);
}

void ILayouterElement.SetMeasuredDimensionInternal(int width, int height)
{
SetMeasuredDimension(width, height);
}

partial void OnLayoutPartial(bool changed, int left, int top, int right, int bottom)
{
var newSize = new Rect(0, 0, right - left, bottom - top).PhysicalToLogicalPixels();

// WARNING: The layouter must be called every time here,
// even if the size has not changed. Failing to call the layouter
// may leave the default ScrollViewer implementation place
// the child at an invalid location when the visibility changes.

_layouter.Arrange(newSize);
}

private class NativeRefreshControlLayouter : Layouter
{
public NativeRefreshControlLayouter(NativeRefreshControl view) : base(view)
{
}

private NativeRefreshControl RefreshControl => Panel as NativeRefreshControl;

protected override void MeasureChild(View child, int widthSpec, int heightSpec)
{
var childMargin = (child as FrameworkElement)?.Margin ?? Thickness.Empty;

RefreshControl.Content?.Measure(widthSpec, heightSpec);
}

protected override Size MeasureOverride(Size availableSize)
{
var child = RefreshControl.Content;

var desiredChildSize = default(Size);
if (child != null)
{
var scrollSpace = availableSize;

desiredChildSize = MeasureChild(child, scrollSpace);

// Give opportunity to the the content to define the viewport size itself
(child as ICustomScrollInfo)?.ApplyViewport(ref desiredChildSize);
}

return desiredChildSize;
}

protected override Size ArrangeOverride(Size slotSize)
{
var child = RefreshControl.Content;

if (child != null)
{
ArrangeChild(child, new Rect(
0,
0,
slotSize.Width,
slotSize.Height
));

// Give opportunity to the the content to define the viewport size itself
(child as ICustomScrollInfo)?.ApplyViewport(ref slotSize);

}

return slotSize;
}

protected override string Name => Panel.Name;
}

private ViewGroup GetDescendantScrollable()
Expand Down
117 changes: 51 additions & 66 deletions src/Uno.UI/UI/Xaml/Controls/FlipView/NativePagedView.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,21 @@ private void Initialize()
{
InitializeBinder();
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
_layouter = new NativePagedViewLayouter(this);
}

private ILayouter _layouter;

ILayouter ILayouterElement.Layouter => _layouter;
Size ILayouterElement.LastAvailableSize => LayoutInformation.GetAvailableSize(this);
bool ILayouterElement.IsMeasureDirty => true;
bool ILayouterElement.IsFirstMeasureDoneAndManagedElement => false;
bool ILayouterElement.StretchAffectsMeasure => false;
bool ILayouterElement.IsMeasureDirtyPathDisabled => true;

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
var measuredSize = ((ILayouterElement)this).OnMeasureInternal(widthMeasureSpec, heightMeasureSpec);

var logicalMeasuredSize = measuredSize.PhysicalToLogicalPixels();

//We call ViewPager.OnMeasure here, because it creates the page views.
base.OnMeasure(
ViewHelper.SpecFromLogicalSize(logicalMeasuredSize.Width),
ViewHelper.SpecFromLogicalSize(logicalMeasuredSize.Height)
);
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}

IFrameworkElementHelper.OnMeasureOverride(this);
Size ILayouterElement.Measure(Size availableSize)
{
return default; // TODO
}

void ILayouterElement.SetMeasuredDimensionInternal(int width, int height)
void ILayouterElement.Arrange(Rect finalRect)
{
SetMeasuredDimension(width, height);
// TODO
}

//TODO generated code
Expand All @@ -73,7 +58,7 @@ partial void OnLayoutPartial(bool changed, int left, int top, int right, int bot
{
_lastLayoutSize = newSize;

_layouter.Arrange(new global::Windows.Foundation.Rect(0, 0, newSize.Width, newSize.Height));
//_layouter.Arrange(new global::Windows.Foundation.Rect(0, 0, newSize.Width, newSize.Height));
}
}

Expand All @@ -99,48 +84,48 @@ public override void RemoveViewAt(int index)

public bool IsHeightConstrained(View requester) => (Parent as ILayoutConstraints)?.IsHeightConstrained(this) ?? false;

private class NativePagedViewLayouter : Layouter
{

public NativePagedViewLayouter(NativePagedView view) : base(view) { }

protected override string Name => Panel.Name;


protected override void MeasureChild(View view, int widthSpec, int heightSpec)
{
(Panel as NativePagedView).MeasureChild(view, widthSpec, heightSpec);
}

protected override Size ArrangeOverride(Size finalSize)
{
//Do nothing here. FrameworkElementMixins.OnLayout calls ViewPager.OnLayout, which lays out its visible page.
return finalSize;
}

protected override Size MeasureOverride(Size availableSize)
{
var sizeThatFits = IFrameworkElementHelper.SizeThatFits(Panel, availableSize);

double maxChildWidth = 0f, maxChildHeight = 0f;

//Per the link, if the NativePagedView has no fixed size in a dimension, wrap it to the size of its largest child. - http://stackoverflow.com/questions/8394681/android-i-am-unable-to-have-viewpager-wrap-content
//This might be brittle if items have varying dimensions along the unfixed axis; one (hackish) solution would be to increase OffscreenPageLimit (the number of offscreen pages that are kept).
if (double.IsPositiveInfinity(sizeThatFits.Width) || double.IsPositiveInfinity(sizeThatFits.Height))
{
foreach (var child in this.GetChildren())
{
var desiredChildSize = MeasureChild(child, sizeThatFits);
maxChildWidth = Math.Max(maxChildWidth, desiredChildSize.Width);
maxChildHeight = Math.Max(maxChildHeight, desiredChildSize.Height);
}
}

return new Size(
!double.IsPositiveInfinity(sizeThatFits.Width) ? sizeThatFits.Width : maxChildWidth,
!double.IsPositiveInfinity(sizeThatFits.Height) ? sizeThatFits.Height : maxChildHeight
);
}
}
//private class NativePagedViewLayouter : Layouter
//{

Check warning on line 88 in src/Uno.UI/UI/Xaml/Controls/FlipView/NativePagedView.Android.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI/UI/Xaml/Controls/FlipView/NativePagedView.Android.cs#L88

Remove this commented out code.

// public NativePagedViewLayouter(NativePagedView view) : base(view) { }

// protected override string Name => Panel.Name;


// protected override void MeasureChild(View view, int widthSpec, int heightSpec)
// {
// (Panel as NativePagedView).MeasureChild(view, widthSpec, heightSpec);
// }

// protected override Size ArrangeOverride(Size finalSize)
// {
// //Do nothing here. FrameworkElementMixins.OnLayout calls ViewPager.OnLayout, which lays out its visible page.
// return finalSize;
// }

// protected override Size MeasureOverride(Size availableSize)
// {
// var sizeThatFits = IFrameworkElementHelper.SizeThatFits(Panel, availableSize);

// double maxChildWidth = 0f, maxChildHeight = 0f;

// //Per the link, if the NativePagedView has no fixed size in a dimension, wrap it to the size of its largest child. - http://stackoverflow.com/questions/8394681/android-i-am-unable-to-have-viewpager-wrap-content
// //This might be brittle if items have varying dimensions along the unfixed axis; one (hackish) solution would be to increase OffscreenPageLimit (the number of offscreen pages that are kept).
// if (double.IsPositiveInfinity(sizeThatFits.Width) || double.IsPositiveInfinity(sizeThatFits.Height))
// {
// foreach (var child in this.GetChildren())
// {
// var desiredChildSize = MeasureChild(child, sizeThatFits);
// maxChildWidth = Math.Max(maxChildWidth, desiredChildSize.Width);
// maxChildHeight = Math.Max(maxChildHeight, desiredChildSize.Height);
// }
// }

// return new Size(
// !double.IsPositiveInfinity(sizeThatFits.Width) ? sizeThatFits.Width : maxChildWidth,
// !double.IsPositiveInfinity(sizeThatFits.Height) ? sizeThatFits.Height : maxChildHeight
// );
// }
//}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ public partial class ManagedItemsStackPanel : Panel
{
ManagedVirtualizingPanelLayout _layout;

#if !__IOS__
internal bool ShouldInterceptInvalidate { get; set; }
#endif

public ManagedItemsStackPanel()
{
if (FeatureConfiguration.ListViewBase.DefaultCacheLength.HasValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ bool isNewGroup
AddView(view, direction);

var slotSize = new Size(availableWidth, availableHeight).PhysicalToLogicalPixels();
var measuredSize = _layouter.MeasureChild(view, slotSize);
//var measuredSize = _layouter.MeasureChild(view, slotSize);

Check warning on line 82 in src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGridLayout.Android.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGridLayout.Android.cs#L82

Remove this commented out code.
var measuredSize = slotSize; // TODO
var physicalMeasuredSize = measuredSize.LogicalToPhysicalPixels();
var measuredWidth = (int)physicalMeasuredSize.Width;
var measuredHeight = (int)physicalMeasuredSize.Height;
Expand Down
65 changes: 0 additions & 65 deletions src/Uno.UI/UI/Xaml/Controls/Layouter/ILayouter.cs

This file was deleted.

Loading

0 comments on commit 4582818

Please sign in to comment.