| 1 | #nullable enable |
| 2 | |
| 3 | using System.ComponentModel; |
| 4 | using CascadeIDE.Features.Chat; |
| 5 | using CascadeIDE.Features.Cockpit.Application; |
| 6 | using CascadeIDE.IdeDisplay.CockpitCommandLine; |
| 7 | using CascadeIDE.Models; |
| 8 | using CascadeIDE.Models.Shell; |
| 9 | using CommunityToolkit.Mvvm.ComponentModel; |
| 10 | |
| 11 | namespace CascadeIDE.ViewModels; |
| 12 | |
| 13 | /// <summary>Presentation Cockpit Command Line overlay (editor host, ADR 0120 / IDS 0079).</summary> |
| 14 | public sealed partial class CockpitCommandLineOverlayViewModel : ObservableObject |
| 15 | { |
| 16 | private readonly CockpitCommandLineSurfaceCompositor _surfaceCompositor = new(); |
| 17 | private readonly Func<PrimaryWorkSurfaceKind> _getPrimaryWorkSurface; |
| 18 | private readonly Func<CommandPaletteHost> _getCommandPaletteHost; |
| 19 | |
| 20 | public CockpitCommandLineOverlayViewModel( |
| 21 | ChatPanelViewModel chatPanel, |
| 22 | Func<PrimaryWorkSurfaceKind> getPrimaryWorkSurface, |
| 23 | Func<CommandPaletteHost> getCommandPaletteHost) |
| 24 | { |
| 25 | ChatPanel = chatPanel; |
| 26 | _getPrimaryWorkSurface = getPrimaryWorkSurface; |
| 27 | _getCommandPaletteHost = getCommandPaletteHost; |
| 28 | ChatPanel.PropertyChanged += OnChatPanelPropertyChanged; |
| 29 | RefreshCockpitCommandLineSurfaceSnapshot(); |
| 30 | } |
| 31 | |
| 32 | public ChatPanelViewModel ChatPanel { get; } |
| 33 | |
| 34 | public CockpitCommandLineSurfaceSnapshot CockpitCommandLineSurfaceSnapshot { get; private set; } = |
| 35 | CockpitCommandLineSurfaceSnapshot.Empty; |
| 36 | |
| 37 | public bool IsOverlayVisible(CommandPaletteHost currentTopLevelHost) => |
| 38 | CockpitCommandLineHostPolicy.ShouldShowEditorOverlay( |
| 39 | ChatPanel.IsCockpitCommandLineOpen, |
| 40 | ChatPanel.CommandLineSession.ActiveHost, |
| 41 | _getPrimaryWorkSurface(), |
| 42 | _getCommandPaletteHost(), |
| 43 | currentTopLevelHost); |
| 44 | |
| 45 | private void OnChatPanelPropertyChanged(object? sender, PropertyChangedEventArgs e) |
| 46 | { |
| 47 | if (e.PropertyName is nameof(ChatPanelViewModel.IsCockpitCommandLineOpen) |
| 48 | or nameof(ChatPanelViewModel.CockpitCommandLineText) |
| 49 | or nameof(ChatPanelViewModel.CockpitCommandLineCaretIndex) |
| 50 | or nameof(ChatPanelViewModel.CommandLineSlashPreview) |
| 51 | or nameof(ChatPanelViewModel.IsChatSlashAutocompleteVisible) |
| 52 | or nameof(ChatPanelViewModel.SelectedChatSlashSuggestionIndex) |
| 53 | or nameof(ChatPanelViewModel.ChatSlashBreadcrumb) |
| 54 | or nameof(ChatPanelViewModel.ComposerPopupSuggestions)) |
| 55 | { |
| 56 | RefreshCockpitCommandLineSurfaceSnapshot(); |
| 57 | OnPropertyChanged(string.Empty); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | public void NotifyShellPresentationChanged() => OnPropertyChanged(nameof(IsOverlayVisible)); |
| 62 | |
| 63 | internal void RefreshCockpitCommandLineSurfaceSnapshot() |
| 64 | { |
| 65 | if (!ChatPanel.IsCockpitCommandLineOpen) |
| 66 | { |
| 67 | CockpitCommandLineSurfaceSnapshot = CockpitCommandLineSurfaceSnapshot.Empty; |
| 68 | OnPropertyChanged(nameof(CockpitCommandLineSurfaceSnapshot)); |
| 69 | return; |
| 70 | } |
| 71 | |
| 72 | var suggestions = ChatPanel.ComposerPopupSuggestions |
| 73 | .Select(s => new CockpitCommandLineSuggestionRow(s.ListTitle, s.ListSubtitle)) |
| 74 | .ToArray(); |
| 75 | |
| 76 | var intent = new CockpitCommandLineSurfaceIntent( |
| 77 | ChatPanel.CockpitCommandLineText, |
| 78 | ChatPanel.CockpitCommandLineCaretIndex, |
| 79 | ChatPanel.SelectedChatSlashSuggestionIndex, |
| 80 | ChatPanel.ChatSlashBreadcrumb, |
| 81 | ChatPanel.IsChatSlashAutocompleteVisible, |
| 82 | suggestions); |
| 83 | |
| 84 | CockpitCommandLineSurfaceSnapshot = _surfaceCompositor.Compose(intent); |
| 85 | OnPropertyChanged(nameof(CockpitCommandLineSurfaceSnapshot)); |
| 86 | } |
| 87 | } |
| 88 | |