using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Windows; using System.Windows.Forms; using System.Windows.Media; namespace AxCopilot.Views; internal sealed class ModernTrayRenderer : ToolStripProfessionalRenderer { private static readonly System.Drawing.Color BulbOnColor = System.Drawing.Color.FromArgb(255, 185, 0); private static readonly System.Drawing.Color BulbGlowHalo = System.Drawing.Color.FromArgb(50, 255, 185, 0); private static System.Drawing.Color BgColor => ThemeColor("LauncherBackground", System.Drawing.Color.FromArgb(250, 250, 252)); private static System.Drawing.Color HoverColor => ThemeColor("ItemHoverBackground", System.Drawing.Color.FromArgb(234, 234, 247)); private static System.Drawing.Color AccentColor => ThemeColor("AccentColor", System.Drawing.Color.FromArgb(75, 94, 252)); private static System.Drawing.Color TextColor => ThemeColor("PrimaryText", System.Drawing.Color.FromArgb(22, 23, 42)); private static System.Drawing.Color TextDimColor => ThemeColor("SecondaryText", System.Drawing.Color.FromArgb(90, 92, 128)); private static System.Drawing.Color SepColor => ThemeColor("SeparatorColor", System.Drawing.Color.FromArgb(228, 228, 242)); private static System.Drawing.Color BorderColor => ThemeColor("BorderColor", System.Drawing.Color.FromArgb(210, 210, 232)); private static System.Drawing.Color IconColor => ThemeColor("SecondaryText", System.Drawing.Color.FromArgb(110, 112, 148)); public ModernTrayRenderer() : base(new ModernColorTable()) { } private static System.Drawing.Color ThemeColor(string key, System.Drawing.Color fallback) { try { if (System.Windows.Application.Current?.Resources[key] is SolidColorBrush { Color: var color } solidColorBrush) { return System.Drawing.Color.FromArgb(color.A, solidColorBrush.Color.R, solidColorBrush.Color.G, solidColorBrush.Color.B); } } catch { } return fallback; } protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) { using SolidBrush brush = new SolidBrush(BgColor); e.Graphics.FillRectangle(brush, e.AffectedBounds); } protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) { Graphics graphics = e.Graphics; graphics.SmoothingMode = SmoothingMode.AntiAlias; using System.Drawing.Pen pen = new System.Drawing.Pen(BorderColor, 1f); RectangleF rect = new RectangleF(0.5f, 0.5f, (float)e.ToolStrip.Width - 1f, (float)e.ToolStrip.Height - 1f); using GraphicsPath path = BuildRoundedPath(rect, 15f); graphics.DrawPath(pen, path); graphics.SmoothingMode = SmoothingMode.Default; } protected override void OnRenderImageMargin(ToolStripRenderEventArgs e) { using SolidBrush brush = new SolidBrush(BgColor); e.Graphics.FillRectangle(brush, e.AffectedBounds); } protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e) { Graphics graphics = e.Graphics; ToolStripItem item = e.Item; using SolidBrush brush = new SolidBrush(BgColor); graphics.FillRectangle(brush, 0, 0, item.Width, item.Height); if (!item.Selected || !item.Enabled) { return; } graphics.SmoothingMode = SmoothingMode.AntiAlias; using SolidBrush brush2 = new SolidBrush(HoverColor); DrawRoundedFill(graphics, brush2, new RectangleF(6f, 2f, item.Width - 12, item.Height - 4), 8f); graphics.SmoothingMode = SmoothingMode.Default; } protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e) { int num = e.Item.Height / 2; using System.Drawing.Pen pen = new System.Drawing.Pen(SepColor); e.Graphics.DrawLine(pen, 16, num, e.Item.Width - 16, num); } protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { e.TextColor = (e.Item.Enabled ? TextColor : TextDimColor); e.TextFormat = TextFormatFlags.VerticalCenter; base.OnRenderItemText(e); } protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e) { DrawGlyph(e.Graphics, e.Item, e.ImageRectangle); } protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) { DrawGlyph(e.Graphics, e.Item, e.ImageRectangle); } private static void DrawGlyph(Graphics g, ToolStripItem item, Rectangle bounds) { if (!(item.Tag is string text) || string.IsNullOrEmpty(text) || bounds.Width <= 0 || bounds.Height <= 0) { return; } g.TextRenderingHint = TextRenderingHint.AntiAlias; bool flag = text == "\ue82f"; bool flag2 = item is ToolStripMenuItem toolStripMenuItem && toolStripMenuItem.Checked; System.Drawing.Color color; if (!(flag && flag2)) { color = ((flag && !flag2) ? System.Drawing.Color.FromArgb(120, 120, 140) : ((!item.Selected || !item.Enabled) ? IconColor : AccentColor)); } else { DrawLightbulbGlow(g, text, bounds); color = BulbOnColor; } using Font font = new Font("Segoe MDL2 Assets", 12f, GraphicsUnit.Point); using SolidBrush brush = new SolidBrush(color); StringFormat genericTypographic = StringFormat.GenericTypographic; SizeF sizeF = g.MeasureString(text, font, 0, genericTypographic); float x = (float)bounds.X + ((float)bounds.Width - sizeF.Width) / 2f + 2f; float y = (float)bounds.Y + ((float)bounds.Height - sizeF.Height) / 2f; g.DrawString(text, font, brush, x, y, genericTypographic); } private static void DrawLightbulbGlow(Graphics g, string glyph, Rectangle bounds) { g.SmoothingMode = SmoothingMode.AntiAlias; float num = (float)bounds.X + (float)bounds.Width / 2f; float num2 = (float)bounds.Y + (float)bounds.Height / 2f; float num3 = (float)Math.Max(bounds.Width, bounds.Height) * 0.85f; RectangleF rect = new RectangleF(num - num3, num2 - num3, num3 * 2f, num3 * 2f); using GraphicsPath graphicsPath = new GraphicsPath(); graphicsPath.AddEllipse(rect); PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath); pathGradientBrush.CenterColor = System.Drawing.Color.FromArgb(60, 255, 185, 0); pathGradientBrush.SurroundColors = new System.Drawing.Color[1] { System.Drawing.Color.FromArgb(0, 255, 185, 0) }; pathGradientBrush.CenterPoint = new PointF(num, num2); using PathGradientBrush brush = pathGradientBrush; g.FillEllipse(brush, rect); g.SmoothingMode = SmoothingMode.Default; } private static GraphicsPath BuildRoundedPath(RectangleF rect, float radius) { float num = radius * 2f; GraphicsPath graphicsPath = new GraphicsPath(); graphicsPath.AddArc(rect.X, rect.Y, num, num, 180f, 90f); graphicsPath.AddArc(rect.Right - num, rect.Y, num, num, 270f, 90f); graphicsPath.AddArc(rect.Right - num, rect.Bottom - num, num, num, 0f, 90f); graphicsPath.AddArc(rect.X, rect.Bottom - num, num, num, 90f, 90f); graphicsPath.CloseFigure(); return graphicsPath; } private static void DrawRoundedFill(Graphics g, System.Drawing.Brush brush, RectangleF rect, float radius) { using GraphicsPath path = BuildRoundedPath(rect, radius); g.FillPath(brush, path); } }