Forge
csharpdeeb25a2
1using CascadeIDE.Cockpit.Cds;
2using CascadeIDE.Models;
3using CascadeIDE.Services.Presentation;
4
5namespace CascadeIDE.Cockpit.Composition.Shell;
6
7/// <summary>
8/// Композитор <b>оболочки</b> главного окна (ADR 0036 п.3): из intent + CDS policy + топологии хоста MFD
9/// получает видимость колонок и ширину региона MFD в <c>MainGrid</c> (не дерево контролов, не данные каналов).
10/// Полный кадр для хоста (колонки + инструменты слотов) — <c>MainWindowHostSurfaceCompositor</c> в <c>Cockpit/Composition/HostSurface</c>.
11/// </summary>
12public static class MainWindowShellSurfaceCompositor
13{
14 public static MainWindowShellSurfaceComposition Compose(in MainWindowShellSurfaceCompositionInput input)
15 {
16 if (input.EffectivePresentationTier == PresentationTierKind.Compact)
17 return ComposeCompact(input);
18
19 return ComposeCockpit(input);
20 }
21
22 private static MainWindowShellSurfaceComposition ComposeCompact(in MainWindowShellSurfaceCompositionInput input)
23 {
24 var presentation = input.DisplaySettings.Presentation;
25 var placement = presentation.CompactIntercomPlacement?.Trim() ?? "side";
26 var sideIntercom = !string.Equals(placement, "bottom", StringComparison.OrdinalIgnoreCase);
27 var chatExpanded = input.IntentChatPanelExpanded && !input.SuppressMfdColumnForMfdHostWindow;
28 var intercomAuxVisible = sideIntercom && chatExpanded;
29 var intercomBottomVisible = !sideIntercom && chatExpanded;
30
31 var intercomWidth = intercomAuxVisible
32 ? Math.Max(
33 input.CollapsedMfdWidthPixels,
34 presentation.CompactAuxiliaryPanelWidthPx)
35 : 0;
36
37 var pfdRightVisible = input.IntentSolutionExplorerVisible
38 && !input.SuppressPfdColumnForPfdHostWindow;
39 var pfdRightWidth = pfdRightVisible
40 ? CompactIdeLayoutMetrics.PfdRightColumnWidthPixels
41 : 0;
42
43 var rightChromeWidth = Math.Max(intercomWidth, pfdRightWidth);
44
45 return new MainWindowShellSurfaceComposition(
46 PfdSurfaceVisible: false,
47 MfdSurfaceExpanded: input.IntentChatPanelExpanded,
48 MfdColumnVisibleInMainGrid: false,
49 MfdColumnPixelWidthInMainGrid: 0,
50 CompactIdeLayout: true,
51 IntercomAuxColumnVisible: intercomAuxVisible,
52 IntercomAuxColumnPixelWidth: intercomWidth,
53 IntercomBottomDockVisible: intercomBottomVisible,
54 IntercomBottomDockHeightPx: presentation.CompactIntercomBottomDockHeightPx,
55 PfdRightColumnVisible: pfdRightVisible,
56 PfdRightColumnPixelWidth: pfdRightWidth,
57 CompactRightChromeColumnVisible: intercomAuxVisible || pfdRightVisible,
58 CompactRightChromeColumnPixelWidth: rightChromeWidth,
59 MfdBottomDockHeightPx: presentation.CompactMfdBottomDockHeightPx);
60 }
61
62 private static MainWindowShellSurfaceComposition ComposeCockpit(in MainWindowShellSurfaceCompositionInput input)
63 {
64 var tier = input.EffectivePresentationTier;
65 var presentationSpecifiesScreens = input.PresentationParse.IsSuccess && input.PresentationParse.Screens.Count > 0;
66 var pfdRequiredOnMain = !presentationSpecifiesScreens
67 || CockpitPresentationLayoutPolicy.RequiresPfdRegionInMainWindow(input.PresentationParse, tier);
68 var pfdCoerced = CockpitPresentationLayoutPolicy.CoercePfdRegionExpanded(
69 input.PresentationParse,
70 tier,
71 input.IntentSolutionExplorerVisible);
72 var pfdVisible = pfdRequiredOnMain && pfdCoerced && !input.SuppressPfdColumnForPfdHostWindow;
73
74 var mfdRequiredOnMain = !presentationSpecifiesScreens
75 || CockpitPresentationLayoutPolicy.RequiresMfdRegionInMainWindow(input.PresentationParse, tier);
76 var mfdExpanded = CockpitPresentationLayoutPolicy.CoerceMfdRegionExpanded(
77 input.PresentationParse,
78 tier,
79 input.IntentChatPanelExpanded);
80
81 var mfdColumnInMain = mfdRequiredOnMain && !input.SuppressMfdColumnForMfdHostWindow && mfdExpanded;
82
83 var width = mfdColumnInMain
84 ? (mfdExpanded ? input.ExpandedMfdWidthPixels : input.CollapsedMfdWidthPixels)
85 : 0;
86
87 return new MainWindowShellSurfaceComposition(
88 PfdSurfaceVisible: pfdVisible,
89 MfdSurfaceExpanded: mfdExpanded,
90 MfdColumnVisibleInMainGrid: mfdColumnInMain,
91 MfdColumnPixelWidthInMainGrid: width);
92 }
93}
94
95/// <summary>Вход композитора: intent пользователя, пресет, подавление колонок PFD/MFD в main при открытых хостах, числа ширин из UI-режима.</summary>
96public readonly record struct MainWindowShellSurfaceCompositionInput(
97 PresentationParseResult PresentationParse,
98 bool IntentSolutionExplorerVisible,
99 bool IntentChatPanelExpanded,
100 bool SuppressPfdColumnForPfdHostWindow,
101 bool SuppressMfdColumnForMfdHostWindow,
102 int ExpandedMfdWidthPixels,
103 int CollapsedMfdWidthPixels,
104 DisplaySettings DisplaySettings,
105 string SafetyLevel,
106 PresentationTierKind EffectivePresentationTier = PresentationTierKind.Cockpit);
107
108/// <summary>Результат: что отдать слою поверхности (привязки VM / code-behind) для колонок PFD/MFD.</summary>
109public readonly record struct MainWindowShellSurfaceComposition(
110 bool PfdSurfaceVisible,
111 bool MfdSurfaceExpanded,
112 bool MfdColumnVisibleInMainGrid,
113 int MfdColumnPixelWidthInMainGrid,
114 bool CompactIdeLayout = false,
115 bool IntercomAuxColumnVisible = false,
116 int IntercomAuxColumnPixelWidth = 0,
117 bool IntercomBottomDockVisible = false,
118 int IntercomBottomDockHeightPx = CompactIdeLayoutMetrics.IntercomBottomDockDefaultHeightPixels,
119 bool PfdRightColumnVisible = false,
120 int PfdRightColumnPixelWidth = 0,
121 bool CompactRightChromeColumnVisible = false,
122 int CompactRightChromeColumnPixelWidth = 0,
123 int MfdBottomDockHeightPx = 220);
124
View only · write via MCP/CIDE