Skip to content

Commit

Permalink
fix(autolayout): padding refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-Louis committed Mar 17, 2023
1 parent 7e80e66 commit 28f9783
Showing 1 changed file with 87 additions and 107 deletions.
194 changes: 87 additions & 107 deletions src/Uno.Toolkit.UI/Controls/AutoLayout/AutoLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,7 @@ private void UpdateAutoLayout()
return;
}

var padding = Padding;
var hasPadding = !padding.Equals(default(Thickness));
var isVertical = Orientation is Orientation.Vertical;
var spacing = Spacing;
var hasSpace = Spacing != 0 || Justify == AutoLayoutJustify.SpaceBetween;
var hasSpaceBetween = Justify == AutoLayoutJustify.SpaceBetween;
var isSpacing = spacing != 0 && !hasSpaceBetween;

var children = Children;

var childrenCount = children.Count;

if (childrenCount == 0)
Expand All @@ -241,15 +232,34 @@ private void UpdateAutoLayout()
return;
}

var padding = Padding;
var isVertical = Orientation is Orientation.Vertical;
var spacing = Spacing;
var hasSpace = Spacing != 0 || Justify == AutoLayoutJustify.SpaceBetween;
var hasSpaceBetween = Justify == AutoLayoutJustify.SpaceBetween;
var isSpacing = spacing != 0 && !hasSpaceBetween;

var childrenCounterALignment = children.Any() ? GetCounterAlignment(children.First()) : AutoLayoutAlignment.Start;

bool atLeastOneChildFillAvailableSpaceInPrimaryAxis = children.Where(child => GetPrimaryAlignment(child) is AutoLayoutPrimaryAlignment.Stretch).Any();
bool atLeastOneChildFillAvailableSpaceInCounterAxis = children.Where(child => GetCounterAlignment(child) is AutoLayoutAlignment.Stretch).Any();

var childrenVerticallAlignment = Orientation == Orientation.Vertical ?
atLeastOneChildFillAvailableSpaceInPrimaryAxis ? VerticalAlignment.Stretch : PrimaryAxisAlignment.ToVerticalAlignment() :
atLeastOneChildFillAvailableSpaceInCounterAxis ? VerticalAlignment.Stretch : childrenCounterALignment.ToVerticalAlignment();
var childrenHorizontalAlignment = Orientation == Orientation.Vertical ?
atLeastOneChildFillAvailableSpaceInCounterAxis ? HorizontalAlignment.Stretch : childrenCounterALignment.ToHorizontalAlignment() :
atLeastOneChildFillAvailableSpaceInPrimaryAxis ? HorizontalAlignment.Stretch : PrimaryAxisAlignment.ToHorizontalAlignment();

_grid.Padding = new Thickness(0);

var independentLayoutCount = children.Where(child => GetIsIndependentLayout(child)).Count();
var hasIndependentLayout = independentLayoutCount > 0;

var hasPadding = !padding.Equals(default(Thickness));

var gridIndexOffSet = 0;

bool atLeastOneChildFillAvailableSpaceInPrimaryAxis = children.Where(child => GetPrimaryAlignment(child) is AutoLayoutPrimaryAlignment.Stretch).Any();
var gridRowIndexOffSet = 0;
var gridColumnIndexOffSet = 0;

var shouldAddInBetweenRow = (hasSpaceBetween && atLeastOneChildFillAvailableSpaceInPrimaryAxis is false) || spacing > 0;
var gridDefinitionsCount = shouldAddInBetweenRow ? ((childrenCount - independentLayoutCount) * 2) - 1 : (childrenCount - independentLayoutCount);
Expand Down Expand Up @@ -299,44 +309,60 @@ private void UpdateAutoLayout()
_grid.ClearValue(Grid.RowSpacingProperty);
}


if (isVertical)
{
// Ensure no columns defined (orientation is vertical)
_grid.ColumnDefinitions.Clear();
}
else
{
// Ensure no rows defined (orientation is horizontal)
_grid.RowDefinitions.Clear();
}

// Ensure definitions is of right size
while (_grid.RowDefinitions.Count < gridDefinitionsCount)
if (hasPadding)
{
if (IsVerticalHug || childrenVerticallAlignment is VerticalAlignment.Top or VerticalAlignment.Stretch || hasSpaceBetween)
{
_grid.RowDefinitions.Add(new RowDefinition());
var topPaddingSize = spacing < 0 ? padding.Top - spacing : padding.Top;
_grid.RowDefinitions.Insert(0, new RowDefinition() { Height = new GridLength(topPaddingSize), MaxHeight = topPaddingSize });
gridRowIndexOffSet += 1;
}

while (_grid.RowDefinitions.Count > gridDefinitionsCount)
if (IsHorizontalHug || childrenHorizontalAlignment is HorizontalAlignment.Left or HorizontalAlignment.Stretch || hasSpaceBetween)
{
_grid.RowDefinitions.RemoveAt(_grid.RowDefinitions.Count - 1);
var firstColumnWidthSize = spacing < 0 ? padding.Left - spacing : padding.Left;
_grid.ColumnDefinitions.Insert(0, new ColumnDefinition() { Width = new GridLength(firstColumnWidthSize), MaxWidth = firstColumnWidthSize });
gridColumnIndexOffSet += 1;
}
}

var rawChildIndex = 0;
if (isVertical)
{

if (hasPadding)
{
_grid.Padding = new Thickness(0);

var topPaddingSize = spacing < 0 ? padding.Top - spacing : padding.Top;
var topPadding = new GridLength(topPaddingSize);
_grid.ColumnDefinitions.Insert(gridColumnIndexOffSet, new ColumnDefinition() { Width = new GridLength(1, IsHorizontalHug ? GridUnitType.Auto : GridUnitType.Star) });
}

_grid.RowDefinitions.Insert(gridIndexOffSet, new RowDefinition() { Height = topPadding, MaxHeight = topPaddingSize});
gridIndexOffSet += 1;
// Ensure definitions is of right size
while (_grid.RowDefinitions.Count < gridDefinitionsCount + gridRowIndexOffSet)
{
_grid.RowDefinitions.Add(new RowDefinition());
}

_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(padding.Left )});
_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, IsHorizontalHug ? GridUnitType.Auto : GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(padding.Right) });
while (_grid.RowDefinitions.Count > gridDefinitionsCount + gridRowIndexOffSet)
{
_grid.RowDefinitions.RemoveAt(_grid.RowDefinitions.Count - 1);
}

var rawChildIndex = 0;
_grid.Padding = new Thickness(0);

if (hasSpaceBetween is false && atLeastOneChildFillAvailableSpaceInPrimaryAxis is false && isPrimaryAxisAlignmentCenterOrEnd)
{
_grid.RowDefinitions.Insert(gridIndexOffSet, new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
gridIndexOffSet += 1;
_grid.RowDefinitions.Insert(gridRowIndexOffSet, new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
gridRowIndexOffSet += 1;
}
// Process children
for (var i = 0; i < childrenCount; i++)
Expand All @@ -354,7 +380,7 @@ private void UpdateAutoLayout()

var gridIndex = shouldAddInBetweenRow ? rawChildIndex * 2 : rawChildIndex;
//We add a grid. we need to adjust the index.
var adjustGridIndex = gridIndex + gridIndexOffSet;
var adjustGridIndex = gridIndex + gridRowIndexOffSet;
Grid.SetRow(child, adjustGridIndex);
var gridDefinition = _grid.RowDefinitions[adjustGridIndex];

Expand All @@ -380,29 +406,11 @@ private void UpdateAutoLayout()

child.HorizontalAlignment = counterAlignment;

if (hasPadding)
if (gridColumnIndexOffSet > 0)
{
switch (counterAlignment)
{
case HorizontalAlignment.Left:
Grid.SetColumn(child, 1);
Grid.SetColumnSpan(child, IsHorizontalHug ? 1 : 2);
break;
case HorizontalAlignment.Center:
Grid.SetColumn(child, 1);
break;
case HorizontalAlignment.Right:
Grid.SetColumn(child, IsHorizontalHug ? 1 : 0);
Grid.SetColumnSpan(child, IsHorizontalHug ? 1 : 2);
break;
case HorizontalAlignment.Stretch:
Grid.SetColumn(child, 1);
break;
default:
break;
}
Grid.SetColumn(child, gridColumnIndexOffSet);
}

if (GetCounterLength(child) is var width and > 0)
{
child.Width = width;
Expand All @@ -422,15 +430,15 @@ private void UpdateAutoLayout()
}
else
{
for (var i = 1 + gridIndexOffSet; i < gridDefinitionsCount + gridIndexOffSet; i += 2)
for (var i = 1 + gridRowIndexOffSet; i < gridDefinitionsCount + gridRowIndexOffSet; i += 2)
{
_grid.RowDefinitions[i].Height = new GridLength(spacing);
}
}
}
else if (hasSpaceBetween)
{
for (var i = 1 + gridIndexOffSet; i < gridDefinitionsCount + gridIndexOffSet; i += 2)
for (var i = 1 + gridRowIndexOffSet; i < gridDefinitionsCount + gridRowIndexOffSet; i += 2)
{
_grid.RowDefinitions[i].Height = new GridLength(1, GridUnitType.Star);
}
Expand All @@ -445,49 +453,31 @@ private void UpdateAutoLayout()

var paddingCondition = atLeastOneChildFillAvailableSpaceInPrimaryAxis || PrimaryAxisAlignment is not AutoLayoutAlignment.Start || IsVerticalHug;

if ( hasSpaceBetween || (hasPadding && paddingCondition))
{
var bottomPaddingSize = spacing < 0 ? padding.Bottom - spacing : padding.Bottom;
_grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(bottomPaddingSize), MaxHeight = bottomPaddingSize });
}
}
else // Horizontal
{
// Ensure no rows defined (orientation is horizontal)
_grid.RowDefinitions.Clear();
if (hasPadding)
{
_grid.RowDefinitions.Insert(gridRowIndexOffSet ,new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
}

// Ensure definitions is of right size
while (_grid.ColumnDefinitions.Count < gridDefinitionsCount)
while (_grid.ColumnDefinitions.Count < gridDefinitionsCount + gridColumnIndexOffSet)
{
_grid.ColumnDefinitions.Add(new ColumnDefinition());
}

while (_grid.ColumnDefinitions.Count > gridDefinitionsCount)
while (_grid.ColumnDefinitions.Count > gridDefinitionsCount + gridColumnIndexOffSet)
{
_grid.ColumnDefinitions.RemoveAt(_grid.ColumnDefinitions.Count - 1);
}

var rawChildIndex = 0;

if (hasPadding)
{
_grid.Padding = new Thickness(0);

var firstColumnWidthSize = spacing < 0 ? padding.Left - spacing : padding.Left;
var firstColumnWidth = new GridLength(firstColumnWidthSize);

_grid.ColumnDefinitions.Insert(gridIndexOffSet, new ColumnDefinition() { Width = firstColumnWidth, MaxWidth = firstColumnWidthSize });
gridIndexOffSet += 1;

_grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(padding.Top) });
_grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(padding.Bottom) });
}

if (hasSpaceBetween is false && atLeastOneChildFillAvailableSpaceInPrimaryAxis is false && isPrimaryAxisAlignmentCenterOrEnd )
{
_grid.ColumnDefinitions.Insert(gridIndexOffSet, new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
gridIndexOffSet += 1;
_grid.ColumnDefinitions.Insert(gridColumnIndexOffSet, new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
gridColumnIndexOffSet += 1;
}
// Process children
for (var i = 0; i < childrenCount; i++)
Expand All @@ -504,7 +494,7 @@ private void UpdateAutoLayout()

var gridIndex = shouldAddInBetweenRow ? rawChildIndex * 2 : rawChildIndex;
//We add a grid. we need to adjust the index.
var adjustGridIndex = gridIndex + gridIndexOffSet;
var adjustGridIndex = gridIndex + gridColumnIndexOffSet;
var gridDefinition = _grid.ColumnDefinitions[adjustGridIndex];
Grid.SetColumn(child, adjustGridIndex);

Expand All @@ -530,27 +520,10 @@ private void UpdateAutoLayout()

child.VerticalAlignment = counterAlignment;

if (hasPadding)

if (gridRowIndexOffSet > 0)
{
switch (counterAlignment)
{
case VerticalAlignment.Top:
Grid.SetRow(child, 1);
Grid.SetRowSpan(child, IsVerticalHug ? 1 : 2);
break;
case VerticalAlignment.Center:
Grid.SetRow(child, 1);
break;
case VerticalAlignment.Bottom:
Grid.SetRow(child, IsVerticalHug ? 1 : 0);
Grid.SetRowSpan(child, 2);
break;
case VerticalAlignment.Stretch:
Grid.SetRow(child, 1);
break;
default:
break;
}
Grid.SetRow(child, 1);
}

if (GetCounterLength(child) is var height and > 0)
Expand All @@ -573,15 +546,15 @@ private void UpdateAutoLayout()
}
else
{
for (var i = 1 + gridIndexOffSet; i < gridDefinitionsCount + gridIndexOffSet; i += 2)
for (var i = 1 + gridColumnIndexOffSet; i < gridDefinitionsCount + gridColumnIndexOffSet; i += 2)
{
_grid.ColumnDefinitions[i].Width = new GridLength(spacing);
}
}
}
else if (hasSpaceBetween)
{
for (var i = 1 + gridIndexOffSet; i < gridDefinitionsCount + gridIndexOffSet; i += 2)
for (var i = 1 + gridColumnIndexOffSet; i < gridDefinitionsCount + gridColumnIndexOffSet; i += 2)
{
_grid.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Star);
}
Expand All @@ -595,13 +568,20 @@ private void UpdateAutoLayout()
}

var paddingCondition = atLeastOneChildFillAvailableSpaceInPrimaryAxis || PrimaryAxisAlignment is not AutoLayoutAlignment.Start || IsHorizontalHug;
}

if (hasSpaceBetween || (hasPadding && paddingCondition))
if (hasPadding)
{
if (IsVerticalHug || childrenVerticallAlignment is VerticalAlignment.Bottom or VerticalAlignment.Stretch || hasSpaceBetween)
{
var rightPaddingsize = spacing < 0 ? padding.Right - spacing : padding.Right;
var lastColumnWidth = new GridLength(rightPaddingsize);
var bottomPaddingSize = spacing < 0 ? padding.Bottom - spacing : padding.Bottom;
_grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(bottomPaddingSize), MaxHeight = bottomPaddingSize });
}

_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = lastColumnWidth, MaxWidth = rightPaddingsize });
if (IsHorizontalHug || childrenHorizontalAlignment is HorizontalAlignment.Right or HorizontalAlignment.Stretch || hasSpaceBetween)
{
var rightPaddingsize = spacing < 0 ? padding.Right - spacing : padding.Right;
_grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(rightPaddingsize), MaxWidth = rightPaddingsize });
}
}

Expand Down

0 comments on commit 28f9783

Please sign in to comment.