161 lines
4.3 KiB
C#
161 lines
4.3 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
namespace ProductionControl.UIExtend
|
|
{
|
|
public struct ProTransformation
|
|
{
|
|
public Point Translation { get { return _translation; } }
|
|
public double Scale { get { return _scale; } }
|
|
private readonly Point _translation;
|
|
private readonly double _scale;
|
|
|
|
public ProTransformation(Point translation, double scale)
|
|
{
|
|
_translation = translation;
|
|
_scale = scale;
|
|
}
|
|
|
|
public Point ConvertToIm(Point p)
|
|
{
|
|
return new Point((int)(p.X * _scale + _translation.X), (int)(p.Y * _scale + _translation.Y));
|
|
}
|
|
|
|
public Size ConvertToIm(Size p)
|
|
{
|
|
return new Size((int)(p.Width * _scale), (int)(p.Height * _scale));
|
|
}
|
|
|
|
public Rectangle ConvertToIm(Rectangle r)
|
|
{
|
|
return new Rectangle(ConvertToIm(r.Location), ConvertToIm(r.Size));
|
|
}
|
|
|
|
public Point ConvertToPb(Point p)
|
|
{
|
|
return new Point((int)((p.X - _translation.X) / _scale), (int)((p.Y - _translation.Y) / _scale));
|
|
}
|
|
|
|
public Size ConvertToPb(Size p)
|
|
{
|
|
return new Size((int)(p.Width / _scale), (int)(p.Height / _scale));
|
|
}
|
|
|
|
public Rectangle ConvertToPb(Rectangle r)
|
|
{
|
|
return new Rectangle(ConvertToPb(r.Location), ConvertToPb(r.Size));
|
|
}
|
|
|
|
public ProTransformation SetTranslate(Point p)
|
|
{
|
|
return new ProTransformation(p, _scale);
|
|
}
|
|
|
|
public ProTransformation AddTranslate(Point p)
|
|
{
|
|
return SetTranslate(new Point(p.X + _translation.X, p.Y + _translation.Y));
|
|
}
|
|
|
|
public ProTransformation SetScale(double scale)
|
|
{
|
|
return new ProTransformation(_translation, scale);
|
|
}
|
|
}
|
|
|
|
public class ProPictureBox : PictureBox
|
|
{
|
|
private Point? _clickedPoint;
|
|
private ProTransformation _transformation;
|
|
public ProTransformation Transformation
|
|
{
|
|
set
|
|
{
|
|
_transformation = FixTranslation(value);
|
|
Invalidate();
|
|
}
|
|
get
|
|
{
|
|
return _transformation;
|
|
}
|
|
}
|
|
|
|
public ProPictureBox()
|
|
{
|
|
_transformation = new ProTransformation(new Point(1000, 0), 0.5f);
|
|
MouseDown += OnMouseDown;
|
|
MouseMove += OnMouseMove;
|
|
MouseUp += OnMouseUp;
|
|
MouseWheel += OnMouseWheel;
|
|
Resize += OnResize;
|
|
}
|
|
|
|
private ProTransformation FixTranslation(ProTransformation value)
|
|
{
|
|
var maxScale = Math.Max((double)Image.Width / ClientRectangle.Width, (double)Image.Height / ClientRectangle.Height);
|
|
if (value.Scale > maxScale)
|
|
value = value.SetScale(maxScale);
|
|
if (value.Scale < 0.3)
|
|
value = value.SetScale(0.3);
|
|
var rectSize = value.ConvertToIm(ClientRectangle.Size);
|
|
var max = new Size(Image.Width - rectSize.Width, Image.Height - rectSize.Height);
|
|
|
|
value = value.SetTranslate((new Point(Math.Min(value.Translation.X, max.Width), Math.Min(value.Translation.Y, max.Height))));
|
|
if (value.Translation.X < 0 || value.Translation.Y < 0)
|
|
{
|
|
value = value.SetTranslate(new Point(Math.Max(value.Translation.X, 0), Math.Max(value.Translation.Y, 0)));
|
|
}
|
|
return value;
|
|
}
|
|
|
|
private void OnResize(object sender, EventArgs eventArgs)
|
|
{
|
|
if (Image == null)
|
|
return;
|
|
Transformation = Transformation;
|
|
}
|
|
|
|
private void OnMouseWheel(object sender, MouseEventArgs e)
|
|
{
|
|
var transformation = _transformation;
|
|
var pos1 = transformation.ConvertToIm(e.Location);
|
|
if (e.Delta > 0)
|
|
transformation = (transformation.SetScale(Transformation.Scale / 1.25));
|
|
else
|
|
transformation = (transformation.SetScale(Transformation.Scale * 1.25));
|
|
var pos2 = transformation.ConvertToIm(e.Location);
|
|
transformation = transformation.AddTranslate(pos1 - (Size)pos2);
|
|
Transformation = transformation;
|
|
}
|
|
|
|
private void OnMouseUp(object sender, MouseEventArgs mouseEventArgs)
|
|
{
|
|
_clickedPoint = null;
|
|
}
|
|
|
|
private void OnMouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if (_clickedPoint == null)
|
|
return;
|
|
var p = _transformation.ConvertToIm((Size)e.Location);
|
|
Transformation = _transformation.SetTranslate(_clickedPoint.Value - p);
|
|
}
|
|
|
|
private void OnMouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
Focus();
|
|
_clickedPoint = _transformation.ConvertToIm(e.Location);
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
var imRect = Transformation.ConvertToIm(ClientRectangle);
|
|
e.Graphics.DrawImage(Image, ClientRectangle, imRect, GraphicsUnit.Pixel);
|
|
}
|
|
|
|
public void DecideInitialTransformation()
|
|
{
|
|
Transformation = new ProTransformation(Point.Empty, int.MaxValue);
|
|
}
|
|
}
|
|
} |