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,156 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Lattice.UI.DragDrop.WinUI.Controls;
/// <summary>
/// Оверлей для отображения визуальных элементов перетаскивания.
/// </summary>
public class DragDropOverlay : Canvas
{
private readonly List<UIElement> _dragVisuals = new();
private readonly List<DropPreviewAdorner> _dropAdorners = new();
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DragDropOverlay"/>.
/// </summary>
public DragDropOverlay()
{
IsHitTestVisible = false;
Background = null;
// Устанавливаем высокий Z-Index, чтобы быть поверх всего
Canvas.SetZIndex(this, 10000);
}
/// <summary>
/// Показывает визуальное представление перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
/// <param name="initialX">Начальная позиция X.</param>
/// <param name="initialY">Начальная позиция Y.</param>
public void ShowDragVisual(UIElement dragVisual, double initialX, double initialY)
{
if (!Children.Contains(dragVisual))
{
Children.Add(dragVisual);
_dragVisuals.Add(dragVisual);
}
SetLeft(dragVisual, initialX);
SetTop(dragVisual, initialY);
dragVisual.Visibility = Visibility.Visible;
}
/// <summary>
/// Обновляет позицию визуального представления перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
/// <param name="x">Новая позиция X.</param>
/// <param name="y">Новая позиция Y.</param>
public void UpdateDragVisualPosition(UIElement dragVisual, double x, double y)
{
if (Children.Contains(dragVisual))
{
SetLeft(dragVisual, x);
SetTop(dragVisual, y);
}
}
/// <summary>
/// Скрывает визуальное представление перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
public void HideDragVisual(UIElement dragVisual)
{
dragVisual.Visibility = Visibility.Collapsed;
if (Children.Contains(dragVisual))
{
Children.Remove(dragVisual);
_dragVisuals.Remove(dragVisual);
}
}
/// <summary>
/// Показывает предварительный просмотр области сброса.
/// </summary>
/// <param name="bounds">Границы области.</param>
/// <returns>Созданный элемент предварительного просмотра.</returns>
public DropPreviewAdorner ShowDropPreview(Core.Geometry.Rect bounds)
{
var adorner = new DropPreviewAdorner
{
PreviewColor = Windows.UI.Color.FromArgb(100, 0, 120, 215),
PreviewThickness = 2.0
};
Children.Add(adorner);
_dropAdorners.Add(adorner);
adorner.Show(bounds);
return adorner;
}
/// <summary>
/// Обновляет предварительный просмотр области сброса.
/// </summary>
/// <param name="adorner">Элемент предварительного просмотра.</param>
/// <param name="bounds">Новые границы.</param>
public void UpdateDropPreview(DropPreviewAdorner adorner, Core.Geometry.Rect bounds)
{
adorner.UpdatePosition(bounds);
}
/// <summary>
/// Скрывает все предварительные просмотры областей сброса.
/// </summary>
public void HideAllDropPreviews()
{
foreach (var adorner in _dropAdorners.ToList())
{
adorner.Hide();
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(200)
};
timer.Tick += (s, e) =>
{
timer.Stop();
if (Children.Contains(adorner))
{
Children.Remove(adorner);
}
_dropAdorners.Remove(adorner);
};
timer.Start();
}
}
/// <summary>
/// Скрывает все визуальные элементы.
/// </summary>
public void ClearAllVisuals()
{
foreach (var visual in _dragVisuals.ToList())
{
HideDragVisual(visual);
}
HideAllDropPreviews();
}
/// <summary>
/// Получает текущий элемент перетаскивания.
/// </summary>
/// <returns>Элемент перетаскивания или null.</returns>
public UIElement? GetCurrentDragVisual()
{
return _dragVisuals.FirstOrDefault();
}
}