using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Lattice.UI.DragDrop.WinUI.Controls;
///
/// Оверлей для отображения визуальных элементов перетаскивания.
///
public class DragDropOverlay : Canvas
{
private readonly List _dragVisuals = new();
private readonly List _dropAdorners = new();
///
/// Инициализирует новый экземпляр класса .
///
public DragDropOverlay()
{
IsHitTestVisible = false;
Background = null;
// Устанавливаем высокий Z-Index, чтобы быть поверх всего
Canvas.SetZIndex(this, 10000);
}
///
/// Показывает визуальное представление перетаскивания.
///
/// Визуальное представление.
/// Начальная позиция X.
/// Начальная позиция Y.
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;
}
///
/// Обновляет позицию визуального представления перетаскивания.
///
/// Визуальное представление.
/// Новая позиция X.
/// Новая позиция Y.
public void UpdateDragVisualPosition(UIElement dragVisual, double x, double y)
{
if (Children.Contains(dragVisual))
{
SetLeft(dragVisual, x);
SetTop(dragVisual, y);
}
}
///
/// Скрывает визуальное представление перетаскивания.
///
/// Визуальное представление.
public void HideDragVisual(UIElement dragVisual)
{
dragVisual.Visibility = Visibility.Collapsed;
if (Children.Contains(dragVisual))
{
Children.Remove(dragVisual);
_dragVisuals.Remove(dragVisual);
}
}
///
/// Показывает предварительный просмотр области сброса.
///
/// Границы области.
/// Созданный элемент предварительного просмотра.
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;
}
///
/// Обновляет предварительный просмотр области сброса.
///
/// Элемент предварительного просмотра.
/// Новые границы.
public void UpdateDropPreview(DropPreviewAdorner adorner, Core.Geometry.Rect bounds)
{
adorner.UpdatePosition(bounds);
}
///
/// Скрывает все предварительные просмотры областей сброса.
///
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();
}
}
///
/// Скрывает все визуальные элементы.
///
public void ClearAllVisuals()
{
foreach (var visual in _dragVisuals.ToList())
{
HideDragVisual(visual);
}
HideAllDropPreviews();
}
///
/// Получает текущий элемент перетаскивания.
///
/// Элемент перетаскивания или null.
public UIElement? GetCurrentDragVisual()
{
return _dragVisuals.FirstOrDefault();
}
}