| 1 | using Avalonia; |
| 2 | using Avalonia.Media; |
| 3 | using static CascadeIDE.Cockpit.PrimitivesKit.CockpitPrimitivesPalette.Annunciator; |
| 4 | |
| 5 | namespace CascadeIDE.Cockpit.PrimitivesKit; |
| 6 | |
| 7 | /// <summary> |
| 8 | /// Общий корпус Korry / annunciator и утилиты отрисовки для <see cref="CommandArmedStripLampFace"/>, |
| 9 | /// <see cref="WorkspaceSplittersTolLampFace"/>, <see cref="LabeledAnnunciatorLampFace"/> (ADR 0063/0064). |
| 10 | /// </summary> |
| 11 | internal static class AnnunciatorLampChrome |
| 12 | { |
| 13 | internal static readonly Typeface LabelTypeface = new(FontFamily.Default, FontStyle.Normal, FontWeight.Bold); |
| 14 | |
| 15 | internal static void DrawCellHousing(DrawingContext context, Rect outerRect) |
| 16 | { |
| 17 | context.DrawRectangle(new SolidColorBrush(Housing), new Pen(new SolidColorBrush(BezelInner), 1), outerRect); |
| 18 | |
| 19 | var penHi = new Pen(new SolidColorBrush(BevelHighlight), 1); |
| 20 | var penLo = new Pen(new SolidColorBrush(BevelShadow), 1); |
| 21 | context.DrawLine(penHi, outerRect.TopLeft, outerRect.TopRight); |
| 22 | context.DrawLine(penHi, outerRect.TopLeft, outerRect.BottomLeft); |
| 23 | context.DrawLine(penLo, outerRect.BottomLeft, outerRect.BottomRight); |
| 24 | context.DrawLine(penLo, outerRect.TopRight, outerRect.BottomRight); |
| 25 | |
| 26 | var bezel = Deflate(outerRect, 2); |
| 27 | context.DrawRectangle(null, new Pen(new SolidColorBrush(BezelInner), 1), bezel); |
| 28 | } |
| 29 | |
| 30 | /// <summary>Квадратная линза по центру <paramref name="outerRect"/>.</summary> |
| 31 | internal static Rect ComputeFaceSquare(Rect outerRect, double inset = 5.0) |
| 32 | { |
| 33 | var side = Math.Max(4, Math.Min(outerRect.Width, outerRect.Height) - 2 * inset); |
| 34 | return new Rect( |
| 35 | outerRect.X + (outerRect.Width - side) / 2, |
| 36 | outerRect.Y + (outerRect.Height - side) / 2, |
| 37 | side, |
| 38 | side); |
| 39 | } |
| 40 | |
| 41 | internal static void DrawOutlinedText(DrawingContext context, FormattedText stroke, FormattedText fill, Point origin) |
| 42 | { |
| 43 | for (var dy = -1; dy <= 1; dy++) |
| 44 | { |
| 45 | for (var dx = -1; dx <= 1; dx++) |
| 46 | { |
| 47 | if (dx == 0 && dy == 0) |
| 48 | continue; |
| 49 | context.DrawText(stroke, origin + new Vector(dx, dy)); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | context.DrawText(fill, origin); |
| 54 | } |
| 55 | |
| 56 | internal static Rect Deflate(Rect r, double d) |
| 57 | { |
| 58 | if (r.Width <= 2 * d || r.Height <= 2 * d) |
| 59 | return new Rect(r.X + d, r.Y + d, 0, 0); |
| 60 | return new Rect(r.X + d, r.Y + d, r.Width - 2 * d, r.Height - 2 * d); |
| 61 | } |
| 62 | |
| 63 | internal static Color Lighten(Color c, double amount) |
| 64 | { |
| 65 | amount = Math.Clamp(amount, 0, 1); |
| 66 | return Color.FromArgb( |
| 67 | c.A, |
| 68 | (byte)Math.Clamp(c.R + (255 - c.R) * amount, 0, 255), |
| 69 | (byte)Math.Clamp(c.G + (255 - c.G) * amount, 0, 255), |
| 70 | (byte)Math.Clamp(c.B + (255 - c.B) * amount, 0, 255)); |
| 71 | } |
| 72 | |
| 73 | internal static Color Darken(Color c, double amount) |
| 74 | { |
| 75 | amount = Math.Clamp(amount, 0, 1); |
| 76 | return Color.FromArgb( |
| 77 | c.A, |
| 78 | (byte)Math.Clamp(c.R * (1 - amount), 0, 255), |
| 79 | (byte)Math.Clamp(c.G * (1 - amount), 0, 255), |
| 80 | (byte)Math.Clamp(c.B * (1 - amount), 0, 255)); |
| 81 | } |
| 82 | } |
| 83 | |