CustomPanel.cs 4.58 KB
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace flowchart
{
    // flowchart를 그리는 판넬에 필요한 기능을 삽입. (Panel 객체를 상속해서 사용했음)
    // 마우스 클릭을 놓으면 어떤 도형을 선택했는지 판단해서, 해당 자료구조를 생성하고, 페인트 함수를 통해 그린다. 
    class CustomPanel : Panel
    {
        private String _figName;                              // NONE, RECTANGLE, RHOMBUS
        private List<FigBase> _shapes = new List<FigBase>();  // 선택된 도형을 저장한 리스트 자료구조
        private String _state;                                // NONE, DRAW, MOVE
        private Point _dragStartPoint = new Point(-1, -1);    // 도형을 움직일때 시작위치
        private FigBase _findShape = null;                     // 자료구조에서 찾은 도형을 임시 저장하는 변수

        // 변수를 클래스 밖에서 읽고 쓰게 하는 함수
        public string FigName { get { return _figName; }  set { _figName = value; } }
        public String State { get { return _state; } set { _state = value; } }

        // 마우스를 판넬에서 움질일때 호출되는 이벤트
        protected override void OnMouseMove(MouseEventArgs e)
        {
            // System.Diagnostics.Trace.WriteLine("debug >>>" + e.Location);
            // 마우스 버튼을 누르지 않은 상태일 경우
            if (e.Button == MouseButtons.None )
            {
                bool find = false;

                foreach (FigBase s in _shapes)
                {
                    // 현재 마우스 위치가 지금껏 그린 리스트 자료구조 안의 도형의 영역안에 있는지 확인
                    if (s.PointInRegion(e.Location))
                    {
                        find = true;
                    }
                }
                // 그려진 도형위에 마우스가 오면 마우스 모양을 변경
                if (find)
                    Cursor = Cursors.SizeAll;
                else
                    Cursor = Cursors.Default;

            }
            // 마우스를 클릭했을때
            else if (e.Button == MouseButtons.Left)
            {
                foreach (FigBase s in _shapes)
                {
                    // 자료구조안의 위치와 동일할 경우 해당 자료구조를 다시 가져온다.
                    if (s.PointInRegion(e.Location))
                    {
                        _findShape = s;
                        break;
                    }
                }
                // 도형을 찾았으면 움직이는 상태로 변경 후, 현재 마우스 위치를 저장함.
                if (_findShape != null)
                {
                    State = "MOVE";
                    _dragStartPoint = e.Location;
                }
            }

            base.OnMouseMove(e);
        }

        // 실제 도형을 그리거나 이동하는 함수, 최종 OnPaint() 함수가 호출되어 실행됨
        protected override void OnMouseUp(MouseEventArgs e)
        {
            // 그리기 상태
            if (State == "DRAW")
            {

                if (FigName == "RECTANGLE")
                {
                    // 사각형에 대한 정보를 자료구조에 삽입한다.
                    FigRectangle rectangle = new FigRectangle(e.Location, new System.Drawing.Size(100, 100));
                    _shapes.Add(rectangle);
                }
                else if (FigName == "RHOMBUS")
                {
                    FigRhombus rhombus = new FigRhombus(e.Location, new System.Drawing.Size(100, 100));
                    _shapes.Add(rhombus);
                }
                else if (FigName == "TRIANGLE")
                {
                    // TODO : 삼각형 그리기
                }
            }
            // 움직이는 상태
            else if (State == "MOVE")
            {
                if (_findShape != null)
                {
                    _findShape.Location = e.Location;
                }
            }

            State = "NONE";
            this.Refresh(); // 다시 그리기 요청: OnPaint()
            base.OnMouseUp(e);
        }

        // 실제 그리는 OnPaint를 통해 내가 작성한 Draw함수를 호출한다.
        protected override void OnPaint(PaintEventArgs e)
        {
            foreach (FigBase s in _shapes)
            {
                s.Draw(e.Graphics);
            }

            base.OnPaint(e);
        }
    }
}