Forge
csharpdeeb25a2
1using System.Globalization;
2using Avalonia;
3using Avalonia.Media;
4using CascadeIDE.Models;
5using static CascadeIDE.Cockpit.PrimitivesKit.CockpitPrimitivesPalette.Annunciator;
6
7namespace CascadeIDE.Cockpit.PrimitivesKit;
8
9/// <summary>
10/// Стандартная ячейка annunciator: подпись и уровень <see cref="AnnunciatorLampLevel"/> (ADR 0021 §5, ADR 0063).
11/// </summary>
12public readonly record struct LabeledAnnunciatorLampFace(string ShortLabel, AnnunciatorLampLevel Level)
13{
14 public void Draw(DrawingContext context, Rect outerRect)
15 {
16 AnnunciatorLampChrome.DrawCellHousing(context, outerRect);
17
18 var lens = AnnunciatorLampChrome.ComputeFaceSquare(outerRect);
19
20 var isOff = Level == AnnunciatorLampLevel.Ok;
21 if (lens.Width > 1 && lens.Height > 1)
22 {
23 if (isOff)
24 {
25 var offBrush = new LinearGradientBrush
26 {
27 StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
28 EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
29 GradientStops =
30 {
31 new GradientStop(OffLensTop, 0),
32 new GradientStop(OffLensBottom, 1),
33 },
34 };
35 context.DrawRectangle(offBrush, new Pen(new SolidColorBrush(OffLensBorder), 0.75), lens);
36 }
37 else
38 {
39 var lampFillColor = LitLens(Level);
40 var top = AnnunciatorLampChrome.Lighten(lampFillColor, 0.2);
41 var bottom = AnnunciatorLampChrome.Darken(lampFillColor, 0.24);
42 var lensBrush = new LinearGradientBrush
43 {
44 StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
45 EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
46 GradientStops =
47 {
48 new GradientStop(top, 0),
49 new GradientStop(lampFillColor, 0.48),
50 new GradientStop(bottom, 1),
51 },
52 };
53 context.DrawRectangle(lensBrush, new Pen(Brushes.Black, 0.75), lens);
54
55 var hlH = Math.Max(1.5, lens.Height * 0.22);
56 var highlight = new Rect(lens.X + 1, lens.Y + 1, lens.Width - 2, hlH);
57 context.DrawRectangle(new SolidColorBrush(Color.FromArgb(48, 255, 255, 255)), null, highlight);
58 }
59 }
60
61 IBrush fillBrush = isOff
62 ? new SolidColorBrush(OffLabelFill)
63 : Brushes.White;
64 var strokeBrush = isOff
65 ? new SolidColorBrush(OutlinedTextStrokeDim)
66 : new SolidColorBrush(OutlinedTextStrokeLit);
67
68 DrawLampShortLabel(context, outerRect, ShortLabel, fillBrush, strokeBrush);
69 }
70
71 private static void DrawLampShortLabel(
72 DrawingContext context,
73 Rect outerRect,
74 string shortLabel,
75 IBrush fillBrush,
76 IBrush strokeBrush)
77 {
78 var rawLines = shortLabel.Split('\n', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
79 var lines = rawLines.Length <= 2 ? rawLines : rawLines.Take(2).ToArray();
80 if (lines.Length == 0)
81 return;
82
83 if (lines.Length == 1)
84 {
85 var line = lines[0];
86 var ftFill = new FormattedText(
87 line,
88 CultureInfo.InvariantCulture,
89 FlowDirection.LeftToRight,
90 AnnunciatorLampChrome.LabelTypeface,
91 AnnunciatorLampMetrics.LabelFontSize,
92 fillBrush);
93 var ftStroke = new FormattedText(
94 line,
95 CultureInfo.InvariantCulture,
96 FlowDirection.LeftToRight,
97 AnnunciatorLampChrome.LabelTypeface,
98 AnnunciatorLampMetrics.LabelFontSize,
99 strokeBrush);
100 var origin = new Point(
101 outerRect.X + (outerRect.Width - ftFill.Width) / 2,
102 outerRect.Y + (outerRect.Height - ftFill.Height) / 2);
103 AnnunciatorLampChrome.DrawOutlinedText(context, ftStroke, ftFill, origin);
104 return;
105 }
106
107 const double lineGap = 0.5;
108 var fontSize = AnnunciatorLampMetrics.TwoLineLabelFontSize;
109 var formatted = new (FormattedText Fill, FormattedText Stroke)[2];
110 double totalH = 0;
111 for (var i = 0; i < lines.Length; i++)
112 {
113 var line = lines[i];
114 var fFill = new FormattedText(
115 line,
116 CultureInfo.InvariantCulture,
117 FlowDirection.LeftToRight,
118 AnnunciatorLampChrome.LabelTypeface,
119 fontSize,
120 fillBrush);
121 var fStroke = new FormattedText(
122 line,
123 CultureInfo.InvariantCulture,
124 FlowDirection.LeftToRight,
125 AnnunciatorLampChrome.LabelTypeface,
126 fontSize,
127 strokeBrush);
128 formatted[i] = (fFill, fStroke);
129 totalH += fFill.Height;
130 }
131
132 totalH += lineGap;
133 var y = outerRect.Y + (outerRect.Height - totalH) / 2;
134 for (var i = 0; i < lines.Length; i++)
135 {
136 var (ftFill, ftStroke) = formatted[i];
137 var x = outerRect.X + (outerRect.Width - ftFill.Width) / 2;
138 AnnunciatorLampChrome.DrawOutlinedText(context, ftStroke, ftFill, new Point(x, y));
139 y += ftFill.Height + (i == 0 ? lineGap : 0);
140 }
141 }
142}
143
View only · write via MCP/CIDE