Forge
csharp4405de34
1#nullable enable
2using Avalonia;
3using CascadeIDE.ViewModels;
4
5namespace CascadeIDE.Services.Navigation;
6
7/// <summary>Стабильные id внутренних блоков прибора карты намерений (ADR 0088 §2.4) — не путать с <c>cell_id</c> deck региона.</summary>
8public static class CodeNavigationMapWorkspaceInstrumentBlockIds
9{
10 public const string Graph = "code_navigation.workspace_instrument.block.graph";
11 public const string Legend = "code_navigation.workspace_instrument.block.legend";
12}
13
14/// <summary>Вид внутреннего блока кабинного прибора карты намерений.</summary>
15public enum CodeNavigationMapWorkspaceInstrumentBlockKind
16{
17 /// <summary>Подграф (узлы, рёбра) в зарезервированной области графа.</summary>
18 Graph = 0,
19
20 /// <summary>Легенда (индексы шагов, ключи фигур, стили рёбер).</summary>
21 Legend = 1
22}
23
24/// <summary>Размещение одного внутреннего блока в системе координат мини-карты (0,0 — левый верх вьюпорта).</summary>
25public sealed record CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
26 string Id,
27 CodeNavigationMapWorkspaceInstrumentBlockKind Kind,
28 Rect Bounds)
29{
30 public bool IsEmpty => Bounds.Width <= 0 || Bounds.Height <= 0;
31}
32
33/// <summary>
34/// Композитор <b>внутренних</b> блоков прибора: по уже уложенной <see cref="CodeNavigationMapGraphSceneVm"/> и размеру вьюпорта
35/// вычисляет осмысленные прямоугольники «граф / легенда» (тот же смысл, что разнесение в <see cref="Cockpit.PrimitivesKit.CodeNavigationMapSceneDrawing"/>).
36/// </summary>
37public static class CodeNavigationMapWorkspaceInstrumentBlockCompositor
38{
39 public static IReadOnlyList<CodeNavigationMapWorkspaceInstrumentBlockDescriptor> Compose(
40 CodeNavigationMapGraphSceneVm scene,
41 double viewportWidth,
42 double viewportHeight)
43 {
44 if (scene.IsEmpty || viewportWidth <= 0 || viewportHeight <= 0)
45 return Array.Empty<CodeNavigationMapWorkspaceInstrumentBlockDescriptor>();
46
47 if (!scene.UseLegendColumn)
48 {
49 return
50 [
51 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
52 CodeNavigationMapWorkspaceInstrumentBlockIds.Graph,
53 CodeNavigationMapWorkspaceInstrumentBlockKind.Graph,
54 new Rect(0, 0, viewportWidth, viewportHeight))
55 ];
56 }
57
58 if (scene.LegendPlacement == CodeNavigationMapLegendBlockPlacement.BelowGraph
59 && scene.LegendBlockTopY > 0
60 && scene.LegendBlockTopY < viewportHeight)
61 {
62 var graphH = Math.Min(scene.LegendBlockTopY, viewportHeight);
63 return
64 [
65 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
66 CodeNavigationMapWorkspaceInstrumentBlockIds.Graph,
67 CodeNavigationMapWorkspaceInstrumentBlockKind.Graph,
68 new Rect(0, 0, viewportWidth, graphH)),
69 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
70 CodeNavigationMapWorkspaceInstrumentBlockIds.Legend,
71 CodeNavigationMapWorkspaceInstrumentBlockKind.Legend,
72 new Rect(0, scene.LegendBlockTopY, viewportWidth, viewportHeight - scene.LegendBlockTopY))
73 ];
74 }
75
76 // Соседняя колонка: легенда справа от <see cref="CodeNavigationMapGraphSceneVm.LegendColumnLeft"/>
77 var legendX = Math.Min(scene.LegendColumnLeft, viewportWidth);
78 if (legendX >= viewportWidth - 1)
79 {
80 return
81 [
82 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
83 CodeNavigationMapWorkspaceInstrumentBlockIds.Graph,
84 CodeNavigationMapWorkspaceInstrumentBlockKind.Graph,
85 new Rect(0, 0, viewportWidth, viewportHeight))
86 ];
87 }
88
89 var graphW = Math.Max(0, legendX);
90 return
91 [
92 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
93 CodeNavigationMapWorkspaceInstrumentBlockIds.Graph,
94 CodeNavigationMapWorkspaceInstrumentBlockKind.Graph,
95 new Rect(0, 0, graphW, viewportHeight)),
96 new CodeNavigationMapWorkspaceInstrumentBlockDescriptor(
97 CodeNavigationMapWorkspaceInstrumentBlockIds.Legend,
98 CodeNavigationMapWorkspaceInstrumentBlockKind.Legend,
99 new Rect(legendX, 0, viewportWidth - legendX, viewportHeight))
100 ];
101 }
102}
103
View only · write via MCP/CIDE