2025-03-16 13:11:08 +08:00

630 lines
19 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
public partial class Canvas : UserControl
{
readonly CanvasImage cvImage = new CanvasImage();
#region Grid
readonly GridCtrl gridCtrl = new GridCtrl();
private void GridValueChanged(int gridValue)
{
cvImage.GridValue = gridValue;
}
private void ShowGridChanged(bool isShowGrid)
{
cvImage.ShowGrid = isShowGrid;
}
private void GridColorChanged(Color obj)
{
cvImage.Pen_Grid.Color = obj;
}
#endregion
public Canvas()
{
InitializeComponent();
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
cvImage.Dock = DockStyle.Fill;
scMain.Panel1.Controls.Add(cvImage);
dgElements.AutoGenerateColumns = false;
var checkHead = new DataGridViewCheckboxHeaderCell();
checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked;
dgElements.Columns[0].HeaderCell = checkHead;
dgElements.Columns[0].HeaderCell.Value = string.Empty;
Elements.CollectionChanged += Elements_CollectionChanged;
cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated;
cvImage.OnMouseStateChanged += OnMouseStateChanged;
gridCtrl.IsShowGridChanged = ShowGridChanged;
gridCtrl.GridValueChanged = GridValueChanged;
gridCtrl.GridColorChanged = GridColorChanged;
gridCtrl.Padding = new Padding(0, 5, 0, 5);
tsTool.Items.Add(new GridCtrlHost(gridCtrl));
tsTool.Invalidate();
_eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1);
//tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false;
}
private void OnMouseStateChanged(MouseState ms)
{
if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing)
{
if (this.IsHandleCreated)
{
this.Invoke(new Action(() =>
{
tsBtnModeSelection.Checked = false;
tsBtnModeNormal.Checked = true;
}));
}
}
}
#region
public bool IsShowStatusBar
{
get => stsStatus.Visible;
set => stsStatus.Visible = value;
}
private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc)
{
//await Task.Run(() => tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}");
this.Invoke(new Action(() =>
{
tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X.ToString("f2")}Y{imagePoint.Y.ToString("f2")} 颜色:{colorDesc}";
}));
}
//private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc)
//{
// if (InvokeRequired)
// {
// Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint);
// }
// else
// {
// tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}";
// }
//}
#endregion
#region
#region CanvasImage相关
//private MouseState mouseState = MouseState.Normal;
//public MouseState MouseState
//{
// get
// {
// return mouseState;
// }
// set
// {
// if (mouseState != value)
// {
// mouseState = value;
// tsslMouseState.Text = mouseState.ToString();
// if (mouseState >= MouseState.SelectionZone)
// {
// tsBtnModeSelection.Checked = true;
// }
// else
// {
// tsBtnModeNormal.Checked = true;
// }
// }
// }
//}
public string ImageFilePath { get; set; }
public Bitmap MAP
{
get => cvImage.MAP;
set => cvImage.MAP = value;
}
public Matrix Matrix
{
get => cvImage.Matrix;
set => cvImage.Matrix = value;
}
public MouseState MouseState
{
get => cvImage.MouseState;
set => cvImage.MouseState = value;
}
public ObservableCollection<IShapeElement> Elements
{
get => cvImage.Elements;
}
#endregion
private bool isShowElementList = false;
public bool IsShowElementList
{
get => isShowElementList;
set
{
//if (isShowElementList != value)
{
isShowElementList = value;
scMain.Panel2Collapsed = !value;
}
}
}
private bool isShowROITool = false;
public bool IsShowROITool
{
get => isShowROITool;
set
{
tsROIs.Visible = isShowROITool = value;
}
}
#endregion
#region
/// <summary>
/// 载入图片
/// </summary>
/// <param name="map"></param>
public void LoadImage(Bitmap map)
{
cvImage.LoadImage(map);
OnImageChanged?.Invoke();
}
public void Clear()
{
cvImage.Clear();
}
/// <summary>
/// 设置图片为原始尺寸
/// </summary>
public void SetMapSize()
{
cvImage.SetMapSize();
}
/// <summary>
/// 设置图片为适配尺寸
/// </summary>
public void SetScreenSize()
{
cvImage.SetScreenSize();
}
#endregion
#region
private void chkShowChecked_CheckedChanged(object sender, EventArgs e)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList();
}
}
}
private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// ele.IsEnabled = e.CheckedState;
//}
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].IsEnabled = e.CheckedState;
}
OnElementChanged(null);
}
private void dgElements_SelectionChanged(object sender, EventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
propGridElement.SelectedObject = ele;
}
}
private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].State = ElementState.Normal;
}
ele.State = ElementState.Selected;
SetDeviceByElement?.Invoke(ele);
Invalidate();
}
}
System.Threading.Timer _eleCollectionChangedTimer = null;
private void OnElementCollectionChangedBufferTimer(object state)
{
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
//foreach (IShapeElement ele in Elements)
//{
// ele.PropertyChanged -= Ele_PropertyChanged;
// ele.PropertyChanged += Ele_PropertyChanged;
//}
}
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//_eleCollectionChangedTimer?.Change(200, -1);
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
}
private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsEnabled")
{
OnElementChanged(sender as IShapeElement);
}
else
{
Invoke(new Action(() =>
{
cvImage.Invalidate();
}));
}
}
private void OnElementChanged(IShapeElement ele)
{
if (ele != null)
OnElementChangedHandle?.Invoke(ele);
if (InvokeRequired)
{
Invoke(new Action(() => OnElementChanged(ele)));
}
else
{
if (isShowElementList)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList();
}
}
Invalidate();
}
}
}
private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e)
{
propGridElement.ExpandAllGridItems();
}
#region
private void tsmiResort_Click(object sender, EventArgs e)
{
//Elements.Sort();
}
private void tsmiClearActualValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetActualValue(0.0);
// }
//}
}
private void tsmiInitialState_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.State = ElementState.Normal;
// ele.InitialMeasureResult();
// }
//}
}
private void tsmiClearStandardValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetStandardValue(0.0);
// }
//}
}
#endregion
#endregion
#region
private void tsmiKeepUnselected_Click(object sender, EventArgs e)
{
KeepElements(false);
}
private void tsmiKeepSelected_Click(object sender, EventArgs e)
{
KeepElements(true);
}
private void KeepElements(bool isKeepSelected)
{
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
{
if (ele.State == ElementState.Selected)
{
ele.IsEnabled = isKeepSelected;
}
else
{
ele.IsEnabled = !isKeepSelected;
}
}
}
}
private void tsmiUnselectElements_Click(object sender, EventArgs e)
{
//if (MouseState == MouseState.SelectedElement)
//{
// MouseState = MouseState.Normal;
// //Elements.ForEach(ele =>
// foreach (IShapeElement ele in Elements)
// {
// ele.State = ElementState.Normal;
// }
// //);
//}
}
#endregion
#region
public Action<IShapeElement> SetElementDevicePara;
public Action<IShapeElement> SetDeviceByElement;
#endregion
#region
public bool IsShowToolBar
{
get => tsTool.Visible;
set => tsTool.Visible = value;
}
private void tsBtnLoadImage_Click(object sender, EventArgs e)
{
Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage));
InvokeThread.SetApartmentState(ApartmentState.STA);
InvokeThread.Start();
InvokeThread.Join();
}
private void OpenLoadImage()
{
ImageFilePath = "";
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
ImageFilePath = ofd.FileName;
LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath));
}
}
private void tsBtnSaveImage_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
if (filePath.EndsWith("bmp"))
{
MAP.Save(filePath, ImageFormat.Bmp);
}
else
{
MAP.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("图片保存成功!");
}
}
private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.DrawImage(MAP, 0, 0);
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
ele.Draw(g);
}
}
if (filePath.EndsWith("bmp"))
{
bmp.Save(filePath, ImageFormat.Bmp);
}
else
{
bmp.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("带基元图片保存成功!");
}
}
private void tsBtnMapSize_Click(object sender, EventArgs e)
{
SetMapSize();
}
private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e)
{
var btn = sender as ToolStripButton;
if (btn.Checked)
{
btn.BackColor = SystemColors.ActiveCaption;
foreach (ToolStripItem c in tsTool.Items)
{
if (c is ToolStripButton)
{
if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name)
{
var temp = c as ToolStripButton;
temp.Checked = false;
temp.BackColor = SystemColors.Control;
}
}
}
switch (btn.Name)
{
case "tsBtnModeNormal":
MouseState = MouseState.Normal;
break;
case "tsBtnModeSelection":
MouseState = MouseState.SelectionZone;
break;
}
}
}
private void tsBtnScreenSize_Click(object sender, EventArgs e)
{
SetScreenSize();
}
#endregion
#region
//private void LoadElementTools()
//{
// var eleDict = ElementFactory.GetAllElementsInfo();
// foreach (KeyValuePair<ElementAttribute, Type> pair in eleDict)
// {
// }
//}
public void SetNewROIType(IShapeElement element)
{
cvImage.DrawTemplate = element;
}
#endregion
#region
public event Action<IShapeElement> OnElementChangedHandle;
public event Action OnImageChanged;
#endregion
#region /
private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowToolBar = tsmiShowToolBar.Checked;
}
private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowStatusBar = tsmiShowStatusBar.Checked;
}
#endregion
}
}