| 1 | #nullable enable |
| 2 | using CascadeIDE.Features.Chat; |
| 3 | using SkiaSharp; |
| 4 | |
| 5 | namespace CascadeIDE.Views.Chat.Skia; |
| 6 | |
| 7 | /// <summary>Иконка статуса слэш-команды (часы / галочка / крест).</summary> |
| 8 | internal static class SkiaSlashCommandStatusIconRenderer |
| 9 | { |
| 10 | public const float IconSize = 16f; |
| 11 | public const float IconMargin = 10f; |
| 12 | |
| 13 | public static SKRect ResolveIconRect( |
| 14 | SKRect bubbleRect, |
| 15 | ChatSlashCommandStatusIconPlacement placement) |
| 16 | { |
| 17 | var size = IconSize; |
| 18 | return placement switch |
| 19 | { |
| 20 | ChatSlashCommandStatusIconPlacement.TopLeft => new SKRect( |
| 21 | bubbleRect.Left + IconMargin, |
| 22 | bubbleRect.Top + IconMargin, |
| 23 | bubbleRect.Left + IconMargin + size, |
| 24 | bubbleRect.Top + IconMargin + size), |
| 25 | ChatSlashCommandStatusIconPlacement.BottomLeft => new SKRect( |
| 26 | bubbleRect.Left + IconMargin, |
| 27 | bubbleRect.Bottom - IconMargin - size, |
| 28 | bubbleRect.Left + IconMargin + size, |
| 29 | bubbleRect.Bottom - IconMargin), |
| 30 | ChatSlashCommandStatusIconPlacement.BottomRight => new SKRect( |
| 31 | bubbleRect.Right - IconMargin - size, |
| 32 | bubbleRect.Bottom - IconMargin - size, |
| 33 | bubbleRect.Right - IconMargin, |
| 34 | bubbleRect.Bottom - IconMargin), |
| 35 | _ => new SKRect( |
| 36 | bubbleRect.Right - IconMargin - size, |
| 37 | bubbleRect.Top + IconMargin, |
| 38 | bubbleRect.Right - IconMargin, |
| 39 | bubbleRect.Top + IconMargin + size), |
| 40 | }; |
| 41 | } |
| 42 | |
| 43 | public static void Draw( |
| 44 | SKCanvas canvas, |
| 45 | in SKRect iconRect, |
| 46 | SkiaChatTheme theme, |
| 47 | ChatSlashCommandStatus status) |
| 48 | { |
| 49 | var color = status switch |
| 50 | { |
| 51 | ChatSlashCommandStatus.Succeeded => theme.HoverBorder, |
| 52 | ChatSlashCommandStatus.Failed or ChatSlashCommandStatus.Cancelled => new SKColor(240, 110, 110), |
| 53 | _ => theme.MutedContent, |
| 54 | }; |
| 55 | |
| 56 | using var paint = new SKPaint |
| 57 | { |
| 58 | Color = color, |
| 59 | IsAntialias = true, |
| 60 | Style = SKPaintStyle.Stroke, |
| 61 | StrokeWidth = 1.6f, |
| 62 | StrokeCap = SKStrokeCap.Round, |
| 63 | StrokeJoin = SKStrokeJoin.Round, |
| 64 | }; |
| 65 | |
| 66 | var cx = iconRect.MidX; |
| 67 | var cy = iconRect.MidY; |
| 68 | var r = iconRect.Width * 0.42f; |
| 69 | |
| 70 | switch (status) |
| 71 | { |
| 72 | case ChatSlashCommandStatus.Running: |
| 73 | canvas.DrawCircle(cx, cy, r, paint); |
| 74 | canvas.DrawLine(cx, cy, cx, cy - r * 0.55f, paint); |
| 75 | canvas.DrawLine(cx, cy, cx + r * 0.45f, cy + r * 0.12f, paint); |
| 76 | break; |
| 77 | case ChatSlashCommandStatus.Succeeded: |
| 78 | canvas.DrawLine(cx - r * 0.55f, cy, cx - r * 0.1f, cy + r * 0.5f, paint); |
| 79 | canvas.DrawLine(cx - r * 0.1f, cy + r * 0.5f, cx + r * 0.62f, cy - r * 0.55f, paint); |
| 80 | break; |
| 81 | case ChatSlashCommandStatus.Failed: |
| 82 | case ChatSlashCommandStatus.Cancelled: |
| 83 | canvas.DrawLine(cx - r * 0.45f, cy - r * 0.45f, cx + r * 0.45f, cy + r * 0.45f, paint); |
| 84 | canvas.DrawLine(cx + r * 0.45f, cy - r * 0.45f, cx - r * 0.45f, cy + r * 0.45f, paint); |
| 85 | break; |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | |