Skip to content

Commit

Permalink
IContainer proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
hartez committed Jul 21, 2021
1 parent 6d04022 commit ac26dba
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 105 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions src/Controls/src/Core/HandlerImpl/Layout.Impl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Maui.Controls
{
public abstract partial class Layout<T>
{
int ICollection<IView>.Count => _children.Count;
bool ICollection<IView>.IsReadOnly => ((ICollection<IView>) _children).IsReadOnly;
public IView this[int index] { get => _children[index]; set => _children[index] = (T)value; }

public void Add(IView child)
{
if (child is T view)
{
_children.Add(view);
}
}

public bool Remove(IView child)
{
if (child is T view)
{
_children.Remove(view);
return true;
}

return false;
}

int IList<IView>.IndexOf(IView child)
{
return _children.IndexOf(child);
}

void IList<IView>.Insert(int index, IView child)
{
if (child is T view)
{
_children.Insert(index, view);
}
}

void IList<IView>.RemoveAt(int index)
{
_children.RemoveAt(index);
}

void ICollection<IView>.Clear()
{
_children.Clear();
}

bool ICollection<IView>.Contains(IView child)
{
return _children.Contains(child);
}

void ICollection<IView>.CopyTo(IView[] array, int arrayIndex)
{
_children.CopyTo(array, arrayIndex);
}

IEnumerator<IView> IEnumerable<IView>.GetEnumerator()
{
return _children.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return _children.GetEnumerator();
}
}
}
26 changes: 3 additions & 23 deletions src/Controls/src/Core/Layout.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
Expand All @@ -10,11 +11,8 @@
namespace Microsoft.Maui.Controls
{
[ContentProperty(nameof(Children))]
public abstract class Layout<T> : Layout, Microsoft.Maui.ILayout, IViewContainer<T> where T : View
public abstract partial class Layout<T> : Layout, Microsoft.Maui.ILayout, IViewContainer<T> where T : View
{
// TODO ezhart We should look for a way to optimize this a bit
IReadOnlyList<Microsoft.Maui.IView> Microsoft.Maui.IContainer.Children => Children.ToList();

readonly ElementCollection<T> _children;

protected Layout() => _children = new ElementCollection<T>(InternalChildren);
Expand Down Expand Up @@ -46,28 +44,10 @@ protected virtual void OnAdded(T view)
protected virtual void OnRemoved(T view)
{
}

public void Add(IView child)
{
if (child is T view)
{
Children.Add(view);
}
}

public void Remove(IView child)
{
if (child is T view)
{
Children.Remove(view);
}
}
}

public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement, Microsoft.Maui.IContainer
public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement//, Microsoft.Maui.IContainer
{
IReadOnlyList<Microsoft.Maui.IView> Microsoft.Maui.IContainer.Children => InternalChildren.OfType<IView>().ToList();

public static readonly BindableProperty IsClippedToBoundsProperty =
BindableProperty.Create(nameof(IsClippedToBounds), typeof(bool), typeof(Layout), false);

Expand Down
4 changes: 2 additions & 2 deletions src/Controls/src/Core/Layout/GridLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ public override void Add(IView child)
}
}

public override void Remove(IView child)
public override bool Remove(IView child)
{
_viewInfo.Remove(child);
base.Remove(child);
return base.Remove(child);
}

protected override ILayoutManager CreateLayoutManager() => new GridLayoutManager(this);
Expand Down
44 changes: 7 additions & 37 deletions src/Controls/src/Core/Layout/Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ public abstract class Layout : View, Microsoft.Maui.ILayout, IList<IView>, IPadd

public bool IsReadOnly => ((ICollection<IView>)_children).IsReadOnly;

IReadOnlyList<IView> IContainer.Children => _children.AsReadOnly();

public IView this[int index] { get => _children[index]; set => _children[index] = value; }


public Thickness Padding
{
get => (Thickness)GetValue(PaddingElement.PaddingProperty);
Expand All @@ -53,56 +50,44 @@ public override SizeRequest GetSizeRequest(double widthConstraint, double height
protected override Size MeasureOverride(double widthConstraint, double heightConstraint)
{
var margin = (this as IView)?.Margin ?? Thickness.Zero;

// Adjust the constraints to account for the margins
widthConstraint -= margin.HorizontalThickness;
heightConstraint -= margin.VerticalThickness;

var sizeWithoutMargins = LayoutManager.Measure(widthConstraint, heightConstraint);
DesiredSize = new Size(sizeWithoutMargins.Width + Margin.HorizontalThickness,
sizeWithoutMargins.Height + Margin.VerticalThickness);

return DesiredSize;
}

protected override Size ArrangeOverride(Rectangle bounds)
{
base.ArrangeOverride(bounds);

Frame = bounds;

LayoutManager.ArrangeChildren(Frame);

foreach (var child in Children)
{
child.Handler?.NativeArrange(child.Frame);
}

return Frame.Size;
}

protected override void InvalidateMeasureOverride()
{
base.InvalidateMeasureOverride();

foreach (var child in Children)
{
child.InvalidateMeasure();
}
}

public virtual void Add(IView child)
{
if (child == null)
return;

_children.Add(child);

if (child is Element element)
element.Parent = this;

InvalidateMeasure();

LayoutHandler?.Add(child);
}

Expand Down Expand Up @@ -144,19 +129,21 @@ public void Insert(int index, IView child)
LayoutHandler?.Add(child);
}

public virtual void Remove(IView child)
public virtual bool Remove(IView child)
{
if (child == null)
return;
return false;

_children.Remove(child);
var result = _children.Remove(child);

if (child is Element element)
element.Parent = null;

InvalidateMeasure();

LayoutHandler?.Remove(child);

return result;
}

public void RemoveAt(int index)
Expand All @@ -178,23 +165,6 @@ public void RemoveAt(int index)
LayoutHandler?.Remove(child);
}

bool ICollection<IView>.Remove(IView child)
{
if (child == null)
return false;

var result = _children.Remove(child);

if (child is Element element)
element.Parent = null;

InvalidateMeasure();

LayoutHandler?.Remove(child);

return result;
}

void IPaddingElement.OnPaddingPropertyChanged(Thickness oldValue, Thickness newValue)
{
InvalidateMeasure();
Expand Down
7 changes: 2 additions & 5 deletions src/Core/src/Core/IContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ namespace Microsoft.Maui
/// <summary>
/// Provides functionality to act as containers for views.
/// </summary>
public interface IContainer
public interface IContainer : IList<IView>
{
/// <summary>
/// Gets the collection of children that the Container contains.
/// </summary>
IReadOnlyList<IView> Children { get; }

}
}
12 changes: 0 additions & 12 deletions src/Core/src/Core/ILayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@ public interface ILayout : IView, IContainer
/// </summary>
ILayoutHandler LayoutHandler { get; }

/// <summary>
/// Add a child View to the Layout.
/// </summary>
/// <param name="child">The child View to add to the Layout.</param>
void Add(IView child);

/// <summary>
/// Remove a child View from the Layout.
/// </summary>
/// <param name="child">The child View to remove from the Layout.</param>
void Remove(IView child);

/// <summary>
/// The space between the outer edge of the ILayout's content area and its children.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Layout/LayoutHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override void SetVirtualView(IView view)
NativeView.CrossPlatformArrange = VirtualView.Arrange;

NativeView.RemoveAllViews();
foreach (var child in VirtualView.Children)
foreach (var child in VirtualView)
{
NativeView.AddView(child.ToNative(MauiContext));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Layout/LayoutHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override void SetVirtualView(IView view)
child.RemoveFromSuperview();
}

foreach (var child in VirtualView.Children)
foreach (var child in VirtualView)
{
NativeView.AddSubview(child.ToNative(MauiContext));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/HotReload/HotReloadExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void CheckHandlers(this IView view)

if (view is IContainer layout)
{
foreach (var v in layout.Children)
foreach (var v in layout)
CheckHandlers(v);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Layouts/FlexLayoutManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public void ArrangeChildren(Rectangle childBounds)
{
FlexLayout.Layout(childBounds.Width, childBounds.Height);

foreach (var child in FlexLayout.Children)
foreach (var child in FlexLayout)
{
var frame = FlexLayout.GetFlexFrame(child);
if (double.IsNaN(frame.X)
Expand Down
12 changes: 5 additions & 7 deletions src/Core/src/Layouts/GridLayoutManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void ArrangeChildren(Rectangle childBounds)
{
var structure = _gridStructure ?? new GridStructure(Grid, childBounds.Width, childBounds.Height);

foreach (var view in Grid.Children)
foreach (var view in Grid)
{
if (view.Visibility == Visibility.Collapsed)
{
Expand Down Expand Up @@ -56,7 +56,6 @@ class GridStructure
readonly double _columnSpacing;
readonly IReadOnlyList<IGridRowDefinition> _rowDefinitions;
readonly IReadOnlyList<IGridColumnDefinition> _columnDefinitions;
readonly IReadOnlyList<IView> _gridChildren;

readonly Dictionary<SpanKey, Span> _spans = new();

Expand All @@ -75,7 +74,6 @@ public GridStructure(IGridLayout grid, double widthConstraint, double heightCons
_rowSpacing = grid.RowSpacing;
_rowDefinitions = grid.RowDefinitions;
_columnDefinitions = grid.ColumnDefinitions;
_gridChildren = grid.Children;

if (_rowDefinitions.Count == 0)
{
Expand Down Expand Up @@ -112,15 +110,15 @@ public GridStructure(IGridLayout grid, double widthConstraint, double heightCons
// We could work out the _childrenToLayOut array (with the Collapsed items filtered out) with a Linq 1-liner
// but doing it the hard way means we don't allocate extra enumerators, especially if we're in the
// happy path where _none_ of the children are Collapsed.
var gridChildCount = _gridChildren.Count;
var gridChildCount = _grid.Count;

_childrenToLayOut = new IView[gridChildCount];
int currentChild = 0;
for (int n = 0; n < gridChildCount; n++)
{
if (_gridChildren[n].Visibility != Visibility.Collapsed)
if (_grid[n].Visibility != Visibility.Collapsed)
{
_childrenToLayOut[currentChild] = _gridChildren[n];
_childrenToLayOut[currentChild] = _grid[n];
currentChild += 1;
}
}
Expand Down Expand Up @@ -429,7 +427,7 @@ void ResolveStars(Definition[] defs, double availableSpace, Func<Cell, bool> cel
if (cellCheck(cell)) // Check whether this cell should count toward the type of star value were measuring
{
// Update the star width if the view in this cell is bigger
starSize = Math.Max(starSize, dimension(_gridChildren[cell.ViewIndex].DesiredSize));
starSize = Math.Max(starSize, dimension(_grid[cell.ViewIndex].DesiredSize));
}
}
}
Expand Down
Loading

0 comments on commit ac26dba

Please sign in to comment.