630 lines
19 KiB
C#
Raw Normal View History

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

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
}
}