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,439 @@
using Lattice.Core.Docking.Abstractions;
using Lattice.Core.Docking.Engine;
using Lattice.Core.Docking.Services;
using Lattice.UI.Docking.Abstractions;
using Lattice.UI.Docking.Factories;
namespace Lattice.UI.Docking;
/// <summary>
/// Предоставляет статический API для инициализации и управления UI-фреймворком Lattice.
/// Является точкой входа для интеграции док-системы в приложение и централизованным
/// хранилищем для основных сервисов и компонентов.
/// </summary>
/// <remarks>
/// Этот класс реализует шаблон Singleton для доступа к глобальным сервисам.
/// Все компоненты инициализируются через строитель <see cref="LatticeBuilder"/>,
/// что обеспечивает гибкую конфигурацию и соблюдение принципа инверсии зависимостей.
/// </remarks>
public static class LatticeUIFramework
{
private static bool _isInitialized;
private static LatticeBuilder? _currentBuilder;
/// <summary>
/// Получает значение, указывающее, инициализирован ли фреймворк.
/// </summary>
/// <value>
/// true, если фреймворк был инициализирован вызовом <see cref="Initialize"/>;
/// в противном случае — false.
/// </value>
public static bool IsInitialized => _isInitialized;
/// <summary>
/// Получает текущий строитель конфигурации фреймворка.
/// </summary>
/// <value>
/// Экземпляр <see cref="LatticeBuilder"/>, используемый для настройки фреймворка.
/// Возвращает null, если фреймворк не инициализирован.
/// </value>
/// <exception cref="InvalidOperationException">
/// Выбрасывается при попытке доступа к свойству до инициализации фреймворка.
/// </exception>
public static LatticeBuilder CurrentBuilder
{
get
{
if (!_isInitialized)
throw new InvalidOperationException("Lattice framework is not initialized. Call Initialize() first.");
return _currentBuilder!;
}
}
/// <summary>
/// Получает менеджер макета из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="LayoutManager"/>, управляющий структурой док-системы.
/// </value>
public static LayoutManager? LayoutManager => _currentBuilder?.LayoutManager;
/// <summary>
/// Получает реестр контента из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="ContentRegistry"/>, содержащий зарегистрированные типы контента.
/// </value>
public static ContentRegistry? ContentRegistry => _currentBuilder?.ContentRegistry;
/// <summary>
/// Получает фабрику контролов из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControlFactory"/> для создания UI-контролов.
/// </value>
public static IDockControlFactory? ControlFactory => _currentBuilder?.ControlFactory;
/// <summary>
/// Получает сервис перетаскивания из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockDragDropService"/> для управления операциями drag-and-drop.
/// </value>
public static IDockDragDropService? DragDropService => _currentBuilder?.DragDropService;
/// <summary>
/// Получает менеджер контекстных меню из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockContextManager"/> для управления контекстными меню.
/// </value>
public static IDockContextManager? ContextManager => _currentBuilder?.ContextManager;
/// <summary>
/// Получает UI-сервис из текущего строителя.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockUIService"/> для выполнения платформенно-зависимых операций.
/// </value>
public static IDockUIService? UIService => _currentBuilder?.UIService;
/// <summary>
/// Инициализирует фреймворк Lattice с указанными параметрами.
/// </summary>
/// <param name="options">
/// Настройки инициализации. Если null, используются параметры по умолчанию.
/// </param>
/// <returns>
/// Экземпляр <see cref="LatticeBuilder"/> для дальнейшей конфигурации фреймворка.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Выбрасывается, если фреймворк уже инициализирован.
/// </exception>
/// <remarks>
/// Этот метод должен вызываться один раз при запуске приложения, перед любыми
/// попытками использования компонентов док-системы.
/// </remarks>
public static LatticeBuilder Initialize(LatticeOptions? options = null)
{
if (_isInitialized)
throw new InvalidOperationException("Lattice framework is already initialized");
options ??= new LatticeOptions();
// Создаем основные компоненты Core-слоя
var layoutManager = new LayoutManager();
var contentRegistry = new ContentRegistry();
// Создаем строитель с основными компонентами
_currentBuilder = new LatticeBuilder(layoutManager, contentRegistry, options);
_isInitialized = true;
return _currentBuilder;
}
/// <summary>
/// Сбрасывает состояние фреймворка к неинициализированному.
/// </summary>
/// <remarks>
/// Используется в основном для целей тестирования. В рабочем приложении
/// фреймворк должен инициализироваться один раз на протяжении жизненного цикла.
/// </remarks>
public static void Reset()
{
_isInitialized = false;
_currentBuilder = null;
}
}
/// <summary>
/// Представляет настройки инициализации фреймворка Lattice.
/// Позволяет кастомизировать поведение системы при запуске.
/// </summary>
public class LatticeOptions
{
/// <summary>
/// Получает или задает значение, указывающее, следует ли автоматически
/// регистрировать стандартные команды (закрыть, сделать плавающим и т.д.).
/// </summary>
/// <value>
/// true, чтобы зарегистрировать стандартные команды; в противном случае — false.
/// Значение по умолчанию: true.
/// </value>
public bool RegisterDefaultCommands { get; set; } = true;
/// <summary>
/// Получает или задает значение, указывающее, следует ли автоматически
/// создавать сервисы при их первом запросе.
/// </summary>
/// <value>
/// true, чтобы автоматически создавать сервисы; в противном случае — false.
/// Значение по умолчанию: true.
/// </value>
public bool AutoCreateServices { get; set; } = true;
/// <summary>
/// Получает или задает идентификатор приложения, используемый при
/// сериализации макета для различения конфигураций разных приложений.
/// </summary>
/// <value>
/// Строковый идентификатор приложения или null, если идентификатор не задан.
/// </value>
public string? ApplicationId { get; set; }
/// <summary>
/// Получает или задает значение, указывающее, следует ли включить
/// расширенное логирование операций системы.
/// </summary>
/// <value>
/// true, чтобы включить подробное логирование; в противном случае — false.
/// Значение по умолчанию: false.
/// </value>
public bool EnableVerboseLogging { get; set; } = false;
}
/// <summary>
/// Предоставляет fluent-интерфейс для конфигурации фреймворка Lattice.
/// Инкапсулирует процесс настройки всех компонентов системы и обеспечивает
/// согласованное состояние после инициализации.
/// </summary>
public sealed class LatticeBuilder
{
private readonly LayoutManager _layoutManager;
private readonly ContentRegistry _contentRegistry;
private readonly LatticeOptions _options;
private IDockControlFactory? _controlFactory;
private IDockDragDropService? _dragDropService;
private IDockContextManager? _contextManager;
private IDockUIService? _uiService;
private bool _isBuilt;
/// <summary>
/// Получает менеджер макета, связанный с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="LayoutManager"/> для управления структурой док-системы.
/// </value>
public LayoutManager LayoutManager => _layoutManager;
/// <summary>
/// Получает реестр контента, связанный с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="ContentRegistry"/> для регистрации типов контента.
/// </value>
public ContentRegistry ContentRegistry => _contentRegistry;
/// <summary>
/// Получает фабрику контролов, связанную с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControlFactory"/> или null, если фабрика не задана.
/// </value>
public IDockControlFactory? ControlFactory => _controlFactory;
/// <summary>
/// Получает сервис перетаскивания, связанный с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockDragDropService"/> или null, если сервис не задан.
/// </value>
public IDockDragDropService? DragDropService => _dragDropService;
/// <summary>
/// Получает менеджер контекстных меню, связанный с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockContextManager"/> или null, если менеджер не задан.
/// </value>
public IDockContextManager? ContextManager => _contextManager;
/// <summary>
/// Получает UI-сервис, связанный с этим строителем.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockUIService"/> или null, если сервис не задан.
/// </value>
public IDockUIService? UIService => _uiService;
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="LatticeBuilder"/>.
/// </summary>
/// <param name="layoutManager">Менеджер макета.</param>
/// <param name="contentRegistry">Реестр контента.</param>
/// <param name="options">Опции инициализации.</param>
internal LatticeBuilder(LayoutManager layoutManager, ContentRegistry contentRegistry, LatticeOptions options)
{
_layoutManager = layoutManager ?? throw new ArgumentNullException(nameof(layoutManager));
_contentRegistry = contentRegistry ?? throw new ArgumentNullException(nameof(contentRegistry));
_options = options ?? throw new ArgumentNullException(nameof(options));
}
/// <summary>
/// Регистрирует фабрику контролов для создания UI-элементов.
/// </summary>
/// <param name="factory">
/// Фабрика контролов, реализующая <see cref="IDockControlFactory"/>.
/// </param>
/// <returns>
/// Текущий экземпляр строителя для цепочки вызовов.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="factory"/> равен null.
/// </exception>
public LatticeBuilder WithControlFactory(IDockControlFactory factory)
{
_controlFactory = factory ?? throw new ArgumentNullException(nameof(factory));
return this;
}
/// <summary>
/// Регистрирует сервис перетаскивания для управления операциями drag-and-drop.
/// </summary>
/// <param name="service">
/// Сервис перетаскивания, реализующий <see cref="IDockDragDropService"/>.
/// </param>
/// <returns>
/// Текущий экземпляр строителя для цепочки вызовов.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="service"/> равен null.
/// </exception>
public LatticeBuilder WithDragDropService(IDockDragDropService service)
{
_dragDropService = service ?? throw new ArgumentNullException(nameof(service));
return this;
}
/// <summary>
/// Регистрирует менеджер контекстных меню для управления контекстными действиями.
/// </summary>
/// <param name="manager">
/// Менеджер контекстных меню, реализующий <see cref="IDockContextManager"/>.
/// </param>
/// <returns>
/// Текущий экземпляр строителя для цепочки вызовов.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="manager"/> равен null.
/// </exception>
public LatticeBuilder WithContextManager(IDockContextManager manager)
{
_contextManager = manager ?? throw new ArgumentNullException(nameof(manager));
return this;
}
/// <summary>
/// Регистрирует UI-сервис для выполнения платформенно-зависимых операций.
/// </summary>
/// <param name="service">
/// UI-сервис, реализующий <see cref="IDockUIService"/>.
/// </param>
/// <returns>
/// Текущий экземпляр строителя для цепочки вызовов.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="service"/> равен null.
/// </exception>
public LatticeBuilder WithUIService(IDockUIService service)
{
_uiService = service ?? throw new ArgumentNullException(nameof(service));
return this;
}
/// <summary>
/// Регистрирует тип контента в реестре для последующего создания экземпляров.
/// </summary>
/// <typeparam name="T">
/// Тип контента, реализующий <see cref="IDockContent"/>.
/// </typeparam>
/// <param name="contentTypeId">Уникальный идентификатор типа контента.</param>
/// <param name="factory">Фабричный метод для создания экземпляров контента.</param>
/// <param name="metadata">Метаданные типа контента (опционально).</param>
/// <returns>
/// Текущий экземпляр строителя для цепочки вызовов.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="contentTypeId"/> или <paramref name="factory"/> равны null.
/// </exception>
public LatticeBuilder RegisterContentType<T>(string contentTypeId, Func<T> factory, ContentMetadata? metadata = null)
where T : Core.Docking.Abstractions.IDockContent
{
if (string.IsNullOrWhiteSpace(contentTypeId))
throw new ArgumentNullException(nameof(contentTypeId));
_contentRegistry.Register(contentTypeId, factory, metadata);
return this;
}
/// <summary>
/// Завершает конфигурацию и создает готовый к использованию док-хост.
/// </summary>
/// <returns>
/// Экземпляр <see cref="IDockHost"/>, настроенный в соответствии с текущей конфигурацией.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Выбрасывается, если не задана фабрика контролов или метод уже был вызван.
/// </exception>
public IDockHost Build()
{
if (_isBuilt)
throw new InvalidOperationException("Builder has already been built.");
if (_controlFactory == null)
throw new InvalidOperationException("Control factory must be specified. Call WithControlFactory() first.");
// Автоматически создаем отсутствующие сервисы, если включена опция
if (_options.AutoCreateServices)
{
_dragDropService ??= CreateDefaultDragDropService();
_contextManager ??= CreateDefaultContextManager();
_uiService ??= CreateDefaultUIService();
}
// Создаем хост через фабрику
// (предполагается, что фабрика имеет метод CreateDockHost)
if (_controlFactory is WinUI.Factories.WinUIDockControlFactory winUIFactory)
{
var host = winUIFactory.CreateDockHost();
// Настраиваем хост
host.LayoutManager = _layoutManager;
host.DragDropService = _dragDropService;
host.ContextManager = _contextManager;
_isBuilt = true;
return host;
}
throw new NotSupportedException($"Control factory of type {_controlFactory.GetType().Name} is not supported.");
}
/// <summary>
/// Создает сервис перетаскивания по умолчанию.
/// </summary>
private IDockDragDropService CreateDefaultDragDropService()
{
// Реализация зависит от платформы
// В реальном коде здесь должна быть проверка платформы
return new WinUI.Services.WinUIDragDropService();
}
/// <summary>
/// Создает менеджер контекстных меню по умолчанию.
/// </summary>
private IDockContextManager CreateDefaultContextManager()
{
// Реализация зависит от платформы
return new WinUI.Services.WinUIDockContextManager();
}
/// <summary>
/// Создает UI-сервис по умолчанию.
/// </summary>
private IDockUIService CreateDefaultUIService()
{
// Реализация зависит от платформы
return new WinUI.Services.WinUIDockUIService();
}
}