Files
Pilz/Pilz.UI.WinForms/DisplayHelp.cs

253 lines
7.9 KiB
C#

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;
}
}
}