944 lines
31 KiB
C#
944 lines
31 KiB
C#
|
||
using DH.Commons.Enums;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.Drawing.Drawing2D;
|
||
using System.Drawing.Imaging;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Windows.Forms;
|
||
|
||
using static DH.Commons.Enums.EnumHelper;
|
||
|
||
|
||
namespace DH.UI.Model.Winform
|
||
{
|
||
public partial class CanvasImage : UserControl
|
||
{
|
||
public CanvasImage()
|
||
{
|
||
InitializeComponent();
|
||
|
||
DoubleBuffered = true;
|
||
SetStyle(ControlStyles.OptimizedDoubleBuffer |
|
||
ControlStyles.ResizeRedraw |
|
||
ControlStyles.AllPaintingInWmPaint, true);
|
||
|
||
MouseWheel += Canvas_MouseWheel;
|
||
KeyDown += OnCanvasKeyDown;
|
||
KeyPress += OnCanvasKeyPressed;
|
||
MouseDoubleClick += Canvas_MouseDoubleClick;
|
||
MouseDown += Canvas_MouseDown;
|
||
MouseMove += Canvas_MouseMove;
|
||
MouseUp += Canvas_MouseUp;
|
||
|
||
// EventRouter.ChangeElementsMouseState -= OnElementChangeMouseState;
|
||
// EventRouter.ChangeElementsMouseState += OnElementChangeMouseState;
|
||
|
||
//Elements.CollectionChanged += Elements_CollectionChanged;
|
||
}
|
||
|
||
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||
{
|
||
//this.Invoke(new Action(() =>
|
||
//{
|
||
// this.Invalidate();
|
||
//}));
|
||
}
|
||
|
||
#region Event
|
||
public Action<MouseState> OnMouseStateChanged;
|
||
public Action<IShapeElement> DrawTemplateChanged = null;
|
||
public Action<Point, PointF, string> OnMouseLocationUpdated;
|
||
#endregion
|
||
|
||
private MouseState mouseState = MouseState.Normal;
|
||
public MouseState MouseState
|
||
{
|
||
get
|
||
{
|
||
return mouseState;
|
||
}
|
||
set
|
||
{
|
||
if (mouseState != value)
|
||
{
|
||
mouseState = value;
|
||
|
||
// OnMouseStateChanged?.BeginInvoke(value, null, null);
|
||
Task.Run(() => OnMouseStateChanged.Invoke(value));
|
||
}
|
||
}
|
||
}
|
||
|
||
#region 属性和字段
|
||
|
||
//private Bitmap map = new Bitmap(10, 10);
|
||
//public Bitmap MAP
|
||
//{
|
||
// get
|
||
// {
|
||
// _mapLoadHandler.WaitOne();
|
||
// return map;
|
||
// }
|
||
// set
|
||
// {
|
||
// map = value;
|
||
// }
|
||
//}
|
||
|
||
public Bitmap MAP { get; set; } = new Bitmap(10, 10);
|
||
|
||
public Matrix Matrix { get; set; } = new Matrix();
|
||
public ObservableCollection<IShapeElement> Elements { get; set; } = new ObservableCollection<IShapeElement>();
|
||
|
||
RectangleF _selectionRect = new RectangleF();
|
||
#endregion
|
||
|
||
#region 重绘
|
||
protected override void OnPaint(PaintEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
//lock (_mapLoadLock)
|
||
//{ }
|
||
|
||
Rectangle rect = ClientRectangle;
|
||
Graphics originG = e.Graphics;
|
||
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
|
||
BufferedGraphics myBuffer = currentContext.Allocate(originG, rect);
|
||
Graphics g = myBuffer.Graphics;
|
||
g.SmoothingMode = SmoothingMode.HighSpeed;
|
||
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
|
||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||
g.Clear(BackColor);
|
||
|
||
g.MultiplyTransform(Matrix);
|
||
|
||
if (MAP != null)
|
||
{
|
||
try
|
||
{
|
||
g.DrawImage(MAP, 0, 0, MAP.Width, MAP.Height);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
}
|
||
}
|
||
else
|
||
{
|
||
g.Clear(BackColor);
|
||
}
|
||
|
||
DrawTemplate?.Draw(g);
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
if (ele.IsEnabled && ele.IsShowing)
|
||
{
|
||
ele.Draw(g);
|
||
}
|
||
}
|
||
|
||
#region Grid
|
||
if (MAP != null)
|
||
{
|
||
if (ShowGrid)
|
||
{
|
||
int baseX = MAP.Width / 2;
|
||
int baseY = MAP.Height / 2;
|
||
|
||
Point[] xPoint = new Point[] { new Point(0, baseY), new Point(MAP.Width, baseY) };
|
||
Point[] yPoint = new Point[] { new Point(baseX, 0), new Point(baseX, MAP.Height) };
|
||
|
||
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), xPoint[0], xPoint[1]);
|
||
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), yPoint[0], yPoint[1]);
|
||
|
||
if (GridValue > 0)
|
||
{
|
||
int stepX = MAP.Width / 2 / (GridValue * MAP.Width / 2 / _minGridStep / 10);
|
||
int stepY = MAP.Height / 2 / (GridValue * MAP.Height / 2 / _minGridStep / 10);
|
||
|
||
//int stepX = _minGridStep + (10 - GridValue) * (MAP.Width / 2 - _minGridStep) / 10;
|
||
//int stepY = _minGridStep + (10 - GridValue) * (MAP.Height / 2 - _minGridStep) / 10;
|
||
|
||
int yPositive = baseY;
|
||
do
|
||
{
|
||
xPoint = new Point[] { new Point(0, yPositive), new Point(MAP.Width, yPositive) };
|
||
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
|
||
yPositive -= stepY;
|
||
} while (yPositive > 0);
|
||
|
||
int yNegative = baseY;
|
||
do
|
||
{
|
||
xPoint = new Point[] { new Point(0, yNegative), new Point(MAP.Width, yNegative) };
|
||
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
|
||
yNegative += stepY;
|
||
} while (yNegative < MAP.Height);
|
||
|
||
int xPositive = baseX;
|
||
do
|
||
{
|
||
yPoint = new Point[] { new Point(xPositive, 0), new Point(xPositive, MAP.Height) };
|
||
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
|
||
xPositive -= stepX;
|
||
} while (xPositive > 0);
|
||
|
||
int xNegative = baseX;
|
||
do
|
||
{
|
||
yPoint = new Point[] { new Point(xNegative, 0), new Point(xNegative, MAP.Height) };
|
||
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
|
||
xNegative += stepX;
|
||
} while (xNegative < MAP.Width);
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
if (MouseState == MouseState.SelectionZoneDoing)
|
||
{
|
||
g.DrawRectangle(Pens.AliceBlue, _selectionRect.X, _selectionRect.Y, _selectionRect.Width, _selectionRect.Height);
|
||
g.FillRectangle(new SolidBrush(Color.FromArgb(40, 0, 0, 255)), _selectionRect);
|
||
}
|
||
|
||
myBuffer.Render(originG);
|
||
g.Dispose();
|
||
myBuffer.Dispose();//释放资源
|
||
}
|
||
catch (Exception)
|
||
{
|
||
}
|
||
}
|
||
|
||
private void halfTransparent()
|
||
{
|
||
}
|
||
#endregion
|
||
|
||
#region 绘制类型
|
||
private IShapeElement drawTemplate = null;
|
||
public IShapeElement DrawTemplate
|
||
{
|
||
get
|
||
{
|
||
return drawTemplate;
|
||
}
|
||
set
|
||
{
|
||
if (drawTemplate != value)
|
||
{
|
||
|
||
drawTemplate = value;
|
||
|
||
//DrawTemplateChanged?.BeginInvoke(value, null, null);
|
||
Task.Run(() => DrawTemplateChanged.Invoke(value));
|
||
|
||
if (value == null)
|
||
{
|
||
MouseState = MouseState.Normal;
|
||
return;
|
||
}
|
||
|
||
MouseState = MouseState.New;
|
||
|
||
var existed = Elements.FirstOrDefault(e => e.ID == value.ID);
|
||
if (existed != null)
|
||
{
|
||
Elements.Remove(existed);
|
||
}
|
||
|
||
//if (DrawTemplate != null)
|
||
//{
|
||
// DrawTemplate.OnDrawDone += OnElementDrawDone;
|
||
//}
|
||
}
|
||
}
|
||
}
|
||
|
||
string currentElementId = "";
|
||
string CurrentElementId
|
||
{
|
||
get
|
||
{
|
||
return currentElementId;
|
||
}
|
||
set
|
||
{
|
||
if (currentElementId != value)
|
||
{
|
||
currentElementId = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnElementDrawDone(IShapeElement ele)
|
||
{
|
||
//int maxIndex = 1;
|
||
//if (Elements.Count > 0)
|
||
//{
|
||
// maxIndex = Elements.Max(u => u.Index) + 1;
|
||
//}
|
||
//ele.Index = maxIndex;
|
||
//ele.Name = maxIndex.ToString();
|
||
|
||
//#region 获取基元的设备属性,目前包括运动坐标和相机参数
|
||
//SetElementDevicePara?.Invoke(ele);
|
||
//#endregion
|
||
|
||
//Elements.Add(ele);
|
||
//DrawTemplate = DrawTemplate?.Clone() as IShapeElement;
|
||
}
|
||
#endregion
|
||
|
||
#region 状态变换
|
||
private void OnElementChangeMouseState(IShapeElement ele, ElementState preState, ElementState curState)
|
||
{
|
||
if (curState != ElementState.Normal)
|
||
{
|
||
switch (curState)
|
||
{
|
||
case ElementState.New:
|
||
MouseState = MouseState.New;
|
||
break;
|
||
case ElementState.Selected:
|
||
CurrentElementId = ele.ID;
|
||
Cursor = Cursors.Default;
|
||
break;
|
||
case ElementState.Moving:
|
||
MouseState = MouseState.MoveElement;
|
||
Cursor = Cursors.NoMove2D;
|
||
break;
|
||
case ElementState.Editing:
|
||
MouseState = MouseState.Editing;
|
||
Cursor = Cursors.Hand;
|
||
break;
|
||
case ElementState.MouseInSide:
|
||
MouseState = MouseState.InSideElement;
|
||
break;
|
||
case ElementState.MouseHover:
|
||
MouseState = MouseState.HoverElement;
|
||
break;
|
||
case ElementState.CanStretchLeft:
|
||
Cursor = Cursors.SizeWE;
|
||
break;
|
||
case ElementState.StretchingLeft:
|
||
MouseState = MouseState.StretchingLeft;
|
||
Cursor = Cursors.SizeWE;
|
||
break;
|
||
case ElementState.CanStretchBottom:
|
||
Cursor = Cursors.SizeNS;
|
||
break;
|
||
case ElementState.StretchingBottom:
|
||
MouseState = MouseState.StretchingBottom;
|
||
Cursor = Cursors.SizeNS;
|
||
break;
|
||
case ElementState.CanStretchRight:
|
||
Cursor = Cursors.SizeWE;
|
||
break;
|
||
case ElementState.StretchingRight:
|
||
MouseState = MouseState.StretchingRight;
|
||
Cursor = Cursors.SizeWE;
|
||
break;
|
||
case ElementState.CanStretchTop:
|
||
Cursor = Cursors.SizeNS;
|
||
break;
|
||
case ElementState.StretchingTop:
|
||
MouseState = MouseState.StretchingTop;
|
||
Cursor = Cursors.SizeNS;
|
||
break;
|
||
|
||
case ElementState.CanStretchLeftLowerCorner:
|
||
Cursor = Cursors.SizeNESW;
|
||
break;
|
||
case ElementState.StretchingLeftLowerCorner:
|
||
MouseState = MouseState.StretchingLeftLowerCorner;
|
||
Cursor = Cursors.SizeNESW;
|
||
break;
|
||
case ElementState.CanStretchLeftUpperCorner:
|
||
Cursor = Cursors.SizeNWSE;
|
||
break;
|
||
case ElementState.StretchingLeftUpperCorner:
|
||
MouseState = MouseState.StretchingLeftUpperCorner;
|
||
Cursor = Cursors.SizeNWSE;
|
||
break;
|
||
case ElementState.CanStretchRightLowerCorner:
|
||
Cursor = Cursors.SizeNWSE;
|
||
break;
|
||
case ElementState.StretchingRightLowerCorner:
|
||
MouseState = MouseState.StretchingRightLowerCorner;
|
||
Cursor = Cursors.SizeNWSE;
|
||
break;
|
||
case ElementState.CanStretchRightUpperCorner:
|
||
Cursor = Cursors.SizeNESW;
|
||
break;
|
||
case ElementState.StretchingRightUpperCorner:
|
||
MouseState = MouseState.StretchingRightUpperCorner;
|
||
Cursor = Cursors.SizeNESW;
|
||
break;
|
||
default:
|
||
//MouseState = MouseState.Normal;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (Elements.All(e => e.State == ElementState.Normal))
|
||
{
|
||
CurrentElementId = null;
|
||
|
||
if (preState == ElementState.Selected)
|
||
{
|
||
DrawTemplate = null;
|
||
}
|
||
else if (DrawTemplate != null)
|
||
{
|
||
MouseState = MouseState.New;
|
||
return;
|
||
}
|
||
|
||
//MouseState = MouseState.Normal;
|
||
}
|
||
}
|
||
|
||
this.Invalidate();
|
||
}
|
||
#endregion
|
||
|
||
#region 鼠标动作
|
||
private void Canvas_MouseWheel(object sender, MouseEventArgs e)
|
||
{
|
||
PointF prePoint = ToMapPoint(e.Location);
|
||
|
||
//先缩放
|
||
if (e.Delta > 0)
|
||
{
|
||
Matrix.Scale((float)1.1, (float)1.1);
|
||
}
|
||
else
|
||
{
|
||
Matrix.Scale((float)0.9, (float)0.9);
|
||
}
|
||
|
||
PointF afterPoint = ToMapPoint(e.Location);
|
||
|
||
//后平移
|
||
Matrix.Translate(afterPoint.X - prePoint.X, afterPoint.Y - prePoint.Y);
|
||
|
||
Invalidate();
|
||
}
|
||
|
||
PointF startPoint, currentPoint;
|
||
bool _isMouseBtnPressing = false;
|
||
|
||
private void Canvas_MouseDown(object sender, MouseEventArgs e)
|
||
{
|
||
PointF p = ToMapPoint(e.Location);
|
||
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
_isMouseBtnPressing = true;
|
||
|
||
switch (MouseState)
|
||
{
|
||
case MouseState.Normal:
|
||
startPoint = e.Location;
|
||
break;
|
||
case MouseState.StretchingLeft:
|
||
break;
|
||
case MouseState.StretchingRight:
|
||
break;
|
||
case MouseState.StretchingTop:
|
||
break;
|
||
case MouseState.StretchingBottom:
|
||
break;
|
||
case MouseState.MoveElement:
|
||
break;
|
||
case MouseState.HoverElement:
|
||
case MouseState.InSideElement:
|
||
case MouseState.New:
|
||
DrawTemplate?.OnMouseDown(p);
|
||
break;
|
||
case MouseState.Editing:
|
||
break;
|
||
case MouseState.SelectionZone:
|
||
MouseState = MouseState.SelectionZoneDoing;
|
||
startPoint = p;
|
||
break;
|
||
}
|
||
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
ele.OnMouseDown(p);
|
||
}
|
||
}
|
||
else if (e.Button == MouseButtons.Right)
|
||
{
|
||
if (DrawTemplate != null && DrawTemplate.State == ElementState.New && DrawTemplate.IsCreatedDone())
|
||
{
|
||
IShapeElement ele = DrawTemplate.Clone() as IShapeElement;
|
||
ele.State = ElementState.Normal;
|
||
Elements.Add(ele);
|
||
|
||
// (DrawTemplate as ElementBase).Initial();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void Canvas_MouseUp(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button != MouseButtons.Left)
|
||
return;
|
||
|
||
_isMouseBtnPressing = false;
|
||
switch (MouseState)
|
||
{
|
||
case MouseState.Normal:
|
||
break;
|
||
case MouseState.HoverElement:
|
||
break;
|
||
case MouseState.InSideElement:
|
||
break;
|
||
case MouseState.StretchingLeft:
|
||
break;
|
||
case MouseState.StretchingRight:
|
||
break;
|
||
case MouseState.StretchingTop:
|
||
break;
|
||
case MouseState.StretchingBottom:
|
||
break;
|
||
case MouseState.MoveElement:
|
||
//MouseState = MouseState.SelectedElement;
|
||
break;
|
||
case MouseState.New:
|
||
break;
|
||
case MouseState.Editing:
|
||
break;
|
||
case MouseState.MovingAll:
|
||
MouseState = MouseState.Normal;
|
||
break;
|
||
case MouseState.SelectionZone:
|
||
break;
|
||
case MouseState.SelectionZoneDoing:
|
||
MouseState = MouseState.SelectionZone;
|
||
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
ele.State = ElementState.Normal;
|
||
if (ele.IsIntersect(_selectionRect))
|
||
{
|
||
ele.State = ElementState.Selected;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
Cursor = Cursors.Default;
|
||
|
||
if (MouseState != MouseState.SelectionZone)
|
||
{
|
||
PointF p = ToMapPoint(e.Location);
|
||
DrawTemplate?.OnMouseUp(p);
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
ele.OnMouseUp(p);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void Canvas_MouseMove(object sender, MouseEventArgs e)
|
||
{
|
||
PointF p = ToMapPoint(e.Location);
|
||
|
||
switch (MouseState)
|
||
{
|
||
case MouseState.Normal:
|
||
{
|
||
if (_isMouseBtnPressing)
|
||
{
|
||
currentPoint = e.Location;
|
||
PointF p1 = ToMapPoint(startPoint);
|
||
PointF p2 = ToMapPoint(currentPoint);
|
||
Matrix.Translate(p2.X - p1.X, p2.Y - p1.Y);
|
||
startPoint = e.Location;
|
||
}
|
||
}
|
||
break;
|
||
case MouseState.StretchingLeft:
|
||
break;
|
||
case MouseState.StretchingRight:
|
||
break;
|
||
case MouseState.StretchingTop:
|
||
break;
|
||
case MouseState.StretchingBottom:
|
||
break;
|
||
case MouseState.MoveElement:
|
||
break;
|
||
case MouseState.HoverElement:
|
||
case MouseState.InSideElement:
|
||
case MouseState.New:
|
||
DrawTemplate?.OnMouseMove(p);
|
||
break;
|
||
case MouseState.Editing:
|
||
break;
|
||
case MouseState.MovingAll:
|
||
break;
|
||
case MouseState.SelectionZoneDoing:
|
||
{
|
||
currentPoint = p;
|
||
|
||
float[] x2 = new float[2] { startPoint.X, currentPoint.X };
|
||
float[] y2 = new float[2] { startPoint.Y, currentPoint.Y };
|
||
|
||
float xMin = x2.Min();
|
||
float xMax = x2.Max();
|
||
float yMin = y2.Min();
|
||
float yMax = y2.Max();
|
||
|
||
_selectionRect = new RectangleF(xMin, yMin, xMax - xMin, yMax - yMin);
|
||
}
|
||
break;
|
||
}
|
||
|
||
PointF mapPoint = ToMapPoint(e.Location);
|
||
Color color = Color.Transparent;
|
||
if (MAP != null && mapPoint.X > 0 && mapPoint.X < MAP.Width && mapPoint.Y > 0 && mapPoint.Y < MAP.Height)
|
||
{
|
||
color = MAP.GetPixel((int)mapPoint.X, (int)mapPoint.Y);
|
||
}
|
||
|
||
// OnMouseLocationUpdated?.BeginInvoke(e.Location, mapPoint, color.Name, null, null);
|
||
Task.Run(() => OnMouseLocationUpdated?.Invoke(e.Location, mapPoint, color.Name));
|
||
|
||
if (MouseState != MouseState.SelectionZoneDoing)
|
||
{
|
||
Elements.ToList().ForEach(ele => ele?.OnMouseMove(p));
|
||
}
|
||
|
||
Invalidate();
|
||
}
|
||
|
||
private void Canvas_MouseDoubleClick(object sender, MouseEventArgs e)
|
||
{
|
||
PointF p = ToMapPoint(e.Location);
|
||
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
switch (MouseState)
|
||
{
|
||
//case MouseState.SelectedElement:
|
||
case MouseState.HoverElement:
|
||
case MouseState.InSideElement:
|
||
case MouseState.MoveElement:
|
||
case MouseState.Normal:
|
||
//Elements.ForEach(ele =>
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
ele.OnMouseDoubleClick(p);
|
||
}
|
||
//);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//if (MouseState == MouseState.SelectedElement)
|
||
{
|
||
MouseState = MouseState.Normal;
|
||
|
||
//Elements.ForEach(ele =>
|
||
foreach (IShapeElement ele in Elements)
|
||
{
|
||
ele.State = ElementState.Normal;
|
||
}
|
||
//);
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 图片操作
|
||
bool _firstLoad = true;
|
||
object _mapLoadLock = new object();
|
||
ManualResetEvent _mapLoadHandler = new ManualResetEvent(true);
|
||
ManualResetEvent _mapUsingHandler = new ManualResetEvent(false);
|
||
|
||
/// <summary>
|
||
/// 载入图片
|
||
/// </summary>
|
||
/// <param name="bitmap"></param>
|
||
public void LoadImage(Bitmap bitmap)
|
||
{
|
||
if (bitmap == null)
|
||
return;
|
||
|
||
////lock (_mapLoadLock)
|
||
////_mapUsingHandler.WaitOne();
|
||
//_mapLoadHandler.Reset();
|
||
//{
|
||
// map?.Dispose();
|
||
// map = null;
|
||
// map = bitmap;
|
||
//}
|
||
//_mapLoadHandler.Set();
|
||
|
||
MAP = bitmap;
|
||
|
||
if (_firstLoad)
|
||
{
|
||
SetScreenSize();
|
||
_firstLoad = false;
|
||
}
|
||
Invalidate();
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
MAP = null;
|
||
Elements.Clear();
|
||
|
||
Invalidate();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置图片为原始尺寸
|
||
/// </summary>
|
||
public void SetMapSize()
|
||
{
|
||
Matrix = new Matrix();
|
||
Invalidate();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置图片为适配尺寸
|
||
/// </summary>
|
||
public void SetScreenSize()
|
||
{
|
||
try
|
||
{
|
||
if (MAP == null)
|
||
return;
|
||
|
||
Matrix = new Matrix();
|
||
|
||
//先缩放
|
||
List<float> ratios = new List<float>() { MAP.Width / (float)Width, MAP.Height / (float)Height };
|
||
float ratio = 1 / ratios.Max();
|
||
Matrix.Scale(ratio, ratio);
|
||
|
||
//再平移
|
||
//将plMain的中心转换为图片坐标
|
||
PointF screenCenter = new PointF(Width / 2.0f, Height / 2.0f);
|
||
PointF mapPoint = ToMapPoint(screenCenter);
|
||
|
||
//目标坐标减去当前坐标
|
||
Matrix.Translate(-MAP.Width / 2.0f + mapPoint.X, -MAP.Height / 2.0f + mapPoint.Y);
|
||
|
||
Invalidate();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//Trace.TraceError(ex.GetExceptionMessage());
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
//private void DisplayMouseLocation(Point location)
|
||
//{
|
||
// string screenPoint = string.Format("屏幕坐标X:{0};Y:{1}", location.X, location.Y);
|
||
|
||
// Point mapPoint = ToMapPoint(location);
|
||
// string mapPointStr = string.Format("图片坐标X:{0};Y:{1}", mapPoint.X, mapPoint.Y);
|
||
|
||
// tsslLocation.Text = screenPoint + " " + mapPointStr;
|
||
//}
|
||
|
||
private PointF ToMapPoint(PointF p)
|
||
{
|
||
PointF[] ps = new PointF[] { p };
|
||
Matrix invertMatrix = Matrix.Clone();
|
||
invertMatrix.Invert();
|
||
invertMatrix.TransformPoints(ps);
|
||
|
||
return ps[0];
|
||
}
|
||
|
||
private Point ToScreenPoint(Point p)
|
||
{
|
||
Point[] ps = new Point[] { p };
|
||
Matrix.TransformPoints(ps);
|
||
|
||
return ps[0];
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 按键操作
|
||
public void OnCanvasKeyPressed(object sender, KeyPressEventArgs e)
|
||
{
|
||
//if (e.KeyChar == 27) //Esc
|
||
//{
|
||
// //if (MouseState == MouseState.SelectedElement)
|
||
// {
|
||
// MouseState = MouseState.Normal;
|
||
|
||
// //Elements.ForEach(ele =>
|
||
// foreach (IShapeElement ele in Elements)
|
||
// {
|
||
// ele.State = ElementState.Normal;
|
||
// }
|
||
// //);
|
||
// }
|
||
//}
|
||
|
||
//Invalidate();
|
||
}
|
||
|
||
public void OnCanvasKeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.Delete) //delete键
|
||
{
|
||
Elements.Remove(Elements.FirstOrDefault(u => u.ID == CurrentElementId));
|
||
}
|
||
|
||
if (e.KeyData == Keys.Escape) //Esc
|
||
{
|
||
if (DrawTemplate != null /*&& (DrawTemplate as ElementBase).CreatePoints.Count > 0*/)
|
||
{
|
||
DrawTemplate.Initial();
|
||
}
|
||
else
|
||
{
|
||
DrawTemplate = null;
|
||
|
||
if (MouseState != MouseState.Normal)
|
||
{
|
||
MouseState = MouseState.Normal;
|
||
}
|
||
else
|
||
{
|
||
Elements.ToList().ForEach(u => u.State = ElementState.Normal);
|
||
}
|
||
}
|
||
}
|
||
|
||
//if (e.KeyData == Keys.Up)
|
||
//{
|
||
// Elements.ToList().ForEach(u =>
|
||
// {
|
||
// if (u.State == ElementState.Selected)
|
||
// {
|
||
// u.Translate(0, -1);
|
||
// }
|
||
// });
|
||
//}
|
||
|
||
//if (e.KeyData == Keys.Down)
|
||
//{
|
||
// Elements.ToList().ForEach(u =>
|
||
// {
|
||
// if (u.State == ElementState.Selected)
|
||
// {
|
||
// u.Translate(0, 1);
|
||
// }
|
||
// });
|
||
//}
|
||
|
||
//if (e.KeyData == Keys.Left)
|
||
//{
|
||
// Elements.ToList().ForEach(u =>
|
||
// {
|
||
// if (u.State == ElementState.Selected)
|
||
// {
|
||
// u.Translate(-1, 0);
|
||
// }
|
||
// });
|
||
//}
|
||
|
||
//if (e.KeyData == Keys.Right)
|
||
//{
|
||
// Elements.ToList().ForEach(u =>
|
||
// {
|
||
// if (u.State == ElementState.Selected)
|
||
// {
|
||
// u.Translate(1, 0);
|
||
// }
|
||
// });
|
||
//}
|
||
|
||
Invalidate();
|
||
}
|
||
#endregion
|
||
|
||
#region 基元的设备属性 运动设置和相机设置
|
||
public Action<IShapeElement> SetElementDevicePara;
|
||
|
||
public Action<IShapeElement> SetDeviceByElement;
|
||
#endregion
|
||
|
||
#region Grid
|
||
private bool showGrid = false;
|
||
public bool ShowGrid
|
||
{
|
||
get => showGrid;
|
||
set
|
||
{
|
||
showGrid = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
private int gridValue = 0;
|
||
public int GridValue
|
||
{
|
||
get => gridValue;
|
||
set
|
||
{
|
||
gridValue = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
private Pen penGrid = new Pen(Color.FromArgb(120, Color.Red), 1.0f);
|
||
public Pen Pen_Grid
|
||
{
|
||
get => penGrid;
|
||
set
|
||
{
|
||
penGrid = value;
|
||
Invalidate();
|
||
}
|
||
}
|
||
|
||
readonly int _minGridStep = 10;
|
||
#endregion
|
||
|
||
#region Dispose
|
||
/// <summary>
|
||
/// 清理所有正在使用的资源。
|
||
/// </summary>
|
||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||
protected override void Dispose(bool disposing)
|
||
{
|
||
MAP?.Dispose();
|
||
Matrix?.Dispose();
|
||
penGrid?.Dispose();
|
||
|
||
if (disposing && (components != null))
|
||
{
|
||
components.Dispose();
|
||
}
|
||
base.Dispose(disposing);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|