using System.Drawing.Drawing2D; using System.Runtime.InteropServices; namespace Zcbot.WindowsNode; internal static class TrayIconFactory { internal static Icon Create(NodeState state) { var color = state switch { NodeState.Online => Color.FromArgb(34, 197, 94), NodeState.Connecting => Color.FromArgb(245, 158, 11), NodeState.NotRegistered or NodeState.AuthenticationRequired => Color.FromArgb(239, 68, 68), _ => Color.FromArgb(107, 114, 128), }; using var bitmap = new Bitmap(32, 32); using var graphics = Graphics.FromImage(bitmap); graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.Clear(Color.Transparent); using var background = new SolidBrush(Color.FromArgb(14, 40, 36)); using var badge = new SolidBrush(color); using var logoBrush = new SolidBrush(Color.FromArgb(153, 246, 228)); using var logoShape = CreateRoundedRectangle(new RectangleF(1, 1, 30, 30), 7); graphics.FillPath(background, logoShape); graphics.FillPolygon( logoBrush, new PointF[] { new(8.5f, 8), new(23.5f, 8), new(23.5f, 11.5f), new(14.5f, 21), new(23.5f, 21), new(23.5f, 24), new(8.5f, 24), new(8.5f, 20.5f), new(17.5f, 11), new(8.5f, 11), }); graphics.FillEllipse(badge, 20, 20, 11, 11); using var border = new Pen(Color.White, 2); graphics.DrawEllipse(border, 20, 20, 11, 11); var handle = bitmap.GetHicon(); try { using var icon = Icon.FromHandle(handle); return (Icon)icon.Clone(); } finally { DestroyIcon(handle); } } private static GraphicsPath CreateRoundedRectangle(RectangleF bounds, float radius) { var diameter = radius * 2; var path = new GraphicsPath(); path.AddArc(bounds.Left, bounds.Top, diameter, diameter, 180, 90); path.AddArc(bounds.Right - diameter, bounds.Top, diameter, diameter, 270, 90); path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90); path.AddArc(bounds.Left, bounds.Bottom - diameter, diameter, diameter, 90, 90); path.CloseFigure(); return path; } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DestroyIcon(nint handle); }