using CommonLang;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using CommonLang.Vector;
using System.Windows.Forms;
namespace CommonFroms.Drawing
{
public static class DrawingUtils
{
public static void DrawCross(Graphics g, Pen pen, float cx, float cy, float cr)
{
g.DrawLine(pen, cx - cr, cy, cx + cr, cy);
g.DrawLine(pen, cx, cy - cr, cx, cy + cr);
}
public static void DrawFan(Graphics g, Pen pen, float direction, float range, float angle)
{
if (angle != 0)
{
float startRadians = direction - angle / 2;
float endRadians = direction + angle / 2;
g.DrawArc(pen,
-range,
-range,
range * 2,
range * 2,
CMath.RadiansToDegrees(startRadians),
CMath.RadiansToDegrees(angle));
g.DrawLine(pen, 0, 0,
(float)Math.Cos(startRadians) * range,
(float)Math.Sin(startRadians) * range);
g.DrawLine(pen, 0, 0,
(float)Math.Cos(endRadians) * range,
(float)Math.Sin(endRadians) * range);
}
else
{
g.DrawLine(pen, 0, 0,
(float)Math.Cos(direction) * range,
(float)Math.Sin(direction) * range);
}
}
public static void FillFan(Graphics g, Brush pen, float direction, float range, float angle)
{
float startRadians = direction - angle / 2;
float endRadians = direction + angle / 2;
g.FillPie(pen,
-range,
-range,
range * 2,
range * 2,
CMath.RadiansToDegrees(startRadians),
CMath.RadiansToDegrees(angle));
}
///
/// 画粗线条
///
///
///
///
///
///
public static void DrawLineRect(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float line_r)
{
float direction = MathVector.getDegree(sx, sy, dx, dy);
Vector2 s_l = new Vector2(sx, sy);
Vector2 s_r = new Vector2(sx, sy);
Vector2 d_l = new Vector2(dx, dy);
Vector2 d_r = new Vector2(dx, dy);
MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, line_r);
MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, line_r);
MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, line_r);
MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, line_r);
g.DrawLine(pen, s_l.X, s_l.Y, d_l.X, d_l.Y);
g.DrawLine(pen, s_r.X, s_r.Y, d_r.X, d_r.Y);
g.DrawLine(pen, s_l.X, s_l.Y, s_r.X, s_r.Y);
g.DrawLine(pen, d_l.X, d_l.Y, d_r.X, d_r.Y);
}
public static void FillLineRect(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float line_r)
{
float direction = MathVector.getDegree(sx, sy, dx, dy);
Vector2 s_l = new Vector2(sx, sy);
Vector2 s_r = new Vector2(sx, sy);
Vector2 d_l = new Vector2(dx, dy);
Vector2 d_r = new Vector2(dx, dy);
MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, line_r);
MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, line_r);
MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, line_r);
MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, line_r);
g.FillPolygon(brush,
new PointF[] {
new PointF(s_l.X, s_l.Y),
new PointF(s_r.X, s_r.Y),
new PointF(d_r.X, d_r.Y),
new PointF(d_l.X, d_l.Y)
},
System.Drawing.Drawing2D.FillMode.Winding);
}
///
/// 画圆角粗线条
///
///
///
///
///
///
///
///
public static void DrawLineRoundRect(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float line_r)
{
float direction = MathVector.getDegree(sx, sy, dx, dy);
float r = line_r;
float size = r * 2;
Vector2 s_l = new Vector2(sx, sy);
Vector2 s_r = new Vector2(sx, sy);
Vector2 d_l = new Vector2(dx, dy);
Vector2 d_r = new Vector2(dx, dy);
MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, r);
MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, r);
MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, r);
MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, r);
g.DrawLine(pen, s_l.X, s_l.Y, d_l.X, d_l.Y);
g.DrawLine(pen, s_r.X, s_r.Y, d_r.X, d_r.Y);
float angle = CMath.RadiansToDegrees(direction);
g.DrawArc(pen, sx - r, sy - r, size, size, angle + 180 - 90, 180);
g.DrawArc(pen, dx - r, dy - r, size, size, angle + 360 - 90, 180);
}
public static void FillLineRoundRect(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float line_r)
{
float direction = MathVector.getDegree(sx, sy, dx, dy);
float r = line_r;
float size = r * 2;
Vector2 s_l = new Vector2(sx, sy);
Vector2 s_r = new Vector2(sx, sy);
Vector2 d_l = new Vector2(dx, dy);
Vector2 d_r = new Vector2(dx, dy);
MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, r);
MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, r);
MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, r);
MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, r);
g.FillPolygon(brush,
new PointF[] {
new PointF(s_l.X, s_l.Y),
new PointF(s_r.X, s_r.Y),
new PointF(d_r.X, d_r.Y),
new PointF(d_l.X, d_l.Y)
},
System.Drawing.Drawing2D.FillMode.Winding);
float angle = CMath.RadiansToDegrees(direction);
g.FillPie(brush, sx - r, sy - r, size, size, angle + 180 - 90, 180);
g.FillPie(brush, dx - r, dy - r, size, size, angle + 360 - 90, 180);
}
public static PointF[] GenCursor(float sx, float sy, float dx, float dy, float width, float cursor_width, float cursor_height)
{
if (cursor_width < width)
cursor_width = width;
float ox = sx - dx;
float oy = sy - dy;
float ds = CMath.getDistance(sx, sy, dx, dy);
float hw = width / 2f;
float cw = cursor_width / 2;
float od = (float)Math.Atan2(oy, ox);
PointF sC = new Point(0, 0);
PointF sL = new PointF(-hw, 0);
PointF sR = new PointF(+hw, 0);
PointF dC = new PointF(0, ds);
PointF dL = new PointF(-hw, ds - cursor_height);
PointF dR = new PointF(+hw, ds - cursor_height);
PointF dLL = new PointF(-cw, ds - cursor_height);
PointF dRR = new PointF(+cw, ds - cursor_height);
PointF[] points = new PointF[] { sC, sL, dL, dLL, dC, dRR, dR, sR, sC };
for (int i = 0; i < points.Length; i++)
{
float x = points[i].X;
float y = points[i].Y;
MathVector.rotate(ref x, ref y, 0, 0, od + CMath.PI_DIV_2);
points[i].X = x + sx;
points[i].Y = y + sy;
}
return points;
}
public static void FillCursor(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float width, float cursor_width = 0, float cursor_height = 0)
{
PointF[] points = GenCursor(sx, sy, dx, dy, width, cursor_width, cursor_height);
System.Drawing.Drawing2D.GraphicsState gs = g.Save();
try
{
g.FillPolygon(brush, points);
}
finally
{
g.Restore(gs);
}
}
public static void DrawCursor(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float width, float cursor_width = 0, float cursor_height = 0)
{
PointF[] points = GenCursor(sx, sy, dx, dy, width, cursor_width, cursor_height);
System.Drawing.Drawing2D.GraphicsState gs = g.Save();
try
{
g.DrawPolygon(pen, points);
}
finally
{
g.Restore(gs);
}
}
}
public abstract class Drawable
{
public int spacing = 2;
public StringFormat format = new StringFormat(StringFormat.GenericDefault);
public Font font = Form.DefaultFont;
public AnchorStyles anchor = AnchorStyles.Left | AnchorStyles.Top;
public virtual float Draw(Graphics g, float sx, float sy, float sw, float sh)
{
sx = sx - (((anchor & AnchorStyles.Right) != 0) ? sw : 0);
sy = sy - (((anchor & AnchorStyles.Bottom) != 0) ? sh : 0);
float x = sx + spacing;
float y = sy + spacing;
float w = sw - (spacing << 1);
float h = sh - (spacing << 1);
var clip = new RectangleF(x, y, w, h);
g.SetClip(clip);
try
{
DrawSelf(g, x, y, w, h);
}
finally
{
g.ResetClip();
}
return ((anchor & AnchorStyles.Bottom) != 0) ? -sh : sh;
}
protected abstract void DrawSelf(Graphics g, float x, float y, float w, float h);
}
public class GaugeRectFan : Drawable
{
public Brush body_brush = new SolidBrush(Color.FromArgb(0xFF, 0x40, 0x40, 0x40));
public Brush border_brush = new SolidBrush(Color.Gray);
public Brush cd_brush = new SolidBrush(Color.FromArgb(0x80, 0xFF, 0xFF, 0xFF));
public Brush text_brush = new SolidBrush(Color.White);
public int border = 1;
public string text1;
public string text2;
public float percent;
public GaugeRectFan SetText(string t1, string t2)
{
this.text1 = t1;
this.text2 = t2;
return this;
}
public GaugeRectFan SetPercent(float pct)
{
this.percent = pct;
return this;
}
protected override void DrawSelf(Graphics g, float x, float y, float w, float h)
{
g.FillRectangle(border_brush, x, y, w, h);
x += border;
y += border;
w -= (border << 1);
h -= (border << 1);
g.FillRectangle(body_brush, x, y, w, h);
if (percent > 0f && percent < 1f)
{
g.FillPie(cd_brush, x - w, y - h, w * 3, h * 3, -90, 360 * percent);
}
if (!string.IsNullOrEmpty(text1) && string.IsNullOrEmpty(text2))
{
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString(text1, font, text_brush, x, y + border, StringFormat.GenericDefault);
}
else
{
x += 1;
y += 1;
w -= 2;
h -= 2;
if (!string.IsNullOrEmpty(text1))
{
format.Alignment = StringAlignment.Near;
format.LineAlignment = StringAlignment.Near;
g.DrawString(text1, font, text_brush, x, y + border, StringFormat.GenericDefault);
}
if (!string.IsNullOrEmpty(text2))
{
format.Alignment = StringAlignment.Near;
format.LineAlignment = StringAlignment.Far;
g.DrawString(text2, font, text_brush, new RectangleF(x, y, w, h - border), format);
}
}
}
}
public class GaugeStrip : Drawable
{
public Brush back_brush = new SolidBrush(Color.FromArgb(0xFF, 0x40, 0x40, 0x40));
public Brush cd_brush = new SolidBrush(Color.FromArgb(0xA0, 0x20, 0xFF, 0x20));
public Brush text_brush = new SolidBrush(Color.White);
public int border = 1;
public string text;
public float percent;
public GaugeStrip SetText(string t)
{
this.text = t;
return this;
}
public GaugeStrip SetPercent(float pct)
{
this.percent = pct;
return this;
}
public override float Draw(Graphics g, float sx, float sy, float sw, float sh)
{
var trect = g.MeasureString(text, font);
sw = Math.Max(sw, trect.Width + (spacing << 1) + 2);
sh = Math.Max(sh, trect.Height + (spacing << 1) + 2);
return base.Draw(g, sx, sy, sw, sh);
}
protected override void DrawSelf(Graphics g, float x, float y, float w, float h)
{
g.FillRectangle(back_brush, x, y, w, h);
x += border;
y += border;
w -= (border << 1);
h -= (border << 1);
if (percent > 0f && percent < 1f)
{
g.FillRectangle(cd_brush, x, y, w * percent, h);
}
g.DrawString(text, font, text_brush, x + 1, y + 1, format);
}
}
public class TextLine : Drawable
{
public string text;
public Brush text_brush = new SolidBrush(Color.White);
public TextLine SetText(string t)
{
this.text = t;
return this;
}
public override float Draw(Graphics g, float sx, float sy, float sw, float sh)
{
var trect = g.MeasureString(text, font);
sw = Math.Max(sw, trect.Width + (spacing << 1));
sh = Math.Max(sh, trect.Height + (spacing << 1));
return base.Draw(g, sx, sy, sw, sh);
}
protected override void DrawSelf(Graphics g, float x, float y, float w, float h)
{
g.DrawString(text, font, text_brush, x, y, format);
}
}
public class TextRect : Drawable
{
public string text;
public Brush text_brush = new SolidBrush(Color.White);
public TextRect SetText(string t)
{
this.text = t;
return this;
}
public override float Draw(Graphics g, float sx, float sy, float sw, float sh)
{
var trect = g.MeasureString(text, font, (int)sw - (spacing << 1));
sw = Math.Max(sw, trect.Width + (spacing << 1));
sh = Math.Max(sh, trect.Height + (spacing << 1));
return base.Draw(g, sx, sy, sw, sh);
}
protected override void DrawSelf(Graphics g, float x, float y, float w, float h)
{
g.DrawString(text, font, text_brush, new RectangleF(x, y, w, h), format);
}
}
}