75 lines
2.4 KiB
C#
Raw Permalink Normal View History

2023-05-11 23:11:39 -04:00
using Avalonia;
using Avalonia.Controls;
using SPTInstaller.Behaviors;
using System.Linq;
namespace SPTInstaller.CustomControls;
public class DistributedSpacePanel : Panel
2023-05-11 23:11:39 -04:00
{
protected override Size MeasureOverride(Size availableSize)
2023-05-11 23:11:39 -04:00
{
var children = Children;
2023-05-11 23:11:39 -04:00
for (int i = 0; i < children.Count; i++)
{
// measure child objects so we can use their desired size in the arrange override
var child = children[i];
child.Measure(availableSize);
2023-05-11 23:11:39 -04:00
}
// we want to use all available space
return availableSize;
}
2023-05-11 23:11:39 -04:00
protected override Size ArrangeOverride(Size finalSize)
{
var children = Children;
Rect rcChild = new Rect(finalSize);
double previousChildSize = 0.0;
2023-05-11 23:11:39 -04:00
// get child objects that don't want to span the entire control
var nonSpanningChildren = children.Where(x => x.GetValue(SpanBehavior.SpanProperty) == false).ToList();
2023-05-11 23:11:39 -04:00
// get the total height off all non-spanning child objects
var totalChildHeight = nonSpanningChildren.Select(x => x.DesiredSize.Height).Sum();
2023-05-11 23:11:39 -04:00
// remove the total child height from our controls final size and divide it by the total non-spanning child objects
// except the last one, since it needs no space after it
var spacing = (finalSize.Height - totalChildHeight) / (nonSpanningChildren.Count - 1);
2023-05-11 23:11:39 -04:00
for (int i = 0; i < children.Count; i++)
{
var child = children[i];
2023-05-11 23:11:39 -04:00
var spanChild = child.GetValue(SpanBehavior.SpanProperty);
2023-05-11 23:11:39 -04:00
if (spanChild)
{
// move any spanning children to the top of the array to push them behind the other controls (visually)
children.Move(i, 0);
2023-05-11 23:11:39 -04:00
rcChild = rcChild.WithY(0)
.WithX(0)
.WithHeight(finalSize.Height)
.WithWidth(finalSize.Width);
2023-05-11 23:11:39 -04:00
child.Arrange(rcChild);
continue;
};
2023-05-11 23:11:39 -04:00
rcChild = rcChild.WithY(rcChild.Y + previousChildSize);
previousChildSize = child.DesiredSize.Height;
rcChild = rcChild.WithHeight(previousChildSize)
.WithWidth(Math.Max(finalSize.Width, child.DesiredSize.Width));
2023-05-11 23:11:39 -04:00
previousChildSize += spacing;
2023-05-11 23:11:39 -04:00
child.Arrange(rcChild);
2023-05-11 23:11:39 -04:00
}
return finalSize;
2023-05-11 23:11:39 -04:00
}
}