using Lattice.Core.Abstractions;
using Lattice.Core.Models;
using Lattice.Core.Models.Enums;
using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
namespace Lattice.Studio.Controls;
///
/// Основная оболочка приложения в стиле Visual Studio 2026.
/// Обеспечивает интеграцию нативного заголовка, системы докинга и контекстных команд.
///
public sealed partial class LatticeStudioShell : UserControl
{
private ILayoutService? _layoutService;
private IContextService? _contextService;
private IEnumerable? _allActions;
#region Dependency Properties (Слоты кастомизации)
public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register(nameof(Title), typeof(string), typeof(LatticeStudioShell), new PropertyMetadata("Lattice IDE"));
public string Subtitle { get => (string)GetValue(SubtitleProperty); set => SetValue(SubtitleProperty, value); }
public static readonly DependencyProperty SubtitleProperty =
DependencyProperty.Register(nameof(Subtitle), typeof(string), typeof(LatticeStudioShell), new PropertyMetadata(string.Empty));
public IconSource TitleBarIcon { get => (IconSource)GetValue(TitleBarIconProperty); set => SetValue(TitleBarIconProperty, value); }
public static readonly DependencyProperty TitleBarIconProperty =
DependencyProperty.Register(nameof(TitleBarIcon), typeof(IconSource), typeof(LatticeStudioShell), new PropertyMetadata(null));
public object MenuContent { get => GetValue(MenuContentProperty); set => SetValue(MenuContentProperty, value); }
public static readonly DependencyProperty MenuContentProperty =
DependencyProperty.Register(nameof(MenuContent), typeof(object), typeof(LatticeStudioShell), new PropertyMetadata(null));
public object StatusContent { get => GetValue(StatusContentProperty); set => SetValue(StatusContentProperty, value); }
public static readonly DependencyProperty StatusContentProperty =
DependencyProperty.Register(nameof(StatusContent), typeof(object), typeof(LatticeStudioShell), new PropertyMetadata(null));
#endregion
public LatticeStudioShell()
{
this.InitializeComponent();
}
///
/// Инициализирует оболочку Studio и связывает её с сервисами Lattice.Core.
///
/// Экземпляр ILayoutService для управления окнами.
/// Экземпляр IContextService для управления кнопками тулбара.
/// Полный список определений команд (ActionDefinition).
public void Initialize(ILayoutService layoutService, IContextService contextService, IEnumerable actions)
{
_layoutService = layoutService;
_contextService = contextService;
_allActions = actions;
// Связываем визуальный хост докинга с логическим движком
MainDockHost.Service = _layoutService;
// Подписываемся на смену контекста (вызывается при переключении вкладок в Lattice.UI)
_contextService.ContextChanged += (s, newContext) =>
{
// Обновляем тулбар в потоке пользовательского интерфейса
this.DispatcherQueue.TryEnqueue(() =>
{
StudioToolbar.UpdateItems(_allActions, newContext);
});
};
// Начальная инициализация тулбара текущим контекстом
StudioToolbar.UpdateItems(_allActions, _contextService.CurrentContext);
}
///
/// Настраивает интеграцию с нативным окном Windows 11 (TitleBar и Backdrop).
/// Вызывается из MainWindow приложения.
///
/// Текущее окно WinUI 3.
public void SetupWindow(Window window)
{
// 1. Расширяем контент в область заголовка (Windowing SDK 1.8)
window.ExtendsContentIntoTitleBar = true;
// 2. Указываем нативный TitleBar для управления перетаскиванием окна
if (AppTitleBar != null)
{
window.SetTitleBar(AppTitleBar);
}
// 3. Применяем Mica Alt для фона в стиле Visual Studio 2026
window.SystemBackdrop = new MicaBackdrop()
{
Kind = MicaKind.BaseAlt
};
}
///
/// Подключает сервис уведомлений к оболочке.
///
public void InitializeNotifications(INotificationService notificationService)
{
notificationService.NotificationReceived += (s, e) =>
{
this.DispatcherQueue.TryEnqueue(() =>
{
var infoBar = new InfoBar
{
Message = e.Message,
Severity = MapSeverity(e.Severity),
IsOpen = true,
Style = (Style)Application.Current.Resources["LatticeNotificationStyle"]
};
// Автоматическое закрытие
if (e.DurationSeconds > 0)
{
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(e.DurationSeconds)
};
timer.Tick += (st, et) => { infoBar.IsOpen = false; timer.Stop(); };
timer.Start();
}
// Удаление из памяти после закрытия
infoBar.CloseButtonClick += (sender, args) => NotificationArea.Children.Remove(infoBar);
NotificationArea.Children.Insert(0, infoBar); // Новые сверху
});
};
}
private InfoBarSeverity MapSeverity(NotificationSeverity severity) => severity switch
{
NotificationSeverity.Error => InfoBarSeverity.Error,
NotificationSeverity.Warning => InfoBarSeverity.Warning,
NotificationSeverity.Success => InfoBarSeverity.Success,
_ => InfoBarSeverity.Informational
};
}