feat(docking): add DockPanel
This commit is contained in:
90
src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs
Normal file
90
src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
|
||||
namespace Ghost.Editor.View.Controls.Docking;
|
||||
|
||||
[TemplatePart(Name = "PART_Grid", Type = typeof(Grid))]
|
||||
public class DockPanel : DockContainer
|
||||
{
|
||||
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
|
||||
nameof(Orientation), typeof(Orientation), typeof(DockPanel), new PropertyMetadata(Orientation.Horizontal, OnOrientationChanged));
|
||||
|
||||
public Orientation Orientation
|
||||
{
|
||||
get => (Orientation)GetValue(OrientationProperty);
|
||||
set => SetValue(OrientationProperty, value);
|
||||
}
|
||||
|
||||
private Grid? _grid;
|
||||
|
||||
public DockPanel()
|
||||
{
|
||||
DefaultStyleKey = typeof(DockPanel);
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_grid = GetTemplateChild("PART_Grid") as Grid;
|
||||
UpdateLayoutStructure();
|
||||
}
|
||||
|
||||
protected override void OnChildrenUpdated()
|
||||
{
|
||||
UpdateLayoutStructure();
|
||||
}
|
||||
|
||||
private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
((DockPanel)d).UpdateLayoutStructure();
|
||||
}
|
||||
|
||||
private void UpdateLayoutStructure()
|
||||
{
|
||||
if (_grid == null) return;
|
||||
|
||||
_grid.Children.Clear();
|
||||
_grid.RowDefinitions.Clear();
|
||||
_grid.ColumnDefinitions.Clear();
|
||||
|
||||
if (Children.Count == 0) return;
|
||||
|
||||
if (Orientation == Orientation.Horizontal)
|
||||
{
|
||||
for (int i = 0; i < Children.Count; i++)
|
||||
{
|
||||
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
var child = Children[i];
|
||||
Grid.SetColumn(child, i * 2);
|
||||
_grid.Children.Add(child);
|
||||
|
||||
if (i < Children.Count - 1)
|
||||
{
|
||||
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Columns, Width = 4 };
|
||||
Grid.SetColumn(splitter, i * 2 + 1);
|
||||
_grid.Children.Add(splitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < Children.Count; i++)
|
||||
{
|
||||
_grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
|
||||
var child = Children[i];
|
||||
Grid.SetRow(child, i * 2);
|
||||
_grid.Children.Add(child);
|
||||
|
||||
if (i < Children.Count - 1)
|
||||
{
|
||||
_grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
|
||||
var splitter = new GridSplitter { ResizeDirection = GridSplitter.GridResizeDirection.Rows, Height = 4 };
|
||||
Grid.SetRow(splitter, i * 2 + 1);
|
||||
_grid.Children.Add(splitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.xaml
Normal file
15
src/Editor/Ghost.Editor/View/Controls/Docking/DockPanel.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Ghost.Editor.View.Controls.Docking">
|
||||
|
||||
<Style TargetType="local:DockPanel">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:DockPanel">
|
||||
<Grid x:Name="PART_Grid" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
Reference in New Issue
Block a user