Draw Shapes – Object Classes and Relationships

DrawShapesMainForm

DrawShapesCd

This is my little version of the old school Microsoft Paint program with only a few features. My plan is to add more in later versions. But for right now I’m showing this to demonstrate how object classes and class relationships can work in a simple form. You will notice from the class designer picture that the Line, Rctangle, and Elipse class all derive from the Shape class. The Shapes class is instantiated in the Mainform class. The Shapes class uses a one-dimensional array to store what is drawn on the screen. I do have to admit that working with graphics is a little more difficult for me. I’m used to just gathering data and performing tasks on it. So this is a fun project to expand my horizons.

Click on more to see the source code.

MainForm Class


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DrawShapes
{
    public partial class MainForm : Form
    {
        private ShapesList _shapesList = new ShapesList();      //List of shapes
        private Shape _draggingCurrentShape;                    //The current shape.
        private bool _dragging = false;                         //Are we rubber banding.
        private int _startingX = 0;                             //Starting X position.
        private int _startingY = 0;                             //Starting Y position.
        private float _lineSize = 0;                            //For the line size.
        private Color _shapeColor = Color.Red;                  //The default shape color.

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //Populate the shape combo box and select the first entry.
            shapeComboBox.Items.Add("Ellipse");
            shapeComboBox.Items.Add("Rectangle");
            shapeComboBox.Items.Add("Line");
            shapeComboBox.SelectedIndex = 0;

            //Set the default color of the shape and the default line size.
            shapeColorPictureBox.BackColor = _shapeColor;
        }

        private void sizeTextBox_TextChanged(object sender, EventArgs e)
        {
            //If the label is red this will reset it back to black.
            sizeLabel.ForeColor = Color.Black;

            //Checking to make sure a valid number has been entered.
            if (!float.TryParse(sizeTextBox.Text, out _lineSize))
            {
                sizeLabel.ForeColor = Color.Red;
                _lineSize = 1;
            }
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Clear the shapes and raise a paint event.
            _shapesList.Clear();
            canvasPictureBox.Invalidate();
        }

        private void colorButton_Click(object sender, EventArgs e)
        {
            //Display a color dialog box.
            ColorDialog colorDialog = new ColorDialog();
            colorDialog.AllowFullOpen = false;
            colorDialog.ShowHelp = false;
            colorDialog.Color = _shapeColor;

            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                //Set the current color and update the UI displaying the current color.
                _shapeColor = colorDialog.Color;
                shapeColorPictureBox.BackColor = colorDialog.Color;
            }
        }

        private void canvasPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (!_dragging)
            {
                //Saving the starting point.
                _startingX = e.X;
                _startingY = e.Y;

                if (shapeComboBox.SelectedIndex == 0)       //If option for the ellipse is selected.
                {
                    //Converting the starting point to a rectangle.
                    Rectangle rectangle = new Rectangle(e.X, e.Y, 0, 0);

                    //Creating the ellipse shape using the elipse class.
                    _draggingCurrentShape = new Elipse(rectangle, _shapeColor, filledCheckBox.Checked, _lineSize);

                    //Indicate we're drawing by rubber banding the image.
                    _dragging = true;
                }
                else if (shapeComboBox.SelectedIndex == 1)      //If option for the rectangle is selected.
                {
                    //Converting the starting point to a rectangle.
                    Rectangle rectangle = new Rectangle(e.X, e.Y, 0, 0);

                    //Creating the rectangle shape using the rctangle class.
                    _draggingCurrentShape = new Rctangle(rectangle, _shapeColor, filledCheckBox.Checked, _lineSize);

                    //Indicate we are drawing by rubber banding the image.
                    _dragging = true;
                }
                else     //If option for line is selected.
                {
                    //Converting the starting point to a rectangle.
                    Rectangle rectangle = new Rectangle(e.X, e.Y, 0, 0);

                    //Creating a line shape using out line class.
                    _draggingCurrentShape = new Line(rectangle, _shapeColor, _lineSize);

                    //Indicate we are drawing by rubber banding the image.
                    _dragging = true;
                }
            }
        }

        private void canvasPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (_dragging)
            {
                //If the line option is selected. This is so when the mouse is moved the line creation starts at the first
                //position of the mouse.
                if (shapeComboBox.SelectedIndex == 2)
                {
                    //Determine and set current shape dimension based on the current position.
                    _draggingCurrentShape.Width = e.X;
                    _draggingCurrentShape.Height = e.Y;

                    //Invalidate to raise the Paint event.
                    canvasPictureBox.Invalidate();
                }
                else
                {
                    //Determine and set current shape dimension based on the current position.
                    _draggingCurrentShape.Width = e.X - _startingX;
                    _draggingCurrentShape.Height = e.Y - _startingY;

                    //Invalidate to raise the Paint event.
                    canvasPictureBox.Invalidate();
                }
            }
        }

        private void canvasPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            //Add to the shape list.
            if (_dragging)
            {
                //Add the new shape and turn dragging off.
                _shapesList.Add(_draggingCurrentShape);
                _dragging = false;

                //Invalidate to raise the Paint event.
                canvasPictureBox.Invalidate();
            }
        }

        private void canvasPictureBox_Paint(object sender, PaintEventArgs e)
        {
            //Clear everything from the picturebox.
            e.Graphics.Clear(canvasPictureBox.BackColor);

            //Draw all previous shapes.
            for (int i = 0; i < _shapesList.Length; i++)
            {
                _shapesList[i].draw(e.Graphics);
            }

            //Draw current.
            if (_dragging)
                _draggingCurrentShape.draw(e.Graphics);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Exit the application.
            this.Close();
        }
    }
}


ShapesList Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DrawShapes
{
    public class ShapesList
    {
        private Shape[] _shapes = null;     //One dimensional array of shape objects.

        //Now for the indexer
        public Shape this[int index]
        {
            get { return _shapes != null ? _shapes[index] : null; }
        }

        //The count of shapes.
        public int Length
        {
            get { return _shapes != null ? _shapes.Length : 0; }
        }

        //Adding a shape.
        public int Add(Shape shape)
        {
            //Create or resize the _shapes array.
            if (_shapes == null)
                _shapes = new Shape[1];
            else
                Array.Resize(ref _shapes, _shapes.Length + 1);

            _shapes[_shapes.Length - 1] = shape;
            return _shapes.Length;
        }

        //Clear all the shapes.
        public void Clear()
        {
            if (_shapes != null)
            {
                Array.Clear(_shapes, 0, _shapes.Length);
                _shapes = null;
            }
        }
    }
}


Shape Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace DrawShapes
{
    public class Shape
    {
        public Color ShapeColor;
        public bool Filled;
        public float LineWidth;
        public int X;
        public int Y;
        public int Width;
        public int Height;
        public Point[] Points;

        public virtual void draw(Graphics graphics)
        {
            //Override this method in the child class.
        }
    }
}


Rctangle Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace DrawShapes
{
    public class Rctangle : Shape
    {
        public Rctangle(Rectangle rectangle, Color shapeColor, bool filled, float lineWidth)
        {
            base.X = rectangle.X;
            base.Y = rectangle.Y;
            base.Width = rectangle.Width;
            base.Height = rectangle.Height;
            base.ShapeColor = shapeColor;
            base.Filled = filled;
            base.LineWidth = lineWidth;
        }

        public override void draw(Graphics graphics)
        {
            if (base.Filled)
                graphics.FillRectangle(new SolidBrush(base.ShapeColor), base.X, base.Y, base.Width, base.Height);
            else
                graphics.DrawRectangle(new Pen(base.ShapeColor, base.LineWidth), base.X, base.Y, base.Width, base.Height);
        }
    }
}


Line Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace DrawShapes
{
    public class Line : Shape
    {
        public Line(Rectangle rectangle, Color shapeColor, float lineWidth)
        {
            base.X = rectangle.X;
            base.Y = rectangle.Y;
            base.Width = rectangle.Width;
            base.Height = rectangle.Height;
            base.ShapeColor = shapeColor;
            base.LineWidth = lineWidth;
        }

        public override void draw(Graphics graphics)
        {
            graphics.DrawLine(new Pen(base.ShapeColor, base.LineWidth), base.X, base.Y, base.Width, base.Height);
        }
    }
}


Elipse Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace DrawShapes
{
    public class Elipse : Shape
    {
        public Elipse(Rectangle rectangle, Color shapeColor, bool filled, float lineWidth)
        {
            base.X = rectangle.X;
            base.Y = rectangle.Y;
            base.Width = rectangle.Width;
            base.Height = rectangle.Height;
            base.ShapeColor = shapeColor;
            base.Filled = filled;
            base.LineWidth = lineWidth;
        }

        public override void draw(Graphics graphics)
        {
            if (base.Filled)
                graphics.FillEllipse(new SolidBrush(base.ShapeColor), base.X, base.Y, base.Width, base.Height);
            else
                graphics.DrawEllipse(new Pen(base.ShapeColor, base.LineWidth), base.X, base.Y, base.Width, base.Height);
        }
    }
}

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s