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