diff --git a/src/Dock.Avalonia/Controls/ProportionalStackPanel.cs b/src/Dock.Avalonia/Controls/ProportionalStackPanel.cs index f937bcb27..dd8df8743 100644 --- a/src/Dock.Avalonia/Controls/ProportionalStackPanel.cs +++ b/src/Dock.Avalonia/Controls/ProportionalStackPanel.cs @@ -224,7 +224,7 @@ protected override Size MeasureOverride(Size constraint) AssignProportions(Children); - var previousisCollapsed = false; + var needsNextSplitter = false; // Measure each of the Children for (var i = 0; i < Children.Count; i++) @@ -242,8 +242,6 @@ protected override Size MeasureOverride(Size constraint) var isCollapsed = !isSplitter && GetIsCollapsed(control); if (isCollapsed) { - // TODO: Also handle next is empty. - previousisCollapsed = true; var size = new Size(); control.Measure(size); continue; @@ -270,29 +268,22 @@ protected override Size MeasureOverride(Size constraint) break; } } + + needsNextSplitter = true; } else { - var nextisCollapsed = false; - if (i + 1 < Children.Count) - { - var nextControl = Children[i + 1]; - nextisCollapsed = !ProportionalStackPanelSplitter.IsSplitter(nextControl, out _ ) && GetIsCollapsed(nextControl); - } - - if (previousisCollapsed || nextisCollapsed) + if (!needsNextSplitter) { var size = new Size(); control.Measure(size); - previousisCollapsed = true; continue; } control.Measure(remainingSize); + needsNextSplitter = false; } - previousisCollapsed = false; - var desiredSize = control.DesiredSize; // Decrease the remaining space for the rest of the children @@ -351,7 +342,7 @@ protected override Size ArrangeOverride(Size arrangeSize) AssignProportions(Children); - var previousisCollapsed = false; + var needsNextSplitter = false; for (var i = 0; i < Children.Count; i++) { @@ -362,31 +353,23 @@ protected override Size ArrangeOverride(Size arrangeSize) var isCollapsed = !isSplitter && GetIsCollapsed(control); if (isCollapsed) { - // TODO: Also handle next is empty. - previousisCollapsed = true; var rect = new Rect(); control.Arrange(rect); index++; continue; } - var nextisCollapsed = false; - if (i + 1 < Children.Count) - { - var nextControl = Children[i + 1]; - nextisCollapsed = !ProportionalStackPanelSplitter.IsSplitter(nextControl, out _) && GetIsCollapsed(nextControl); - } - - if (isSplitter && (previousisCollapsed || nextisCollapsed)) + if (!isSplitter) + needsNextSplitter = true; + else if (isSplitter && !needsNextSplitter) { var rect = new Rect(); control.Arrange(rect); index++; + needsNextSplitter = false; continue; } - previousisCollapsed = false; - // Determine the remaining space left to arrange the element var remainingRect = new Rect( left, diff --git a/src/Dock.Avalonia/Controls/ProportionalStackPanelSplitter.axaml.cs b/src/Dock.Avalonia/Controls/ProportionalStackPanelSplitter.axaml.cs index 19f4e4a69..76077745f 100644 --- a/src/Dock.Avalonia/Controls/ProportionalStackPanelSplitter.axaml.cs +++ b/src/Dock.Avalonia/Controls/ProportionalStackPanelSplitter.axaml.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; @@ -168,26 +169,19 @@ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) private Control? FindNextChild(ProportionalStackPanel panel) { - var children = panel.Children; - int nextIndex; - - if (Parent is ContentPresenter parentContentPresenter) - { - nextIndex = children.IndexOf(parentContentPresenter) + 1; - } - else - { - nextIndex = children.IndexOf(this) + 1; - } - - return children[nextIndex]; + return GetSiblingInDirection(panel, 1); } private void SetTargetProportion(double dragDelta) { - var target = GetTargetElement(); var panel = GetPanel(); - if (target is null || panel is null) + if (panel == null) + { + return; + } + + var target = GetTargetElement(panel); + if (target is null) { return; } @@ -274,35 +268,33 @@ private void UpdateHeightOrWidth() return null; } - private Control? GetTargetElement() + private Control? GetSiblingInDirection(ProportionalStackPanel panel, int direction) { - if (Parent is ContentPresenter presenter) - { - if (presenter.GetVisualParent() is not Panel panel) - { - return null; - } + Debug.Assert(direction == -1 || direction == 1); + + var children = panel.Children; + int siblingIndex; - var parent = Parent as Control; - var index = parent is null ? -1 : panel.Children.IndexOf(parent); - if (index > 0 && panel.Children.Count > 0) - { - return panel.Children[index - 1]; - } + if (Parent is ContentPresenter parentContentPresenter) + { + siblingIndex = children.IndexOf(parentContentPresenter) + direction; } else { - var panel = GetPanel(); - if (panel is not null) - { - var index = panel.Children.IndexOf(this); - if (index > 0 && panel.Children.Count > 0) - { - return panel.Children[index - 1]; - } - } + siblingIndex = children.IndexOf(this) + direction; } - return null; + while (siblingIndex >= 0 && siblingIndex < children.Count && + (ProportionalStackPanel.GetIsCollapsed(children[siblingIndex]) || IsSplitter(children[siblingIndex], out _))) + { + siblingIndex += direction; + } + + return siblingIndex >= 0 && siblingIndex < children.Count ? children[siblingIndex] : null; + } + + private Control? GetTargetElement(ProportionalStackPanel panel) + { + return GetSiblingInDirection(panel, -1); } }