PrintLabelShow.cs 13.3 KB
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 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;
        }

        public void Load(PrintLabelTemplate temp)
        {
            labelTemp = temp;
            fieldIndex = -1;
            if (labelTemp != null)
            {
                SizeF size = ObjConversion.MmToPx(labelTemp.Size);
                float x = (picShow.Width - size.Width) / 2f;
                float y = (picShow.Height - size.Height) / 2f;
                labelOffset = new PointF(x, y);

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

                CalcSize();
            }
            picShow.Refresh();
        }

        public void Refresh()
        {
            CalcSize();
            picShow.Refresh();
        }

        public void FieldSelected(int index)
        {
            fieldIndex = index;
            CalcSize();
            picShow.Refresh();
            FieldSizeChanged?.Invoke(fieldIndex);
        }




        private void CalcSize(bool recalc = true)
        {
            using Graphics g = picShow.CreateGraphics();
            SizeF sf;

            if (recalc)
            {
                //标签整体
                sf = ObjConversion.MmToPx(labelTemp.Size);
                labelRect = new RectangleF(labelOffset, sf);

                //标签上方文字
             
                labelText = string.Format("{0:0.00}×{1:0.00} (mm)", labelTemp.Size.Width, labelTemp.Size.Height);
                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++)
                {
                    fieldRect[i] = ObjConversion.MmToPx(labelTemp.Field[i].Rectangle);
                    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);
                sf = g.MeasureString(fieldText, labelTemp.Field[fieldIndex].Font);
                fieldTextRect = new RectangleF(fieldRect[fieldIndex].X, fieldRect[fieldIndex].Y - sf.Height, sf.Width, sf.Height);
            }


        }

        private void FindFieldMargin(Point pt)
        {
            fieldMargin = FieldMargin.Outside;
            RectangleF rect = fieldRect[fieldIndex];

            if (Math.Abs(rect.X - pt.X) < FIELD_MARGIN)
            {
                if (Math.Abs(rect.Y - pt.Y) < FIELD_MARGIN)
                    fieldMargin = FieldMargin.LeftTop;
                else if (Math.Abs(pt.Y - rect.Y - rect.Height) < FIELD_MARGIN)
                    fieldMargin = FieldMargin.LeftBottom;
                else if (pt.Y > rect.Y && pt.Y < rect.Y + rect.Height)
                    fieldMargin = FieldMargin.Left;
            }
            else if (Math.Abs(rect.X + rect.Width - pt.X) < FIELD_MARGIN)
            {
                if (Math.Abs(rect.Y - pt.Y) < FIELD_MARGIN)
                    fieldMargin = FieldMargin.RightTop;
                else if (Math.Abs(pt.Y - rect.Y - rect.Height) < FIELD_MARGIN)
                    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 (Math.Abs(rect.Y - pt.Y) < FIELD_MARGIN)
                    fieldMargin = FieldMargin.Top;
                else if (Math.Abs(pt.Y - rect.Y - rect.Height) < FIELD_MARGIN)
                    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;
            }
        }

        private void ChangeFieldMargin(int x, int y)
        {
            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.FillRectangle(Brushes.White, labelRect);
            e.Graphics.DrawRectangle(Pens.Black, labelRect.X, labelRect.Y, labelRect.Width, labelRect.Height);
            e.Graphics.DrawString(labelText, LABEL_TEXT_FONT, Brushes.White, labelTextRect);

            for (int i = 0; i < fieldRect.Length; i++)
            {
                RectangleF rect = fieldRect[i];
                PrintLabelField field = labelTemp.Field[i];

                if (field.Type == PrintLabelFieldType.Text)
                {
                    if (labelTemp.FieldShowKey)
                        e.Graphics.DrawString(field.Text, field.Font, Brushes.Black, rect);
                    else
                        e.Graphics.DrawString(ObjConversion.StrRemoveKey(field.Text), field.Font, Brushes.Black, rect);
                }
                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);
                    e.Graphics.DrawRectangle(Pens.Black, rect.X - FIELD_MARGIN, rect.Y - FIELD_MARGIN, FIELD_MARGIN, FIELD_MARGIN);
                    e.Graphics.DrawRectangle(Pens.Black, rect.X + rect.Width, rect.Y - FIELD_MARGIN, FIELD_MARGIN, FIELD_MARGIN);
                    e.Graphics.DrawRectangle(Pens.Black, rect.X - FIELD_MARGIN, rect.Y + rect.Height, FIELD_MARGIN, FIELD_MARGIN);
                    e.Graphics.DrawRectangle(Pens.Black, rect.X + rect.Width, rect.Y + rect.Height, FIELD_MARGIN, FIELD_MARGIN);
                    e.Graphics.DrawString(fieldText, labelTemp.Field[i].Font, Brushes.Red, fieldTextRect);
                }
                else
                {
                    e.Graphics.DrawRectangle(Pens.LightGray, rect.X, rect.Y, rect.Width, rect.Height);
                }
            }


        }

        private void PicEdit_MouseUp(object sender, MouseEventArgs e)
        {
            if (fieldMarginChange)
            {
                fieldMarginChange = false;
             
                FieldSizeChanged?.Invoke(fieldIndex);
            }
        }

        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 (fieldIndex == -1)
                {
                    labelOffset.X += x;
                    labelOffset.Y += y;
                    CalcSize(true);
                }
                else
                {
                    fieldMarginChange = true;
                    ChangeFieldMargin(x, y);
                    RectangleF rect = fieldRect[fieldIndex];
                    rect.Offset(-labelOffset.X, -labelOffset.Y);
                    labelTemp.Field[fieldIndex].Rectangle = ObjConversion.PxToMm(rect);
                    CalcSize(false);
                }
                oldPoint = e.Location;
               
                picShow.Refresh();
            }
            else if (e.Button == MouseButtons.None)
            {
                if (fieldIndex < 0) return;
                FindFieldMargin(e.Location);
            }
        }

        private void PicEdit_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            oldPoint = e.Location;

            ////标签显示大小的位置
            //bool rtn = labelSizeShow.Contains(e.Location);
            //if (rtn)
            //{
            //    ResizeLabel();
            //    return;
            //}

            ////查找文本索引
            if (fieldMargin != FieldMargin.Outside) return;
            int idx = Array.FindIndex(fieldRect, match => match.Contains(e.Location));
            //if (fieldIdx >= 0 && idx == -1)
            //{
            //    rtn = fieldSizeShow.Contains(e.Location);
            //    if (rtn)
            //    {
            //        FieldResize();
            //        return;
            //    }
            //}

            fieldIndex = idx;
            if (fieldIndex == -1)
                LabelSizeShow?.Invoke();
            else
                FieldSizeChanged?.Invoke(fieldIndex);

            CalcSize();
            picShow.Refresh();
        }

        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
        }

    }
}