using Lattice.Core.DragDrop.Factories; using Lattice.Core.DragDrop.Services; using Lattice.UI.DragDrop.WinUI.Behaviors; using Lattice.UI.DragDrop.WinUI.Controls; using Lattice.UI.DragDrop.WinUI.Services; using Microsoft.UI.Xaml; using System; namespace Lattice.UI.DragDrop.WinUI.Factories; /// /// Фабрика для создания компонентов системы перетаскивания WinUI. /// Предоставляет методы для быстрой настройки drag-and-drop в приложениях WinUI. /// /// /// Эта фабрика упрощает интеграцию системы перетаскивания в WinUI приложения, /// предоставляя готовые методы для наиболее распространенных сценариев использования. /// public static class WinUIDragDropFactory { #region Основные компоненты /// /// Создает и инициализирует менеджер перетаскивания для WinUI окна. /// /// /// Окно WinUI, для которого создается менеджер перетаскивания. /// /// /// Инициализированный экземпляр . /// /// /// Выбрасывается, когда равен null. /// /// /// Этот метод создает менеджер перетаскивания и настраивает его для работы с указанным окном. /// Менеджер автоматически создает оверлей для визуальных элементов и подписывается на события. /// /// /// /// public partial class MainWindow : Window /// { /// private WinUIDragDropManager _dragDropManager; /// /// public MainWindow() /// { /// InitializeComponent(); /// _dragDropManager = WinUIDragDropFactory.CreateManager(this); /// } /// } /// /// public static WinUIDragDropManager CreateManager(Window window) { if (window == null) throw new ArgumentNullException(nameof(window)); var manager = WinUIDragDropManager.Instance; manager.Initialize(window); return manager; } /// /// Создает и инициализирует менеджер перетаскивания с пользовательскими настройками. /// /// /// Окно WinUI, для которого создается менеджер перетаскивания. /// /// /// Делегат для настройки менеджера перед инициализацией. /// /// /// Инициализированный экземпляр . /// /// /// Этот метод позволяет настроить параметры менеджера (например, смещение визуального элемента) /// перед его инициализацией. /// public static WinUIDragDropManager CreateManager(Window window, Action configure) { if (window == null) throw new ArgumentNullException(nameof(window)); var manager = WinUIDragDropManager.Instance; configure?.Invoke(manager); manager.Initialize(window); return manager; } /// /// Создает хост для визуальных элементов перетаскивания. /// /// /// Окно, к которому будет привязан хост. /// /// /// Экземпляр , готовый к использованию. /// /// /// Хост управляет отображением визуальных элементов (drag-визуализация, drop-превью) /// на оверлейном слое поверх основного содержимого окна. /// public static WinUIDragDropHost CreateHost(Window window) { if (window == null) throw new ArgumentNullException(nameof(window)); var host = new WinUIDragDropHost(); host.Initialize(window); return host; } #endregion #region Поведения (Behaviors) /// /// Создает поведение источника перетаскивания для элемента WinUI. /// /// /// Сервис перетаскивания, который будет управлять операциями. /// /// /// Хост для отображения визуальных элементов. /// /// /// Экземпляр , готовый к прикреплению к элементу. /// /// /// Выбрасывается, если любой из параметров равен null. /// /// /// Созданное поведение необходимо прикрепить к элементу с помощью метода . /// public static WinUIDragSourceBehavior CreateDragSourceBehavior( IDragDropService dragDropService, WinUIDragDropHost host) { if (dragDropService == null) throw new ArgumentNullException(nameof(dragDropService)); if (host == null) throw new ArgumentNullException(nameof(host)); return new WinUIDragSourceBehavior(dragDropService, host); } /// /// Создает поведение цели сброса для элемента WinUI. /// /// /// Сервис перетаскивания, который будет управлять операциями. /// /// /// Хост для отображения визуальных элементов. /// /// /// Экземпляр , готовый к прикреплению к элементу. /// /// /// Выбрасывается, если любой из параметров равен null. /// /// /// Созданное поведение необходимо прикрепить к элементу с помощью метода . /// public static WinUIDropTargetBehavior CreateDropTargetBehavior( IDragDropService dragDropService, WinUIDragDropHost host) { if (dragDropService == null) throw new ArgumentNullException(nameof(dragDropService)); if (host == null) throw new ArgumentNullException(nameof(host)); return new WinUIDropTargetBehavior(dragDropService, host); } #endregion #region Визуальные элементы /// /// Создает визуальный элемент для отображения во время перетаскивания. /// /// /// Данные, которые будут отображены в визуальном элементе. /// /// /// Прозрачность элемента (от 0.0 до 1.0). /// /// /// Экземпляр , настроенный для отображения указанных данных. /// /// /// Созданный элемент можно использовать с методом /// для отображения во время операции перетаскивания. /// public static DragAdorner CreateDragAdorner(object dragData, double opacity = 0.8) { return new DragAdorner { DragData = dragData, Opacity = opacity }; } /// /// Создает элемент предварительного просмотра для области сброса. /// /// /// Цвет подсветки области. Если не указан, используется цвет из ресурсов темы. /// /// /// Толщина границы подсветки. /// /// /// Экземпляр , готовый к отображению. /// /// /// Этот элемент используется для визуального указания области, на которую можно сбросить данные. /// public static DropPreviewAdorner CreateDropPreviewAdorner( Windows.UI.Color? color = null, double thickness = 2.0) { var adorner = new DropPreviewAdorner { PreviewThickness = thickness }; if (color.HasValue) { adorner.PreviewColor = color.Value; } return adorner; } #endregion #region Готовые конфигурации для типовых сценариев /// /// Создает полную систему перетаскивания для WinUI приложения. /// /// /// Главное окно приложения. /// /// /// Кортеж, содержащий менеджер перетаскивания и сервис перетаскивания. /// /// /// Этот метод создает все необходимые компоненты для работы перетаскивания в приложении. /// Возвращаемый сервис можно использовать для создания дополнительных источников и целей. /// public static (WinUIDragDropManager Manager, IDragDropService Service) CreateCompleteSystem(Window window) { var service = DragDropFactory.CreateDragDropService(); var manager = CreateManager(window); return (manager, service); } /// /// Создает систему перетаскивания, оптимизированную для списков и коллекций. /// /// /// Главное окно приложения. /// /// /// Менеджер перетаскивания, настроенный для переупорядочивания элементов в списках. /// /// /// Эта конфигурация устанавливает оптимальные параметры для перетаскивания элементов /// внутри списков (например, для изменения порядка элементов в ListView или ItemsControl). /// public static WinUIDragDropManager CreateListReorderSystem(Window window) { var manager = CreateManager(window, m => { m.DragVisualOffset = new Core.Geometry.Point(-15, -15); }); return manager; } /// /// Создает систему перетаскивания для файлов и документов. /// /// /// Главное окно приложения. /// /// /// Менеджер перетаскивания, настроенный для работы с файлами. /// /// /// Эта конфигурация устанавливает увеличенный порог перетаскивания и специальные /// визуальные эффекты, характерные для операций с файлами. /// public static WinUIDragDropManager CreateFileDragDropSystem(Window window) { var manager = CreateManager(window, m => { m.DragVisualOffset = new Core.Geometry.Point(-25, -25); }); return manager; } /// /// Создает систему перетаскивания для графических редакторов и инструментов дизайна. /// /// /// Главное окно приложения. /// /// /// Менеджер перетаскивания, настроенный для точного позиционирования. /// /// /// Эта конфигурация уменьшает порог начала перетаскивания для более точного контроля /// и устанавливает минималистичную визуализацию. /// public static WinUIDragDropManager CreateDesignToolSystem(Window window) { var manager = CreateManager(window, m => { m.DragVisualOffset = new Core.Geometry.Point(-10, -10); }); return manager; } #endregion #region Вспомогательные методы /// /// Настраивает элемент как источник перетаскивания с использованием указанного менеджера. /// /// /// Менеджер перетаскивания, который будет управлять операцией. /// /// /// Элемент WinUI, который должен стать источником перетаскивания. /// /// /// Данные для перетаскивания. Если не указаны, будут использованы DataContext или Tag элемента. /// /// /// Этот метод является оберткой вокруг , /// предоставляя более удобный API. /// public static void SetupAsDragSource(WinUIDragDropManager manager, Microsoft.UI.Xaml.FrameworkElement element, object dragData = null) { if (manager == null) throw new ArgumentNullException(nameof(manager)); if (element == null) throw new ArgumentNullException(nameof(element)); manager.MakeDragSource(element, dragData); } /// /// Настраивает элемент как цель сброса с использованием указанного менеджера. /// /// /// Менеджер перетаскивания, который будет управлять операцией. /// /// /// Элемент WinUI, который должен стать целью сброса. /// /// /// Этот метод является оберткой вокруг , /// предоставляя более удобный API. /// public static void SetupAsDropTarget(WinUIDragDropManager manager, Microsoft.UI.Xaml.FrameworkElement element) { if (manager == null) throw new ArgumentNullException(nameof(manager)); if (element == null) throw new ArgumentNullException(nameof(element)); manager.MakeDropTarget(element); } /// /// Настраивает контейнер для поддержки переупорядочивания дочерних элементов. /// /// /// Менеджер перетаскивания. /// /// /// Контейнер (например, StackPanel или Grid), дочерние элементы которого можно переупорядочивать. /// /// /// Функция для получения данных перетаскивания из дочернего элемента. /// Если не указана, используются DataContext дочерних элементов. /// /// /// Этот метод автоматически настраивает все дочерние элементы контейнера как источники перетаскивания, /// а сам контейнер — как цель сброса, создавая функциональность переупорядочивания. /// public static void SetupReorderContainer( WinUIDragDropManager manager, Microsoft.UI.Xaml.Controls.Panel container, Func childSelector = null) { if (manager == null) throw new ArgumentNullException(nameof(manager)); if (container == null) throw new ArgumentNullException(nameof(container)); // Настраиваем контейнер как цель сброса manager.MakeDropTarget(container); // Настраиваем все дочерние элементы как источники перетаскивания foreach (var child in container.Children) { if (child is Microsoft.UI.Xaml.FrameworkElement element) { var data = childSelector?.Invoke(element) ?? element.DataContext ?? element.Tag; manager.MakeDragSource(element, data); } } } #endregion #region Методы для работы с XAML /// /// Настраивает прикрепленные свойства для элемента источника перетаскивания. /// /// /// Элемент, который должен стать источником перетаскивания. /// /// /// Данные для перетаскивания. /// /// /// Этот метод устанавливает attached properties, которые активируют поведение перетаскивания /// при использовании в XAML. Эквивалентно установке свойств IsDragSource и DragData в XAML. /// public static void SetupDragSourceInXaml(Microsoft.UI.Xaml.FrameworkElement element, object dragData) { if (element == null) throw new ArgumentNullException(nameof(element)); // Устанавливаем attached properties element.SetValue(Behaviors.WinUIDragSourceBehavior.IsEnabledProperty, true); if (dragData != null) { element.SetValue(Behaviors.WinUIDragSourceBehavior.DragDataProperty, dragData); } } /// /// Настраивает прикрепленные свойства для элемента цели сброса. /// /// /// Элемент, который должен стать целью сброса. /// /// /// Этот метод устанавливает attached properties, которые активируют поведение цели сброса /// при использовании в XAML. Эквивалентно установке свойства IsDropTarget в XAML. /// public static void SetupDropTargetInXaml(Microsoft.UI.Xaml.FrameworkElement element) { if (element == null) throw new ArgumentNullException(nameof(element)); element.SetValue(Behaviors.WinUIDropTargetBehavior.IsEnabledProperty, true); } #endregion }