using Lattice.UI.Docking.Abstractions; using Lattice.UI.Docking.Services; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System; using System.Threading.Tasks; namespace Lattice.UI.Docking.WinUI.Services; /// /// Реализация UI-сервиса для WinUI. /// public sealed class WinUIDockUIService : DockUIServiceBase { /// public override object CreateMainWindow(IDockHost host) { if (host is not FrameworkElement hostElement) throw new ArgumentException("Host must be a FrameworkElement", nameof(host)); var window = new Window(); window.Content = hostElement; window.AppWindow.Title = "Lattice IDE"; // Регистрируем окно в трекере Themes.WindowTracker.Register(window); return window; } /// public override bool? ShowDialog(string title, object content) { if (content is not FrameworkElement contentElement) return null; var dialog = new ContentDialog { Title = title, Content = contentElement, PrimaryButtonText = "OK", CloseButtonText = "Cancel", XamlRoot = GetActiveXamlRoot() }; // Показываем диалог и возвращаем результат var result = dialog.ShowAsync(); return result.GetAwaiter().GetResult() switch { ContentDialogResult.Primary => true, ContentDialogResult.Secondary => false, _ => null }; } /// public override void ShowMessage(string message, string caption) { var dialog = new ContentDialog { Title = caption, Content = new TextBlock { Text = message }, PrimaryButtonText = "OK", XamlRoot = GetActiveXamlRoot() }; dialog.ShowAsync(); } /// public override bool Confirm(string message, string caption) { var dialog = new ContentDialog { Title = caption, Content = new TextBlock { Text = message }, PrimaryButtonText = "Yes", SecondaryButtonText = "No", XamlRoot = GetActiveXamlRoot() }; var result = dialog.ShowAsync().GetAwaiter().GetResult(); return result == ContentDialogResult.Primary; } /// public override string? Prompt(string prompt, string? defaultValue = null) { var textBox = new TextBox { Text = defaultValue ?? string.Empty, Width = 300, Height = 32 }; var dialog = new ContentDialog { Title = prompt, Content = textBox, PrimaryButtonText = "OK", SecondaryButtonText = "Cancel", XamlRoot = GetActiveXamlRoot() }; var result = dialog.ShowAsync().GetAwaiter().GetResult(); return result == ContentDialogResult.Primary ? textBox.Text : null; } /// public override void InvokeOnUIThread(Action action) { if (action == null) return; var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread(); if (dispatcherQueue.HasThreadAccess) { action(); } else { dispatcherQueue.TryEnqueue(() => action()); } } /// public override async Task InvokeOnUIThreadAsync(Func action) { if (action == null) return; var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread(); if (dispatcherQueue.HasThreadAccess) { await action(); } else { var tcs = new TaskCompletionSource(); dispatcherQueue.TryEnqueue(async () => { try { await action(); tcs.SetResult(true); } catch (Exception ex) { tcs.SetException(ex); } }); await tcs.Task; } } private XamlRoot? GetActiveXamlRoot() { // Получаем XamlRoot из активного окна foreach (var window in Themes.WindowTracker.Windows) { if (window.Content is FrameworkElement element) { return element.XamlRoot; } } return null; } }