Files
Lattice/Lattice.Core.DragDrop/Models/DropInfo.cs
2026-01-18 16:33:35 +03:00

269 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Lattice.Core.DragDrop.Enums;
using Lattice.Core.Geometry;
namespace Lattice.Core.DragDrop.Models;
/// <summary>
/// Содержит информацию о потенциальном или фактическом сбросе в операции перетаскивания.
/// Этот класс используется для передачи данных между системой перетаскивания
/// и целью сброса (<see cref="Abstractions.IDropTarget"/>).
/// </summary>
/// <remarks>
/// <para>
/// <see cref="DropInfo"/> предоставляет цель сброса всей необходимой информацией
/// для принятия решения о возможности сброса и выполнения соответствующей операции.
/// Ключевые аспекты включают:
/// </para>
/// <list type="bullet">
/// <item>Предлагаемые для сброса данные</item>
/// <item>Текущую позицию курсора</item>
/// <item>Разрешенные эффекты от источника</item>
/// <item>Предлагаемые эффекты для сброса</item>
/// <item>Ссылку на цель сброса</item>
/// <item>Флаг обработки операции</item>
/// </list>
/// <para>
/// Этот класс является изменяемым, позволяя цели сброса обновлять предлагаемые
/// эффекты и помечать операцию как обработанную.
/// </para>
/// </remarks>
public class DropInfo
{
private DragDropEffects _effects = DragDropEffects.None;
public DropPosition DropPosition { get; set; } = DropPosition.Inside;
public bool ShowVisualFeedback { get; set; } = true;
public object? VisualFeedbackData { get; set; }
/// <summary>
/// Получает данные, которые предлагаются для сброса.
/// </summary>
/// <value>
/// Данные, переданные от источника перетаскивания, или null, если данные
/// не доступны или операция была отменена.
/// </value>
/// <remarks>
/// Эти данные соответствуют свойству <see cref="DragInfo.Data"/> из
/// исходной информации о перетаскивании.
/// </remarks>
public object? Data { get; }
/// <summary>
/// Получает текущую позицию курсора в координатах экрана.
/// </summary>
/// <value>
/// Точка в экранных координатах, представляющая текущее положение курсора
/// мыши во время операции перетаскивания.
/// </value>
/// <remarks>
/// Эта позиция используется для определения точного места сброса и может
/// влиять на предлагаемые эффекты (например, различные операции для
/// разных областей цели сброса).
/// </remarks>
public Point Position { get; }
/// <summary>
/// Получает разрешенные эффекты от источника перетаскивания.
/// </summary>
/// <value>
/// Комбинация флагов <see cref="Enums.DragDropEffects"/>, определяющая,
/// какие операции разрешил источник.
/// </value>
/// <remarks>
/// Цель сброса должна уважать эти ограничения и не предлагать эффекты,
/// которые не разрешены источником.
/// </remarks>
public Enums.DragDropEffects AllowedEffects { get; }
/// <summary>
/// Получает или задает предлагаемые эффекты для операции сброса.
/// </summary>
/// <value>
/// Комбинация флагов <see cref="Enums.DragDropEffects"/>, предлагаемая
/// целью сброса. По умолчанию равно <see cref="Enums.DragDropEffects.None"/>.
/// </value>
/// <remarks>
/// <para>
/// Цель сброса должна установить это свойство в методе <see cref="Abstractions.IDropTarget.DragOver"/>
/// на основе анализа предоставленных данных и текущего контекста.
/// </para>
/// <para>
/// Если цель не устанавливает это свойство, система перетаскивания
/// будет использовать эффекты по умолчанию.
/// </para>
/// </remarks>
public Enums.DragDropEffects SuggestedEffects
{
get => _effects;
set => _effects = value;
}
/// <summary>
/// Получает цель сброса, которая обрабатывает эту информацию.
/// </summary>
/// <value>
/// Объект, реализующий <see cref="Abstractions.IDropTarget"/>, или null,
/// если цель не определена.
/// </value>
/// <remarks>
/// Эта ссылка позволяет системе идентифицировать, какая цель обрабатывает
/// информацию о сбросе, и используется для отслеживания изменений цели
/// во время операции перетаскивания.
/// </remarks>
public object? Target { get; }
/// <summary>
/// Получает или задает дополнительные параметры, специфичные для конкретной
/// реализации перетаскивания.
/// </summary>
/// <value>
/// Словарь, содержащий пары ключ-значение с дополнительными параметрами.
/// </value>
/// <remarks>
/// Может использоваться для передачи контекстной информации между
/// различными компонентами системы перетаскивания или для хранения
/// временных данных во время обработки операции.
/// </remarks>
public Dictionary<string, object> Parameters { get; set; }
/// <summary>
/// Получает значение, указывающее, был ли сброс уже обработан.
/// </summary>
/// <value>
/// true, если операция сброса была помечена как обработанная;
/// в противном случае — false.
/// </value>
/// <remarks>
/// <para>
/// Это свойство используется для предотвращения множественной обработки
/// одной и той же операции сброса. После вызова метода <see cref="MarkAsHandled"/>,
/// свойство становится true.
/// </para>
/// <para>
/// Система перетаскивания может проверять это свойство, чтобы определить,
/// нужно ли выполнять дополнительную обработку по умолчанию.
/// </para>
/// </remarks>
public bool Handled { get; private set; }
/// <summary>
/// Получает дополнительные параметры, специфичные для конкретной
/// реализации перетаскивания.
/// </summary>
public T? GetParameter<T>(string key, T? defaultValue = default)
{
if (Parameters.TryGetValue(key, out var value) && value is T typedValue)
{
return typedValue;
}
return defaultValue;
}
/// <summary>
/// Получает дополнительные параметры, специфичные для конкретной
/// реализации перетаскивания.
/// </summary>
public bool TryGetParameter<T>(string key, out T? value)
{
value = default;
if (Parameters.TryGetValue(key, out var objValue) && objValue is T typedValue)
{
value = typedValue;
return true;
}
return false;
}
/// <summary>
/// Задает дополнительные параметры, специфичные для конкретной
/// реализации перетаскивания.
/// </summary>
public void SetParameter<T>(string key, T value)
{
Parameters[key] = value!;
}
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DropInfo"/>.
/// </summary>
/// <param name="data">
/// Данные, которые предлагаются для сброса. Может быть null.
/// </param>
/// <param name="position">
/// Текущая позиция курсора в координатах экрана.
/// </param>
/// <param name="allowedEffects">
/// Разрешенные эффекты от источника перетаскивания.
/// </param>
/// <param name="target">
/// Цель сброса, которая обрабатывает эту информацию. Может быть null.
/// </param>
/// <remarks>
/// Конструктор создает экземпляр <see cref="DropInfo"/> с указанными
/// параметрами, инициализирует коллекцию параметров пустым словарем
/// и устанавливает флаг <see cref="Handled"/> в false.
/// </remarks>
public DropInfo(object? data, Point position, Enums.DragDropEffects allowedEffects, object? target = null)
{
Data = data;
Position = position;
AllowedEffects = allowedEffects;
Target = target;
Parameters = new Dictionary<string, object>();
Handled = false;
}
/// <summary>
/// Помечает сброс как обработанный.
/// </summary>
/// <remarks>
/// <para>
/// Этот метод должен вызываться целью сброса в методе <see cref="Abstractions.IDropTarget.Drop"/>,
/// если она успешно обработала операцию сброса.
/// </para>
/// <para>
/// После вызова этого метода свойство <see cref="Handled"/> становится true,
/// что сигнализирует системе перетаскивания о том, что дополнительная
/// обработка не требуется.
/// </para>
/// </remarks>
public void MarkAsHandled()
{
Handled = true;
}
/// <summary>
/// Создает новый экземпляр <see cref="DropInfo"/> с теми же данными,
/// но новой позицией.
/// </summary>
/// <param name="newPosition">
/// Новая позиция для информации о сбросе.
/// </param>
/// <returns>
/// Новый экземпляр <see cref="DropInfo"/> с обновленной позицией.
/// </returns>
/// <remarks>
/// Этот метод используется для обновления информации о сбросе при
/// перемещении курсора, сохраняя исходные данные и параметры.
/// </remarks>
public DropInfo WithPosition(Point newPosition)
{
return new DropInfo(Data, newPosition, AllowedEffects, Target)
{
Parameters = new Dictionary<string, object>(Parameters),
SuggestedEffects = _effects,
DropPosition = DropPosition,
ShowVisualFeedback = ShowVisualFeedback,
VisualFeedbackData = VisualFeedbackData
};
}
/// <summary>
/// Проверка установки эффекта перетаскивания в разрешенные эффекты.
/// </summary>
public bool CanAcceptEffect(Enums.DragDropEffects effect)
{
return (AllowedEffects & effect) != Enums.DragDropEffects.None;
}
}