Доработан Docking

This commit is contained in:
2026-01-27 05:17:35 +03:00
parent 33abd94f6e
commit 584df249f6
99 changed files with 2270 additions and 12792 deletions

View File

@@ -77,21 +77,23 @@ public interface IAutoHidePanelControl : IDockControl
/// <summary>
/// Задает фиксированное состояние панели.
/// </summary>
/// <param name="pinned">true, чтобы зафиксировать панель; false, чтобы разрешить автоскрытие.</param>
/// <param name="pinned">
/// true, чтобы зафиксировать панель; false, чтобы разрешить автоскрытие.
/// </param>
void SetPinned(bool pinned);
/// <summary>
/// Событие, возникающее при изменении видимости панели.
/// Происходит при изменении видимости панели.
/// </summary>
event EventHandler VisibilityChanged;
/// <summary>
/// Событие, возникающее при наведении курсора на панель.
/// Происходит при наведении курсора на панель.
/// </summary>
event EventHandler MouseEntered;
/// <summary>
/// Событие, возникающее при уходе курсора с панели.
/// Происходит при уходе курсора с панели.
/// </summary>
event EventHandler MouseLeft;
}

View File

@@ -1,40 +1,58 @@
namespace Lattice.UI.Docking.Abstractions;
/// <summary>
/// Определяет контракт для команды док-системы.
/// Определяет контракт для команды в UI-слое док-системы.
/// Команды представляют действия, которые могут быть выполнены пользователем.
/// </summary>
public interface IDockCommand
{
/// <summary>
/// Получает идентификатор команды.
/// Получает уникальный идентификатор команды.
/// </summary>
/// <value>
/// Строковый идентификатор команды.
/// </value>
string Id { get; }
/// <summary>
/// Получает отображаемое имя команды.
/// </summary>
/// <value>
/// Имя команды, отображаемое в пользовательском интерфейсе.
/// </value>
string Name { get; }
/// <summary>
/// Получает описание команды.
/// </summary>
/// <value>
/// Текстовое описание функциональности команды.
/// </value>
string Description { get; }
/// <summary>
/// Получает значок команды.
/// Получает идентификатор ресурса для иконки команды.
/// </summary>
/// <value>
/// Имя ресурса иконки или путь к файлу иконки.
/// </value>
string Icon { get; }
/// <summary>
/// Получает комбинацию клавиш для команды.
/// Получает комбинацию клавиш для быстрого вызова команды.
/// </summary>
/// <value>
/// Строковое представление горячей клавиши (например, "Ctrl+S").
/// </value>
string Shortcut { get; }
/// <summary>
/// Определяет, можно ли выполнить команду.
/// Определяет, можно ли выполнить команду в текущем контексте.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <returns>true, если команду можно выполнить; в противном случае — false.</returns>
/// <returns>
/// true, если команду можно выполнить; в противном случае false.
/// </returns>
bool CanExecute(object? parameter);
/// <summary>
@@ -44,7 +62,7 @@ public interface IDockCommand
void Execute(object? parameter);
/// <summary>
/// Событие, возникающее при изменении возможности выполнения команды.
/// Происходит при изменении возможности выполнения команды.
/// </summary>
event EventHandler CanExecuteChanged;
}
}

View File

@@ -11,6 +11,9 @@ public interface IDockContextManager
/// <param name="element">Элемент, для которого показывается меню.</param>
/// <param name="x">Координата X для отображения меню.</param>
/// <param name="y">Координата Y для отображения меню.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="element"/> равен null.
/// </exception>
void ShowContextMenu(IDockControl element, double x, double y);
/// <summary>
@@ -23,6 +26,10 @@ public interface IDockContextManager
/// </summary>
/// <param name="commandId">Идентификатор команды.</param>
/// <param name="command">Команда для регистрации.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="commandId"/> или <paramref name="command"/>
/// равны null.
/// </exception>
void RegisterCommand(string commandId, IDockCommand command);
/// <summary>
@@ -32,12 +39,12 @@ public interface IDockContextManager
void UnregisterCommand(string commandId);
/// <summary>
/// Событие, возникающее при показе контекстного меню.
/// Происходит при показе контекстного меню.
/// </summary>
event EventHandler<ContextMenuShownEventArgs> ContextMenuShown;
/// <summary>
/// Событие, возникающее при скрытии контекстного меню.
/// Происходит при скрытии контекстного меню.
/// </summary>
event EventHandler ContextMenuHidden;
}
}

View File

@@ -7,11 +7,12 @@ namespace Lattice.UI.Docking.Abstractions;
/// <summary>
/// Определяет базовый контракт для всех UI-контролов, участвующих в системе докинга.
/// Этот интерфейс предоставляет общие свойства и методы, необходимые для интеграции
/// с менеджером макета и системой перетаскивания.
/// с менеджером макета и UI-сервисами.
/// </summary>
/// <remarks>
/// Реализации этого интерфейса должны отображать элементы док-системы (DockGroup, DockLeaf)
/// и обеспечивать взаимодействие пользователя с ними через жесты мыши, клавиатуру и сенсорный ввод.
/// Интерфейс обеспечивает двухстороннюю связь между визуальными элементами и их моделями данных.
/// </remarks>
public interface IDockControl : INotifyPropertyChanged
{
@@ -22,6 +23,10 @@ public interface IDockControl : INotifyPropertyChanged
/// Экземпляр класса, реализующего <see cref="IDockElement"/>, который представляет
/// состояние и структуру отображаемого элемента док-системы.
/// </value>
/// <remarks>
/// Изменение модели должно приводить к обновлению визуального представления.
/// Свойство используется для привязки данных между UI-слоем и слоем бизнес-логики.
/// </remarks>
IDockElement? Model { get; set; }
/// <summary>
@@ -30,62 +35,57 @@ public interface IDockControl : INotifyPropertyChanged
/// <value>
/// Экземпляр <see cref="LayoutManager"/>, управляющий структурой док-системы.
/// </value>
/// <remarks>
/// Менеджер макета предоставляет доступ к дереву компоновки, плавающим окнам
/// и автоскрываемым панелям, а также методы для манипуляции структурой.
/// </remarks>
LayoutManager? LayoutManager { get; set; }
/// <summary>
/// Получает или задает сервис перетаскивания, используемый этим контролом.
/// </summary>
/// <value>
/// Реализация <see cref="IDragDropService"/> для обработки операций перетаскивания.
/// </value>
IDragDropService? DragDropService { get; set; }
/// <summary>
/// Получает или задает контекстный менеджер для этого контрола.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockContextManager"/>, управляющий контекстными меню и действиями.
/// </value>
/// <remarks>
/// Контекстный менеджер используется для отображения контекстно-зависимых команд
/// при щелчке правой кнопкой мыши или других пользовательских действиях.
/// </remarks>
IDockContextManager? ContextManager { get; set; }
/// <summary>
/// Получает или задает признак того, что контрол выбран.
/// </summary>
/// <value>
/// true, если контрол выбран; в противном случае false.
/// true, если контрол выбран; в противном случае false.
/// </value>
/// <remarks>
/// Выделение контрола обычно визуально выделяет его границы или фон,
/// чтобы указать пользователю на активный элемент. В каждый момент времени
/// может быть выбран только один контрол в пределах контейнера.
/// </remarks>
bool IsSelected { get; set; }
/// <summary>
/// Получает или задает признак того, что контрол активен.
/// </summary>
/// <value>
/// true, если контрол активен; в противном случае false.
/// true, если контрол активен; в противном случае false.
/// </value>
/// <remarks>
/// Активный контрол получает фокус ввода и может обрабатывать команды клавиатуры.
/// Обычно соответствует активной вкладке в контейнере или активному окну.
/// </remarks>
bool IsActive { get; set; }
/// <summary>
/// Получает или задает признак того, что контрол можно перетаскивать.
/// </summary>
/// <value>
/// true, если контрол можно перетаскивать; в противном случае — false.
/// </value>
bool CanDrag { get; set; }
/// <summary>
/// Получает или задает признак того, что контрол может принимать сброс.
/// </summary>
/// <value>
/// true, если контрол может принимать сброс; в противном случае — false.
/// </value>
bool CanDrop { get; set; }
/// <summary>
/// Обновляет внешний вид контрола в соответствии с текущим состоянием модели.
/// </summary>
/// <remarks>
/// Этот метод должен вызываться при изменении свойств модели или при необходимости
/// принудительного обновления UI (например, после изменения темы или масштаба).
/// Реализация должна обеспечить синхронизацию всех визуальных аспектов контрола
/// с текущими значениями свойств модели.
/// </remarks>
void Refresh();
@@ -93,11 +93,23 @@ public interface IDockControl : INotifyPropertyChanged
/// Применяет указанную тему к контролу.
/// </summary>
/// <param name="theme">Тема для применения.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="theme"/> равен null.
/// </exception>
/// <remarks>
/// Метод должен обновить все стили, цвета и параметры отображения контрола
/// в соответствии с переданной темой. Изменения должны применяться немедленно.
/// </remarks>
void ApplyTheme(IDockTheme theme);
/// <summary>
/// Вызывается при изменении состояния модели для обновления UI.
/// </summary>
/// <param name="propertyName">Имя изменившегося свойства модели.</param>
/// <remarks>
/// Этот метод предназначен для уведомления UI о конкретных изменениях в модели,
/// что позволяет выполнять точечные обновления вместо полного перестроения.
/// Должен вызываться из обработчиков событий изменения свойств модели.
/// </remarks>
void OnModelPropertyChanged(string propertyName);
}

View File

@@ -1,256 +0,0 @@
namespace Lattice.UI.Docking.Abstractions;
/// <summary>
/// Предоставляет сервис для операций перетаскивания в UI-слое док-системы.
/// Абстрагирует платформенно-зависимую логику перетаскивания и обеспечивает
/// единый интерфейс для управления операциями drag-and-drop.
/// </summary>
/// <remarks>
/// Этот интерфейс служит мостом между базовым менеджером перетаскивания из Core
/// и UI-контролами, добавляя визуальную обратную связь и обработку событий,
/// специфичных для пользовательского интерфейса.
/// </remarks>
public interface IDockDragDropService
{
/// <summary>
/// Начинает операцию перетаскивания для указанного элемента.
/// </summary>
/// <param name="element">UI-контрол, который инициирует перетаскивание.</param>
/// <param name="dragInfo">
/// Информация о перетаскивании, содержащая данные и параметры операции.
/// </param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="element"/> или <paramref name="dragInfo"/> равны null.
/// </exception>
/// <remarks>
/// Этот метод должен создавать визуальное представление перетаскиваемого элемента
/// и инициировать отслеживание перемещения мыши.
/// </remarks>
void StartDrag(IDockControl element, Core.DragDrop.Models.DragInfo dragInfo);
/// <summary>
/// Обновляет позицию текущей операции перетаскивания.
/// </summary>
/// <param name="x">Новая координата X курсора в экранных координатах.</param>
/// <param name="y">Новая координата Y курсора в экранных координатах.</param>
/// <remarks>
/// Вызывается при каждом перемещении мыши во время операции перетаскивания.
/// Должен обновлять позицию визуального представления и проверять возможные цели сброса.
/// </remarks>
void UpdateDrag(double x, double y);
/// <summary>
/// Завершает текущую операцию перетаскивания в указанной позиции.
/// </summary>
/// <param name="x">Координата X завершения перетаскивания.</param>
/// <param name="y">Координата Y завершения перетаскивания.</param>
/// <remarks>
/// Выполняет сброс данных на текущую цель (если она есть) и очищает ресурсы,
/// выделенные для операции перетаскивания.
/// </remarks>
void EndDrag(double x, double y);
/// <summary>
/// Отменяет текущую операцию перетаскивания.
/// </summary>
/// <remarks>
/// Вызывается при нажатии клавиши Escape или других действиях, приводящих к отмене.
/// Должен восстанавливать исходное состояние элементов и очищать ресурсы.
/// </remarks>
void CancelDrag();
/// <summary>
/// Показывает визуальную подсказку о возможной позиции сброса.
/// </summary>
/// <param name="element">UI-контрол, для которого показывается подсказка.</param>
/// <param name="position">Предполагаемая позиция сброса.</param>
/// <remarks>
/// Используется для визуальной обратной связи, чтобы пользователь видел,
/// куда будет помещен элемент при отпускании кнопки мыши.
/// </remarks>
void ShowDropHint(IDockControl element, Models.DropPosition position);
/// <summary>
/// Скрывает текущую визуальную подсказку о сбросе.
/// </summary>
/// <remarks>
/// Вызывается, когда курсор покидает допустимую область сброса
/// или операция перетаскивания завершается.
/// </remarks>
void HideDropHint();
/// <summary>
/// Событие, возникающее при начале операции перетаскивания.
/// </summary>
event EventHandler<DragStartedEventArgs> DragStarted;
/// <summary>
/// Событие, возникающее при обновлении позиции перетаскивания.
/// </summary>
event EventHandler<DragUpdatedEventArgs> DragUpdated;
/// <summary>
/// Событие, возникающее при завершении операции перетаскивания.
/// </summary>
event EventHandler<DragCompletedEventArgs> DragCompleted;
/// <summary>
/// Событие, возникающее при отмене операции перетаскивания.
/// </summary>
event EventHandler DragCancelled;
}
/// <summary>
/// Предоставляет данные для события начала перетаскивания.
/// </summary>
public class DragStartedEventArgs : EventArgs
{
/// <summary>
/// Получает UI-контрол, который инициировал перетаскивание.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControl"/>, представляющий источник перетаскивания.
/// Может быть null, если перетаскивание инициировано не из UI-элемента.
/// </value>
public IDockControl? Source { get; }
/// <summary>
/// Получает информацию о перетаскивании.
/// </summary>
/// <value>
/// Экземпляр <see cref="Core.DragDrop.Models.DragInfo"/> с данными перетаскивания.
/// </value>
public Core.DragDrop.Models.DragInfo DragInfo { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DragStartedEventArgs"/>.
/// </summary>
/// <param name="source">Источник перетаскивания.</param>
/// <param name="dragInfo">Информация о перетаскивании.</param>
public DragStartedEventArgs(IDockControl? source, Core.DragDrop.Models.DragInfo dragInfo)
{
Source = source;
DragInfo = dragInfo;
}
}
/// <summary>
/// Предоставляет данные для события обновления перетаскивания.
/// </summary>
public class DragUpdatedEventArgs : EventArgs
{
/// <summary>
/// Получает UI-контрол, который инициировал перетаскивание.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControl"/>, представляющий источник перетаскивания.
/// </value>
public IDockControl? Source { get; }
/// <summary>
/// Получает текущую координату X курсора.
/// </summary>
/// <value>
/// Координата X в экранных координатах.
/// </value>
public double X { get; }
/// <summary>
/// Получает текущую координату Y курсора.
/// </summary>
/// <value>
/// Координата Y в экранных координатах.
/// </value>
public double Y { get; }
/// <summary>
/// Получает информацию о перетаскивании.
/// </summary>
/// <value>
/// Экземпляр <see cref="Core.DragDrop.Models.DragInfo"/> с текущими данными перетаскивания.
/// </value>
public Core.DragDrop.Models.DragInfo DragInfo { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DragUpdatedEventArgs"/>.
/// </summary>
/// <param name="source">Источник перетаскивания.</param>
/// <param name="x">Текущая координата X.</param>
/// <param name="y">Текущая координата Y.</param>
/// <param name="dragInfo">Информация о перетаскивании.</param>
public DragUpdatedEventArgs(IDockControl? source, double x, double y, Core.DragDrop.Models.DragInfo dragInfo)
{
Source = source;
X = x;
Y = y;
DragInfo = dragInfo;
}
}
/// <summary>
/// Предоставляет данные для события завершения перетаскивания.
/// </summary>
public class DragCompletedEventArgs : EventArgs
{
/// <summary>
/// Получает UI-контрол, который инициировал перетаскивание.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControl"/>, представляющий источник перетаскивания.
/// Может быть null, если операция была инициирована не из UI.
/// </value>
public IDockControl? Source { get; }
/// <summary>
/// Получает UI-контрол, на который был выполнен сброс.
/// </summary>
/// <value>
/// Экземпляр <see cref="IDockControl"/>, представляющий цель сброса.
/// Может быть null, если сброс был выполнен вне допустимой области.
/// </value>
public IDockControl? Target { get; }
/// <summary>
/// Получает позицию сброса относительно целевого элемента.
/// </summary>
/// <value>
/// Значение перечисления <see cref="DropPosition"/>, указывающее позицию сброса.
/// </value>
public Models.DropPosition DropPosition { get; }
/// <summary>
/// Получает информацию о перетаскивании.
/// </summary>
/// <value>
/// Экземпляр <see cref="Core.DragDrop.Models.DragInfo"/> с данными завершенной операции.
/// Может быть null, если операция была отменена.
/// </value>
public Core.DragDrop.Models.DragInfo? DragInfo { get; }
/// <summary>
/// Получает значение, указывающее успешность операции сброса.
/// </summary>
/// <value>
/// true, если данные были успешно сброшены на цель; false, если операция была отменена
/// или сброс не был выполнен.
/// </value>
public bool Success { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DragCompletedEventArgs"/>.
/// </summary>
/// <param name="source">Источник перетаскивания.</param>
/// <param name="target">Цель сброса.</param>
/// <param name="dropPosition">Позиция сброса.</param>
/// <param name="dragInfo">Информация о перетаскивании.</param>
/// <param name="success">Признак успешности операции.</param>
public DragCompletedEventArgs(IDockControl? source, IDockControl? target,
Models.DropPosition dropPosition, Core.DragDrop.Models.DragInfo? dragInfo, bool success)
{
Source = source;
Target = target;
DropPosition = dropPosition;
DragInfo = dragInfo;
Success = success;
}
}

View File

@@ -60,23 +60,23 @@ public interface IDockGroupControl : IDockControl
void SetChildren(IDockControl? firstChild, IDockControl? secondChild);
/// <summary>
/// Событие, возникающее при изменении соотношения разделения.
/// Происходит при изменении соотношения разделения.
/// </summary>
event EventHandler<SplitRatioChangedEventArgs> SplitRatioChanged;
}
/// <summary>
/// Аргументы события изменения соотношения разделения.
/// Предоставляет данные для события изменения соотношения разделения.
/// </summary>
public class SplitRatioChangedEventArgs : EventArgs
{
/// <summary>
/// Новое соотношение разделения.
/// Получает новое соотношение разделения.
/// </summary>
public double NewRatio { get; }
/// <summary>
/// Источник изменения (пользователь или программа).
/// Получает источник изменения соотношения разделения.
/// </summary>
public SplitRatioChangeSource Source { get; }
@@ -93,16 +93,22 @@ public class SplitRatioChangedEventArgs : EventArgs
}
/// <summary>
/// Источник изменения соотношения разделения.
/// Определяет источник изменения соотношения разделения.
/// </summary>
public enum SplitRatioChangeSource
{
/// <summary>Изменение выполнено пользователем.</summary>
/// <summary>
/// Изменение выполнено пользователем.
/// </summary>
User,
/// <summary>Изменение выполнено программой.</summary>
/// <summary>
/// Изменение выполнено программой.
/// </summary>
Programmatic,
/// <summary>Изменение выполнено при восстановлении состояния.</summary>
/// <summary>
/// Изменение выполнено при восстановлении состояния.
/// </summary>
Restore
}

View File

@@ -10,8 +10,7 @@ namespace Lattice.UI.Docking.Abstractions;
/// </summary>
/// <remarks>
/// Реализации этого интерфейса представляют собой центральный координатор UI-слоя,
/// который интегрирует функциональность менеджера макета, системы перетаскивания
/// и контекстных меню в единый визуальный компонент.
/// который интегрирует функциональность менеджера макета и контекстных меню в единый визуальный компонент.
/// </remarks>
public interface IDockHost : IDockControl
{
@@ -23,8 +22,7 @@ public interface IDockHost : IDockControl
/// представляющих все активные плавающие окна в системе.
/// </value>
/// <remarks>
/// Плавающие окна могут быть созданы пользователем путем перетаскивания элементов
/// за пределы основного окна или программно через методы API.
/// Плавающие окна могут быть созданы пользователем или программно через методы API.
/// </remarks>
IEnumerable<IFloatingWindowControl> FloatingWindows { get; }
@@ -45,7 +43,7 @@ public interface IDockHost : IDockControl
/// Получает или задает значение, указывающее, отображается ли панель инструментов (Toolbox).
/// </summary>
/// <value>
/// true, если панель инструментов видима; в противном случае false.
/// true, если панель инструментов видима; в противном случае false.
/// Значение по умолчанию зависит от реализации.
/// </value>
/// <remarks>
@@ -58,7 +56,7 @@ public interface IDockHost : IDockControl
/// Получает или задает значение, указывающее, отображается ли строка состояния.
/// </summary>
/// <value>
/// true, если строка состояния видима; в противном случае false.
/// true, если строка состояния видима; в противном случае false.
/// Значение по умолчанию зависит от реализации.
/// </value>
/// <remarks>
@@ -71,9 +69,9 @@ public interface IDockHost : IDockControl
/// Получает или задает значение, указывающее, отображается ли главное меню приложения.
/// </summary>
/// <value>
/// true, если главное меню видимо; в противном случае false.
/// true, если главное меню видимо; в противном случае false.
/// Значение по умолчанию зависит от реализации.
/// </remarks>
/// </value>
bool ShowMenu { get; set; }
/// <summary>
@@ -148,7 +146,7 @@ public interface IDockHost : IDockControl
void RemoveAutoHidePanel(IAutoHidePanelControl panel);
/// <summary>
/// Событие, возникающее при изменении структуры макета док-системы.
/// Происходит при изменении структуры макета док-системы.
/// </summary>
/// <remarks>
/// Может вызываться при добавлении/удалении элементов, изменении размеров,
@@ -157,12 +155,12 @@ public interface IDockHost : IDockControl
event EventHandler LayoutChanged;
/// <summary>
/// Событие, возникающее при создании нового плавающего окна.
/// Происходит при создании нового плавающего окна.
/// </summary>
event EventHandler<FloatingWindowCreatedEventArgs> FloatingWindowCreated;
/// <summary>
/// Событие, возникающее при закрытии плавающего окна.
/// Происходит при закрытии плавающего окна.
/// </summary>
event EventHandler<FloatingWindowClosedEventArgs> FloatingWindowClosed;
}

View File

@@ -26,7 +26,7 @@ public interface IDockLeafControl : IDockControl
/// Получает или задает признак отображения кнопки закрытия на вкладках.
/// </summary>
/// <value>
/// true, если кнопки закрытия отображаются; в противном случае false.
/// true, если кнопки закрытия отображаются; в противном случае false.
/// </value>
bool ShowCloseButtons { get; set; }
@@ -34,7 +34,7 @@ public interface IDockLeafControl : IDockControl
/// Получает или задает признак возможности изменения порядка вкладок.
/// </summary>
/// <value>
/// true, если порядок вкладок можно изменять; в противном случае false.
/// true, если порядок вкладок можно изменять; в противном случае false.
/// </value>
bool CanReorderTabs { get; set; }
@@ -50,25 +50,39 @@ public interface IDockLeafControl : IDockControl
/// Добавляет вкладку в контрол.
/// </summary>
/// <param name="content">Контент для добавления.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="content"/> равен null.
/// </exception>
void AddContent(IDockContent content);
/// <summary>
/// Удаляет вкладку из контрола.
/// </summary>
/// <param name="content">Контент для удаления.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="content"/> равен null.
/// </exception>
void RemoveContent(IDockContent content);
/// <summary>
/// Закрывает указанную вкладку.
/// </summary>
/// <param name="content">Контент для закрытия.</param>
/// <returns>true, если вкладка была закрыта; в противном случае — false.</returns>
/// <returns>
/// true, если вкладка была закрыта; в противном случае false.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="content"/> равен null.
/// </exception>
bool CloseContent(IDockContent content);
/// <summary>
/// Закрывает все вкладки, кроме указанной.
/// </summary>
/// <param name="exceptContent">Вкладка, которую нужно оставить открытой.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="exceptContent"/> равен null.
/// </exception>
void CloseAllExcept(IDockContent exceptContent);
/// <summary>
@@ -77,39 +91,41 @@ public interface IDockLeafControl : IDockControl
void CloseAll();
/// <summary>
/// Событие, возникающее при изменении активной вкладки.
/// Происходит при изменении активной вкладки.
/// </summary>
event EventHandler<ActiveContentChangedEventArgs> ActiveContentChanged;
/// <summary>
/// Событие, возникающее при запросе закрытия вкладки.
/// Происходит при запросе закрытия вкладки.
/// </summary>
event EventHandler<ContentClosingEventArgs> ContentClosing;
/// <summary>
/// Событие, возникающее при изменении порядка вкладок.
/// Происходит при изменении порядка вкладок.
/// </summary>
event EventHandler<TabsReorderedEventArgs> TabsReordered;
}
/// <summary>
/// Аргументы события изменения активного контента.
/// Предоставляет данные для события изменения активного контента.
/// </summary>
public class ActiveContentChangedEventArgs : EventArgs
{
/// <summary>
/// Предыдущий активный контент.
/// Получает предыдущий активный контент.
/// </summary>
public IDockContent? OldContent { get; }
/// <summary>
/// Новый активный контент.
/// Получает новый активный контент.
/// </summary>
public IDockContent? NewContent { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="ActiveContentChangedEventArgs"/>.
/// </summary>
/// <param name="oldContent">Предыдущий активный контент.</param>
/// <param name="newContent">Новый активный контент.</param>
public ActiveContentChangedEventArgs(IDockContent? oldContent, IDockContent? newContent)
{
OldContent = oldContent;
@@ -118,63 +134,79 @@ public class ActiveContentChangedEventArgs : EventArgs
}
/// <summary>
/// Аргументы события закрытия контента.
/// Предоставляет данные для события закрытия контента.
/// </summary>
public class ContentClosingEventArgs : EventArgs
{
/// <summary>
/// Контент, который закрывается.
/// Получает контент, который закрывается.
/// </summary>
public IDockContent Content { get; }
/// <summary>
/// Показывает, можно ли отменить закрытие.
/// Получает или задает значение, указывающее, можно ли отменить закрытие.
/// </summary>
/// <value>
/// true, если закрытие можно отменить; в противном случае false.
/// </value>
public bool CanCancel { get; set; }
/// <summary>
/// Получает или задает признак отмены закрытия.
/// </summary>
/// <value>
/// true, если закрытие отменено; в противном случае false.
/// </value>
public bool Cancel { get; set; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="ContentClosingEventArgs"/>.
/// </summary>
/// <param name="content">Контент, который закрывается.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="content"/> равен null.
/// </exception>
public ContentClosingEventArgs(IDockContent content)
{
Content = content;
Content = content ?? throw new ArgumentNullException(nameof(content));
CanCancel = true;
Cancel = false;
}
}
/// <summary>
/// Аргументы события изменения порядка вкладок.
/// Предоставляет данные для события изменения порядка вкладок.
/// </summary>
public class TabsReorderedEventArgs : EventArgs
{
/// <summary>
/// Старый индекс вкладки.
/// Получает старый индекс вкладки.
/// </summary>
public int OldIndex { get; }
/// <summary>
/// Новый индекс вкладки.
/// Получает новый индекс вкладки.
/// </summary>
public int NewIndex { get; }
/// <summary>
/// Перемещаемый контент.
/// Получает перемещаемый контент.
/// </summary>
public IDockContent Content { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="TabsReorderedEventArgs"/>.
/// </summary>
/// <param name="oldIndex">Старый индекс вкладки.</param>
/// <param name="newIndex">Новый индекс вкладки.</param>
/// <param name="content">Перемещаемый контент.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="content"/> равен null.
/// </exception>
public TabsReorderedEventArgs(int oldIndex, int newIndex, IDockContent content)
{
OldIndex = oldIndex;
NewIndex = newIndex;
Content = content;
Content = content ?? throw new ArgumentNullException(nameof(content));
}
}

View File

@@ -0,0 +1,72 @@
namespace Lattice.UI.Docking.Abstractions;
/// <summary>
/// Определяет контракт для контрола разделителя между элементами док-системы.
/// Разделитель позволяет пользователю изменять размер смежных элементов.
/// </summary>
public interface IDockSplitterControl : IDockControl
{
/// <summary>
/// Получает или задает ориентацию разделителя.
/// </summary>
/// <value>
/// Ориентация разделителя (горизонтальная или вертикальная).
/// </value>
Core.Docking.Models.SplitDirection Orientation { get; set; }
/// <summary>
/// Получает или задает признак того, что разделитель активен (перетаскивается).
/// </summary>
/// <value>
/// true, если разделитель активен; в противном случае false.
/// </value>
bool IsDragging { get; set; }
/// <summary>
/// Происходит при начале перетаскивания разделителя.
/// </summary>
event EventHandler DragStarted;
/// <summary>
/// Происходит при перетаскивании разделителя.
/// </summary>
event EventHandler<SplitterDraggedEventArgs> DragDelta;
/// <summary>
/// Происходит при завершении перетаскивания разделителя.
/// </summary>
event EventHandler DragCompleted;
}
/// <summary>
/// Предоставляет данные для события перетаскивания разделителя.
/// </summary>
public class SplitterDraggedEventArgs : EventArgs
{
/// <summary>
/// Получает изменение позиции по горизонтали.
/// </summary>
/// <value>
/// Изменение по горизонтали в пикселях.
/// </value>
public double HorizontalChange { get; }
/// <summary>
/// Получает изменение позиции по вертикали.
/// </summary>
/// <value>
/// Изменение по вертикали в пикселях.
/// </value>
public double VerticalChange { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="SplitterDraggedEventArgs"/>.
/// </summary>
/// <param name="horizontalChange">Изменение по горизонтали.</param>
/// <param name="verticalChange">Изменение по вертикали.</param>
public SplitterDraggedEventArgs(double horizontalChange, double verticalChange)
{
HorizontalChange = horizontalChange;
VerticalChange = verticalChange;
}
}

View File

@@ -77,31 +77,37 @@ public interface IDockTheme
}
/// <summary>
/// Аргументы события показа контекстного меню.
/// Предоставляет данные для события показа контекстного меню.
/// </summary>
public class ContextMenuShownEventArgs : EventArgs
{
/// <summary>
/// Элемент, для которого показано меню.
/// Получает элемент, для которого показано меню.
/// </summary>
public IDockControl Target { get; }
/// <summary>
/// Координата X меню.
/// Получает координату X меню.
/// </summary>
public double X { get; }
/// <summary>
/// Координата Y меню.
/// Получает координату Y меню.
/// </summary>
public double Y { get; }
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="ContextMenuShownEventArgs"/>.
/// </summary>
/// <param name="target">Элемент, для которого показано меню.</param>
/// <param name="x">Координата X меню.</param>
/// <param name="y">Координата Y меню.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="target"/> равен null.
/// </exception>
public ContextMenuShownEventArgs(IDockControl target, double x, double y)
{
Target = target;
Target = target ?? throw new ArgumentNullException(nameof(target));
X = x;
Y = y;
}

View File

@@ -22,12 +22,8 @@ public interface IDockUIService
/// Платформенно-зависимый объект окна, который можно отобразить.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="host"/> равен null.
/// Выбрасывается, когда <paramref name="host"/> равен null.
/// </exception>
/// <remarks>
/// Реализация должна создавать окно с соответствующими стилями и поведением
/// для целевой платформы, настроенное для работы с док-системой.
/// </remarks>
object CreateMainWindow(IDockHost host);
/// <summary>
@@ -42,12 +38,8 @@ public interface IDockUIService
/// null - диалог был закрыт без выбора.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="title"/> или <paramref name="content"/> равны null.
/// Выбрасывается, когда <paramref name="title"/> или <paramref name="content"/> равны null.
/// </exception>
/// <remarks>
/// Реализация должна блокировать взаимодействие с родительским окном
/// до закрытия диалога.
/// </remarks>
bool? ShowDialog(string title, object content);
/// <summary>
@@ -56,12 +48,8 @@ public interface IDockUIService
/// <param name="message">Текст сообщения.</param>
/// <param name="caption">Заголовок окна сообщения.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="message"/> или <paramref name="caption"/> равны null.
/// Выбрасывается, когда <paramref name="message"/> или <paramref name="caption"/> равны null.
/// </exception>
/// <remarks>
/// Реализация должна использовать стандартные диалоги платформы
/// или создавать кастомные окна сообщений.
/// </remarks>
void ShowMessage(string message, string caption);
/// <summary>
@@ -73,12 +61,8 @@ public interface IDockUIService
/// true, если пользователь выбрал "Yes"; false, если пользователь выбрал "No".
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="message"/> или <paramref name="caption"/> равны null.
/// Выбрасывается, когда <paramref name="message"/> или <paramref name="caption"/> равны null.
/// </exception>
/// <remarks>
/// Используется для получения подтверждения от пользователя перед выполнением
/// критических операций (закрытие вкладок, сброс настроек и т.д.).
/// </remarks>
bool Confirm(string message, string caption);
/// <summary>
@@ -90,12 +74,8 @@ public interface IDockUIService
/// Введенный пользователем текст или null, если диалог был отменен.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="prompt"/> равен null.
/// Выбрасывается, когда <paramref name="prompt"/> равен null.
/// </exception>
/// <remarks>
/// Реализация должна предоставлять однострочное поле ввода текста
/// с возможностью отмены операции.
/// </remarks>
string? Prompt(string prompt, string? defaultValue = null);
/// <summary>
@@ -103,12 +83,7 @@ public interface IDockUIService
/// </summary>
/// <param name="action">Действие для выполнения.</param>
/// <exception cref="ArgumentNullException">
/// Выбрасывается, если <paramref name="action"/> равен null.
/// Выбрасывается, когда <paramref name="action"/> равен null.
/// </exception>
/// <remarks>
/// Этот метод гарантирует, что действие будет выполнено в потоке,
/// связанном с пользовательским интерфейсом, что необходимо для
/// безопасного обновления UI-элементов.
/// </remarks>
void InvokeOnUIThread(Action action);
}

View File

@@ -53,7 +53,7 @@ public interface IFloatingWindowControl : IDockControl
/// Получает или задает признак того, что окно можно изменять.
/// </summary>
/// <value>
/// true, если размеры окна можно изменять; в противном случае false.
/// true, если размеры окна можно изменять; в противном случае false.
/// </value>
bool CanResize { get; set; }
@@ -61,7 +61,7 @@ public interface IFloatingWindowControl : IDockControl
/// Получает или задает признак того, что окно можно перемещать.
/// </summary>
/// <value>
/// true, если окно можно перемещать; в противном случае false.
/// true, если окно можно перемещать; в противном случае false.
/// </value>
bool CanMove { get; set; }
@@ -69,7 +69,7 @@ public interface IFloatingWindowControl : IDockControl
/// Получает или задает признак того, что окно всегда поверх других окон.
/// </summary>
/// <value>
/// true, если окно всегда поверх; в противном случае false.
/// true, если окно всегда поверх; в противном случае false.
/// </value>
bool AlwaysOnTop { get; set; }
@@ -94,17 +94,17 @@ public interface IFloatingWindowControl : IDockControl
void Activate();
/// <summary>
/// Событие, возникающее при закрытии окна.
/// Происходит при закрытии окна.
/// </summary>
event EventHandler Closing;
/// <summary>
/// Событие, возникающее при изменении положения окна.
/// Происходит при изменении положения окна.
/// </summary>
event EventHandler LocationChanged;
/// <summary>
/// Событие, возникающее при изменении размера окна.
/// Происходит при изменении размера окна.
/// </summary>
event EventHandler SizeChanged;
}