Добавлен проект UI
This commit is contained in:
99
Lattice.UI/Controls/LatticeSplitter.cs
Normal file
99
Lattice.UI/Controls/LatticeSplitter.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user