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:
@@ -12,6 +12,11 @@ public abstract class DockModule : Control
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DockContainer? Owner { get; internal set; }
|
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;
|
private DockingLayout? _root;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -45,6 +45,33 @@ public partial class DockPanel : DockContainer
|
|||||||
UpdateLayoutStructure();
|
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()
|
internal override void CheckCleanup()
|
||||||
{
|
{
|
||||||
base.CheckCleanup();
|
base.CheckCleanup();
|
||||||
@@ -85,7 +112,7 @@ public partial class DockPanel : DockContainer
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < Children.Count; i++)
|
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];
|
var child = Children[i];
|
||||||
Grid.SetColumn(child, i * 2);
|
Grid.SetColumn(child, i * 2);
|
||||||
_grid.Children.Add(child);
|
_grid.Children.Add(child);
|
||||||
@@ -103,7 +130,7 @@ public partial class DockPanel : DockContainer
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < Children.Count; i++)
|
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];
|
var child = Children[i];
|
||||||
Grid.SetRow(child, i * 2);
|
Grid.SetRow(child, i * 2);
|
||||||
_grid.Children.Add(child);
|
_grid.Children.Add(child);
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ public partial class DockingLayout : Control
|
|||||||
private void SplitGroup(DockGroup targetGroup, DockDocument doc, DockTarget target)
|
private void SplitGroup(DockGroup targetGroup, DockDocument doc, DockTarget target)
|
||||||
{
|
{
|
||||||
var parentPanel = targetGroup.Owner as DockPanel;
|
var parentPanel = targetGroup.Owner as DockPanel;
|
||||||
|
parentPanel?.SyncLengths(); // Sync before modifying!
|
||||||
|
|
||||||
var newGroup = new DockGroup();
|
var newGroup = new DockGroup();
|
||||||
newGroup.AddChild(doc);
|
newGroup.AddChild(doc);
|
||||||
@@ -156,6 +157,9 @@ public partial class DockingLayout : Control
|
|||||||
var newPanel = new DockPanel { Orientation = orientation };
|
var newPanel = new DockPanel { Orientation = orientation };
|
||||||
RootModule = newPanel;
|
RootModule = newPanel;
|
||||||
|
|
||||||
|
targetGroup.DockLength = 1.0;
|
||||||
|
newGroup.DockLength = 1.0;
|
||||||
|
|
||||||
if (target == DockTarget.Left || target == DockTarget.Top)
|
if (target == DockTarget.Left || target == DockTarget.Top)
|
||||||
{
|
{
|
||||||
newPanel.AddChild(newGroup);
|
newPanel.AddChild(newGroup);
|
||||||
@@ -178,7 +182,11 @@ public partial class DockingLayout : Control
|
|||||||
|
|
||||||
if (parentPanel.Orientation == orientation)
|
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)
|
if (target == DockTarget.Left || target == DockTarget.Top)
|
||||||
{
|
{
|
||||||
parentPanel.InsertChild(index, newGroup);
|
parentPanel.InsertChild(index, newGroup);
|
||||||
@@ -190,8 +198,13 @@ public partial class DockingLayout : Control
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Different orientation, need a new sub-panel
|
// Splitting in opposite orientation. New panel takes the full length.
|
||||||
var newPanel = new DockPanel { Orientation = orientation };
|
var newPanel = new DockPanel { Orientation = orientation };
|
||||||
|
newPanel.DockLength = targetGroup.DockLength;
|
||||||
|
|
||||||
|
targetGroup.DockLength = 1.0;
|
||||||
|
newGroup.DockLength = 1.0;
|
||||||
|
|
||||||
parentPanel.ReplaceChild(targetGroup, newPanel);
|
parentPanel.ReplaceChild(targetGroup, newPanel);
|
||||||
|
|
||||||
if (target == DockTarget.Left || target == DockTarget.Top)
|
if (target == DockTarget.Left || target == DockTarget.Top)
|
||||||
|
|||||||
Reference in New Issue
Block a user