fix(dock): enforce tree invariants, sync selection, and fix AOT warnings

This commit is contained in:
2026-03-28 12:38:29 +09:00
parent 8ba976b0ba
commit 4052ffb854
4 changed files with 216 additions and 4 deletions

View File

@@ -7,12 +7,45 @@ namespace Ghost.Editor.Core.Controls.Internal.Docking;
public partial class DockGroupNode : DockNode
{
[ObservableProperty]
private Orientation _orientation = Orientation.Horizontal;
public partial Orientation Orientation { get; set; }
public DockGroupNode()
{
Orientation = Orientation.Horizontal;
}
public ObservableCollection<DockNode> Children { get; } = new();
public void AddChild(DockNode node)
{
ArgumentNullException.ThrowIfNull(node);
if (node == this)
{
throw new InvalidOperationException("Cannot add a node to itself.");
}
if (Children.Contains(node))
{
return;
}
// Check for cycles
var current = this.Parent;
while (current != null)
{
if (current == node)
{
throw new InvalidOperationException("Cannot add an ancestor as a child (cycle detected).");
}
current = current.Parent;
}
if (node.Parent != null && node.Parent != this)
{
node.Parent.RemoveChild(node);
}
node.Parent = this;
Children.Add(node);
}

View File

@@ -5,5 +5,5 @@ namespace Ghost.Editor.Core.Controls.Internal.Docking;
public abstract partial class DockNode : ObservableObject
{
[ObservableProperty]
private DockGroupNode? _parent;
public partial DockGroupNode? Parent { get; set; }
}

View File

@@ -8,8 +8,64 @@ public partial class DockPanelNode : DockNode
public ObservableCollection<object> Items { get; } = new();
[ObservableProperty]
private int _selectedIndex = -1;
public partial int SelectedIndex { get; set; }
[ObservableProperty]
private object? _selectedItem;
public partial object? SelectedItem { get; set; }
public DockPanelNode()
{
SelectedIndex = -1;
Items.CollectionChanged += OnItemsCollectionChanged;
}
private void OnItemsCollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (Items.Count == 0)
{
SelectedIndex = -1;
SelectedItem = null;
}
else if (SelectedIndex >= Items.Count)
{
SelectedIndex = Items.Count - 1;
}
else if (SelectedIndex == -1 && Items.Count > 0)
{
SelectedIndex = 0;
}
}
partial void OnSelectedIndexChanged(int value)
{
if (value >= 0 && value < Items.Count)
{
SelectedItem = Items[value];
}
else if (value == -1)
{
SelectedItem = null;
}
else
{
// Clamp or reset if out of bounds
SelectedIndex = Items.Count > 0 ? 0 : -1;
}
}
partial void OnSelectedItemChanged(object? value)
{
if (value == null)
{
SelectedIndex = -1;
}
else
{
int index = Items.IndexOf(value);
if (index != -1)
{
SelectedIndex = index;
}
}
}
}