diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs index 8dd3a29..6449a80 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs @@ -128,24 +128,49 @@ public partial class DockGroup : DockContainer } } - // Add new tabs that aren't in TabItems yet - foreach (var child in Children) + // Add new tabs that aren't in TabItems yet, and ensure correct order + for (int i = 0; i < Children.Count; i++) { - if (child is DockDocument doc && !_tabView.TabItems.Any(t => t is TabViewItem item && item.Tag.Equals(doc))) + if (Children[i] is DockDocument doc) { - var tabItem = new TabViewItem { Tag = doc, Content = doc }; - tabItem.SetBinding(TabViewItem.HeaderProperty, new Microsoft.UI.Xaml.Data.Binding + TabViewItem? existingTab = null; + for (int j = 0; j < _tabView.TabItems.Count; j++) { - Source = doc, - Path = new PropertyPath(nameof(DockDocument.Title)), - Mode = BindingMode.OneWay - }); - _tabView.TabItems.Add(tabItem); + if (_tabView.TabItems[j] is TabViewItem tabItem && tabItem.Tag == doc) + { + existingTab = tabItem; + // Fix order if necessary + if (j != i) + { + _tabView.TabItems.RemoveAt(j); + _tabView.TabItems.Insert(i, existingTab); + } + break; + } + } + + if (existingTab == null) + { + existingTab = new TabViewItem + { + Tag = doc, + Content = doc + }; + + existingTab.SetBinding(TabViewItem.HeaderProperty, new Microsoft.UI.Xaml.Data.Binding + { + Source = doc, + Path = new PropertyPath(nameof(DockDocument.Title)), + Mode = Microsoft.UI.Xaml.Data.BindingMode.OneWay + }); + + _tabView.TabItems.Insert(i, existingTab); + } } } // Restore selection - if (selectedDoc != null && _tabView.TabItems.FirstOrDefault(t => t is TabViewItem item && item.Tag.Equals(selectedDoc)) is TabViewItem newSelected) + if (selectedDoc != null && _tabView.TabItems.FirstOrDefault(t => t is TabViewItem item && item.Tag == selectedDoc) is TabViewItem newSelected) { _tabView.SelectedItem = newSelected; } diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs index 040343a..541c207 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs @@ -102,44 +102,125 @@ public partial class DockPanel : DockContainer { if (_grid == null) return; - _grid.Children.Clear(); - _grid.RowDefinitions.Clear(); - _grid.ColumnDefinitions.Clear(); + // Remove splitters and children that are no longer in the collection + for (int i = _grid.Children.Count - 1; i >= 0; i--) + { + var child = _grid.Children[i]; + if (child is GridSplitter) + { + _grid.Children.RemoveAt(i); + } + else if (child is DockModule module && !Children.Contains(module)) + { + _grid.Children.RemoveAt(i); + } + } - if (Children.Count == 0) return; + if (Children.Count == 0) + { + _grid.RowDefinitions.Clear(); + _grid.ColumnDefinitions.Clear(); + return; + } if (Orientation == Orientation.Horizontal) { - for (int i = 0; i < Children.Count; i++) + _grid.RowDefinitions.Clear(); + + int requiredColumns = (Children.Count * 2) - 1; + while (_grid.ColumnDefinitions.Count > requiredColumns) { - _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(Children[i].DockLength, GridUnitType.Star) }); + _grid.ColumnDefinitions.RemoveAt(_grid.ColumnDefinitions.Count - 1); + } + + for (var i = 0; i < Children.Count; i++) + { + int columnIndex = i * 2; + if (columnIndex >= _grid.ColumnDefinitions.Count) + { + _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(Children[i].DockLength, GridUnitType.Star), MinWidth = 250 }); + } + else + { + _grid.ColumnDefinitions[columnIndex].Width = new GridLength(Children[i].DockLength, GridUnitType.Star); + _grid.ColumnDefinitions[columnIndex].MinWidth = 250; + } + var child = Children[i]; - Grid.SetColumn(child, i * 2); - _grid.Children.Add(child); + if (!_grid.Children.Contains(child)) + { + _grid.Children.Add(child); + } + + Grid.SetColumn(child, columnIndex); + Grid.SetRow(child, 0); if (i < Children.Count - 1) { - _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + int splitterIndex = columnIndex + 1; + if (splitterIndex >= _grid.ColumnDefinitions.Count) + { + _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + } + else + { + _grid.ColumnDefinitions[splitterIndex].Width = GridLength.Auto; + } + var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Columns, Width = SPLITTER_THICKNESS }; - Grid.SetColumn(splitter, i * 2 + 1); + Grid.SetColumn(splitter, splitterIndex); + Grid.SetRow(splitter, 0); _grid.Children.Add(splitter); } } } else { - for (int i = 0; i < Children.Count; i++) + _grid.ColumnDefinitions.Clear(); + + int requiredRows = (Children.Count * 2) - 1; + while (_grid.RowDefinitions.Count > requiredRows) { - _grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(Children[i].DockLength, GridUnitType.Star) }); + _grid.RowDefinitions.RemoveAt(_grid.RowDefinitions.Count - 1); + } + + for (var i = 0; i < Children.Count; i++) + { + int rowIndex = i * 2; + if (rowIndex >= _grid.RowDefinitions.Count) + { + _grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(Children[i].DockLength, GridUnitType.Star), MinHeight = 250 }); + } + else + { + _grid.RowDefinitions[rowIndex].Height = new GridLength(Children[i].DockLength, GridUnitType.Star); + _grid.RowDefinitions[rowIndex].MinHeight = 250; + } + var child = Children[i]; - Grid.SetRow(child, i * 2); - _grid.Children.Add(child); + if (!_grid.Children.Contains(child)) + { + _grid.Children.Add(child); + } + + Grid.SetRow(child, rowIndex); + Grid.SetColumn(child, 0); if (i < Children.Count - 1) { - _grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + int splitterIndex = rowIndex + 1; + if (splitterIndex >= _grid.RowDefinitions.Count) + { + _grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + } + else + { + _grid.RowDefinitions[splitterIndex].Height = GridLength.Auto; + } + var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Rows, Height = SPLITTER_THICKNESS }; - Grid.SetRow(splitter, i * 2 + 1); + Grid.SetRow(splitter, splitterIndex); + Grid.SetColumn(splitter, 0); _grid.Children.Add(splitter); } }