DragAndDrop core
This commit is contained in:
96
Lattice.UI.Docking/Services/DockContextManagerBase.cs
Normal file
96
Lattice.UI.Docking/Services/DockContextManagerBase.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using Lattice.UI.Docking.Abstractions;
|
||||
|
||||
namespace Lattice.UI.Docking.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Базовая реализация менеджера контекстных меню.
|
||||
/// </summary>
|
||||
public abstract class DockContextManagerBase : IDockContextManager
|
||||
{
|
||||
private readonly Dictionary<string, IDockCommand> _commands = new();
|
||||
private IDockControl? _currentContextTarget;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<ContextMenuShownEventArgs>? ContextMenuShown;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler? ContextMenuHidden;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void ShowContextMenu(IDockControl element, double x, double y);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract void HideContextMenu();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void RegisterCommand(string commandId, IDockCommand command)
|
||||
{
|
||||
if (string.IsNullOrEmpty(commandId))
|
||||
throw new ArgumentNullException(nameof(commandId));
|
||||
|
||||
_commands[commandId] = command ?? throw new ArgumentNullException(nameof(command));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void UnregisterCommand(string commandId)
|
||||
{
|
||||
_commands.Remove(commandId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает команду по идентификатору.
|
||||
/// </summary>
|
||||
public IDockCommand? GetCommand(string commandId)
|
||||
{
|
||||
_commands.TryGetValue(commandId, out var command);
|
||||
return command;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает все доступные команды для указанного элемента.
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<IDockCommand> GetCommandsForElement(IDockControl element)
|
||||
{
|
||||
// Фильтрация команд по типу элемента и его состоянию
|
||||
return _commands.Values.Where(c => CanExecuteCommand(c, element));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, можно ли выполнить команду для указанного элемента.
|
||||
/// </summary>
|
||||
protected virtual bool CanExecuteCommand(IDockCommand command, IDockControl element)
|
||||
{
|
||||
return command.CanExecute(element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выполняет команду для указанного элемента.
|
||||
/// </summary>
|
||||
protected virtual void ExecuteCommand(IDockCommand command, IDockControl element)
|
||||
{
|
||||
command.Execute(element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вызывает событие показа контекстного меню.
|
||||
/// </summary>
|
||||
protected virtual void OnContextMenuShown(IDockControl target, double x, double y)
|
||||
{
|
||||
_currentContextTarget = target;
|
||||
ContextMenuShown?.Invoke(this, new ContextMenuShownEventArgs(target, x, y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вызывает событие скрытия контекстного меню.
|
||||
/// </summary>
|
||||
protected virtual void OnContextMenuHidden()
|
||||
{
|
||||
_currentContextTarget = null;
|
||||
ContextMenuHidden?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает текущий целевой элемент контекстного меню.
|
||||
/// </summary>
|
||||
protected IDockControl? CurrentContextTarget => _currentContextTarget;
|
||||
}
|
||||
417
Lattice.UI.Docking/Services/DockDragDropService.cs
Normal file
417
Lattice.UI.Docking/Services/DockDragDropService.cs
Normal file
@@ -0,0 +1,417 @@
|
||||
using Lattice.Core.DragDrop.Abstractions;
|
||||
using Lattice.Core.DragDrop.Services;
|
||||
using Lattice.UI.Docking.Abstractions;
|
||||
using Lattice.UI.Docking.Models;
|
||||
|
||||
namespace Lattice.UI.Docking.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Реализация сервиса перетаскивания для UI-слоя док-системы.
|
||||
/// Координирует взаимодействие между базовым менеджером перетаскивания
|
||||
/// и UI-контролами, обеспечивая визуальную обратную связь.
|
||||
/// </summary>
|
||||
public class DockDragDropService : IDockDragDropService
|
||||
{
|
||||
private readonly DragDropManagerEx _dragDropManager;
|
||||
private readonly Dictionary<IDockControl, IDragSource> _registeredDragSources = new();
|
||||
private readonly Dictionary<IDockControl, IDropTarget> _registeredDropTargets = new();
|
||||
private UiDragInfo? _currentUiDragInfo;
|
||||
private UiDropInfo? _currentUiDropInfo;
|
||||
private IDropTarget? _lastDropTarget;
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр <see cref="DockDragDropService"/>.
|
||||
/// </summary>
|
||||
public DockDragDropService()
|
||||
{
|
||||
_dragDropManager = new DragDropManagerEx();
|
||||
HookEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр с указанным менеджером перетаскивания.
|
||||
/// </summary>
|
||||
public DockDragDropService(DragDropManagerEx dragDropManager)
|
||||
{
|
||||
_dragDropManager = dragDropManager;
|
||||
HookEvents();
|
||||
}
|
||||
|
||||
private void HookEvents()
|
||||
{
|
||||
_dragDropManager.DragStarted += OnDragStarted;
|
||||
_dragDropManager.DragUpdated += OnDragUpdated;
|
||||
_dragDropManager.DragCompleted += OnDragCompleted;
|
||||
_dragDropManager.DragCancelled += OnDragCancelled;
|
||||
_dragDropManager.DropTargetChanged += OnDropTargetChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RegisterDragSource(IDockControl element, IDragSource dragSource)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
if (dragSource == null) throw new ArgumentNullException(nameof(dragSource));
|
||||
|
||||
_registeredDragSources[element] = dragSource;
|
||||
|
||||
// Регистрируем границы элемента в менеджере
|
||||
var bounds = CalculateBounds(element);
|
||||
_dragDropManager.RegisterDropTarget(dragSource as IDropTarget ?? new AdapterDropTarget(dragSource),
|
||||
bounds, 0, element.GetType().Name);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RegisterDropTarget(IDockControl element, IDropTarget dropTarget)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
if (dropTarget == null) throw new ArgumentNullException(nameof(dropTarget));
|
||||
|
||||
_registeredDropTargets[element] = dropTarget;
|
||||
|
||||
var bounds = CalculateBounds(element);
|
||||
_dragDropManager.RegisterDropTarget(dropTarget, bounds, 0, element.GetType().Name);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UnregisterDragSource(IDockControl element)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
|
||||
_registeredDragSources.Remove(element);
|
||||
// TODO: Реализовать отмену регистрации в менеджере
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UnregisterDropTarget(IDockControl element)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
|
||||
_registeredDropTargets.Remove(element);
|
||||
// TODO: Реализовать отмену регистрации в менеджере
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void StartDrag(IDockControl element, Core.DragDrop.Models.DragInfo dragInfo)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
if (dragInfo == null) throw new ArgumentNullException(nameof(dragInfo));
|
||||
|
||||
if (_registeredDragSources.TryGetValue(element, out var dragSource))
|
||||
{
|
||||
_currentUiDragInfo = new UiDragInfo(dragInfo, element);
|
||||
_dragDropManager.StartDrag(dragSource, dragInfo.StartPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UpdateDragVisual(double x, double y)
|
||||
{
|
||||
var position = new Core.DragDrop.Geometry.Point(x, y);
|
||||
_dragDropManager.UpdateDrag(position);
|
||||
|
||||
if (_currentUiDragInfo != null)
|
||||
{
|
||||
// Обновляем позицию визуального представления
|
||||
OnDragVisualUpdated?.Invoke(this, new DragVisualUpdatedEventArgs(
|
||||
_currentUiDragInfo, position));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void EndDrag(double x, double y)
|
||||
{
|
||||
var position = new Core.DragDrop.Geometry.Point(x, y);
|
||||
_dragDropManager.EndDrag(position);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void CancelDrag()
|
||||
{
|
||||
_dragDropManager.CancelDrag();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ShowDropHint(IDockControl element, DropPosition position)
|
||||
{
|
||||
if (_currentUiDropInfo != null)
|
||||
{
|
||||
_currentUiDropInfo.DropPosition = position;
|
||||
_currentUiDropInfo.IsOverValidTarget = true;
|
||||
_currentUiDropInfo.HighlightIntensity = 0.8;
|
||||
|
||||
OnDropHintChanged?.Invoke(this, new DropHintEventArgs(
|
||||
element, position, true, _currentUiDropInfo.HighlightIntensity));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void HideDropHint()
|
||||
{
|
||||
if (_currentUiDropInfo != null)
|
||||
{
|
||||
_currentUiDropInfo.IsOverValidTarget = false;
|
||||
_currentUiDropInfo.HighlightIntensity = 0.0;
|
||||
|
||||
OnDropHintChanged?.Invoke(this, new DropHintEventArgs(
|
||||
_currentUiDropInfo.TargetControl,
|
||||
_currentUiDropInfo.DropPosition,
|
||||
false,
|
||||
0.0));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<DragStartedEventArgs>? DragStarted;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<DragUpdatedEventArgs>? DragUpdated;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler<DragCompletedEventArgs>? DragCompleted;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event EventHandler? DragCancelled;
|
||||
|
||||
/// <summary>
|
||||
/// Событие, возникающее при обновлении визуального представления перетаскивания.
|
||||
/// </summary>
|
||||
public event EventHandler<DragVisualUpdatedEventArgs>? OnDragVisualUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Событие, возникающее при изменении визуальной подсказки сброса.
|
||||
/// </summary>
|
||||
public event EventHandler<DropHintEventArgs>? OnDropHintChanged;
|
||||
|
||||
private void OnDragStarted(object? sender, DragStartedEventArgs e)
|
||||
{
|
||||
// Обновляем UI-информацию
|
||||
if (_currentUiDragInfo != null)
|
||||
{
|
||||
_currentUiDragInfo.BaseDragInfo.StartPosition = e.StartPosition;
|
||||
|
||||
// Создаем визуальное представление
|
||||
CreateDragVisual(_currentUiDragInfo);
|
||||
|
||||
DragStarted?.Invoke(this, new DragStartedEventArgs(
|
||||
_currentUiDragInfo.SourceControl,
|
||||
_currentUiDragInfo.BaseDragInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragUpdated(object? sender, DragUpdatedEventArgs e)
|
||||
{
|
||||
if (_currentUiDragInfo != null)
|
||||
{
|
||||
// Обновляем позицию визуального представления
|
||||
UpdateDragVisualPosition(e.Position);
|
||||
|
||||
DragUpdated?.Invoke(this, new DragUpdatedEventArgs(
|
||||
_currentUiDragInfo.SourceControl,
|
||||
e.Position.X,
|
||||
e.Position.Y,
|
||||
_currentUiDragInfo.BaseDragInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragCompleted(object? sender, DragCompletedEventArgs e)
|
||||
{
|
||||
var targetControl = _currentUiDropInfo?.TargetControl;
|
||||
var dropPosition = _currentUiDropInfo?.DropPosition ?? DropPosition.Center;
|
||||
|
||||
DragCompleted?.Invoke(this, new DragCompletedEventArgs(
|
||||
_currentUiDragInfo?.SourceControl,
|
||||
targetControl,
|
||||
dropPosition,
|
||||
_currentUiDragInfo?.BaseDragInfo,
|
||||
e.Effects != Core.DragDrop.Enums.DragDropEffects.None));
|
||||
|
||||
// Очищаем визуальные представления
|
||||
CleanupDragVisual();
|
||||
CleanupDropHint();
|
||||
|
||||
_currentUiDragInfo = null;
|
||||
_currentUiDropInfo = null;
|
||||
_lastDropTarget = null;
|
||||
}
|
||||
|
||||
private void OnDragCancelled(object? sender, DragCancelledEventArgs e)
|
||||
{
|
||||
DragCancelled?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
CleanupDragVisual();
|
||||
CleanupDropHint();
|
||||
|
||||
_currentUiDragInfo = null;
|
||||
_currentUiDropInfo = null;
|
||||
_lastDropTarget = null;
|
||||
}
|
||||
|
||||
private void OnDropTargetChanged(object? sender, DropTargetChangedEventArgs e)
|
||||
{
|
||||
var dropTarget = e.Target;
|
||||
|
||||
// Обновляем UI-информацию о сбросе
|
||||
if (dropTarget != null)
|
||||
{
|
||||
// Находим соответствующий UI-контрол
|
||||
var targetControl = _registeredDropTargets
|
||||
.FirstOrDefault(kv => kv.Value == dropTarget)
|
||||
.Key;
|
||||
|
||||
_currentUiDropInfo = new UiDropInfo(
|
||||
new Core.DragDrop.Models.DropInfo(
|
||||
_dragDropManager.CurrentDragInfo?.Data,
|
||||
e.TargetBounds.Center,
|
||||
_dragDropManager.CurrentDragInfo?.AllowedEffects ?? Core.DragDrop.Enums.DragDropEffects.None,
|
||||
dropTarget),
|
||||
targetControl);
|
||||
|
||||
_currentUiDropInfo.DropPosition = CalculateDropPosition(
|
||||
_currentUiDragInfo?.BaseDragInfo.StartPosition ?? Core.DragDrop.Geometry.Point.Zero,
|
||||
e.TargetBounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentUiDropInfo = null;
|
||||
}
|
||||
|
||||
// Уведомляем об изменении цели сброса
|
||||
if (_lastDropTarget != dropTarget)
|
||||
{
|
||||
if (_lastDropTarget != null)
|
||||
{
|
||||
HideDropHint();
|
||||
}
|
||||
|
||||
if (dropTarget != null && _currentUiDropInfo != null)
|
||||
{
|
||||
ShowDropHint(_currentUiDropInfo.TargetControl, _currentUiDropInfo.DropPosition);
|
||||
}
|
||||
|
||||
_lastDropTarget = dropTarget;
|
||||
}
|
||||
}
|
||||
|
||||
private Core.DragDrop.Geometry.Rect CalculateBounds(IDockControl element)
|
||||
{
|
||||
// В UI-реализациях этот метод должен быть переопределен
|
||||
// для вычисления реальных границ элемента на экране
|
||||
return new Core.DragDrop.Geometry.Rect(0, 0, 100, 100);
|
||||
}
|
||||
|
||||
private DropPosition CalculateDropPosition(Core.DragDrop.Geometry.Point cursorPos, Core.DragDrop.Geometry.Rect targetBounds)
|
||||
{
|
||||
// Простая логика определения позиции сброса
|
||||
var center = targetBounds.Center;
|
||||
var relativeX = (cursorPos.X - targetBounds.X) / targetBounds.Width;
|
||||
var relativeY = (cursorPos.Y - targetBounds.Y) / targetBounds.Height;
|
||||
|
||||
if (relativeX < 0.25) return DropPosition.Left;
|
||||
if (relativeX > 0.75) return DropPosition.Right;
|
||||
if (relativeY < 0.25) return DropPosition.Top;
|
||||
if (relativeY > 0.75) return DropPosition.Bottom;
|
||||
|
||||
return DropPosition.Center;
|
||||
}
|
||||
|
||||
private void CreateDragVisual(UiDragInfo dragInfo)
|
||||
{
|
||||
// В UI-реализациях этот метод должен создавать визуальное представление
|
||||
OnDragVisualUpdated?.Invoke(this, new DragVisualUpdatedEventArgs(
|
||||
dragInfo, dragInfo.BaseDragInfo.StartPosition));
|
||||
}
|
||||
|
||||
private void UpdateDragVisualPosition(Core.DragDrop.Geometry.Point position)
|
||||
{
|
||||
if (_currentUiDragInfo != null)
|
||||
{
|
||||
OnDragVisualUpdated?.Invoke(this, new DragVisualUpdatedEventArgs(
|
||||
_currentUiDragInfo, position));
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupDragVisual()
|
||||
{
|
||||
// В UI-реализациях этот метод должен очищать визуальное представление
|
||||
OnDragVisualUpdated?.Invoke(this, new DragVisualUpdatedEventArgs(null, Core.DragDrop.Geometry.Point.Zero));
|
||||
}
|
||||
|
||||
private void CleanupDropHint()
|
||||
{
|
||||
HideDropHint();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Адаптер для преобразования IDragSource в IDropTarget.
|
||||
/// </summary>
|
||||
internal class AdapterDropTarget : IDropTarget
|
||||
{
|
||||
private readonly IDragSource _dragSource;
|
||||
|
||||
public AdapterDropTarget(IDragSource dragSource)
|
||||
{
|
||||
_dragSource = dragSource;
|
||||
}
|
||||
|
||||
public bool CanAcceptDrop(Core.DragDrop.Models.DropInfo dropInfo) => false;
|
||||
public void DragOver(Core.DragDrop.Models.DropInfo dropInfo) { }
|
||||
public void Drop(Core.DragDrop.Models.DropInfo dropInfo) { }
|
||||
public void DragLeave() { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Аргументы события обновления визуального представления перетаскивания.
|
||||
/// </summary>
|
||||
public class DragVisualUpdatedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Информация о перетаскивании.
|
||||
/// </summary>
|
||||
public UiDragInfo? DragInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Текущая позиция.
|
||||
/// </summary>
|
||||
public Core.DragDrop.Geometry.Point Position { get; }
|
||||
|
||||
public DragVisualUpdatedEventArgs(UiDragInfo? dragInfo, Core.DragDrop.Geometry.Point position)
|
||||
{
|
||||
DragInfo = dragInfo;
|
||||
Position = position;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Аргументы события изменения визуальной подсказки сброса.
|
||||
/// </summary>
|
||||
public class DropHintEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Целевой элемент.
|
||||
/// </summary>
|
||||
public IDockControl? Target { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Позиция сброса.
|
||||
/// </summary>
|
||||
public DropPosition Position { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Показывает, видима ли подсказка.
|
||||
/// </summary>
|
||||
public bool IsVisible { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Интенсивность подсветки.
|
||||
/// </summary>
|
||||
public double Intensity { get; }
|
||||
|
||||
public DropHintEventArgs(IDockControl? target, DropPosition position, bool isVisible, double intensity)
|
||||
{
|
||||
Target = target;
|
||||
Position = position;
|
||||
IsVisible = isVisible;
|
||||
Intensity = intensity;
|
||||
}
|
||||
}
|
||||
113
Lattice.UI.Docking/Services/DockUIServiceBase.cs
Normal file
113
Lattice.UI.Docking/Services/DockUIServiceBase.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using Lattice.UI.Docking.Abstractions;
|
||||
|
||||
namespace Lattice.UI.Docking.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Базовая реализация UI-сервиса с общими функциями.
|
||||
/// </summary>
|
||||
public abstract class DockUIServiceBase : IDockUIService
|
||||
{
|
||||
private IDockTheme? _currentTheme;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract object CreateMainWindow(IDockHost host);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool? ShowDialog(string title, object content)
|
||||
{
|
||||
// Базовая реализация - просто возвращает null
|
||||
// В производных классах должна быть реальная реализация
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void ShowMessage(string message, string caption)
|
||||
{
|
||||
// Базовая реализация не делает ничего
|
||||
// В производных классах должна быть реальная реализация
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool Confirm(string message, string caption)
|
||||
{
|
||||
// Базовая реализация всегда возвращает true
|
||||
// В производных классах должна быть реальная реализация
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual string? Prompt(string prompt, string? defaultValue = null)
|
||||
{
|
||||
// Базовая реализация возвращает значение по умолчанию
|
||||
// В производных классах должна быть реальная реализация
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void InvokeOnUIThread(Action action)
|
||||
{
|
||||
// Базовая реализация просто выполняет действие
|
||||
// В производных классах должна быть синхронизация с UI-потоком
|
||||
action?.Invoke();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual IDockTheme GetCurrentTheme()
|
||||
{
|
||||
return _currentTheme ?? CreateDefaultTheme();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void SetTheme(IDockTheme theme)
|
||||
{
|
||||
_currentTheme = theme;
|
||||
theme.Apply();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает тему по умолчанию.
|
||||
/// </summary>
|
||||
protected virtual IDockTheme CreateDefaultTheme()
|
||||
{
|
||||
return new DefaultDockTheme();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Тема оформления по умолчанию.
|
||||
/// </summary>
|
||||
public class DefaultDockTheme : IDockTheme
|
||||
{
|
||||
public string Name => "Default";
|
||||
public string BackgroundColor { get; set; } = "#1E1E1E";
|
||||
public string PanelBackgroundColor { get; set; } = "#252526";
|
||||
public string TabBackgroundColor { get; set; } = "#2D2D2D";
|
||||
public string ActiveTabBackgroundColor { get; set; } = "#3E3E3E";
|
||||
public string BorderColor { get; set; } = "#3F3F46";
|
||||
public string SplitterColor { get; set; } = "#2D2D2D";
|
||||
public string TextColor { get; set; } = "#CCCCCC";
|
||||
public string AccentColor { get; set; } = "#007ACC";
|
||||
public double CornerRadius { get; set; } = 3.0;
|
||||
public double BorderThickness { get; set; } = 1.0;
|
||||
public double SplitterWidth { get; set; } = 4.0;
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
// В UI-реализациях этот метод должен применять тему к элементам
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
BackgroundColor = "#1E1E1E";
|
||||
PanelBackgroundColor = "#252526";
|
||||
TabBackgroundColor = "#2D2D2D";
|
||||
ActiveTabBackgroundColor = "#3E3E3E";
|
||||
BorderColor = "#3F3F46";
|
||||
SplitterColor = "#2D2D2D";
|
||||
TextColor = "#CCCCCC";
|
||||
AccentColor = "#007ACC";
|
||||
CornerRadius = 3.0;
|
||||
BorderThickness = 1.0;
|
||||
SplitterWidth = 4.0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user