You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.8 KiB
C#

using DeepNestLib;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
namespace DeepNestPort
{
public class DrawingContext
{
public DrawingContext(PictureBox pb)
{
box = pb;
bmp = new Bitmap(pb.Width, pb.Height);
pb.SizeChanged += Pb_SizeChanged;
gr = Graphics.FromImage(bmp);
gr.SmoothingMode = SmoothingMode.AntiAlias;
box.Image = bmp;
pb.MouseDown += PictureBox1_MouseDown;
pb.MouseUp += PictureBox1_MouseUp;
pb.MouseMove += Pb_MouseMove;
sx = box.Width / 2;
sy = -box.Height / 2;
pb.MouseWheel += Pb_MouseWheel;
}
public bool EnableWheel = true;
GraphicsPath getGraphicsPath(NFP nfp)
{
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(nfp.Points.Select(z => Transform(z.x, z.y)).ToArray());
if (nfp.children != null)
{
foreach (var item in nfp.children)
{
gp.AddPolygon(item.Points.Select(z => Transform(z.x, z.y)).ToArray());
}
}
return gp;
}
GraphicsPath getGraphicsPath(RawDetail det)
{
GraphicsPath gp = new GraphicsPath();
foreach (var item in det.Outers)
{
gp.AddPolygon(item.Points.Select(z => Transform(z)).ToArray());
}
return gp;
}
public float GetLabelHeight()
{
return SystemFonts.DefaultFont.GetHeight();
}
public SizeF DrawLabel(string text, Brush fontBrush, Color backColor, int x, int y, int opacity = 128)
{
var ms = gr.MeasureString(text, SystemFonts.DefaultFont);
gr.FillRectangle(new SolidBrush(Color.FromArgb(opacity, backColor)), x, y, ms.Width, ms.Height);
gr.DrawString(text, SystemFonts.DefaultFont, fontBrush, x, y);
return ms;
}
public GraphicsPath Draw(NFP nfp, Pen pen = null, Brush brush = null)
{
var gp = getGraphicsPath(nfp);
if (brush != null)
gr.FillPath(brush, gp);
if (pen != null)
gr.DrawPath(pen, gp);
return gp;
}
public GraphicsPath Draw(RawDetail det, Pen pen = null, Brush brush = null)
{
var gp = getGraphicsPath(det);
if (brush != null)
gr.FillPath(brush, gp);
if (pen != null)
gr.DrawPath(pen, gp);
return gp;
}
protected virtual void Pb_MouseWheel(object sender, MouseEventArgs e)
{
if (!EnableWheel) return;
float zold = zoom;
if (e.Delta > 0) { zoom *= 1.5f; ; }
else { zoom *= 0.5f; }
if (zoom < 0.08) { zoom = 0.08f; }
if (zoom > 1000) { zoom = 1000f; }
var pos = box.PointToClient(Cursor.Position);
sx = -(pos.X / zold - sx - pos.X / zoom);
sy = (pos.Y / zold + sy - pos.Y / zoom);
}
public bool FocusOnMove = true;
private void Pb_MouseMove(object sender, MouseEventArgs e)
{
if (!FocusOnMove) return;
box.Focus();
}
private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDrag = false;
var p = box.PointToClient(Cursor.Position);
var pos = box.PointToClient(Cursor.Position);
var posx = (pos.X / zoom - sx);
var posy = (-pos.Y / zoom - sy);
}
private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
{
var pos = box.PointToClient(Cursor.Position);
var p = Transform(pos);
if (e.Button == MouseButtons.Right)
{
isDrag = true;
startx = pos.X;
starty = pos.Y;
origsx = sx;
origsy = sy;
}
}
internal void Clear(Color color)
{
gr.Clear(color);
}
float startx, starty;
internal void Reset()
{
gr.ResetTransform();
}
float origsx, origsy;
bool isDrag = false;
PictureBox box;
public float sx, sy;
public float zoom = 1;
public Graphics gr;
public Bitmap bmp;
public bool InvertY = true;
public virtual PointF Transform(PointF p1)
{
return new PointF((p1.X + sx) * zoom, (InvertY ? (-1) : 1) * (p1.Y + sy) * zoom);
}
public virtual PointF BackTransform(PointF p1)
{
return new PointF((p1.X / zoom - sx), (InvertY ? (-1) : 1) * (p1.Y / zoom - sy));
}
public virtual PointF Transform(double x, double y)
{
return new PointF(((float)(x) + sx) * zoom, (InvertY ? (-1) : 1) * ((float)(y) + sy) * zoom);
}
private void Pb_SizeChanged(object sender, EventArgs e)
{
if (box.Width <= 0 || box.Height <= 0) return;
bmp = new Bitmap(box.Width, box.Height);
gr = Graphics.FromImage(bmp);
box.Image = bmp;
}
public PointF GetPos()
{
var pos = box.PointToClient(Cursor.Position);
var posx = (pos.X / zoom - sx);
var posy = (-pos.Y / zoom - sy);
return new PointF(posx, posy);
}
public void Update()
{
if (isDrag)
{
var p = box.PointToClient(Cursor.Position);
sx = origsx + ((p.X - startx) / zoom);
sy = origsy + (-(p.Y - starty) / zoom);
}
}
public void Setup()
{
box.Invalidate();
}
public void FitToPoints(PointF[] points, int gap = 0)
{
var maxx = points.Max(z => z.X) + gap;
var minx = points.Min(z => z.X) - gap;
var maxy = points.Max(z => z.Y) + gap;
var miny = points.Min(z => z.Y) - gap;
var w = box.Width;
var h = box.Height;
var dx = maxx - minx;
var kx = w / dx;
var dy = maxy - miny;
var ky = h / dy;
var oz = zoom;
var sz1 = new Size((int)(dx * kx), (int)(dy * kx));
var sz2 = new Size((int)(dx * ky), (int)(dy * ky));
zoom = kx;
if (sz1.Width > w || sz1.Height > h) zoom = ky;
var x = dx / 2 + minx;
var y = dy / 2 + miny;
sx = ((w / 2f) / zoom - x);
sy = -((h / 2f) / zoom + y);
var test = Transform(new PointF(x, y));
}
}
}