feat(docking): implement proportional sizing for docking layout

- Add DockLength property to DockModule to track star weights
- Add SyncLengths() to DockPanel to capture current Grid weights
- Update DockPanel.UpdateLayoutStructure to use DockLength
- Update DockingLayout.SplitGroup to distribute weights when splitting
This commit is contained in:
2026-03-29 19:02:21 +09:00
parent 2e6e705558
commit ff22b89ba3
3 changed files with 49 additions and 4 deletions

View File

@@ -12,6 +12,11 @@ public abstract class DockModule : Control
/// </summary>
public DockContainer? Owner { get; internal set; }
/// <summary>
/// Gets or sets the proportional length (star weight) of this module within its parent panel.
/// </summary>
public double DockLength { get; set; } = 1.0;
private DockingLayout? _root;
/// <summary>

View File

@@ -45,6 +45,33 @@ public partial class DockPanel : DockContainer
UpdateLayoutStructure();
}
internal void SyncLengths()
{
if (_grid == null) return;
if (Orientation == Orientation.Horizontal)
{
for (int i = 0; i < Children.Count; i++)
{
int col = i * 2;
if (col < _grid.ColumnDefinitions.Count)
{
Children[i].DockLength = _grid.ColumnDefinitions[col].Width.Value;
}
}
}
else
{
for (int i = 0; i < Children.Count; i++)
{
int row = i * 2;
if (row < _grid.RowDefinitions.Count)
{
Children[i].DockLength = _grid.RowDefinitions[row].Height.Value;
}
}
}
}
internal override void CheckCleanup()
{
base.CheckCleanup();
@@ -85,7 +112,7 @@ public partial class DockPanel : DockContainer
{
for (int i = 0; i < Children.Count; i++)
{
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(Children[i].DockLength, GridUnitType.Star) });
var child = Children[i];
Grid.SetColumn(child, i * 2);
_grid.Children.Add(child);
@@ -103,7 +130,7 @@ public partial class DockPanel : DockContainer
{
for (int i = 0; i < Children.Count; i++)
{
_grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(Children[i].DockLength, GridUnitType.Star) });
var child = Children[i];
Grid.SetRow(child, i * 2);
_grid.Children.Add(child);

View File

@@ -144,6 +144,7 @@ public partial class DockingLayout : Control
private void SplitGroup(DockGroup targetGroup, DockDocument doc, DockTarget target)
{
var parentPanel = targetGroup.Owner as DockPanel;
parentPanel?.SyncLengths(); // Sync before modifying!
var newGroup = new DockGroup();
newGroup.AddChild(doc);
@@ -156,6 +157,9 @@ public partial class DockingLayout : Control
var newPanel = new DockPanel { Orientation = orientation };
RootModule = newPanel;
targetGroup.DockLength = 1.0;
newGroup.DockLength = 1.0;
if (target == DockTarget.Left || target == DockTarget.Top)
{
newPanel.AddChild(newGroup);
@@ -178,7 +182,11 @@ public partial class DockingLayout : Control
if (parentPanel.Orientation == orientation)
{
// Same orientation, just insert
// Splitting in the same orientation. Share the length.
double halfLength = targetGroup.DockLength / 2.0;
targetGroup.DockLength = halfLength;
newGroup.DockLength = halfLength;
if (target == DockTarget.Left || target == DockTarget.Top)
{
parentPanel.InsertChild(index, newGroup);
@@ -190,8 +198,13 @@ public partial class DockingLayout : Control
}
else
{
// Different orientation, need a new sub-panel
// Splitting in opposite orientation. New panel takes the full length.
var newPanel = new DockPanel { Orientation = orientation };
newPanel.DockLength = targetGroup.DockLength;
targetGroup.DockLength = 1.0;
newGroup.DockLength = 1.0;
parentPanel.ReplaceChild(targetGroup, newPanel);
if (target == DockTarget.Left || target == DockTarget.Top)