using Lattice.Core.Models;
using Lattice.Core.Models.Enums;
using Lattice.UI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Lattice.UI.Primitives;
///
/// Кастомный контейнер, преобразующий иерархию узлов Lattice в визуальные элементы WinUI 3.
///
public class LayoutPanel : Grid
{
private readonly LatticeDockHost _host;
///
/// Создает новый экземпляр панели компоновки.
///
/// Корневой хост, управляющий макетом.
public LayoutPanel(LatticeDockHost host)
{
_host = host;
}
///
/// Выполняет рекурсивную отрисовку дерева узлов.
///
public void Build(LayoutNode node)
{
this.Children.Clear();
this.ColumnDefinitions.Clear();
this.RowDefinitions.Clear();
if (node is SplitContainerNode splitContainer)
{
RenderSplit(splitContainer);
}
else if (node is ContentNode contentNode)
{
RenderContent(contentNode);
}
}
private void RenderSplit(SplitContainerNode container)
{
for (int i = 0; i < container.Children.Count; i++)
{
var child = container.Children[i];
var childPresenter = new LayoutPanel(_host);
if (container.Orientation == SplitOrientation.Horizontal)
{
this.ColumnDefinitions.Add(new ColumnDefinition
{
Width = child.IsWidthStar ? new GridLength(child.WidthValue, GridUnitType.Star) : new GridLength(child.WidthValue)
});
Grid.SetColumn(childPresenter, this.ColumnDefinitions.Count - 1);
}
else
{
this.RowDefinitions.Add(new RowDefinition
{
Height = child.IsHeightStar ? new GridLength(child.HeightValue, GridUnitType.Star) : new GridLength(child.HeightValue)
});
Grid.SetRow(childPresenter, this.RowDefinitions.Count - 1);
}
this.Children.Add(childPresenter);
childPresenter.Build(child);
// Добавляем сплиттер между элементами (кроме последнего)
if (i < container.Children.Count - 1)
{
AddSplitter(container, i);
}
}
}
private void AddSplitter(SplitContainerNode container, int index)
{
var splitter = new LatticeSplitter
{
LeftNode = container.Children[index],
RightNode = container.Children[index + 1],
Orientation = container.Orientation,
};
double thickness = (double)Application.Current.Resources["LatticeSplitterThickness"];
if (container.Orientation == SplitOrientation.Horizontal)
{
// Сплиттер занимает очень узкую колонку между основными
this.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(thickness) });
Grid.SetColumn(splitter, this.ColumnDefinitions.Count - 1);
}
else
{
this.RowDefinitions.Add(new RowDefinition { Height = new GridLength(thickness) });
Grid.SetRow(splitter, this.RowDefinitions.Count - 1);
}
this.Children.Add(splitter);
}
private void RenderContent(ContentNode node)
{
var pane = new LatticePane
{
Title = node.Name,
Content = node.Component,
DataContext = node,
};
pane.CloseClick += (s, e) =>
{
_host.Manager?.Remove(node);
};
this.Children.Add(pane);
}
}