using System.Drawing.Drawing2D; namespace Pilz.UI.WinForms; public class DisplayHelp { public static void FillRectangle(Graphics g, Rectangle bounds, Color color1) { FillRectangle(g, bounds, color1, Color.Empty, 90); } public static void FillRectangle(Graphics g, Rectangle bounds, Color color1, Color color2) { FillRectangle(g, bounds, color1, color2, 90); } public static void FillRectangle(Graphics g, Rectangle r, Color color1, Color color2, int gradientAngle) { if (r.Width == 0 || r.Height == 0) return; if (color2.IsEmpty) { if (!color1.IsEmpty) { var sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; using var brush = new SolidBrush(color1); g.FillRectangle(brush, r); g.SmoothingMode = sm; } } else { using var brush = CreateLinearGradientBrush(r, color1, color2, gradientAngle); g.FillRectangle(brush, r); } } public static void FillRectangle(Graphics g, Rectangle r, Color color1, Color color2, int gradientAngle, float[] factors, float[] positions) { if (r.Width == 0 || r.Height == 0) return; if (color2.IsEmpty) { if (!color1.IsEmpty) { var sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; using var brush = new SolidBrush(color1); g.FillRectangle(brush, r); g.SmoothingMode = sm; } } else { using var brush = CreateLinearGradientBrush(r, color1, color2, gradientAngle); var blend = new Blend(factors.Length) { Factors = factors, Positions = positions }; brush.Blend = blend; g.FillRectangle(brush, r); } } public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1, Color color2, int gradientAngle) { if (color2.IsEmpty) { if (!color1.IsEmpty) { using var brush = new SolidBrush(color1); FillRoundedRectangle(g, brush, bounds, cornerSize); } } else { using var brush = CreateLinearGradientBrush(bounds, color1, color2, gradientAngle); FillRoundedRectangle(g, brush, bounds, cornerSize); } } public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1, Color color2) { FillRoundedRectangle(g, bounds, cornerSize, color1, color2, 90); } public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1) { using var brush = new SolidBrush(color1); FillRoundedRectangle(g, brush, bounds, cornerSize); } public static void FillRoundedRectangle(Graphics g, Brush brush, Rectangle bounds, int cornerSize) { if (cornerSize <= 0) { var sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; g.FillRectangle(brush, bounds); g.SmoothingMode = sm; } else { bounds.Width -= 1; bounds.Height -= 1; using var path = GetRoundedRectanglePath(bounds, cornerSize); g.FillPath(brush, path); } } public static void DrawRectangle(Graphics g, Color color, int x, int y, int width, int height) { using var pen = new Pen(color, 1f); DrawRectangle(g, pen, x, y, width, height); } public static void DrawRectangle(Graphics g, Color color, Rectangle r) { DrawRectangle(g, color, r.X, r.Y, r.Width, r.Height); } public static void DrawRectangle(Graphics g, Pen pen, int x, int y, int width, int height) { width -= 1; height -= 1; g.DrawRectangle(pen, x, y, width, height); } public static void DrawRoundedRectangle(Graphics g, Color color, Rectangle bounds, int cornerSize) { if (color.IsEmpty) return; using var pen = new Pen(color); DrawRoundedRectangle(g, pen, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize); } public static void DrawRoundedRectangle(Graphics g, Pen pen, int x, int y, int width, int height, int cornerSize) { DrawRoundedRectangle(g, pen, null, x, y, width, height, cornerSize); } public static void DrawRoundedRectangle(Graphics g, Pen pen, Brush fill, int x, int y, int width, int height, int cornerSize) { width -= 1; height -= 1; var r = new Rectangle(x, y, width, height); using var path = GetRoundedRectanglePath(r, cornerSize); if (fill is not null) g.FillPath(fill, path); g.DrawPath(pen, path); } public static GraphicsPath GetRoundedRectanglePath(Rectangle r, int cornerSize) { var path = new GraphicsPath(); if (cornerSize == 0) path.AddRectangle(r); else { AddCornerArc(path, r, cornerSize, eCornerArc.TopLeft); AddCornerArc(path, r, cornerSize, eCornerArc.TopRight); AddCornerArc(path, r, cornerSize, eCornerArc.BottomRight); AddCornerArc(path, r, cornerSize, eCornerArc.BottomLeft); path.CloseAllFigures(); } return path; } public static LinearGradientBrush CreateLinearGradientBrush(Rectangle r, Color color1, Color color2, float gradientAngle) { if (r.Width <= 0) r.Width = 1; if (r.Height <= 0) r.Height = 1; return new LinearGradientBrush(new Rectangle(r.X, r.Y - 1, r.Width, r.Height + 1), color1, color2, gradientAngle); } public static void AddCornerArc(GraphicsPath path, Rectangle bounds, int cornerDiameter, eCornerArc corner) { if (cornerDiameter > 0) { var a = GetCornerArc(bounds, cornerDiameter, corner); path.AddArc(a.X, a.Y, a.Width, a.Height, a.StartAngle, a.SweepAngle); } else if (corner == eCornerArc.TopLeft) path.AddLine(bounds.X, bounds.Y + 2, bounds.X, bounds.Y); else if (corner == eCornerArc.BottomLeft) path.AddLine(bounds.X + 2, bounds.Bottom, bounds.X, bounds.Bottom); else if (corner == eCornerArc.TopRight) path.AddLine(bounds.Right - 2, bounds.Y, bounds.Right, bounds.Y); else if (corner == eCornerArc.BottomRight) path.AddLine(bounds.Right, bounds.Bottom - 2, bounds.Right, bounds.Bottom); } internal static ArcData GetCornerArc(Rectangle bounds, int cornerDiameter, eCornerArc corner) { if (cornerDiameter == 0) cornerDiameter = 1; var diameter = cornerDiameter * 2; return corner switch { eCornerArc.TopLeft => new ArcData(bounds.X, bounds.Y, diameter, diameter, 180f, 90f), eCornerArc.TopRight => new ArcData(bounds.Right - diameter, bounds.Y, diameter, diameter, 270f, 90f), eCornerArc.BottomLeft => new ArcData(bounds.X, bounds.Bottom - diameter, diameter, diameter, 90f, 90f), _ => new ArcData(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0f, 90f), }; } public enum eCornerArc { TopLeft, TopRight, BottomLeft, BottomRight } internal struct ArcData { public int X; public int Y; public int Width; public int Height; public float StartAngle; public float SweepAngle; public ArcData(int x, int y, int width, int height, float startAngle, float sweepAngle) { X = x; Y = y; Width = width; Height = height; StartAngle = startAngle; SweepAngle = sweepAngle; } } }