PrintLabelShow.cs
28.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
using System;
using System.Collections.Generic;
using System.Drawing;
using Model;
using System.Windows.Forms;
namespace BLL
{
public class PrintLabelShow
{
public delegate void SizeShow();
public delegate void SizeChanged(int fieldIndex);
public event SizeChanged FieldSizeChanged;
public event SizeShow LabelSizeShow;
private PictureBox picShow;
private PrintLabelTemplate labelTemp;
private Point oldPoint;
private PointF labelOffset;
private RectangleF labelRect = new();
private string labelText = "";
private RectangleF labelTextRect = new();
private int fieldIndex = -1;
private RectangleF[] fieldRect;
private string fieldText = "";
private RectangleF fieldTextRect = new();
private bool fieldMarginChange = false;
private FieldMargin fieldMargin = FieldMargin.Outside;
// 添加缩放相关属性
private float zoomFactor = 1.0f;
private Size lastPicBoxSize;
private bool autoScale = true; // 是否启用自动缩放
private bool isPanning=false;
private const int FIELD_MARGIN = 5;
private readonly Font LABEL_TEXT_FONT = new("宋体", 12f);
public PrintLabelShow(PictureBox pic)
{
picShow = pic;
pic.MouseDown += PicEdit_MouseDown;
pic.MouseMove += PicEdit_MouseMove;
pic.MouseUp += PicEdit_MouseUp;
pic.Paint += PicEdit_Paint;
pic.MouseEnter += PicEdit_MouseEnter;
pic.MouseLeave += PicEdit_MouseLeave;
// 添加缩放相关事件
lastPicBoxSize = pic.Size;
pic.SizeChanged += PicShow_SizeChanged;
pic.MouseWheel += PicShow_MouseWheel;
}
// 缩放属性设置
public bool AutoScale
{
get { return autoScale; }
set
{
autoScale = value;
if (autoScale && labelTemp != null)
{
RecalculateZoomFactor();
CalcSize(true);
picShow.Refresh();
}
}
}
public float ZoomFactor
{
get { return zoomFactor; }
set
{
if (value >= 0.1f && value <= 5.0f)
{
zoomFactor = value;
CalcSize(true);
picShow.Refresh();
}
}
}
public void Load(PrintLabelTemplate temp)
{
labelTemp = temp;
fieldIndex = -1;
if (labelTemp != null)
{
// 设置初始偏移位置(居中)
if (autoScale)
{
SizeF labelSize = ObjConversion.MmToPx(labelTemp.Size);
labelOffset = new PointF(
(picShow.Width - labelSize.Width) / 2,
(picShow.Height - labelSize.Height) / 2);
}
// 正确初始化所有字段图像
for (int i = 0; i < labelTemp.Field.Count; i++)
{
if (labelTemp.Field[i].Type == PrintLabelFieldType.Text)
{
labelTemp.Field[i].Image = null;
}
else
{
SizeF sf = ObjConversion.MmToPx(labelTemp.Field[i].Rectangle.Size);
labelTemp.Field[i].Image = ConvertBarcode.StrToCode(
labelTemp.Field[i].Type,
labelTemp.Field[i].Text,
sf);
}
}
// 计算缩放比例
if (autoScale)
RecalculateZoomFactor();
CalcSize();
}
picShow.Refresh();
}
public void Refresh()
{
if (labelTemp == null) return;
if (autoScale)
RecalculateZoomFactor();
// 刷新条码图像
RefreshBarcodeImages();
CalcSize();
picShow.Refresh();
}
public void FieldSelected(int index)
{
fieldIndex = index;
CalcSize();
picShow.Refresh();
FieldSizeChanged?.Invoke(fieldIndex);
}
// 添加字段方法
public void AddField(PrintLabelField field)
{
if (labelTemp == null) return;
// 添加新字段
labelTemp.Field.Add(field);
// 如果是条码类型,生成图像
if (field.Type != PrintLabelFieldType.Text)
{
SizeF sf = ObjConversion.MmToPx(field.Rectangle.Size);
field.Image = ConvertBarcode.StrToCode(field.Type, field.Text, sf);
}
// 设置为当前选中字段
fieldIndex = labelTemp.Field.Count - 1;
// 更新计算
CalcSize();
// 重绘
picShow.Refresh();
// 通知外部程序更新字段属性
FieldSizeChanged?.Invoke(fieldIndex);
}
// 缩放事件处理
private void PicShow_SizeChanged(object sender, EventArgs e)
{
if (labelTemp == null || !autoScale) return;
RecalculateZoomFactor();
CalcSize(true);
picShow.Refresh();
lastPicBoxSize = picShow.Size;
}
private void PicShow_MouseWheel(object sender, MouseEventArgs e)
{
if (labelTemp == null) return;
// 暂时禁用自动缩放
bool oldAutoScale = autoScale;
autoScale = false;
// 获取鼠标位置相对于标签的位置(用于以鼠标为中心点缩放)
PointF mouseOnLabel = new PointF(
(e.Location.X - labelOffset.X) / zoomFactor,
(e.Location.Y - labelOffset.Y) / zoomFactor);
// 保存旧的缩放因子
float oldZoomFactor = zoomFactor;
// 调整缩放系数
if (e.Delta > 0)
zoomFactor *= 1.1f; // 放大10%,无上限
else
zoomFactor *= 0.9f; // 缩小10%,无下限
// 防止缩放因子变为0或负数(这会导致显示问题)
if (zoomFactor < 0.001f) // 使用非常小的最小值
zoomFactor = 0.001f;
// 调整标签偏移,使缩放以鼠标位置为中心
labelOffset.X = e.Location.X - mouseOnLabel.X * zoomFactor;
labelOffset.Y = e.Location.Y - mouseOnLabel.Y * zoomFactor;
// 重新生成条码图像(如果缩放系数变化明显)
if (Math.Abs(zoomFactor - oldZoomFactor) > 0.05f)
{
RefreshBarcodeImages();
}
// 限制拖动范围
LimitPanningBounds();
// 重新计算
CalcSize(true);
picShow.Refresh();
// 恢复自动缩放设置
autoScale = oldAutoScale;
}
private void RefreshBarcodeImages()
{
if (labelTemp == null) return;
for (int i = 0; i < labelTemp.Field.Count; i++)
{
if (labelTemp.Field[i].Type != PrintLabelFieldType.Text)
{
// 获取实际大小(考虑缩放)
SizeF originalSize = ObjConversion.MmToPx(labelTemp.Field[i].Rectangle.Size);
// 生成适当大小的条码图像
labelTemp.Field[i].Image = ConvertBarcode.StrToCode(
labelTemp.Field[i].Type,
labelTemp.Field[i].Text,
originalSize); // 不乘以缩放因子,因为绘制时会缩放
}
}
}
private void RecalculateZoomFactor()
{
if (labelTemp == null) return;
// 获取标签尺寸(像素)
SizeF labelSize = ObjConversion.MmToPx(labelTemp.Size);
// 计算当前PictureBox可用空间
float availableWidth = picShow.Width * 0.9f;
float availableHeight = picShow.Height * 0.9f;
// 计算宽度和高度的缩放比例
float widthRatio = availableWidth / labelSize.Width;
float heightRatio = availableHeight / labelSize.Height;
// 选择较小的缩放比例以确保整个标签可见
zoomFactor = Math.Min(widthRatio, heightRatio);
// 限制最小和最大缩放比例
//zoomFactor = Math.Max(0.1f, Math.Min(5.0f, zoomFactor));
// 更新标签位置以居中
labelOffset = new PointF(
(picShow.Width - labelSize.Width * zoomFactor) / 2,
(picShow.Height - labelSize.Height * zoomFactor) / 2);
}
private void CalcSize(bool recalc = true)
{
try
{
using Graphics g = picShow.CreateGraphics();
SizeF sf;
if (recalc)
{
// 应用缩放到标签
sf = ObjConversion.MmToPx(labelTemp.Size);
sf = new SizeF(sf.Width * zoomFactor, sf.Height * zoomFactor);
// 如果允许移动,可以在此限制移动范围
if (isPanning)
{
LimitPanningBounds();
}
// 放置标签于相应位置
labelRect = new RectangleF(labelOffset, sf);
// 标签上方文字
labelText = string.Format("{0:0.00}×{1:0.00} (mm) - 缩放: {2:P0}",
labelTemp.Size.Width, labelTemp.Size.Height, zoomFactor);
sf = g.MeasureString(labelText, LABEL_TEXT_FONT);
labelTextRect = new RectangleF(labelOffset.X, labelOffset.Y - sf.Height, sf.Width, sf.Height);
// 字段位置大小
fieldRect = new RectangleF[labelTemp.Field.Count];
for (int i = 0; i < labelTemp.Field.Count; i++)
{
// 获取原始尺寸
RectangleF rect = ObjConversion.MmToPx(labelTemp.Field[i].Rectangle);
// 应用缩放
rect.X *= zoomFactor;
rect.Y *= zoomFactor;
rect.Width *= zoomFactor;
rect.Height *= zoomFactor;
// 偏移到标签位置
fieldRect[i] = rect;
fieldRect[i].Offset(labelOffset);
}
}
if (fieldIndex > -1 && fieldIndex < labelTemp.Field.Count)
{
fieldText = string.Format("{0:0.00}×{1:0.00}, {2:0.00}×{3:0.00} (mm)",
labelTemp.Field[fieldIndex].Rectangle.X,
labelTemp.Field[fieldIndex].Rectangle.Y,
labelTemp.Field[fieldIndex].Rectangle.Width,
labelTemp.Field[fieldIndex].Rectangle.Height);
// 创建缩放后的字体
Font scaledFont = new Font(labelTemp.Field[fieldIndex].Font.FontFamily,
labelTemp.Field[fieldIndex].Font.Size * zoomFactor,
labelTemp.Field[fieldIndex].Font.Style);
sf = g.MeasureString(fieldText, scaledFont);
fieldTextRect = new RectangleF(fieldRect[fieldIndex].X,
fieldRect[fieldIndex].Y - sf.Height, sf.Width, sf.Height);
scaledFont.Dispose();
}
}
catch (Exception)
{
}
}
private void FindFieldMargin(Point pt)
{
try
{
fieldMargin = FieldMargin.Outside;
if (fieldIndex < 0 || fieldIndex >= fieldRect.Length) return;
RectangleF rect = fieldRect[fieldIndex];
// 计算缩放后的字段边距 - 调整以便在高缩放下更容易选择
float scaledMargin = Math.Max(FIELD_MARGIN * 0.8f, FIELD_MARGIN * zoomFactor * 0.3f);
float handleSize = scaledMargin * 2;
// 检查是否点击在各个控制点上
// 左边
if (pt.X >= rect.X - scaledMargin && pt.X <= rect.X + scaledMargin)
{
// 左上
if (pt.Y >= rect.Y - scaledMargin && pt.Y <= rect.Y + scaledMargin)
fieldMargin = FieldMargin.LeftTop;
// 左下
else if (pt.Y >= rect.Y + rect.Height - scaledMargin && pt.Y <= rect.Y + rect.Height + scaledMargin)
fieldMargin = FieldMargin.LeftBottom;
// 左边
else if (pt.Y > rect.Y && pt.Y < rect.Y + rect.Height)
fieldMargin = FieldMargin.Left;
}
// 右边
else if (pt.X >= rect.X + rect.Width - scaledMargin && pt.X <= rect.X + rect.Width + scaledMargin)
{
// 右上
if (pt.Y >= rect.Y - scaledMargin && pt.Y <= rect.Y + scaledMargin)
fieldMargin = FieldMargin.RightTop;
// 右下
else if (pt.Y >= rect.Y + rect.Height - scaledMargin && pt.Y <= rect.Y + rect.Height + scaledMargin)
fieldMargin = FieldMargin.RightBottom;
// 右边
else if (pt.Y > rect.Y && pt.Y < rect.Y + rect.Height)
fieldMargin = FieldMargin.Right;
}
// 中间区域
else if (pt.X > rect.X && pt.X < rect.X + rect.Width)
{
// 上边
if (pt.Y >= rect.Y - scaledMargin && pt.Y <= rect.Y + scaledMargin)
fieldMargin = FieldMargin.Top;
// 下边
else if (pt.Y >= rect.Y + rect.Height - scaledMargin && pt.Y <= rect.Y + rect.Height + scaledMargin)
fieldMargin = FieldMargin.Bottom;
// 内部
else if (pt.Y > rect.Y && pt.Y < rect.Y + rect.Height)
fieldMargin = FieldMargin.Inside;
}
// 根据边缘位置设置光标
switch (fieldMargin)
{
case FieldMargin.Left: picShow.Cursor = Cursors.SizeWE; break;
case FieldMargin.LeftTop: picShow.Cursor = Cursors.SizeNWSE; break;
case FieldMargin.LeftBottom: picShow.Cursor = Cursors.SizeNESW; break;
case FieldMargin.Right: picShow.Cursor = Cursors.SizeWE; break;
case FieldMargin.RightBottom: picShow.Cursor = Cursors.SizeNWSE; break;
case FieldMargin.RightTop: picShow.Cursor = Cursors.SizeNESW; break;
case FieldMargin.Top: picShow.Cursor = Cursors.SizeNS; break;
case FieldMargin.Bottom: picShow.Cursor = Cursors.SizeNS; break;
case FieldMargin.Inside: picShow.Cursor = Cursors.SizeAll; break;
case FieldMargin.Outside: picShow.Cursor = Cursors.Default; break;
}
}
catch (Exception)
{
}
}
private void ChangeFieldMargin(int x, int y)
{
// 将鼠标移动距离转换为实际移动距离(考虑缩放因子)
float realX = x / zoomFactor;
float realY = y / zoomFactor;
switch (fieldMargin)
{
case FieldMargin.Left:
fieldRect[fieldIndex].X += x;
fieldRect[fieldIndex].Width -= x;
break;
case FieldMargin.Top:
fieldRect[fieldIndex].Y += y;
fieldRect[fieldIndex].Height -= y;
break;
case FieldMargin.Right:
fieldRect[fieldIndex].Width += x;
break;
case FieldMargin.Bottom:
fieldRect[fieldIndex].Height += y;
break;
case FieldMargin.LeftTop:
fieldRect[fieldIndex].X += x;
fieldRect[fieldIndex].Width -= x;
fieldRect[fieldIndex].Y += y;
fieldRect[fieldIndex].Height -= y;
break;
case FieldMargin.RightTop:
fieldRect[fieldIndex].Y += y;
fieldRect[fieldIndex].Height -= y;
fieldRect[fieldIndex].Width += x;
break;
case FieldMargin.LeftBottom:
fieldRect[fieldIndex].X += x;
fieldRect[fieldIndex].Width -= x;
fieldRect[fieldIndex].Height += y;
break;
case FieldMargin.RightBottom:
fieldRect[fieldIndex].Width += x;
fieldRect[fieldIndex].Height += y;
break;
case FieldMargin.Inside:
fieldRect[fieldIndex].X += x;
fieldRect[fieldIndex].Y += y;
break;
}
}
private void PicEdit_Paint(object sender, PaintEventArgs e)
{
if (labelTemp == null) return;
// 设置高质量绘图
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
// 绘制标签背景和边框
e.Graphics.FillRectangle(Brushes.White, labelRect);
e.Graphics.DrawRectangle(Pens.Black, labelRect.X, labelRect.Y, labelRect.Width, labelRect.Height);
// 绘制标签标题文本(使用固定字体)
Font scaledLabelFont = new Font(LABEL_TEXT_FONT.FontFamily,
LABEL_TEXT_FONT.Size * Math.Min(1.5f, zoomFactor * 0.8f),
LABEL_TEXT_FONT.Style);
e.Graphics.DrawString(labelText, scaledLabelFont, Brushes.Black, labelTextRect);
scaledLabelFont.Dispose();
// 绘制每个字段
for (int i = 0; i < fieldRect.Length; i++)
{
RectangleF rect = fieldRect[i];
PrintLabelField field = labelTemp.Field[i];
if (field.Type == PrintLabelFieldType.Text)
{
// 创建缩放后的字体
Font scaledFont = new Font(field.Font.FontFamily,
field.Font.Size * zoomFactor,
field.Font.Style);
// 设置文本格式
using StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near; // 可以根据需要设置文本对齐
sf.LineAlignment = StringAlignment.Near;
// 决定显示的文本内容
string textToDisplay = labelTemp.FieldShowKey
? field.Text
: ObjConversion.StrRemoveKey(field.Text);
// 绘制文本
e.Graphics.DrawString(textToDisplay, scaledFont, Brushes.Black, rect, sf);
scaledFont.Dispose();
}
else if (field.Image != null)
{
// 绘制图像(条码等)
e.Graphics.DrawImage(field.Image, rect);
}
// 绘制字段边框和控制点
if (i == fieldIndex)
{
// 选中的字段用红色边框
e.Graphics.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width, rect.Height);
// 计算控制点大小 - 随缩放调整但有最小限制
float scaledMargin = FIELD_MARGIN * zoomFactor;
float handleSize = scaledMargin * 2;
// 绘制控制点 - 使用填充矩形更容易点击
// 左上
e.Graphics.FillRectangle(Brushes.White, rect.X - scaledMargin, rect.Y - scaledMargin,
handleSize, handleSize);
e.Graphics.DrawRectangle(Pens.Black, rect.X - scaledMargin, rect.Y - scaledMargin,
handleSize, handleSize);
// 右上
e.Graphics.FillRectangle(Brushes.White, rect.X + rect.Width - scaledMargin, rect.Y - scaledMargin,
handleSize, handleSize);
e.Graphics.DrawRectangle(Pens.Black, rect.X + rect.Width - scaledMargin, rect.Y - scaledMargin,
handleSize, handleSize);
// 左下
e.Graphics.FillRectangle(Brushes.White, rect.X - scaledMargin, rect.Y + rect.Height - scaledMargin,
handleSize, handleSize);
e.Graphics.DrawRectangle(Pens.Black, rect.X - scaledMargin, rect.Y + rect.Height - scaledMargin,
handleSize, handleSize);
// 右下
e.Graphics.FillRectangle(Brushes.White, rect.X + rect.Width - scaledMargin, rect.Y + rect.Height - scaledMargin,
handleSize, handleSize);
e.Graphics.DrawRectangle(Pens.Black, rect.X + rect.Width - scaledMargin, rect.Y + rect.Height - scaledMargin,
handleSize, handleSize);
// 显示字段信息
Font infoFont = new Font(LABEL_TEXT_FONT.FontFamily,
LABEL_TEXT_FONT.Size * Math.Min(1.2f, zoomFactor * 0.7f),
FontStyle.Bold);
e.Graphics.DrawString(fieldText, infoFont, Brushes.Red, fieldTextRect);
infoFont.Dispose();
}
else
{
// 非选中的字段用灰色边框
e.Graphics.DrawRectangle(Pens.LightGray, rect.X, rect.Y, rect.Width, rect.Height);
}
}
}
private void PicEdit_MouseUp(object sender, MouseEventArgs e)
{
// 结束拖动状态
isPanning = false;
if (fieldMarginChange)
{
fieldMarginChange = false;
// 将更改应用回模型
if (fieldIndex >= 0 && fieldIndex < labelTemp.Field.Count)
{
RectangleF rect = fieldRect[fieldIndex];
rect.Offset(-labelOffset.X, -labelOffset.Y); // 移除偏移量
// 从缩放坐标转回原始坐标
rect.X /= zoomFactor;
rect.Y /= zoomFactor;
rect.Width /= zoomFactor;
rect.Height /= zoomFactor;
// 将像素转换为毫米并更新模型
labelTemp.Field[fieldIndex].Rectangle = ObjConversion.PxToMm(rect);
}
FieldSizeChanged?.Invoke(fieldIndex);
}
// 根据当前鼠标位置更新光标状态
if (fieldIndex >= 0)
{
FindFieldMargin(e.Location);
}
else if (labelRect.Contains(e.Location))
{
picShow.Cursor = Cursors.Hand;
}
else
{
picShow.Cursor = Cursors.Default;
}
}
// 可以添加一个方法来限制图像的拖动范围,防止拖出视图范围太远
private void LimitPanningBounds()
{
// 确保标签至少有一部分可见
float minX = -labelRect.Width + 50; // 至少保留50像素在视图内
float maxX = picShow.Width - 50;
float minY = -labelRect.Height + 50;
float maxY = picShow.Height - 50;
labelOffset.X = Math.Max(minX, Math.Min(maxX, labelOffset.X));
labelOffset.Y = Math.Max(minY, Math.Min(maxY, labelOffset.Y));
}
private void PicEdit_MouseMove(object sender, MouseEventArgs e)
{
int x, y;
if (e.Button == MouseButtons.Left)
{
// 计算鼠标移动距离
x = e.X - oldPoint.X;
y = e.Y - oldPoint.Y;
// 如果正在拖动整个图像或没有选中字段
if (isPanning || fieldIndex == -1)
{
// 移动标签位置
labelOffset.X += x;
labelOffset.Y += y;
CalcSize(true);
}
else
{
// 调整字段大小或位置
fieldMarginChange = true;
ChangeFieldMargin(x, y);
CalcSize(false);
}
oldPoint = e.Location; // 更新鼠标位置
picShow.Refresh();
}
else if (e.Button == MouseButtons.None)
{
// 鼠标未按下时的行为
isPanning = false;
// 如果有选中的字段,检测鼠标是否在该字段的边缘
if (fieldIndex >= 0)
{
FindFieldMargin(e.Location);
}
// 如果没有选中字段,但鼠标在标签区域内,显示移动光标
else if (labelRect.Contains(e.Location))
{
picShow.Cursor = Cursors.Hand;
}
else
{
picShow.Cursor = Cursors.Default;
}
}
}
private void PicEdit_MouseDown(object sender, MouseEventArgs e)
{
try
{
if (e.Button != MouseButtons.Left) return;
oldPoint = e.Location;
// 检查是否点击在字段边缘,如果是则准备调整字段大小
if (fieldMargin != FieldMargin.Outside) return;
// 查找是否点击在字段内部
int idx = -1;
for (int i = 0; i < fieldRect.Length; i++)
{
if (fieldRect[i].Contains(e.Location))
{
idx = i;
break;
}
}
// 更新选中的字段
if (idx != fieldIndex)
{
fieldIndex = idx;
if (fieldIndex == -1)
{
LabelSizeShow?.Invoke();
// 判断是否点击在标签区域内,如果是则准备拖动整个标签
if (labelRect.Contains(e.Location))
{
isPanning = true;
picShow.Cursor = Cursors.SizeAll;
}
}
else
{
FieldSizeChanged?.Invoke(fieldIndex);
isPanning = false;
}
CalcSize();
picShow.Refresh();
}
// 如果点击在标签内但没有选中字段,则准备拖动整个标签
else if (fieldIndex == -1 && labelRect.Contains(e.Location))
{
isPanning = true;
picShow.Cursor = Cursors.SizeAll;
}
}
catch (Exception)
{
}
}
private void PicEdit_MouseLeave(object sender, EventArgs e)
{
// 可以在此处理鼠标离开事件
}
private void PicEdit_MouseEnter(object sender, EventArgs e)
{
// 可以在此处理鼠标进入事件
}
private enum FieldMargin
{
Outside,
Inside,
Left,
Top,
Right,
Bottom,
LeftTop,
RightTop,
LeftBottom,
RightBottom
}
}
}