DragAndDrop core

This commit is contained in:
FrigaT
2026-01-18 16:33:35 +03:00
parent 9ea82af329
commit 79bdd8bc62
229 changed files with 21214 additions and 2494 deletions

View File

@@ -0,0 +1,78 @@
using Lattice.Layout.UI.Docking;
using Lattice.Layout.UI.WinUI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using System;
using System.Linq;
using Windows.Foundation;
namespace Lattice.Layout.UI.WinUI.Docking;
/// <summary>
/// Выполняет hit-test для определения зоны докинга в WinUI.
/// </summary>
public static class DockZoneHitTester
{
/// <summary>
/// Выполняет hit-test по экранной точке и возвращает цель докинга.
/// </summary>
/// <param name="host">WinUI-хост раскладки.</param>
/// <param name="screenPoint">Точка в координатах окна.</param>
public static DockTarget? HitTest(WinUILayoutHost host, Point screenPoint)
{
if (host is null)
throw new ArgumentNullException(nameof(host));
// Предполагаем, что LayoutLayer — основной слой, в котором живёт визуальное дерево.
var layoutLayer = host.LayoutLayer;
if (layoutLayer is null)
return null;
// Переводим координаты в систему координат layoutLayer.
var elements = VisualTreeHelper.FindElementsInHostCoordinates(screenPoint, host.LayoutLayer);
var firstElement = elements.FirstOrDefault();
if (firstElement is null)
return null;
// Ищем ближайший IWinUIVisual.
var visual = FindVisual(firstElement);
if (visual is null)
return null;
if (visual is not ILayoutVisual layoutVisual)
return null;
// Вычисляем зону докинга для найденного контрола.
var control = visual.Control;
var bounds = control.TransformToVisual(layoutLayer)
.TransformBounds(new Rect(0, 0, control.ActualWidth, control.ActualHeight));
var localX = screenPoint.X - bounds.X;
var localY = screenPoint.Y - bounds.Y;
var zone = DockingUtils.GetZone(localX, localY, bounds.Width, bounds.Height);
return new DockTarget(layoutVisual, zone);
}
private static IWinUIVisual? FindVisual(UIElement element)
{
DependencyObject? current = element;
while (current is not null)
{
if (current is FrameworkElement fe && fe.DataContext is IWinUIVisual ctxVisual)
return ctxVisual;
if (current is IWinUIVisual winuiVisual)
return winuiVisual;
current = VisualTreeHelper.GetParent(current);
}
return null;
}
}