You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.9 KiB
92 lines
2.9 KiB
using System;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
|
|
namespace AuroraDesk.Presentation.Controls;
|
|
|
|
/// <summary>
|
|
/// 垂直均匀分布子元素的面板,用于渲染节点左右侧连接点。
|
|
/// </summary>
|
|
public class ConnectorColumnPanel : Panel
|
|
{
|
|
public static readonly StyledProperty<ConnectorColumnSide> SideProperty =
|
|
AvaloniaProperty.Register<ConnectorColumnPanel, ConnectorColumnSide>(nameof(Side), ConnectorColumnSide.Center);
|
|
|
|
public ConnectorColumnSide Side
|
|
{
|
|
get => GetValue(SideProperty);
|
|
set => SetValue(SideProperty, value);
|
|
}
|
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
{
|
|
var maxWidth = 0d;
|
|
var totalHeight = 0d;
|
|
|
|
foreach (var child in Children)
|
|
{
|
|
child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
|
var desired = child.DesiredSize;
|
|
var margin = (child as Control)?.Margin ?? new Thickness(0);
|
|
|
|
var horizontalMargin = Math.Abs(margin.Left) + Math.Abs(margin.Right);
|
|
var verticalMargin = Math.Max(0, margin.Top) + Math.Max(0, margin.Bottom);
|
|
|
|
maxWidth = Math.Max(maxWidth, desired.Width + horizontalMargin);
|
|
totalHeight += desired.Height + verticalMargin;
|
|
}
|
|
|
|
var height = double.IsInfinity(availableSize.Height) ? totalHeight : availableSize.Height;
|
|
return new Size(maxWidth, height);
|
|
}
|
|
|
|
protected override Size ArrangeOverride(Size finalSize)
|
|
{
|
|
var count = Children.Count;
|
|
if (count == 0)
|
|
{
|
|
return finalSize;
|
|
}
|
|
|
|
var totalHeight = 0d;
|
|
foreach (var child in Children)
|
|
{
|
|
var margin = (child as Control)?.Margin ?? new Thickness(0);
|
|
totalHeight += child.DesiredSize.Height + Math.Max(0, margin.Top) + Math.Max(0, margin.Bottom);
|
|
}
|
|
|
|
var availableHeight = finalSize.Height;
|
|
var spacing = count > 0
|
|
? Math.Max(0, (availableHeight - totalHeight) / (count + 1))
|
|
: 0;
|
|
|
|
var currentY = spacing;
|
|
foreach (var child in Children)
|
|
{
|
|
var childHeight = child.DesiredSize.Height;
|
|
var childWidth = child.DesiredSize.Width;
|
|
var margin = (child as Control)?.Margin ?? new Thickness(0);
|
|
|
|
double x = Side switch
|
|
{
|
|
ConnectorColumnSide.Left => margin.Left,
|
|
ConnectorColumnSide.Right => finalSize.Width - childWidth + margin.Left,
|
|
_ => (finalSize.Width - childWidth) / 2 + (margin.Left - margin.Right) / 2
|
|
};
|
|
|
|
var y = currentY + Math.Max(0, margin.Top);
|
|
child.Arrange(new Rect(x, y, childWidth, childHeight));
|
|
currentY += Math.Max(0, margin.Top) + childHeight + Math.Max(0, margin.Bottom) + spacing;
|
|
}
|
|
|
|
return finalSize;
|
|
}
|
|
}
|
|
|
|
public enum ConnectorColumnSide
|
|
{
|
|
Center,
|
|
Left,
|
|
Right
|
|
}
|
|
|
|
|