using Lattice.Core.Models;
using Lattice.Core.Models.Enums;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Media;
namespace Lattice.UI.Controls;
///
/// Разделитель между панелями Lattice, позволяющий динамически изменять их размеры.
///
[TemplatePart(Name = "PART_Thumb", Type = typeof(Thumb))]
public class LatticeSplitter : Control
{
private Thumb? _thumb;
///
/// Узел макета, находящийся слева или сверху от разделителя.
///
public LayoutNode? LeftNode { get; set; }
///
/// Узел макета, находящийся справа или снизу от разделителя.
///
public LayoutNode? RightNode { get; set; }
///
/// Ориентация разделителя, определяющая направление изменения размера.
///
public SplitOrientation Orientation { get; set; }
public LatticeSplitter()
{
this.DefaultStyleKey = typeof(LatticeSplitter);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (_thumb != null) _thumb.DragDelta -= OnThumbDragDelta;
_thumb = GetTemplateChild("PART_Thumb") as Thumb;
if (_thumb != null) _thumb.DragDelta += OnThumbDragDelta;
}
private void OnThumbDragDelta(object sender, DragDeltaEventArgs e)
{
if (LeftNode == null || RightNode == null) return;
// В WinUI 3 (2026) для изменения пропорций Star-размеров
// мы корректируем WidthValue/HeightValue и уведомляем менеджер.
double sensitivity = 0.01; // Коэффициент чувствительности для плавности
if (Orientation == SplitOrientation.Horizontal)
{
double delta = e.HorizontalChange * sensitivity;
LeftNode.WidthValue += delta;
RightNode.WidthValue -= delta;
// Ограничения минимального размера (10% от доступного пространства)
if (LeftNode.WidthValue < 0.1) { RightNode.WidthValue += (LeftNode.WidthValue - 0.1); LeftNode.WidthValue = 0.1; }
if (RightNode.WidthValue < 0.1) { LeftNode.WidthValue += (RightNode.WidthValue - 0.1); RightNode.WidthValue = 0.1; }
}
else // Vertical
{
double delta = e.VerticalChange * sensitivity;
LeftNode.HeightValue += delta;
RightNode.HeightValue -= delta;
if (LeftNode.HeightValue < 0.1) { RightNode.HeightValue += (LeftNode.HeightValue - 0.1); LeftNode.HeightValue = 0.1; }
if (RightNode.HeightValue < 0.1) { LeftNode.HeightValue += (RightNode.HeightValue - 0.1); RightNode.HeightValue = 0.1; }
}
// Уведомляем систему об изменении макета через родительский хост
NotifyLayoutUpdated();
}
///
/// Находит хост и вызывает обновление визуального дерева.
///
private void NotifyLayoutUpdated()
{
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (parent != null)
{
if (parent is LatticeDockHost host)
{
// Вызываем метод перерисовки (в Core это может быть событие LayoutUpdated)
// В нашем случае это заставит LayoutPanel пересчитать Column/Row Definitions
host.Service?.Dock(null!, null!, DockDirection.Center); // Фиктивный вызов для обновления
// Или если есть прямой доступ: host.Service.InvokeLayoutUpdated();
break;
}
parent = VisualTreeHelper.GetParent(parent);
}
}
}