using System; using Avalonia; using Avalonia.Controls; namespace AuroraDesk.Presentation.Controls; /// /// 垂直均匀分布子元素的面板,用于渲染节点左右侧连接点。 /// public class ConnectorColumnPanel : Panel { public static readonly StyledProperty SideProperty = AvaloniaProperty.Register(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 }