Forge
csharpdeeb25a2
1#nullable enable
2using Avalonia;
3
4namespace CascadeIDE.Cockpit.Graph.Layout;
5
6/// <summary>
7/// Уложенная сцена graph-backed surface: геометрия узлов/рёбер для Render-слоя (ADR 0055, 0067).
8/// Не зависит от ViewModels; источник — layout stage после <see cref="GraphDocument"/>.
9/// </summary>
10public sealed class GraphLayoutScene
11{
12 public required IReadOnlyList<GraphLayoutNode> Nodes { get; init; }
13 public required IReadOnlyList<GraphLayoutEdge> Edges { get; init; }
14
15 public GraphLayoutPresentation Presentation { get; init; } = GraphLayoutPresentation.CodeControlFlow;
16 public IReadOnlyList<GraphLegendEntry> Legend { get; init; } = [];
17 public bool UseLegendColumn { get; init; }
18 public bool ShowLegendConditionKey { get; init; }
19 public bool ShowLegendReturnKey { get; init; }
20 public bool ShowLegendExceptionFlowKey { get; init; }
21 public bool ShowLegendEdgeStyleKey { get; init; }
22 public double LegendColumnLeft { get; init; } = double.PositiveInfinity;
23 public GraphLegendBlockPlacement LegendPlacement { get; init; } = GraphLegendBlockPlacement.BesideGraph;
24 public double LegendBlockTopY { get; init; }
25 public IReadOnlySet<string> HighlightedNodeIds { get; init; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
26 public IReadOnlySet<string> HighlightedEdgeKeys { get; init; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
27 public double? SideLabelFontSizePx { get; init; }
28
29 /// <summary>Номера шагов на узлах без колонки легенды (code anchor UX).</summary>
30 public bool ShowNodeLegendGlyphs { get; init; }
31
32 /// <summary>Укладка related-files (<c>radial</c> | <c>top_down</c> | <c>bottom_up</c>); только для <see cref="GraphLayoutPresentation.WorkspaceRelatedFiles"/>.</summary>
33 public string RelatedFilesLayout { get; init; } = Models.CodeNavigationMapRelatedGraphLayoutKind.Radial;
34
35 /// <summary>CFG: главная ось потока (автовыбор в <see cref="ControlFlowGraphLayoutEngine"/>).</summary>
36 public GraphControlFlowMainAxis ControlFlowMainAxis { get; init; } = GraphControlFlowMainAxis.Vertical;
37
38 public bool IsEmpty => Nodes.Count == 0;
39
40 public GraphLayoutScene WithPresentation(GraphLayoutPresentation presentation)
41 {
42 if (Presentation == presentation)
43 return this;
44 return new GraphLayoutScene
45 {
46 Nodes = Nodes,
47 Edges = Edges,
48 Presentation = presentation,
49 Legend = Legend,
50 UseLegendColumn = UseLegendColumn,
51 ShowLegendConditionKey = ShowLegendConditionKey,
52 ShowLegendReturnKey = ShowLegendReturnKey,
53 ShowLegendExceptionFlowKey = ShowLegendExceptionFlowKey,
54 ShowLegendEdgeStyleKey = ShowLegendEdgeStyleKey,
55 LegendColumnLeft = LegendColumnLeft,
56 LegendPlacement = LegendPlacement,
57 LegendBlockTopY = LegendBlockTopY,
58 HighlightedNodeIds = HighlightedNodeIds,
59 HighlightedEdgeKeys = HighlightedEdgeKeys,
60 SideLabelFontSizePx = SideLabelFontSizePx,
61 ShowNodeLegendGlyphs = ShowNodeLegendGlyphs,
62 RelatedFilesLayout = RelatedFilesLayout,
63 ControlFlowMainAxis = ControlFlowMainAxis
64 };
65 }
66}
67
68public sealed class GraphLegendEntry
69{
70 public int Index { get; init; }
71 public required string Text { get; init; }
72}
73
74public sealed class GraphLayoutNode
75{
76 public required string Id { get; init; }
77 public required string Kind { get; init; }
78 public required string FullPath { get; init; }
79 public required string Label { get; init; }
80 public required Point Center { get; init; }
81 public required double Radius { get; init; }
82 public required bool IsAnchor { get; init; }
83 public GraphNodeShape Shape { get; init; } = GraphNodeShape.Circle;
84 public int? LegendIndex { get; init; }
85 public string? LegendLine { get; init; }
86 public int? LineStart { get; init; }
87 public int? LineEnd { get; init; }
88 /// <summary>Тот же id, что у <see cref="GraphNode.LoopGroupId"/>; овал на миникарте группирует по этому значению.</summary>
89 public int? LoopGroupId { get; init; }
90}
91
92public sealed class GraphLayoutEdge
93{
94 public required string FromNodeId { get; init; }
95 public required string ToNodeId { get; init; }
96 public required Point From { get; init; }
97 public required Point To { get; init; }
98 public required double ToRadius { get; init; }
99 public string? Kind { get; init; }
100 public string? RelationKind { get; init; }
101 public string? EdgeProvenance { get; init; }
102 public string? BranchLabel { get; init; }
103
104 public string Key => $"{FromNodeId}->{ToNodeId}";
105}
106
View only · write via MCP/CIDE