180 lines
6.8 KiB
C#
180 lines
6.8 KiB
C#
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);
|
|
}
|
|
}
|