Skip to content

Commit

Permalink
Initial layout algorithm for IsEmpty
Browse files Browse the repository at this point in the history
  • Loading branch information
wieslawsoltes committed Sep 14, 2023
1 parent bb027c0 commit 201a2d0
Showing 1 changed file with 62 additions and 16 deletions.
78 changes: 62 additions & 16 deletions src/Dock.Avalonia/Controls/ProportionalStackPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ private void AssignProportions(global::Avalonia.Controls.Controls children)
var assignedProportion = 0.0;
var unassignedProportions = 0;

foreach (var control in children)
for (var i = 0; i < children.Count; i++)
{
if (control is { } && !ProportionalStackPanelSplitter.IsSplitter(control))
var control = children[i];
var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(control);

if (!ProportionalStackPanelSplitter.IsSplitter(control))
{
var proportion = ProportionalStackPanelSplitter.GetControlProportion(control);

if (isEmpty)
{
proportion = 0.0;
}

if (double.IsNaN(proportion))
{
unassignedProportions++;
Expand All @@ -53,7 +61,11 @@ private void AssignProportions(global::Avalonia.Controls.Controls children)
if (unassignedProportions > 0)
{
var toAssign = assignedProportion;
foreach (var control in children.Where(c => double.IsNaN(ProportionalStackPanelSplitter.GetControlProportion(c))))
foreach (var control in children.Where(c =>
{
var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(c);
return !isEmpty && double.IsNaN(ProportionalStackPanelSplitter.GetControlProportion(c));
}))
{
if (!ProportionalStackPanelSplitter.IsSplitter(control))
{
Expand All @@ -70,7 +82,11 @@ private void AssignProportions(global::Avalonia.Controls.Controls children)

var toAdd = (1.0 - assignedProportion) / numChildren;

foreach (var child in children.Where(c => !ProportionalStackPanelSplitter.IsSplitter(c)))
foreach (var child in children.Where(c =>
{
var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(c);
return !isEmpty && !ProportionalStackPanelSplitter.IsSplitter(c);
}))
{
var proportion = ProportionalStackPanelSplitter.GetControlProportion(child) + toAdd;
ProportionalStackPanelSplitter.SetControlProportion(child, proportion);
Expand All @@ -82,7 +98,11 @@ private void AssignProportions(global::Avalonia.Controls.Controls children)

var toRemove = (assignedProportion - 1.0) / numChildren;

foreach (var child in children.Where(c => !ProportionalStackPanelSplitter.IsSplitter(c)))
foreach (var child in children.Where(c =>
{
var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(c);
return !isEmpty && !ProportionalStackPanelSplitter.IsSplitter(c);
}))
{
var proportion = ProportionalStackPanelSplitter.GetControlProportion(child) - toRemove;
ProportionalStackPanelSplitter.SetControlProportion(child, proportion);
Expand Down Expand Up @@ -135,33 +155,40 @@ protected override Size MeasureOverride(Size constraint)
AssignProportions(Children);

// Measure each of the Children
foreach (var control in Children)
for (var i = 0; i < Children.Count; i++)
{
if (control is null)
{
continue;
}

var control = Children[i];

// Get the child's desired size
var remainingSize = new Size(
Math.Max(0.0, constraint.Width - usedWidth - splitterThickness),
Math.Max(0.0, constraint.Height - usedHeight - splitterThickness));

var proportion = ProportionalStackPanelSplitter.GetControlProportion(control);

var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(control);
if (isEmpty)
{
control.Measure(new Size());
continue;
}

if (!ProportionalStackPanelSplitter.IsSplitter(control))
{
Debug.Assert(!double.IsNaN(proportion));

switch (Orientation)
{
case Orientation.Horizontal:
{
control.Measure(constraint.WithWidth(Math.Max(0, (constraint.Width - splitterThickness) * proportion)));
break;

}
case Orientation.Vertical:
{
control.Measure(constraint.WithHeight(Math.Max(0, (constraint.Height - splitterThickness) * proportion)));
break;
}
}
}
else
Expand All @@ -175,6 +202,7 @@ protected override Size MeasureOverride(Size constraint)
switch (Orientation)
{
case Orientation.Horizontal:
{
maximumHeight = Math.Max(maximumHeight, usedHeight + desiredSize.Height);

if (ProportionalStackPanelSplitter.IsSplitter(control))
Expand All @@ -185,8 +213,11 @@ protected override Size MeasureOverride(Size constraint)
{
usedWidth += Math.Max(0, (constraint.Width - splitterThickness) * proportion);
}

break;
}
case Orientation.Vertical:
{
maximumWidth = Math.Max(maximumWidth, usedWidth + desiredSize.Width);

if (ProportionalStackPanelSplitter.IsSplitter(control))
Expand All @@ -197,7 +228,9 @@ protected override Size MeasureOverride(Size constraint)
{
usedHeight += Math.Max(0, (constraint.Height - splitterThickness) * proportion);
}

break;
}
}
}

Expand All @@ -221,10 +254,15 @@ protected override Size ArrangeOverride(Size arrangeSize)

AssignProportions(Children);

foreach (var control in Children)
for (var i = 0; i < Children.Count; i++)
{
if (control is null)
var control = Children[i];

var isEmpty = ProportionalStackPanelSplitter.GetControlIsEmpty(control);
if (isEmpty)
{
control.Arrange(new Rect());
index++;
continue;
}

Expand All @@ -246,6 +284,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
switch (Orientation)
{
case Orientation.Horizontal:
{
if (ProportionalStackPanelSplitter.IsSplitter(control))
{
left += desiredSize.Width;
Expand All @@ -254,11 +293,15 @@ protected override Size ArrangeOverride(Size arrangeSize)
else
{
Debug.Assert(!double.IsNaN(proportion));
remainingRect = remainingRect.WithWidth(Math.Max(0, (arrangeSize.Width - splitterThickness) * proportion));
remainingRect = remainingRect.WithWidth(
Math.Max(0, (arrangeSize.Width - splitterThickness) * proportion));
left += Math.Max(0, (arrangeSize.Width - splitterThickness) * proportion);
}

break;
}
case Orientation.Vertical:
{
if (ProportionalStackPanelSplitter.IsSplitter(control))
{
top += desiredSize.Height;
Expand All @@ -267,10 +310,13 @@ protected override Size ArrangeOverride(Size arrangeSize)
else
{
Debug.Assert(!double.IsNaN(proportion));
remainingRect = remainingRect.WithHeight(Math.Max(0, (arrangeSize.Height - splitterThickness) * proportion));
remainingRect = remainingRect.WithHeight(
Math.Max(0, (arrangeSize.Height - splitterThickness) * proportion));
top += Math.Max(0, (arrangeSize.Height - splitterThickness) * proportion);
}

break;
}
}
}

Expand Down

0 comments on commit 201a2d0

Please sign in to comment.