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;
///
/// Предоставляет статический API для инициализации и управления UI-фреймворком Lattice.
/// Является точкой входа для интеграции док-системы в приложение и централизованным
/// хранилищем для основных сервисов и компонентов.
///
///
/// Этот класс реализует шаблон Singleton для доступа к глобальным сервисам.
/// Все компоненты инициализируются через строитель ,
/// что обеспечивает гибкую конфигурацию и соблюдение принципа инверсии зависимостей.
///
public static class LatticeUIFramework
{
private static bool _isInitialized;
private static LatticeBuilder? _currentBuilder;
///
/// Получает значение, указывающее, инициализирован ли фреймворк.
///
///
/// true, если фреймворк был инициализирован вызовом ;
/// в противном случае — false.
///
public static bool IsInitialized => _isInitialized;
///
/// Получает текущий строитель конфигурации фреймворка.
///
///
/// Экземпляр , используемый для настройки фреймворка.
/// Возвращает null, если фреймворк не инициализирован.
///
///
/// Выбрасывается при попытке доступа к свойству до инициализации фреймворка.
///
public static LatticeBuilder CurrentBuilder
{
get
{
if (!_isInitialized)
throw new InvalidOperationException("Lattice framework is not initialized. Call Initialize() first.");
return _currentBuilder!;
}
}
///
/// Получает менеджер макета из текущего строителя.
///
///
/// Экземпляр , управляющий структурой док-системы.
///
public static LayoutManager? LayoutManager => _currentBuilder?.LayoutManager;
///
/// Получает реестр контента из текущего строителя.
///
///
/// Экземпляр , содержащий зарегистрированные типы контента.
///
public static ContentRegistry? ContentRegistry => _currentBuilder?.ContentRegistry;
///
/// Получает фабрику контролов из текущего строителя.
///
///
/// Экземпляр для создания UI-контролов.
///
public static IDockControlFactory? ControlFactory => _currentBuilder?.ControlFactory;
///
/// Получает сервис перетаскивания из текущего строителя.
///
///
/// Экземпляр для управления операциями drag-and-drop.
///
public static IDockDragDropService? DragDropService => _currentBuilder?.DragDropService;
///
/// Получает менеджер контекстных меню из текущего строителя.
///
///
/// Экземпляр для управления контекстными меню.
///
public static IDockContextManager? ContextManager => _currentBuilder?.ContextManager;
///
/// Получает UI-сервис из текущего строителя.
///
///
/// Экземпляр для выполнения платформенно-зависимых операций.
///
public static IDockUIService? UIService => _currentBuilder?.UIService;
///
/// Инициализирует фреймворк Lattice с указанными параметрами.
///
///
/// Настройки инициализации. Если null, используются параметры по умолчанию.
///
///
/// Экземпляр для дальнейшей конфигурации фреймворка.
///
///
/// Выбрасывается, если фреймворк уже инициализирован.
///
///
/// Этот метод должен вызываться один раз при запуске приложения, перед любыми
/// попытками использования компонентов док-системы.
///
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;
}
///
/// Сбрасывает состояние фреймворка к неинициализированному.
///
///
/// Используется в основном для целей тестирования. В рабочем приложении
/// фреймворк должен инициализироваться один раз на протяжении жизненного цикла.
///
public static void Reset()
{
_isInitialized = false;
_currentBuilder = null;
}
}
///
/// Представляет настройки инициализации фреймворка Lattice.
/// Позволяет кастомизировать поведение системы при запуске.
///
public class LatticeOptions
{
///
/// Получает или задает значение, указывающее, следует ли автоматически
/// регистрировать стандартные команды (закрыть, сделать плавающим и т.д.).
///
///
/// true, чтобы зарегистрировать стандартные команды; в противном случае — false.
/// Значение по умолчанию: true.
///
public bool RegisterDefaultCommands { get; set; } = true;
///
/// Получает или задает значение, указывающее, следует ли автоматически
/// создавать сервисы при их первом запросе.
///
///
/// true, чтобы автоматически создавать сервисы; в противном случае — false.
/// Значение по умолчанию: true.
///
public bool AutoCreateServices { get; set; } = true;
///
/// Получает или задает идентификатор приложения, используемый при
/// сериализации макета для различения конфигураций разных приложений.
///
///
/// Строковый идентификатор приложения или null, если идентификатор не задан.
///
public string? ApplicationId { get; set; }
///
/// Получает или задает значение, указывающее, следует ли включить
/// расширенное логирование операций системы.
///
///
/// true, чтобы включить подробное логирование; в противном случае — false.
/// Значение по умолчанию: false.
///
public bool EnableVerboseLogging { get; set; } = false;
}
///
/// Предоставляет fluent-интерфейс для конфигурации фреймворка Lattice.
/// Инкапсулирует процесс настройки всех компонентов системы и обеспечивает
/// согласованное состояние после инициализации.
///
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;
///
/// Получает менеджер макета, связанный с этим строителем.
///
///
/// Экземпляр для управления структурой док-системы.
///
public LayoutManager LayoutManager => _layoutManager;
///
/// Получает реестр контента, связанный с этим строителем.
///
///
/// Экземпляр для регистрации типов контента.
///
public ContentRegistry ContentRegistry => _contentRegistry;
///
/// Получает фабрику контролов, связанную с этим строителем.
///
///
/// Экземпляр или null, если фабрика не задана.
///
public IDockControlFactory? ControlFactory => _controlFactory;
///
/// Получает сервис перетаскивания, связанный с этим строителем.
///
///
/// Экземпляр или null, если сервис не задан.
///
public IDockDragDropService? DragDropService => _dragDropService;
///
/// Получает менеджер контекстных меню, связанный с этим строителем.
///
///
/// Экземпляр или null, если менеджер не задан.
///
public IDockContextManager? ContextManager => _contextManager;
///
/// Получает UI-сервис, связанный с этим строителем.
///
///
/// Экземпляр или null, если сервис не задан.
///
public IDockUIService? UIService => _uiService;
///
/// Инициализирует новый экземпляр класса .
///
/// Менеджер макета.
/// Реестр контента.
/// Опции инициализации.
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));
}
///
/// Регистрирует фабрику контролов для создания UI-элементов.
///
///
/// Фабрика контролов, реализующая .
///
///
/// Текущий экземпляр строителя для цепочки вызовов.
///
///
/// Выбрасывается, если равен null.
///
public LatticeBuilder WithControlFactory(IDockControlFactory factory)
{
_controlFactory = factory ?? throw new ArgumentNullException(nameof(factory));
return this;
}
///
/// Регистрирует сервис перетаскивания для управления операциями drag-and-drop.
///
///
/// Сервис перетаскивания, реализующий .
///
///
/// Текущий экземпляр строителя для цепочки вызовов.
///
///
/// Выбрасывается, если равен null.
///
public LatticeBuilder WithDragDropService(IDockDragDropService service)
{
_dragDropService = service ?? throw new ArgumentNullException(nameof(service));
return this;
}
///
/// Регистрирует менеджер контекстных меню для управления контекстными действиями.
///
///
/// Менеджер контекстных меню, реализующий .
///
///
/// Текущий экземпляр строителя для цепочки вызовов.
///
///
/// Выбрасывается, если равен null.
///
public LatticeBuilder WithContextManager(IDockContextManager manager)
{
_contextManager = manager ?? throw new ArgumentNullException(nameof(manager));
return this;
}
///
/// Регистрирует UI-сервис для выполнения платформенно-зависимых операций.
///
///
/// UI-сервис, реализующий .
///
///
/// Текущий экземпляр строителя для цепочки вызовов.
///
///
/// Выбрасывается, если равен null.
///
public LatticeBuilder WithUIService(IDockUIService service)
{
_uiService = service ?? throw new ArgumentNullException(nameof(service));
return this;
}
///
/// Регистрирует тип контента в реестре для последующего создания экземпляров.
///
///
/// Тип контента, реализующий .
///
/// Уникальный идентификатор типа контента.
/// Фабричный метод для создания экземпляров контента.
/// Метаданные типа контента (опционально).
///
/// Текущий экземпляр строителя для цепочки вызовов.
///
///
/// Выбрасывается, если или равны null.
///
public LatticeBuilder RegisterContentType(string contentTypeId, Func 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;
}
///
/// Завершает конфигурацию и создает готовый к использованию док-хост.
///
///
/// Экземпляр , настроенный в соответствии с текущей конфигурацией.
///
///
/// Выбрасывается, если не задана фабрика контролов или метод уже был вызван.
///
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.");
}
///
/// Создает сервис перетаскивания по умолчанию.
///
private IDockDragDropService CreateDefaultDragDropService()
{
// Реализация зависит от платформы
// В реальном коде здесь должна быть проверка платформы
return new WinUI.Services.WinUIDragDropService();
}
///
/// Создает менеджер контекстных меню по умолчанию.
///
private IDockContextManager CreateDefaultContextManager()
{
// Реализация зависит от платформы
return new WinUI.Services.WinUIDockContextManager();
}
///
/// Создает UI-сервис по умолчанию.
///
private IDockUIService CreateDefaultUIService()
{
// Реализация зависит от платформы
return new WinUI.Services.WinUIDockUIService();
}
}