Forge
csharpdeeb25a2
1#nullable enable
2
3using System.ComponentModel;
4using CascadeIDE.Features.Chat;
5using CascadeIDE.Features.Cockpit.Application;
6using CascadeIDE.IdeDisplay.CockpitCommandLine;
7using CascadeIDE.Models;
8using CascadeIDE.Models.Shell;
9using CommunityToolkit.Mvvm.ComponentModel;
10
11namespace CascadeIDE.ViewModels;
12
13/// <summary>Presentation Cockpit Command Line overlay (editor host, ADR 0120 / IDS 0079).</summary>
14public 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
View only · write via MCP/CIDE