using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; namespace DrawingProgram { public partial class Form1 : Form { /// /// This is the index in the shapes list from which the currentShape came from. /// Used to make sure that changes to a shape are overwritten over that shape, /// rather than the changed shape being added to a new index in the list. /// private int currentIndex; /// /// This tells us whether the currentShape we are working with is a new one that does /// not yet exist in the 'shapes' list. /// private bool blnNewShape; public enum MouseMoveMode { Nothing, // mouse is not moving/dragging anything DragShape, // mouse is moving a new shape into position DragHandle // mouse is dragging a handle around }; /// /// Says what the mouse move events are currently doing. /// Note that when mouseMove==DragShape, then currentShape /// is being moved around, so it must be non-null. /// When mouseMove==DragHandle, then currentShape must be /// non-null and currentHandle must be > 0. /// protected MouseMoveMode mouseMoveMode = MouseMoveMode.Nothing; /// /// This is the main list of all the shapes in the design. /// private List shapes; /// /// This is the currently selected shape in the design, /// or the new shape that is about to be added to the design. /// private Shape currentShape; /// /// This is the handle of currentShape that is being /// moved around or modified. It is 0 if no handle is /// being moved. /// private int currentHandle = 0; /// /// This tells us whether we have moved any of the handles belonging /// to the current shape. /// private bool blnMoveHandle; /// /// This records the position where the mouse button goes down. /// protected Point mouseStartPoint; /// /// Creates a new CAD program with an empty shapes list. /// public Form1() { InitializeComponent(); shapes = new List(); } /******************************************************************** * Event Handlers ********************************************************************/ private void rectangleButton_Click(object sender, EventArgs e) { // Create a new rectangle and tell the mouse move event // to drag it into the design. When the mouse button is // clicked, this rectangle will be added to the shapes list. blnNewShape = true; currentShape = new Rect(colorDialog1.Color); mouseMoveMode = MouseMoveMode.DragShape; currentHandle = 1; } /// /// This handler draws all the shapes in the 'shapes' list onto 'panel'. /// It also draws currentShape, because that might not have /// been added to the shapes list yet. /// /// /// private void panel_Paint(object sender, PaintEventArgs e) { Debug.WriteLine("panel_Paint"); foreach (Shape sh in shapes) { if (e.ClipRectangle.IntersectsWith(sh.BoundingBox)) { sh.Draw(e.Graphics, e.ClipRectangle); } } if (currentShape != null) currentShape.Draw(e.Graphics, e.ClipRectangle); } private void panel_MouseMove(object sender, MouseEventArgs e) { //Debug.WriteLine("mousemove at " + e.Location); if (mouseMoveMode == MouseMoveMode.DragShape) { blnMoveHandle = true; Debug.Assert(currentShape != null, "currentShape is null, so cannot drag it."); // we are moving the new shape into position panel.Invalidate(currentShape.BoundingBox); // redraw where it was currentShape.MoveHandle(currentHandle, e.Location); // move it panel.Invalidate(currentShape.BoundingBox); // redraw where it is now } else if (mouseMoveMode == MouseMoveMode.DragHandle && e.Button == MouseButtons.Left) // left mouse button is depressed { blnMoveHandle = true; // we are dragging a handle of currentShape Debug.Assert(currentShape != null, "currentShape is null, so cannot drag handle."); Debug.Assert(currentHandle > 0, "currentHandle is not set, so cannot drag a handle."); panel.Invalidate(currentShape.BoundingBox); // redraw where it was currentShape.MoveHandle(currentHandle, e.Location); panel.Invalidate(currentShape.BoundingBox); // redraw the changed shape } else { bool blnOnHandle = false ; foreach (Shape sh in shapes) { if (sh.OnHandle(e.Location) > 0) { this.Cursor = Cursors.Hand; blnOnHandle = true; break; } } if (blnOnHandle == false) { this.Cursor = Cursors.Arrow; } } } private void panel_MouseDown(object sender, MouseEventArgs e) { Debug.WriteLine("mousedown at " + e.Location); mouseStartPoint = e.Location; if (currentShape != null // if there is a current shape && currentShape.Selected // and it is already selected && e.Button == MouseButtons.Left // and we have clicked the left mouse button && currentShape.OnHandle(e.Location) > 0) // on one of its handles { // start dragging this handle currentHandle = currentShape.OnHandle(e.Location); Debug.WriteLine("mousedown selects handle " + currentHandle); if (currentHandle == 1) { mouseMoveMode = MouseMoveMode.DragShape; } else if (currentHandle > 1) { mouseMoveMode = MouseMoveMode.DragHandle; } } } private void AddShape(int index) { if (currentShape != null) { panel.Invalidate(currentShape.Selected); currentShape.Selected = false; if (blnNewShape == true) { // MessageBox.Show("Adding new Shape"); shapes.Add(currentShape); blnNewShape = false; currentIndex = shapes.Count - 1; } else shapes[currentIndex] = currentShape; currentShape = null; currentHandle = 0; //MessageBox.Show(shapes.Count.ToString()); } } //Used for both lines and polygons private bool ExtendShape(Point mousePos) { Point lastPoint = new Point(); //First check that we wish to extend line. int counter = 0; foreach (Shape sh in shapes) { if (sh.OnHandle(mousePos) > 0 && counter != currentIndex) { //MessageBox.Show("On handle"); return false; } counter++; } if (currentShape is Line) { if (((Line)currentShape).PointList.Count > 0) { lastPoint = ((Line)currentShape).PointList[((Line)currentShape).PointList.Count - 1]; } else { ((Line)currentShape).AddPoint(currentShape.Position); } } else if (currentShape is Polygon) { if (((Polygon)currentShape).PointList.Count > 0) { lastPoint = ((Polygon)currentShape).PointList[((Polygon)currentShape).PointList.Count - 1]; } else { //Add the first point for the polygon. ((Polygon)currentShape).AddPoint(currentShape.Position); } } if (currentShape.CloseTo(mousePos, lastPoint)) { AddShape(currentIndex); } else { Point newPoint = new Point(currentShape.X + (mousePos.X - currentShape.X), currentShape.Y + (mousePos.Y - currentShape.Y)); if (currentShape is Polygon) { if (currentShape.CloseTo(newPoint, ((Polygon)currentShape).PointList[0])) { MessageBox.Show("Complete!"); ((Polygon)currentShape).AddPoint(((Polygon)currentShape).PointList[0]); ((Polygon)currentShape).Complete = true; } else { ((Polygon)currentShape).AddPoint(newPoint); } } else if (currentShape is Line) { if (currentShape.CloseTo(newPoint, ((Line)currentShape).PointList[0])) { MessageBox.Show("Complete"); ((Line)currentShape).AddPoint(((Line)currentShape).PointList[0]); ((Line)currentShape).Complete = true; } else { ((Line)currentShape).AddPoint(newPoint); } } panel.Invalidate(currentShape.BoundingBox); } return true; } private void LeftClick(Point mousePos) { bool blnExtendShape = false; bool addedCurrent = false; //First Check if a shape has finished being moved or resized. if (blnMoveHandle) { if (mouseMoveMode == MouseMoveMode.DragShape) { currentShape.Position = mousePos; } AddShape(currentIndex); currentShape = shapes[currentIndex]; currentShape.Selected = true; panel.Invalidate(currentShape.BoundingBox); mouseMoveMode = MouseMoveMode.Nothing; blnMoveHandle = false; return; } else if (currentShape != null) { if ((currentShape is Line && ((Line)currentShape).Complete == false) || (currentShape is Polygon && ((Polygon)currentShape).Complete == false)) { blnExtendShape = ExtendShape(mousePos); if (blnExtendShape == false && currentShape.OnHandle(mousePos) > 0) { AddShape(currentIndex); addedCurrent = true; } } else if (currentShape.OnHandle(mousePos) > 0) { AddShape(currentIndex); addedCurrent = true; } } if (addedCurrent != true && blnExtendShape == false) { int counter = 0; foreach (Shape sh in shapes) { if (sh.OnHandle(mousePos) > 0) { Debug.WriteLine("selected shape " + sh + " at " + mousePos); if (sh.Selected == false) { currentShape = sh; currentIndex = counter; //MessageBox.Show(counter.ToString()); panel.Invalidate(sh.BoundingBox); sh.Selected = true; panel.Invalidate(sh.BoundingBox); // redraw the newly selected shape } else { panel.Invalidate(sh.BoundingBox); sh.Selected = false; } break; // stop once we find the first handle under the mouse. } counter++; } addedCurrent = false; } mouseMoveMode = MouseMoveMode.Nothing; currentHandle = 0; } private void RightClick() { // deselect ALL shapes currentShape = null; foreach (Shape sh in shapes) { if (sh.Selected) { // unselect the shape and redraw it. panel.Invalidate(sh.BoundingBox); sh.Selected = false; } } mouseMoveMode = MouseMoveMode.Nothing; currentHandle = 0; } private void panel_MouseUp(object sender, MouseEventArgs e) { this.Cursor = Cursors.Arrow; if (e.Button == MouseButtons.Left) { LeftClick(e.Location); return; } if (e.Button == MouseButtons.Right) { RightClick(); return; } } private void ellipseButton_Click(object sender, EventArgs e) { blnNewShape = true; currentShape = new Ellipse(colorDialog1.Color); mouseMoveMode = MouseMoveMode.DragShape; currentHandle = 1; } private void mnuExit_Click(object sender, EventArgs e) { this.Close(); } private void mnuShapeColor_Click(object sender, EventArgs e) { colorDialog1.ShowDialog(); if (currentShape != null) { currentShape.ShapeColor = colorDialog1.Color; panel.Invalidate(currentShape.BoundingBox); } } private void lineButton_Click(object sender, EventArgs e) { blnNewShape = true; currentShape = new Line(colorDialog1.Color, lineWidthTrackbar.Value); mouseMoveMode = MouseMoveMode.DragShape; currentHandle = 1; } private void mnuCountSelected_Click(object sender, EventArgs e) { int counter = 0; foreach (Shape sh in shapes) { if (sh.Selected == true) { counter++; } } MessageBox.Show(counter.ToString()); } private void mnuPositionLine_Click(object sender, EventArgs e) { MessageBox.Show(currentHandle.ToString()); } private void lineWidthTrackbar_Scroll(object sender, EventArgs e) { if (currentShape != null && currentShape is Line) { ((Line)currentShape).LineWidth = lineWidthTrackbar.Value; panel.Invalidate(currentShape.BoundingBox); } } private void textButton_Click(object sender, EventArgs e) { blnNewShape = true; this.Cursor = Cursors.IBeam; currentShape = new Text(colorDialog1.Color, fontDialog.Font); mouseMoveMode = MouseMoveMode.DragShape; currentHandle = 1; } private void mnuChangeFont_Click(object sender, EventArgs e) { fontDialog.ShowDialog(); panel.Invalidate(currentShape.BoundingBox); if (currentShape != null && currentShape is Text) ((Text)currentShape).StringFont = fontDialog.Font; Graphics g = this.CreateGraphics(); SizeF stringSize = new SizeF(); stringSize = g.MeasureString(((Text)currentShape).TextContents, ((Text)currentShape).StringFont, 2000); currentShape.Width = (int)stringSize.Width; panel.Invalidate(currentShape.BoundingBox); } private void Form1_KeyPress(object sender, KeyPressEventArgs e) { if (currentShape != null && currentShape is Text) { panel.Invalidate(currentShape.BoundingBox); if (e.KeyChar != '\b') { ((Text)currentShape).TextContents += e.KeyChar; //MessageBox.Show(((Text)currentShape).TextContents); } else if (e.KeyChar == '\b' && ((Text)currentShape).TextContents.Length != 0) { ((Text)currentShape).TextContents = ((Text)currentShape).TextContents.Substring(0, ((Text)currentShape).TextContents.Length - 1); } Graphics g = this.CreateGraphics(); SizeF stringSize = new SizeF(); stringSize = g.MeasureString(((Text)currentShape).TextContents, ((Text)currentShape).StringFont,700); currentShape.Width = (int)stringSize.Width; panel.Invalidate(currentShape.BoundingBox); } } private void polygonButton_Click(object sender, EventArgs e) { blnNewShape = true; currentShape = new Polygon(colorDialog1.Color); mouseMoveMode = MouseMoveMode.DragShape; currentHandle = 1; } private void mnuClearCanvas_Click(object sender, EventArgs e) { currentShape = null; shapes = new List(); Graphics paper = panel.CreateGraphics(); paper.Clear(Color.White); } private void mnuGroupSelected_Click(object sender, EventArgs e) { List tempShapeList = new List(); //MessageBox.Show(shapes.Count.ToString()); blnNewShape = true; currentShape = new Compound(); for (int index = 0; index < shapes.Count; index ++) { if (shapes[index].Selected) { shapes[index].Selected = false; ((Compound)currentShape).AddShape(shapes[index]); shapes.RemoveAt(index); index--; } } ((Compound)currentShape).CalculatePosition(); ((Compound)currentShape).CalcWidthHeight(); AddShape(currentIndex); currentShape = shapes[currentIndex]; currentShape.Selected = true; panel.Invalidate(currentShape.BoundingBox); } private void mnuUngroupSelected_Click(object sender, EventArgs e) { currentShape.Selected = false; foreach (Shape sh in ((Compound)currentShape).ShapeList) { sh.Selected = true; shapes.Add(sh); } currentShape = null; currentHandle = 0; panel.Invalidate(); } } }