Forge
csharpdeeb25a2
1#nullable enable
2using CascadeIDE.Cockpit.Graph;
3using CascadeIDE.Cockpit.Graph.Layout;
4using CascadeIDE.Models;
5using CascadeIDE.Services.CodeNavigation;
6using CascadeIDE.Services.SkiaInstruments;
7using CascadeIDE.ViewModels;
8
9namespace CascadeIDE.Features.WorkspaceNavigation.Application;
10
11/// <summary>Композитор graph-backed карты намерений (Intent → Declutter → Layout), ADR 0055 / 0115.</summary>
12public sealed class CodeNavigationMapCompositor : ICodeNavigationMapCompositor
13{
14 public const double DefaultWidth = GraphViewportMetrics.DefaultWidth;
15 public const double DefaultHeightFile = GraphViewportMetrics.DefaultHeightFile;
16 public const double DefaultHeightControlFlow = GraphViewportMetrics.DefaultHeightControlFlow;
17 public const double MaxHeightControlFlow = GraphViewportMetrics.MaxHeightControlFlow;
18
19 private readonly ICodeNavigationMapIntentStage _intentStage;
20 private readonly ICodeNavigationMapDeclutterStage _declutterStage;
21 private readonly ICodeNavigationMapLayoutStage _layoutStage;
22
23 public CodeNavigationMapCompositor(
24 Func<string, IGraphLayoutEngine>? fileLayoutResolver = null,
25 IGraphLayoutEngine? controlFlowLayout = null,
26 ICodeNavigationMapIntentStage? intentStage = null,
27 ICodeNavigationMapDeclutterStage? declutterStage = null,
28 ICodeNavigationMapLayoutStage? layoutStage = null)
29 {
30 _intentStage = intentStage ?? new CodeNavigationMapIntentStage();
31 _declutterStage = declutterStage ?? new CodeNavigationMapDeclutterStage(_intentStage);
32 _layoutStage = layoutStage ?? new CodeNavigationMapLayoutStage(fileLayoutResolver, controlFlowLayout);
33 }
34
35 public CodeNavigationMapCompositionResult Compose(CodeNavigationMapCompositionIntent intent, in SkiaInstrumentViewport viewport)
36 {
37 var context = new CodeNavigationMapPipelineContext(
38 intent.Subgraph,
39 intent.MapLevel,
40 viewport,
41 intent.DetailLevel,
42 intent.RelatedGraphLayout,
43 intent.ControlFlowMainAxis);
44 var resolved = _intentStage.Resolve(context);
45 var decluttered = _declutterStage.Apply(resolved);
46 return WithCodeNavigationInstrumentBlocks(_layoutStage.Layout(decluttered), decluttered);
47 }
48
49 public CodeNavigationMapCompositionResult Compose(
50 GraphDocument doc,
51 string mapLevel,
52 double availableWidth,
53 double availableHeight,
54 CodeNavigationMapDetailLevel detailLevel = CodeNavigationMapDetailLevel.Normal)
55 {
56 var context = new CodeNavigationMapPipelineContext(
57 doc,
58 mapLevel,
59 new SkiaInstrumentViewport(availableWidth, availableHeight),
60 detailLevel,
61 CodeNavigationMapRelatedGraphLayoutKind.Radial,
62 CodeNavigationMapControlFlowMainAxisKind.Auto);
63 var resolved = _intentStage.Resolve(context);
64 var decluttered = _declutterStage.Apply(resolved);
65 return WithCodeNavigationInstrumentBlocks(_layoutStage.Layout(decluttered), decluttered);
66 }
67
68 private static CodeNavigationMapCompositionResult WithCodeNavigationInstrumentBlocks(
69 CodeNavigationMapCompositionResult laidOut,
70 in CodeNavigationMapPipelineState state)
71 {
72 var vw = state.Viewport.Width > 0 ? state.Viewport.Width : DefaultWidth;
73 var vh = laidOut.PreferredHeight;
74 var blocks = CodeNavigationMapInstrumentBlockCompositor.Compose(laidOut.ToSceneVm(vw, vh), vw, vh);
75 return laidOut with { CodeNavigationMapInstrumentBlocks = blocks };
76 }
77}
78
View only · write via MCP/CIDE