Доработан 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

@@ -1,33 +1,85 @@
using Lattice.UI.Docking.Abstractions;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Lattice.UI.Docking.Commands;
/// <summary>
/// Базовая реализация команды док-системы.
/// Предоставляет базовую реализацию команды док-системы.
/// Реализует интерфейс <see cref="IDockCommand"/> и <see cref="INotifyPropertyChanged"/>
/// для поддержки уведомлений об изменении свойств.
/// </summary>
public abstract class DockCommandBase : IDockCommand
/// <remarks>
/// Этот класс предоставляет общую логику для команд, включая управление состоянием
/// возможности выполнения, уведомление об изменениях и реализацию интерфейса ICommand.
/// </remarks>
public abstract class DockCommandBase : IDockCommand, INotifyPropertyChanged
{
/// <summary>
/// Происходит при изменении возможности выполнения команды.
/// </summary>
public event EventHandler? CanExecuteChanged;
/// <summary>
/// Происходит при изменении значения свойства.
/// </summary>
public event PropertyChangedEventHandler? PropertyChanged;
private bool _canExecute = true;
/// <inheritdoc/>
/// <summary>
/// Получает уникальный идентификатор команды.
/// </summary>
/// <value>
/// Строковый идентификатор команды. Должен быть уникальным в пределах системы.
/// </value>
public abstract string Id { get; }
/// <inheritdoc/>
/// <summary>
/// Получает отображаемое имя команды.
/// </summary>
/// <value>
/// Имя команды, отображаемое в пользовательском интерфейсе.
/// </value>
public abstract string Name { get; }
/// <inheritdoc/>
/// <summary>
/// Получает описание команды.
/// </summary>
/// <value>
/// Текстовое описание функциональности команды.
/// Реализация по умолчанию возвращает пустую строку.
/// </value>
public virtual string Description => string.Empty;
/// <inheritdoc/>
/// <summary>
/// Получает идентификатор ресурса для иконки команды.
/// </summary>
/// <value>
/// Имя ресурса иконки или путь к файлу иконки.
/// Реализация по умолчанию возвращает пустую строку.
/// </value>
public virtual string Icon => string.Empty;
/// <inheritdoc/>
/// <summary>
/// Получает комбинацию клавиш для быстрого вызова команды.
/// </summary>
/// <value>
/// Строковое представление горячей клавиши.
/// Реализация по умолчанию возвращает пустую строку.
/// </value>
public virtual string Shortcut => string.Empty;
/// <summary>
/// Получает или задает признак возможности выполнения команды.
/// Получает или задает значение, указывающее, можно ли выполнить команду.
/// </summary>
public bool CanExecute
/// <value>
/// true, если команду можно выполнить; в противном случае false.
/// </value>
/// <remarks>
/// При изменении этого свойства генерируется событие <see cref="CanExecuteChanged"/>.
/// </remarks>
protected bool CanExecuteValue
{
get => _canExecute;
set
@@ -36,42 +88,131 @@ public abstract class DockCommandBase : IDockCommand
{
_canExecute = value;
OnCanExecuteChanged();
OnPropertyChanged();
}
}
}
/// <inheritdoc/>
public event EventHandler? CanExecuteChanged;
/// <inheritdoc/>
/// <summary>
/// Определяет, можно ли выполнить команду в текущем контексте.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <returns>
/// true, если команду можно выполнить; в противном случае false.
/// </returns>
/// <remarks>
/// Реализация по умолчанию возвращает значение свойства <see cref="CanExecuteValue"/>.
/// </remarks>
public virtual bool CanExecute(object? parameter)
{
return _canExecute;
}
/// <inheritdoc/>
/// <summary>
/// Выполняет команду.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <remarks>
/// Этот метод должен быть реализован в производных классах.
/// </remarks>
public abstract void Execute(object? parameter);
/// <summary>
/// Вызывает событие изменения возможности выполнения команды.
/// </summary>
/// <remarks>
/// Этот метод может быть переопределен в производных классах для добавления
/// дополнительной логики перед вызовом события.
/// </remarks>
protected virtual void OnCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Вызывает событие <see cref="PropertyChanged"/>.
/// </summary>
/// <param name="propertyName">
/// Имя изменившегося свойства. Если не указано, определяется автоматически.
/// </param>
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Базовая команда для закрытия контента.
/// Предоставляет команду для закрытия контента (вкладки).
/// </summary>
/// <remarks>
/// Команда закрывает активную вкладку в указанном контроле листа.
/// </remarks>
public class CloseContentCommand : DockCommandBase
{
/// <summary>
/// Получает уникальный идентификатор команды.
/// </summary>
/// <value>
/// Идентификатор "CloseContent".
/// </value>
public override string Id => "CloseContent";
/// <summary>
/// Получает отображаемое имя команды.
/// </summary>
/// <value>
/// Имя "Close".
/// </value>
public override string Name => "Close";
/// <summary>
/// Получает описание команды.
/// </summary>
/// <value>
/// Описание "Close the current tab".
/// </value>
public override string Description => "Close the current tab";
/// <summary>
/// Получает идентификатор ресурса для иконки команды.
/// </summary>
/// <value>
/// Идентификатор "Close".
/// </value>
public override string Icon => "Close";
/// <summary>
/// Получает комбинацию клавиш для быстрого вызова команды.
/// </summary>
/// <value>
/// Горячая клавиша "Ctrl+F4".
/// </value>
public override string Shortcut => "Ctrl+F4";
/// <summary>
/// Определяет, можно ли выполнить команду в текущем контексте.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <returns>
/// true, если команду можно выполнить; в противном случае false.
/// </returns>
/// <remarks>
/// Команда доступна только если параметр является контролом листа
/// и содержит активный контент.
/// </remarks>
public override bool CanExecute(object? parameter)
{
return parameter is Abstractions.IDockLeafControl leafControl &&
leafControl.ActiveContent != null;
}
/// <summary>
/// Выполняет команду закрытия контента.
/// </summary>
/// <param name="parameter">Параметр команды. Ожидается <see cref="Abstractions.IDockLeafControl"/>.</param>
/// <remarks>
/// Команда закрывает активную вкладку в указанном контроле листа.
/// </remarks>
public override void Execute(object? parameter)
{
if (parameter is Abstractions.IDockLeafControl leafControl &&
@@ -83,33 +224,137 @@ public class CloseContentCommand : DockCommandBase
}
/// <summary>
/// Базовая команда для создания плавающего окна.
/// Предоставляет команду для создания плавающего окна из элемента.
/// </summary>
public class FloatWindowCommand : DockCommandBase
{
/// <summary>
/// Получает уникальный идентификатор команды.
/// </summary>
/// <value>
/// Идентификатор "FloatWindow".
/// </value>
public override string Id => "FloatWindow";
/// <summary>
/// Получает отображаемое имя команды.
/// </summary>
/// <value>
/// Имя "Float".
/// </value>
public override string Name => "Float";
/// <summary>
/// Получает описание команды.
/// </summary>
/// <value>
/// Описание "Float the window as a separate window".
/// </value>
public override string Description => "Float the window as a separate window";
/// <summary>
/// Получает идентификатор ресурса для иконки команды.
/// </summary>
/// <value>
/// Идентификатор "Float".
/// </value>
public override string Icon => "Float";
/// <summary>
/// Определяет, можно ли выполнить команду в текущем контексте.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <returns>
/// true, если команду можно выполнить; в противном случае false.
/// </returns>
/// <remarks>
/// Команда доступна только если параметр является элементом док-системы,
/// который может быть преобразован в плавающее окно.
/// </remarks>
public override bool CanExecute(object? parameter)
{
return parameter is Core.Docking.Abstractions.IDockElement;
}
/// <summary>
/// Выполняет команду создания плавающего окна.
/// </summary>
/// <param name="parameter">Параметр команды. Ожидается <see cref="Core.Docking.Abstractions.IDockElement"/>.</param>
/// <remarks>
/// Реализация зависит от конкретного UI и должна быть предоставлена в производных классах.
/// Базовая реализация не выполняет никаких действий.
/// </remarks>
public override void Execute(object? parameter)
{
// Реализация зависит от конкретного UI
// В базовом классе метод не выполняет никаких действий
}
}
/// <summary>
/// Базовая команда для закрепления окна.
/// Предоставляет команду для закрепления плавающего окна.
/// </summary>
public class DockWindowCommand : DockCommandBase
{
/// <summary>
/// Получает уникальный идентификатор команды.
/// </summary>
/// <value>
/// Идентификатор "DockWindow".
/// </value>
public override string Id => "DockWindow";
/// <summary>
/// Получает отображаемое имя команды.
/// </summary>
/// <value>
/// Имя "Dock".
/// </value>
public override string Name => "Dock";
/// <summary>
/// Получает описание команды.
/// </summary>
/// <value>
/// Описание "Dock the window to the main window".
/// </value>
public override string Description => "Dock the window to the main window";
/// <summary>
/// Получает идентификатор ресурса для иконки команды.
/// </summary>
/// <value>
/// Идентификатор "Dock".
/// </value>
public override string Icon => "Dock";
/// <summary>
/// Определяет, можно ли выполнить команду в текущем контексте.
/// </summary>
/// <param name="parameter">Параметр команды.</param>
/// <returns>
/// true, если команду можно выполнить; в противном случае false.
/// </returns>
/// <remarks>
/// Команда доступна только если параметр является плавающим окном,
/// которое может быть закреплено в основном окне.
/// </remarks>
public override bool CanExecute(object? parameter)
{
return parameter is Abstractions.IFloatingWindowControl;
}
/// <summary>
/// Выполняет команду закрепления окна.
/// </summary>
/// <param name="parameter">Параметр команды. Ожидается <see cref="Abstractions.IFloatingWindowControl"/>.</param>
/// <remarks>
/// Реализация зависит от конкретного UI и должна быть предоставлена в производных классах.
/// Базовая реализация не выполняет никаких действий.
/// </remarks>
public override void Execute(object? parameter)
{
// Реализация зависит от конкретного UI
// В базовом классе метод не выполняет никаких действий
}
}