fix(dock): improve window lifecycle, size sync performance, and code style
This commit is contained in:
@@ -1,18 +1,5 @@
|
||||
namespace Ghost.Editor.Core.Controls.Internal.Docking;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the possible dock positions for a drop operation.
|
||||
/// </summary>
|
||||
internal enum DockPosition
|
||||
{
|
||||
Center,
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right,
|
||||
None
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for docking-related calculations.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Ghost.Editor.Core.Controls.Internal.Docking;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the possible dock positions for a drop operation.
|
||||
/// </summary>
|
||||
internal enum DockPosition
|
||||
{
|
||||
Center,
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right,
|
||||
None
|
||||
}
|
||||
@@ -122,9 +122,13 @@ public sealed partial class DockLayout
|
||||
var newWidth = grid.ColumnDefinitions[i * 2].Width;
|
||||
if (!groupNode.Sizes[i].Equals(newWidth))
|
||||
{
|
||||
_isSyncingSizes = true;
|
||||
groupNode.Sizes[i] = newWidth;
|
||||
changed = true;
|
||||
// Only sync if it's a star or pixel value (not Auto)
|
||||
if (newWidth.IsStar || newWidth.IsAbsolute)
|
||||
{
|
||||
_isSyncingSizes = true;
|
||||
groupNode.Sizes[i] = newWidth;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,9 +142,12 @@ public sealed partial class DockLayout
|
||||
var newHeight = grid.RowDefinitions[i * 2].Height;
|
||||
if (!groupNode.Sizes[i].Equals(newHeight))
|
||||
{
|
||||
_isSyncingSizes = true;
|
||||
groupNode.Sizes[i] = newHeight;
|
||||
changed = true;
|
||||
if (newHeight.IsStar || newHeight.IsAbsolute)
|
||||
{
|
||||
_isSyncingSizes = true;
|
||||
groupNode.Sizes[i] = newHeight;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ namespace Ghost.Editor.View.Windows;
|
||||
|
||||
internal sealed partial class DockWindow : WindowEx
|
||||
{
|
||||
private long _rootPropertyToken;
|
||||
private DockGroupNode? _currentRoot;
|
||||
|
||||
public DockWindow(object initialTabContent)
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -21,47 +24,54 @@ internal sealed partial class DockWindow : WindowEx
|
||||
PART_DockLayout.TabTornOff += OnTabTornOff;
|
||||
|
||||
RegisterCloseHandler();
|
||||
|
||||
this.Closed += (s, e) =>
|
||||
{
|
||||
if (_rootPropertyToken != 0)
|
||||
{
|
||||
PART_DockLayout.UnregisterPropertyChangedCallback(DockLayout.RootProperty, _rootPropertyToken);
|
||||
_rootPropertyToken = 0;
|
||||
}
|
||||
UnsubscribeFromRoot(_currentRoot);
|
||||
};
|
||||
}
|
||||
|
||||
private void RegisterCloseHandler()
|
||||
{
|
||||
// Subscribe to Root changes to ensure we always track the current tree
|
||||
var rootProperty = DockLayout.RootProperty;
|
||||
|
||||
void OnRootChildrenChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
_rootPropertyToken = PART_DockLayout.RegisterPropertyChangedCallback(DockLayout.RootProperty, (s, dp) =>
|
||||
{
|
||||
if (PART_DockLayout.Root?.Children.Count == 0)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
void SubscribeToRoot(DockGroupNode? root)
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
((System.Collections.Specialized.INotifyCollectionChanged)root.Children).CollectionChanged += OnRootChildrenChanged;
|
||||
}
|
||||
}
|
||||
|
||||
void UnsubscribeFromRoot(DockGroupNode? root)
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
((System.Collections.Specialized.INotifyCollectionChanged)root.Children).CollectionChanged -= OnRootChildrenChanged;
|
||||
}
|
||||
}
|
||||
|
||||
PART_DockLayout.RegisterPropertyChangedCallback(DockLayout.RootProperty, (s, dp) =>
|
||||
{
|
||||
// This is a bit tricky since we don't have the old value easily here in RegisterPropertyChangedCallback
|
||||
// But for DockWindow, the root is usually set once.
|
||||
UnsubscribeFromRoot(_currentRoot);
|
||||
SubscribeToRoot(PART_DockLayout.Root);
|
||||
});
|
||||
|
||||
SubscribeToRoot(PART_DockLayout.Root);
|
||||
}
|
||||
|
||||
private void OnRootChildrenChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (PART_DockLayout.Root?.Children.Count == 0)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToRoot(DockGroupNode? root)
|
||||
{
|
||||
_currentRoot = root;
|
||||
if (_currentRoot != null)
|
||||
{
|
||||
((System.Collections.Specialized.INotifyCollectionChanged)_currentRoot.Children).CollectionChanged += OnRootChildrenChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnsubscribeFromRoot(DockGroupNode? root)
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
((System.Collections.Specialized.INotifyCollectionChanged)root.Children).CollectionChanged -= OnRootChildrenChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTabTornOff(object? sender, TabTornOffEventArgs e)
|
||||
{
|
||||
App.CreateAndShowDockWindow(e.TabContent);
|
||||
|
||||
Reference in New Issue
Block a user