diff --git a/src/Editor/Ghost.Editor/Themes/DockingDictionary.xaml b/src/Editor/Ghost.Editor/Themes/DockingDictionary.xaml
index 13dd43f..fb4c973 100644
--- a/src/Editor/Ghost.Editor/Themes/DockingDictionary.xaml
+++ b/src/Editor/Ghost.Editor/Themes/DockingDictionary.xaml
@@ -7,6 +7,7 @@
+
\ No newline at end of file
diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockDocument.xaml b/src/Editor/Ghost.Editor/View/Controls/Docking/DockDocument.xaml
new file mode 100644
index 0000000..2693a12
--- /dev/null
+++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockDocument.xaml
@@ -0,0 +1,21 @@
+
+
+
+
diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs
index c769f63..279c740 100644
--- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs
+++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockGroup.cs
@@ -115,70 +115,41 @@ public partial class DockGroup : DockContainer
var selectedDoc = _tabView.SelectedItem is TabViewItem selectedItem ? selectedItem.Tag as DockDocument : null;
- // Remove tabs that are no longer in Children
- for (int i = _tabView.TabItems.Count - 1; i >= 0; i--)
+ // Detach all existing tabs
+ foreach (var item in _tabView.TabItems)
{
- if (_tabView.TabItems[i] is TabViewItem tabItem && tabItem.Tag is DockDocument doc)
+ if (item is TabViewItem tabItem)
{
- if (!Children.Contains(doc))
- {
- tabItem.ClearValue(ContentControl.ContentProperty);
- tabItem.Content = null;
- _tabView.TabItems.RemoveAt(i);
- }
+ tabItem.Content = null;
}
}
+ _tabView.TabItems.Clear();
TabViewItem? newSelectedItem = null;
- // Add tabs that are in Children but not in TabItems, and ensure correct order
- for (int i = 0; i < Children.Count; i++)
+ foreach (var child in Children)
{
- if (Children[i] is DockDocument doc)
+ if (child is DockDocument doc)
{
- TabViewItem? existingTab = null;
- for (int j = 0; j < _tabView.TabItems.Count; j++)
+ var tabItem = new TabViewItem
{
- 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;
- }
- }
+ Tag = doc
+ };
- if (existingTab == null)
+ tabItem.SetBinding(TabViewItem.HeaderProperty, new Microsoft.UI.Xaml.Data.Binding
{
- existingTab = new TabViewItem
- {
- Tag = doc
- };
+ Source = doc,
+ Path = new PropertyPath(nameof(DockDocument.Title)),
+ Mode = Microsoft.UI.Xaml.Data.BindingMode.OneWay
+ });
- existingTab.SetBinding(TabViewItem.HeaderProperty, new Binding
- {
- Source = doc,
- Path = new PropertyPath(nameof(DockDocument.Title)),
- Mode = BindingMode.OneWay
- });
+ tabItem.Content = doc;
- existingTab.SetBinding(ContentControl.ContentProperty, new Binding
- {
- Source = doc,
- Path = new PropertyPath(nameof(DockDocument.Content)),
- Mode = BindingMode.OneWay
- });
-
- _tabView.TabItems.Insert(i, existingTab);
- }
+ _tabView.TabItems.Add(tabItem);
if (doc == selectedDoc)
{
- newSelectedItem = existingTab;
+ newSelectedItem = tabItem;
}
}
}
diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs
index 69f0bdc..0b007e3 100644
--- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs
+++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs
@@ -1,6 +1,6 @@
-using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
+using CommunityToolkit.WinUI.Controls;
namespace Ghost.Editor.View.Controls.Docking;
@@ -8,10 +8,10 @@ namespace Ghost.Editor.View.Controls.Docking;
/// A container that can host multiple dock modules with splitters.
///
[TemplatePart(Name = PART_GRID, Type = typeof(Grid))]
-public partial class DockPanel : DockContainer
+public class DockPanel : DockContainer
{
private const string PART_GRID = "PART_Grid";
- private const double SPLITTER_THICKNESS = 1;
+ private const double SPLITTER_THICKNESS = 4;
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
nameof(Orientation), typeof(Orientation), typeof(DockPanel), new PropertyMetadata(Orientation.Horizontal, OnOrientationChanged));
@@ -74,123 +74,44 @@ public partial class DockPanel : DockContainer
{
if (_grid == null) return;
- // 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);
- }
- }
+ _grid.Children.Clear();
+ _grid.RowDefinitions.Clear();
+ _grid.ColumnDefinitions.Clear();
- if (Children.Count == 0)
- {
- _grid.RowDefinitions.Clear();
- _grid.ColumnDefinitions.Clear();
- return;
- }
+ if (Children.Count == 0) return;
if (Orientation == Orientation.Horizontal)
{
- _grid.RowDefinitions.Clear();
-
- int requiredColumns = (Children.Count * 2) - 1;
- while (_grid.ColumnDefinitions.Count > requiredColumns)
+ for (int i = 0; i < Children.Count; i++)
{
- _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(1, GridUnitType.Star) });
- }
- else
- {
- _grid.ColumnDefinitions[columnIndex].Width = new GridLength(1, GridUnitType.Star);
- }
-
+ _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var child = Children[i];
- if (!_grid.Children.Contains(child))
- {
- _grid.Children.Add(child);
- }
-
- Grid.SetColumn(child, columnIndex);
- Grid.SetRow(child, 0);
+ Grid.SetColumn(child, i * 2);
+ _grid.Children.Add(child);
if (i < Children.Count - 1)
{
- int splitterIndex = i * 2 + 1;
- if (splitterIndex >= _grid.ColumnDefinitions.Count)
- {
- _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
- }
- else
- {
- _grid.ColumnDefinitions[splitterIndex].Width = GridLength.Auto;
- }
-
+ _grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Columns, Width = SPLITTER_THICKNESS };
- Grid.SetColumn(splitter, splitterIndex);
- Grid.SetRow(splitter, 0);
+ Grid.SetColumn(splitter, i * 2 + 1);
_grid.Children.Add(splitter);
}
}
}
else
{
- _grid.ColumnDefinitions.Clear();
-
- int requiredRows = (Children.Count * 2) - 1;
- while (_grid.RowDefinitions.Count > requiredRows)
+ for (int i = 0; i < Children.Count; i++)
{
- _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(1, GridUnitType.Star) });
- }
- else
- {
- _grid.RowDefinitions[rowIndex].Height = new GridLength(1, GridUnitType.Star);
- }
-
+ _grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
var child = Children[i];
- if (!_grid.Children.Contains(child))
- {
- _grid.Children.Add(child);
- }
-
- Grid.SetRow(child, rowIndex);
- Grid.SetColumn(child, 0);
+ Grid.SetRow(child, i * 2);
+ _grid.Children.Add(child);
if (i < Children.Count - 1)
{
- int splitterIndex = i * 2 + 1;
- if (splitterIndex >= _grid.RowDefinitions.Count)
- {
- _grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
- }
- else
- {
- _grid.RowDefinitions[splitterIndex].Height = GridLength.Auto;
- }
-
+ _grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Rows, Height = SPLITTER_THICKNESS };
- Grid.SetRow(splitter, splitterIndex);
- Grid.SetColumn(splitter, 0);
+ Grid.SetRow(splitter, i * 2 + 1);
_grid.Children.Add(splitter);
}
}
diff --git a/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml b/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml
index 3a3e305..959502a 100644
--- a/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml
+++ b/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml
@@ -152,7 +152,6 @@
diff --git a/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml.cs b/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml.cs
index 7eb931d..4563234 100644
--- a/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml.cs
+++ b/src/Editor/Ghost.Editor/View/Controls/ProjectBrowser.xaml.cs
@@ -17,9 +17,6 @@ internal sealed partial class ProjectBrowser : UserControl
private readonly IInspectorService _inspectorService;
private bool _isUpdatingSelection = false;
- private double _savedHorizontalOffset;
- private double _savedVerticalOffset;
- private ScrollViewer? _filesScrollViewer;
public ProjectBrowserViewModel ViewModel
{
@@ -52,43 +49,12 @@ internal sealed partial class ProjectBrowser : UserControl
private void ProjectBrowser_Loaded(object sender, RoutedEventArgs e)
{
_inspectorService.OnSelectionChanged += _inspectorService_OnSelectionChanged;
- PART_FilesView.UpdateLayout();
-
- DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Low, () =>
- {
- if (_filesScrollViewer == null)
- {
- _filesScrollViewer = FindVisualChild(PART_FilesView);
- }
-
- if (_filesScrollViewer != null)
- {
- // Sometimes resetting the ItemsSource helps clear corrupted virtualization state
- var itemsSource = PART_FilesView.ItemsSource;
- PART_FilesView.ItemsSource = null;
- PART_FilesView.ItemsSource = itemsSource;
-
- PART_FilesView.UpdateLayout();
- _filesScrollViewer.ChangeView(_savedHorizontalOffset, _savedVerticalOffset, null, true);
- }
- });
}
private void ProjectBrowser_Unloaded(object sender, RoutedEventArgs e)
{
_inspectorService.OnSelectionChanged -= _inspectorService_OnSelectionChanged;
- if (_filesScrollViewer == null)
- {
- _filesScrollViewer = FindVisualChild(PART_FilesView);
- }
-
- if (_filesScrollViewer != null)
- {
- _savedHorizontalOffset = _filesScrollViewer.HorizontalOffset;
- _savedVerticalOffset = _filesScrollViewer.VerticalOffset;
- }
-
if (LastFocused == this)
{
LastFocused = null;
@@ -104,26 +70,6 @@ internal sealed partial class ProjectBrowser : UserControl
}
}
- private static T? FindVisualChild(DependencyObject parent) where T : DependencyObject
- {
- for (int i = 0; i < Microsoft.UI.Xaml.Media.VisualTreeHelper.GetChildrenCount(parent); i++)
- {
- var child = Microsoft.UI.Xaml.Media.VisualTreeHelper.GetChild(parent, i);
- if (child is T t)
- {
- return t;
- }
-
- var result = FindVisualChild(child);
- if (result != null)
- {
- return result;
- }
- }
-
- return null;
- }
-
private void PART_DirectoriesView_SelectionChanged(TreeView sender, TreeViewSelectionChangedEventArgs args)
{
if (_isUpdatingSelection)