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:
@@ -11,6 +11,11 @@ public abstract class DockModule : Control
|
||||
/// Gets the container that owns this module.
|
||||
/// </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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user