Files
Lattice/Lattice.UI/Controls/LatticeSplitter.cs

100 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
/// <summary>
/// Разделитель между панелями Lattice, позволяющий динамически изменять их размеры.
/// </summary>
[TemplatePart(Name = "PART_Thumb", Type = typeof(Thumb))]
public class LatticeSplitter : Control
{
private Thumb? _thumb;
/// <summary>
/// Узел макета, находящийся слева или сверху от разделителя.
/// </summary>
public LayoutNode? LeftNode { get; set; }
/// <summary>
/// Узел макета, находящийся справа или снизу от разделителя.
/// </summary>
public LayoutNode? RightNode { get; set; }
/// <summary>
/// Ориентация разделителя, определяющая направление изменения размера.
/// </summary>
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();
}
/// <summary>
/// Находит хост и вызывает обновление визуального дерева.
/// </summary>
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);
}
}
}