DragAndDrop core
This commit is contained in:
134
Lattice.Layout.UI.WinUI/Controls/WinUILayoutHost.cs
Normal file
134
Lattice.Layout.UI.WinUI/Controls/WinUILayoutHost.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using Lattice.Layout.Abstractions;
|
||||
using Lattice.Layout.UI.Docking;
|
||||
using Lattice.Layout.UI.WinUI.Docking;
|
||||
using Lattice.Layout.UI.WinUI.Rendering;
|
||||
using Lattice.Layout.UI.WinUI.Visuals;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
|
||||
namespace Lattice.Layout.UI.WinUI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// WinUI-контрол, отображающий дерево раскладки.
|
||||
/// Оборачивает LayoutRenderer и размещает визуальное дерево внутри себя.
|
||||
/// </summary>
|
||||
public sealed class WinUILayoutHost : UserControl, ILayoutView
|
||||
{
|
||||
/// <summary>
|
||||
/// Слой, в котором размещается визуальное дерево раскладки.
|
||||
/// </summary>
|
||||
public Grid LayoutLayer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Слой для отображения подсветки зон докинга.
|
||||
/// </summary>
|
||||
public DockOverlayHost OverlayLayer { get; }
|
||||
|
||||
private readonly LayoutRenderer _renderer;
|
||||
private readonly WinUIVisualFactory _factory;
|
||||
|
||||
/// <summary>
|
||||
/// Функция, возвращающая UI-содержимое по ContentId.
|
||||
/// Используется визуальными элементами для подстановки реального контрола.
|
||||
/// </summary>
|
||||
public Func<string, UIElement>? ContentResolver { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Корневой элемент раскладки, который необходимо отобразить.
|
||||
/// </summary>
|
||||
public ILayoutRoot? Root
|
||||
{
|
||||
get => (ILayoutRoot?)GetValue(RootProperty);
|
||||
set => SetValue(RootProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Свойство зависимости для <see cref="Root"/>.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty RootProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(Root),
|
||||
typeof(ILayoutRoot),
|
||||
typeof(WinUILayoutHost),
|
||||
new PropertyMetadata(null, OnRootChanged));
|
||||
|
||||
private static void OnRootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is WinUILayoutHost host)
|
||||
{
|
||||
host.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создаёт новый экземпляр <see cref="WinUILayoutHost"/>.
|
||||
/// </summary>
|
||||
public WinUILayoutHost()
|
||||
{
|
||||
LayoutLayer = new Grid();
|
||||
OverlayLayer = new DockOverlayHost();
|
||||
|
||||
var rootGrid = new Grid();
|
||||
rootGrid.Children.Add(LayoutLayer);
|
||||
rootGrid.Children.Add(OverlayLayer);
|
||||
|
||||
Content = rootGrid;
|
||||
|
||||
_factory = new WinUIVisualFactory();
|
||||
_renderer = new LayoutRenderer(_factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выполняет полную перерисовку визуального дерева.
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
LayoutLayer.Children.Clear();
|
||||
|
||||
if (Root?.Child is null)
|
||||
return;
|
||||
|
||||
var visual = _renderer.Build(Root.Child);
|
||||
visual.Attach();
|
||||
|
||||
switch (visual)
|
||||
{
|
||||
case WinUISplitVisual splitVisual:
|
||||
LayoutLayer.Children.Add(splitVisual.Control);
|
||||
break;
|
||||
|
||||
case WinUIGroupVisual groupVisual:
|
||||
LayoutLayer.Children.Add(groupVisual.Control);
|
||||
break;
|
||||
|
||||
case WinUIItemVisual itemVisual:
|
||||
LayoutLayer.Children.Add(itemVisual.Control);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Показывает подсветку зоны докинга для указанной цели.
|
||||
/// </summary>
|
||||
public void ShowDockOverlay(DockTarget target)
|
||||
{
|
||||
if (target.Visual is not IWinUIVisual winuiVisual)
|
||||
return;
|
||||
|
||||
var control = winuiVisual.Control;
|
||||
|
||||
var bounds = control.TransformToVisual(LayoutLayer)
|
||||
.TransformBounds(new Windows.Foundation.Rect(0, 0, control.ActualWidth, control.ActualHeight));
|
||||
|
||||
OverlayLayer.ShowOverlay(target, bounds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Скрывает подсветку зон докинга.
|
||||
/// </summary>
|
||||
public void HideDockOverlay()
|
||||
{
|
||||
OverlayLayer.HideOverlay();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user