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.Manager?.Dock(null!, null!, DockDirection.Center); // Фиктивный вызов для обновления // Или если есть прямой доступ: host.Manager.InvokeLayoutUpdated(); break; } parent = VisualTreeHelper.GetParent(parent); } } }