Files
Lattice/Lattice.UI.Docking/LatticeUIFramework.cs
2026-01-18 16:33:35 +03:00

439 lines
20 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.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();
}
}