fix(docking): address code quality issues and improve docking robustness
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.251219" />
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.251219" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.251219" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.TabbedCommandBar" Version="8.2.251219" />
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.TabbedCommandBar" Version="8.2.251219" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.2" />
|
||||||
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ namespace Ghost.Editor.View.Controls.Docking;
|
|||||||
public abstract class DockContainer : DockModule
|
public abstract class DockContainer : DockModule
|
||||||
{
|
{
|
||||||
private readonly ObservableCollection<DockModule> _children = new();
|
private readonly ObservableCollection<DockModule> _children = new();
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the collection of child modules.
|
||||||
|
/// </summary>
|
||||||
public ReadOnlyObservableCollection<DockModule> Children { get; }
|
public ReadOnlyObservableCollection<DockModule> Children { get; }
|
||||||
|
|
||||||
protected DockContainer()
|
protected DockContainer()
|
||||||
@@ -22,15 +25,27 @@ public abstract class DockContainer : DockModule
|
|||||||
OnChildrenUpdated();
|
OnChildrenUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a child module to the end of the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module">The module to add.</param>
|
||||||
public virtual void AddChild(DockModule module)
|
public virtual void AddChild(DockModule module)
|
||||||
{
|
{
|
||||||
InsertChild(_children.Count, module);
|
InsertChild(_children.Count, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inserts a child module at the specified index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The zero-based index at which the module should be inserted.</param>
|
||||||
|
/// <param name="module">The module to insert.</param>
|
||||||
public virtual void InsertChild(int index, DockModule module)
|
public virtual void InsertChild(int index, DockModule module)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(module);
|
ArgumentNullException.ThrowIfNull(module);
|
||||||
|
|
||||||
|
if (index < 0 || index > _children.Count)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
|
||||||
if (module == this)
|
if (module == this)
|
||||||
throw new ArgumentException("Cannot add a container to itself.", nameof(module));
|
throw new ArgumentException("Cannot add a container to itself.", nameof(module));
|
||||||
|
|
||||||
@@ -54,6 +69,10 @@ public abstract class DockContainer : DockModule
|
|||||||
_children.Insert(index, module);
|
_children.Insert(index, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a child module from the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module">The module to remove.</param>
|
||||||
public virtual void RemoveChild(DockModule module)
|
public virtual void RemoveChild(DockModule module)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(module);
|
ArgumentNullException.ThrowIfNull(module);
|
||||||
@@ -74,6 +93,9 @@ public abstract class DockContainer : DockModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all child modules from the container.
|
||||||
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (var child in _children)
|
foreach (var child in _children)
|
||||||
|
|||||||
@@ -11,12 +11,18 @@ public partial class DockDocument : DockModule
|
|||||||
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
|
||||||
nameof(Content), typeof(object), typeof(DockDocument), new PropertyMetadata(null));
|
nameof(Content), typeof(object), typeof(DockDocument), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the title of the document.
|
||||||
|
/// </summary>
|
||||||
public string? Title
|
public string? Title
|
||||||
{
|
{
|
||||||
get => (string?)GetValue(TitleProperty);
|
get => (string?)GetValue(TitleProperty);
|
||||||
set => SetValue(TitleProperty, value);
|
set => SetValue(TitleProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the content of the document.
|
||||||
|
/// </summary>
|
||||||
public object? Content
|
public object? Content
|
||||||
{
|
{
|
||||||
get => GetValue(ContentProperty);
|
get => GetValue(ContentProperty);
|
||||||
|
|||||||
@@ -157,5 +157,9 @@ public partial class DockGroup : DockContainer
|
|||||||
{
|
{
|
||||||
_tabView.SelectedItem = newSelectedItem;
|
_tabView.SelectedItem = newSelectedItem;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_tabView.SelectedItem = _tabView.TabItems.FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ namespace Ghost.Editor.View.Controls.Docking;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DockModule : Control
|
public abstract class DockModule : Control
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the container that owns this module.
|
||||||
|
/// </summary>
|
||||||
public DockContainer? Owner { get; internal set; }
|
public DockContainer? Owner { get; internal set; }
|
||||||
|
|
||||||
private DockingLayout? _root;
|
private DockingLayout? _root;
|
||||||
@@ -29,6 +32,9 @@ public abstract class DockModule : Control
|
|||||||
|
|
||||||
protected virtual void OnRootChanged() { }
|
protected virtual void OnRootChanged() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detaches this module from its current owner.
|
||||||
|
/// </summary>
|
||||||
public void Detach()
|
public void Detach()
|
||||||
{
|
{
|
||||||
Owner?.RemoveChild(this);
|
Owner?.RemoveChild(this);
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ public class DockPanel : DockContainer
|
|||||||
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
|
||||||
nameof(Orientation), typeof(Orientation), typeof(DockPanel), new PropertyMetadata(Orientation.Horizontal, OnOrientationChanged));
|
nameof(Orientation), typeof(Orientation), typeof(DockPanel), new PropertyMetadata(Orientation.Horizontal, OnOrientationChanged));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the orientation of the panel.
|
||||||
|
/// </summary>
|
||||||
public Orientation Orientation
|
public Orientation Orientation
|
||||||
{
|
{
|
||||||
get => (Orientation)GetValue(OrientationProperty);
|
get => (Orientation)GetValue(OrientationProperty);
|
||||||
@@ -89,7 +92,7 @@ public class DockPanel : DockContainer
|
|||||||
if (i < Children.Count - 1)
|
if (i < Children.Count - 1)
|
||||||
{
|
{
|
||||||
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||||
var splitter = new CommunityToolkit.WinUI.Controls.GridSplitter { ResizeDirection = CommunityToolkit.WinUI.Controls.GridSplitter.GridResizeDirection.Columns, Width = SPLITTER_THICKNESS };
|
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Columns, Width = SPLITTER_THICKNESS };
|
||||||
Grid.SetColumn(splitter, i * 2 + 1);
|
Grid.SetColumn(splitter, i * 2 + 1);
|
||||||
_grid.Children.Add(splitter);
|
_grid.Children.Add(splitter);
|
||||||
}
|
}
|
||||||
@@ -107,7 +110,7 @@ public class DockPanel : DockContainer
|
|||||||
if (i < Children.Count - 1)
|
if (i < Children.Count - 1)
|
||||||
{
|
{
|
||||||
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
||||||
var splitter = new CommunityToolkit.WinUI.Controls.GridSplitter { ResizeDirection = CommunityToolkit.WinUI.Controls.GridSplitter.GridResizeDirection.Rows, Height = SPLITTER_THICKNESS };
|
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Rows, Height = SPLITTER_THICKNESS };
|
||||||
Grid.SetRow(splitter, i * 2 + 1);
|
Grid.SetRow(splitter, i * 2 + 1);
|
||||||
_grid.Children.Add(splitter);
|
_grid.Children.Add(splitter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ public class DockingLayout : Control
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Different orientation, need a new sub-panel
|
// Different orientation, need a new sub-panel
|
||||||
targetGroup.Detach();
|
|
||||||
var newPanel = new DockPanel { Orientation = orientation };
|
var newPanel = new DockPanel { Orientation = orientation };
|
||||||
|
parentPanel.InsertChild(index, newPanel);
|
||||||
|
|
||||||
if (target == DockTarget.Left || target == DockTarget.Top)
|
if (target == DockTarget.Left || target == DockTarget.Top)
|
||||||
{
|
{
|
||||||
@@ -160,8 +160,6 @@ public class DockingLayout : Control
|
|||||||
newPanel.AddChild(targetGroup);
|
newPanel.AddChild(targetGroup);
|
||||||
newPanel.AddChild(newGroup);
|
newPanel.AddChild(newGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
parentPanel.InsertChild(index, newPanel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,10 +226,9 @@ public class DockingLayout : Control
|
|||||||
HideHighlight();
|
HideHighlight();
|
||||||
var target = CalculateDockTarget(targetGroup, position);
|
var target = CalculateDockTarget(targetGroup, position);
|
||||||
|
|
||||||
doc.Detach();
|
|
||||||
|
|
||||||
if (target == DockTarget.Center)
|
if (target == DockTarget.Center)
|
||||||
{
|
{
|
||||||
|
if (doc.Owner == targetGroup) return;
|
||||||
targetGroup.AddChild(doc);
|
targetGroup.AddChild(doc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -256,7 +253,6 @@ public class DockingLayout : Control
|
|||||||
|
|
||||||
internal void CreateFloatingWindow(DockDocument doc)
|
internal void CreateFloatingWindow(DockDocument doc)
|
||||||
{
|
{
|
||||||
doc.Detach();
|
|
||||||
// To be implemented in Task 6
|
// To be implemented in Task 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user