Выделение отдельных сервисов
This commit is contained in:
@@ -20,8 +20,10 @@
|
|||||||
|
|
||||||
* `Abstractions/` — Интерфейсы для расширения системы.
|
* `Abstractions/` — Интерфейсы для расширения системы.
|
||||||
* `Models/` — Базовые сущности дерева (узлы, направления, ориентация).
|
* `Models/` — Базовые сущности дерева (узлы, направления, ориентация).
|
||||||
* `Engine/` — `LayoutManager`, реализующий логику трансформации дерева.
|
* `Services/` - Сервисы управления интерфейсом
|
||||||
* `Context/` — Сервисы управления активными состояниями и командами.
|
* `ContextService` - Сервис управления контекстом приложения.
|
||||||
|
* `LayoutService` - Сервис управления макетом.
|
||||||
|
* `NotificationService` - Сервис уведомлений.
|
||||||
* `Persistence/` — Логика сохранения макета в JSON.
|
* `Persistence/` — Логика сохранения макета в JSON.
|
||||||
|
|
||||||
## 🛠 Использование
|
## 🛠 Использование
|
||||||
@@ -29,20 +31,20 @@
|
|||||||
### Создание базового макета
|
### Создание базового макета
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var layoutManager = new LayoutManager();
|
var layoutService = new LayoutService();
|
||||||
|
|
||||||
// Создаем контентные узлы
|
// Создаем контентные узлы
|
||||||
var explorer = new ContentNode(new MyToolComponent("Solution Explorer", "Explorer"));
|
var explorer = new ContentNode(new MyToolComponent("Solution Explorer", "Explorer"));
|
||||||
var editor = new ContentNode(new MyDocumentComponent("Main.cs", "CodeEditor"));
|
var editor = new ContentNode(new MyDocumentComponent("Main.cs", "CodeEditor"));
|
||||||
|
|
||||||
// Устанавливаем редактор как корень
|
// Устанавливаем редактор как корень
|
||||||
layoutManager.SetRoot(editor);
|
layoutService.SetRoot(editor);
|
||||||
|
|
||||||
// Прикрепляем проводник слева от редактора
|
// Прикрепляем проводник слева от редактора
|
||||||
layoutManager.Dock(explorer, editor, DockDirection.Left);
|
layoutService.Dock(explorer, editor, DockDirection.Left);
|
||||||
|
|
||||||
//Переключение контекста
|
//Переключение контекста
|
||||||
var contextService = new ContextManager();
|
var contextService = new ContextService();
|
||||||
|
|
||||||
// Вызывается при активации вкладки в UI
|
// Вызывается при активации вкладки в UI
|
||||||
contextService.SetContext("CodeEditor");
|
contextService.SetContext("CodeEditor");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Lattice.Studio.Controls;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class LatticeStudioShell : UserControl
|
public sealed partial class LatticeStudioShell : UserControl
|
||||||
{
|
{
|
||||||
private ILayoutService? _layoutManager;
|
private ILayoutService? _layoutService;
|
||||||
private IContextService? _contextService;
|
private IContextService? _contextService;
|
||||||
private IEnumerable<ActionDefinition>? _allActions;
|
private IEnumerable<ActionDefinition>? _allActions;
|
||||||
|
|
||||||
@@ -50,17 +50,17 @@ public sealed partial class LatticeStudioShell : UserControl
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Èíèöèàëèçèðóåò îáîëî÷êó Studio è ñâÿçûâàåò å¸ ñ ñåðâèñàìè Lattice.Core.
|
/// Èíèöèàëèçèðóåò îáîëî÷êó Studio è ñâÿçûâàåò å¸ ñ ñåðâèñàìè Lattice.Core.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="layoutManager">Ýêçåìïëÿð ILayoutService äëÿ óïðàâëåíèÿ îêíàìè.</param>
|
/// <param name="layoutService">Ýêçåìïëÿð ILayoutService äëÿ óïðàâëåíèÿ îêíàìè.</param>
|
||||||
/// <param name="contextService">Ýêçåìïëÿð IContextService äëÿ óïðàâëåíèÿ êíîïêàìè òóëáàðà.</param>
|
/// <param name="contextService">Ýêçåìïëÿð IContextService äëÿ óïðàâëåíèÿ êíîïêàìè òóëáàðà.</param>
|
||||||
/// <param name="actions">Ïîëíûé ñïèñîê îïðåäåëåíèé êîìàíä (ActionDefinition).</param>
|
/// <param name="actions">Ïîëíûé ñïèñîê îïðåäåëåíèé êîìàíä (ActionDefinition).</param>
|
||||||
public void Initialize(ILayoutService layoutManager, IContextService contextService, IEnumerable<ActionDefinition> actions)
|
public void Initialize(ILayoutService layoutService, IContextService contextService, IEnumerable<ActionDefinition> actions)
|
||||||
{
|
{
|
||||||
_layoutManager = layoutManager;
|
_layoutService = layoutService;
|
||||||
_contextService = contextService;
|
_contextService = contextService;
|
||||||
_allActions = actions;
|
_allActions = actions;
|
||||||
|
|
||||||
// Ñâÿçûâàåì âèçóàëüíûé õîñò äîêèíãà ñ ëîãè÷åñêèì äâèæêîì
|
// Ñâÿçûâàåì âèçóàëüíûé õîñò äîêèíãà ñ ëîãè÷åñêèì äâèæêîì
|
||||||
MainDockHost.Manager = _layoutManager;
|
MainDockHost.Service = _layoutService;
|
||||||
|
|
||||||
// Ïîäïèñûâàåìñÿ íà ñìåíó êîíòåêñòà (âûçûâàåòñÿ ïðè ïåðåêëþ÷åíèè âêëàäîê â Lattice.UI)
|
// Ïîäïèñûâàåìñÿ íà ñìåíó êîíòåêñòà (âûçûâàåòñÿ ïðè ïåðåêëþ÷åíèè âêëàäîê â Lattice.UI)
|
||||||
_contextService.ContextChanged += (s, newContext) =>
|
_contextService.ContextChanged += (s, newContext) =>
|
||||||
|
|||||||
@@ -14,26 +14,26 @@ public class LatticeDockHost : Control
|
|||||||
public DockAnchorOverlay? AnchorOverlay => GetTemplateChild("AnchorOverlay") as DockAnchorOverlay;
|
public DockAnchorOverlay? AnchorOverlay => GetTemplateChild("AnchorOverlay") as DockAnchorOverlay;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Определяет свойство зависимости для LayoutManager.
|
/// Определяет свойство зависимости для LayoutService.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly DependencyProperty ManagerProperty =
|
public static readonly DependencyProperty ServiceProperty =
|
||||||
DependencyProperty.Register(nameof(Manager), typeof(ILayoutService), typeof(LatticeDockHost), new PropertyMetadata(null, OnManagerChanged));
|
DependencyProperty.Register(nameof(Service), typeof(ILayoutService), typeof(LatticeDockHost), new PropertyMetadata(null, OnServiceChanged));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сервис управления макетом, привязанный к данному хосту.
|
/// Сервис управления макетом, привязанный к данному хосту.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ILayoutService? Manager
|
public ILayoutService? Service
|
||||||
{
|
{
|
||||||
get => (ILayoutService?)GetValue(ManagerProperty);
|
get => (ILayoutService?)GetValue(ServiceProperty);
|
||||||
set => SetValue(ManagerProperty, value);
|
set => SetValue(ServiceProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Указывает конкретный узел, который должен стать корнем для этого хоста.
|
/// Указывает конкретный узел, который должен стать корнем для этого хоста.
|
||||||
/// Если null — используется Manager.Root.
|
/// Если null — используется Service.Root.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly DependencyProperty RootNodeProperty =
|
public static readonly DependencyProperty RootNodeProperty =
|
||||||
DependencyProperty.Register(nameof(RootNode), typeof(LayoutNode), typeof(LatticeDockHost), new PropertyMetadata(null, OnManagerChanged));
|
DependencyProperty.Register(nameof(RootNode), typeof(LayoutNode), typeof(LatticeDockHost), new PropertyMetadata(null, OnServiceChanged));
|
||||||
|
|
||||||
public LayoutNode? RootNode
|
public LayoutNode? RootNode
|
||||||
{
|
{
|
||||||
@@ -46,7 +46,7 @@ public class LatticeDockHost : Control
|
|||||||
this.DefaultStyleKey = typeof(LatticeDockHost);
|
this.DefaultStyleKey = typeof(LatticeDockHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnManagerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (d is LatticeDockHost host)
|
if (d is LatticeDockHost host)
|
||||||
{
|
{
|
||||||
@@ -86,8 +86,8 @@ public class LatticeDockHost : Control
|
|||||||
{
|
{
|
||||||
if (this.GetTemplateChild("LayoutPresenter") is ContentPresenter presenter)
|
if (this.GetTemplateChild("LayoutPresenter") is ContentPresenter presenter)
|
||||||
{
|
{
|
||||||
// Приоритет: сначала проверяем локальный RootNode, затем глобальный Manager.Root
|
// Приоритет: сначала проверяем локальный RootNode, затем глобальный Service.Root
|
||||||
var effectiveRoot = RootNode ?? Manager?.Root;
|
var effectiveRoot = RootNode ?? Service?.Root;
|
||||||
|
|
||||||
if (effectiveRoot != null)
|
if (effectiveRoot != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ namespace Lattice.UI.Controls;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LatticeFloatingWindowHost
|
public class LatticeFloatingWindowHost
|
||||||
{
|
{
|
||||||
private readonly ILayoutService _manager;
|
private readonly ILayoutService _service;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Инициализирует хост плавающих окон.
|
/// Инициализирует хост плавающих окон.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="manager">Общий менеджер макета приложения.</param>
|
/// <param name="service">Общий менеджер макета приложения.</param>
|
||||||
public LatticeFloatingWindowHost(ILayoutService manager)
|
public LatticeFloatingWindowHost(ILayoutService service)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,7 +33,7 @@ public class LatticeFloatingWindowHost
|
|||||||
// Создаем и настраиваем хост докинга для нового окна
|
// Создаем и настраиваем хост докинга для нового окна
|
||||||
var host = new LatticeDockHost
|
var host = new LatticeDockHost
|
||||||
{
|
{
|
||||||
Manager = _manager, // Передаем общий менеджер, чтобы дерево было синхронизировано
|
Service = _service, // Передаем общий менеджер, чтобы дерево было синхронизировано
|
||||||
RootNode = node, // Указываем хосту отображать ТОЛЬКО этот узел
|
RootNode = node, // Указываем хосту отображать ТОЛЬКО этот узел
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ public class LatticeSplitter : Control
|
|||||||
{
|
{
|
||||||
// Вызываем метод перерисовки (в Core это может быть событие LayoutUpdated)
|
// Вызываем метод перерисовки (в Core это может быть событие LayoutUpdated)
|
||||||
// В нашем случае это заставит LayoutPanel пересчитать Column/Row Definitions
|
// В нашем случае это заставит LayoutPanel пересчитать Column/Row Definitions
|
||||||
host.Manager?.Dock(null!, null!, DockDirection.Center); // Фиктивный вызов для обновления
|
host.Service?.Dock(null!, null!, DockDirection.Center); // Фиктивный вызов для обновления
|
||||||
// Или если есть прямой доступ: host.Manager.InvokeLayoutUpdated();
|
// Или если есть прямой доступ: host.Service.InvokeLayoutUpdated();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parent = VisualTreeHelper.GetParent(parent);
|
parent = VisualTreeHelper.GetParent(parent);
|
||||||
|
|||||||
@@ -125,10 +125,10 @@ public class DockTabHandler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void CompleteDocking()
|
private void CompleteDocking()
|
||||||
{
|
{
|
||||||
if (_sourceNode != null && _targetNode != null && _host.Manager != null)
|
if (_sourceNode != null && _targetNode != null && _host.Service != null)
|
||||||
{
|
{
|
||||||
// Вызываем логику перестроения дерева в Lattice.Core
|
// Вызываем логику перестроения дерева в Lattice.Core
|
||||||
_host.Manager.Dock(_sourceNode, _targetNode, _currentSide);
|
_host.Service.Dock(_sourceNode, _targetNode, _currentSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очистка UI
|
// Очистка UI
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class LayoutPanel : Grid
|
|||||||
|
|
||||||
pane.CloseClick += (s, e) =>
|
pane.CloseClick += (s, e) =>
|
||||||
{
|
{
|
||||||
_host.Manager?.Remove(node);
|
_host.Service?.Remove(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Children.Add(pane);
|
this.Children.Add(pane);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
xmlns:lattice="using:Lattice.UI.Controls">
|
xmlns:lattice="using:Lattice.UI.Controls">
|
||||||
|
|
||||||
<lattice:LatticeDockHost x:Name="MainHost"
|
<lattice:LatticeDockHost x:Name="MainHost"
|
||||||
Manager="{x:Bind ViewModel.LayoutManager}" />
|
Service="{x:Bind ViewModel.LayoutService}" />
|
||||||
</Window>
|
</Window>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user