diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockModule.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockModule.cs index abd74d0..38bc044 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockModule.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockModule.cs @@ -5,8 +5,11 @@ namespace Ghost.Editor.View.Controls.Docking; public abstract class DockModule : Control { public DockContainer? Owner { get; internal set; } - // Note: DockingLayout will be implemented in a later task - // public DockingLayout? Root { get; internal set; } + + /// + /// Gets or sets the root docking layout this module belongs to. + /// + public DockingLayout? Root { get; internal set; } public void Detach() { diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs index 8ea2753..7420275 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs @@ -4,6 +4,9 @@ using CommunityToolkit.WinUI.Controls; namespace Ghost.Editor.View.Controls.Docking; +/// +/// A container that can host multiple dock modules with splitters. +/// [TemplatePart(Name = PART_GRID, Type = typeof(Grid))] public class DockPanel : DockContainer { diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockRegionHighlight.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockRegionHighlight.cs index 6478653..096ddf9 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockRegionHighlight.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockRegionHighlight.cs @@ -2,6 +2,9 @@ using Microsoft.UI.Xaml.Controls; namespace Ghost.Editor.View.Controls.Docking; +/// +/// Represents a visual highlight for a docking region. +/// public class DockRegionHighlight : Control { public DockRegionHighlight() diff --git a/src/Editor/Ghost.Editor/View/Controls/Docking/DockingLayout.cs b/src/Editor/Ghost.Editor/View/Controls/Docking/DockingLayout.cs index 1331203..31a4de9 100644 --- a/src/Editor/Ghost.Editor/View/Controls/Docking/DockingLayout.cs +++ b/src/Editor/Ghost.Editor/View/Controls/Docking/DockingLayout.cs @@ -3,13 +3,25 @@ using Microsoft.UI.Xaml.Controls; namespace Ghost.Editor.View.Controls.Docking; -[TemplatePart(Name = "PART_OverlayCanvas", Type = typeof(Canvas))] -[TemplatePart(Name = "PART_Highlight", Type = typeof(DockRegionHighlight))] +/// +/// The root control for the docking system layout. +/// +[TemplatePart(Name = PART_OVERLAY_CANVAS, Type = typeof(Canvas))] +[TemplatePart(Name = PART_HIGHLIGHT, Type = typeof(DockRegionHighlight))] public class DockingLayout : Control { + private const string PART_OVERLAY_CANVAS = "PART_OverlayCanvas"; + private const string PART_HIGHLIGHT = "PART_Highlight"; + + /// + /// Gets or sets the root panel of the docking layout. + /// public static readonly DependencyProperty RootPanelProperty = DependencyProperty.Register( nameof(RootPanel), typeof(DockPanel), typeof(DockingLayout), new PropertyMetadata(null, OnRootPanelChanged)); + /// + /// Gets or sets the root panel of the docking layout. + /// public DockPanel? RootPanel { get => (DockPanel?)GetValue(RootPanelProperty); @@ -29,8 +41,8 @@ public class DockingLayout : Control protected override void OnApplyTemplate() { base.OnApplyTemplate(); - _overlayCanvas = GetTemplateChild("PART_OverlayCanvas") as Canvas; - _highlight = GetTemplateChild("PART_Highlight") as DockRegionHighlight; + _overlayCanvas = GetTemplateChild(PART_OVERLAY_CANVAS) as Canvas; + _highlight = GetTemplateChild(PART_HIGHLIGHT) as DockRegionHighlight; } private static void OnRootPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -49,6 +61,12 @@ public class DockingLayout : Control } } + /// + /// Adds a document to the docking layout. + /// + /// The document to add. + /// The docking target position. + /// The target group to add the document to. If null, a suitable group will be found or created. public void AddDocument(DockDocument document, DockTarget target, DockGroup? targetGroup = null) { if (target != DockTarget.Center) @@ -63,30 +81,37 @@ public class DockingLayout : Control if (targetGroup == null) { - if (RootPanel.Children.Count == 0) - { - var group = new DockGroup(); - group.AddChild(document); - RootPanel.AddChild(group); - return; - } + targetGroup = FindFirstLeafDockGroup(RootPanel); - if (RootPanel.Children[0] is DockGroup existingGroup) + if (targetGroup == null) { - targetGroup = existingGroup; - } - else - { - var group = new DockGroup(); - group.AddChild(document); - RootPanel.AddChild(group); - return; + targetGroup = new DockGroup(); + RootPanel.AddChild(targetGroup); } } - if (targetGroup != null) + targetGroup.AddChild(document); + } + + private static DockGroup? FindFirstLeafDockGroup(DockContainer container) + { + if (container is DockGroup group) { - targetGroup.AddChild(document); + return group; } + + foreach (var child in container.Children) + { + if (child is DockContainer childContainer) + { + var result = FindFirstLeafDockGroup(childContainer); + if (result != null) + { + return result; + } + } + } + + return null; } }