53 lines
2.4 KiB
C#
53 lines
2.4 KiB
C#
using Lattice.Core.Models.Enums;
|
|
using Microsoft.UI.Xaml;
|
|
using Windows.Foundation;
|
|
|
|
namespace Lattice.UI.Services;
|
|
|
|
/// <summary>
|
|
/// Сервис для анализа визуального дерева и расчета зон взаимодействия.
|
|
/// </summary>
|
|
public static class VisualTreeService
|
|
{
|
|
/// <summary>
|
|
/// Определяет зону докинга на основе позиции курсора относительно элемента.
|
|
/// </summary>
|
|
/// <param name="element">Визуальный элемент (панель), над которым находится курсор.</param>
|
|
/// <param name="relativePoint">Координаты курсора относительно левого верхнего угла элемента.</param>
|
|
/// <returns>Направление докинга (DockDirection).</returns>
|
|
public static DockDirection GetHitZone(FrameworkElement element, Point relativePoint)
|
|
{
|
|
double w = element.ActualWidth;
|
|
double h = element.ActualHeight;
|
|
|
|
// 1. Зона центра (обычно это 40% центральной области)
|
|
// Если курсор в центре, вкладка просто добавится в текущий TabView.
|
|
double centerX = w * 0.3;
|
|
double centerY = h * 0.3;
|
|
Rect centerRect = new Rect(centerX, centerY, w * 0.4, h * 0.4);
|
|
|
|
if (centerRect.Contains(relativePoint))
|
|
{
|
|
return DockDirection.Center;
|
|
}
|
|
|
|
// 2. Расчет по диагоналям для боковых зон
|
|
// Представьте конверт: линии из углов в центр. Это самый точный способ
|
|
// определения стороны в стиле Visual Studio.
|
|
|
|
// Нормализуем координаты в диапазон от 0 до 1
|
|
double nx = relativePoint.X / w;
|
|
double ny = relativePoint.Y / h;
|
|
|
|
// Уравнения диагоналей: y = x и y = 1 - x
|
|
bool isAbovePrimary = ny < nx;
|
|
bool isAboveSecondary = ny < (1 - nx);
|
|
|
|
if (isAbovePrimary && isAboveSecondary) return DockDirection.Top;
|
|
if (isAbovePrimary && !isAboveSecondary) return DockDirection.Right;
|
|
if (!isAbovePrimary && isAboveSecondary) return DockDirection.Left;
|
|
|
|
return DockDirection.Bottom;
|
|
}
|
|
}
|