DragAndDrop core
This commit is contained in:
156
Lattice.UI.DragDrop.WinUI/Controls/DragDropOverlay.cs
Normal file
156
Lattice.UI.DragDrop.WinUI/Controls/DragDropOverlay.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user