DragAndDrop core

This commit is contained in:
FrigaT
2026-01-18 16:33:35 +03:00
parent 9ea82af329
commit 79bdd8bc62
229 changed files with 21214 additions and 2494 deletions

View File

@@ -0,0 +1,81 @@
using Lattice.Layout.Abstractions;
using Lattice.Layout.UI.WinUI.Controls;
using Lattice.Layout.UI.WinUI.Docking;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections.Generic;
using System.Linq;
namespace Lattice.Layout.UI.WinUI.Visuals;
/// <summary>
/// Визуальное представление группы вкладок для WinUI.
/// Управляет <see cref="WinUIGroupControl"/> и вкладками <see cref="TabViewItem"/>.
/// </summary>
public sealed class WinUIGroupVisual : LayoutVisual, IWinUIVisual
{
/// <summary>
/// Реальный WinUI-контрол группы вкладок.
/// </summary>
public WinUIGroupControl GroupControl { get; }
/// <summary>
/// Контрол, используемый докингом и рендерером.
/// </summary>
public FrameworkElement Control => GroupControl;
/// <summary>
/// Визуальные элементы вкладок.
/// </summary>
public IReadOnlyList<ILayoutVisual> Items { get; }
public WinUIGroupVisual(ILayoutGroup model, IReadOnlyList<ILayoutVisual> items)
: base(model)
{
Items = items;
GroupControl = new WinUIGroupControl();
}
/// <inheritdoc />
public override void Attach()
{
// Полная очистка
GroupControl.TabView.TabItems.Clear();
foreach (var visual in Items)
{
visual.Attach();
if (visual is WinUIItemVisual itemVisual)
{
var tab = new TabViewItem
{
Header = itemVisual.Header,
Content = itemVisual.Control // безопасно, т.к. Control — UserControl
};
GroupControl.TabView.TabItems.Add(tab);
}
}
// Активная вкладка по модели
if (Model is ILayoutGroup group && group.ActiveItem is not null)
{
var index = group.Items is IList<ILayoutItem> list
? list.IndexOf(group.ActiveItem)
: group.Items.ToList().IndexOf(group.ActiveItem);
if (index >= 0 && index < GroupControl.TabView.TabItems.Count)
GroupControl.TabView.SelectedIndex = index;
}
}
/// <inheritdoc />
public override void Detach()
{
foreach (var visual in Items)
visual.Detach();
GroupControl.TabView.TabItems.Clear();
}
}

View File

@@ -0,0 +1,51 @@
using Lattice.Layout.Abstractions;
using Lattice.Layout.UI.WinUI.Controls;
using Lattice.Layout.UI.WinUI.Docking;
using Microsoft.UI.Xaml;
namespace Lattice.Layout.UI.WinUI.Visuals;
/// <summary>
/// Визуальное представление конечного элемента раскладки для WinUI.
/// Оборачивает содержимое в <see cref="WinUIItemControl"/>.
/// </summary>
public sealed class WinUIItemVisual : LayoutVisual, IWinUIVisual
{
/// <summary>
/// Реальный WinUI-контрол, отображающий элемент.
/// </summary>
public WinUIItemControl ItemControl { get; }
/// <summary>
/// Контрол, используемый докингом и рендерером.
/// </summary>
public FrameworkElement Control => ItemControl;
/// <summary>
/// Заголовок вкладки или элемента.
/// </summary>
public string Header => ((ILayoutItem)Model).Title;
public WinUIItemVisual(ILayoutItem model)
: base(model)
{
ItemControl = new WinUIItemControl
{
ContentId = model.ContentId
};
}
/// <inheritdoc />
public override void Attach()
{
// Здесь можно привязать реальное содержимое по ContentId через Shell/Service.
// Например:
// ItemControl.Content = resolver(((ILayoutItem)Model).ContentId);
}
/// <inheritdoc />
public override void Detach()
{
ItemControl.Content = null;
}
}

View File

@@ -0,0 +1,82 @@
using Lattice.Layout.Abstractions;
using Lattice.Layout.UI.WinUI.Controls;
using Lattice.Layout.UI.WinUI.Docking;
using Microsoft.UI.Xaml;
using System.Collections.Generic;
namespace Lattice.Layout.UI.WinUI.Visuals;
/// <summary>
/// Визуальное представление сплит-элемента для WinUI.
/// Управляет жизненным циклом соответствующего <see cref="WinUISplitControl"/>.
/// </summary>
public sealed class WinUISplitVisual : LayoutVisual, IWinUIVisual
{
/// <summary>
/// Реальный WinUI-контрол, отображающий сплит.
/// </summary>
public WinUISplitControl SplitControl { get; }
/// <summary>
/// Контрол, используемый рендерером и докингом.
/// </summary>
public FrameworkElement Control => SplitControl;
/// <summary>
/// Дочерние визуальные элементы.
/// </summary>
public IReadOnlyList<ILayoutVisual> Children { get; }
public WinUISplitVisual(ILayoutSplit model, IReadOnlyList<ILayoutVisual> children)
: base(model)
{
Children = children;
SplitControl = new WinUISplitControl
{
LayoutOrientation = model.Orientation switch
{
Lattice.Layout.Abstractions.Orientation.Horizontal => Microsoft.UI.Xaml.Controls.Orientation.Horizontal,
Lattice.Layout.Abstractions.Orientation.Vertical => Microsoft.UI.Xaml.Controls.Orientation.Vertical,
_ => Microsoft.UI.Xaml.Controls.Orientation.Horizontal
}
};
}
/// <inheritdoc />
public override void Attach()
{
SplitControl.Children.Clear();
foreach (var child in Children)
{
child.Attach();
switch (child)
{
case WinUISplitVisual splitVisual:
SplitControl.Children.Add(splitVisual.Control);
break;
case WinUIGroupVisual groupVisual:
SplitControl.Children.Add(groupVisual.Control);
break;
case WinUIItemVisual itemVisual:
SplitControl.Children.Add(itemVisual.Control);
break;
}
}
SplitControl.RebuildGrid();
}
/// <inheritdoc />
public override void Detach()
{
foreach (var child in Children)
child.Detach();
SplitControl.Children.Clear();
}
}