Doodle

A digital drawing application that allows users to create, edit, and save artwork. The project focused on interactive interface design, tool functionality, and user experience.


Project type: Individual

Tools used

C#

C#

CSS

Visual Studio

Drawing App

Normal mode contains the 4 main operations: plus, minus, multiply, divide, while scientific mode contains more functions such as logarithms, square root, trigonometric functions etc. 

Shapes

Users can insert shapes that are available For example: Through the use of the shapes tab and the size selector, they can insert any of the shapes provided. I aim to add more shapes in the future so users are able to be more creative in their drawings/designs..

Shapes

Description

For first-time users, the description provides a clear overview of the button’s function and its expected behavior.

character_limitLoad button character_limitEnable button character_limitPaste button character_limitUndo button

Fonts and Text

Users can add text to the drawing board by typing it into the provided text box and then selecting their preferred font and size. 

Users must first select the text option before being able to paste the text onto the drawing board.

The Backbone

Beyond the interface, this drawing app relies on clear, structured logic. The following snippets show how I handled input processing, pasting of shapes/text and complex operations.

Loading images from
library

This feature allows users to draw directly on imported images. To enable this, the PNG image is converted into a bitmap, which supports drawing. I had the most trouble with this because without converting to a bitmap, users cannot draw anything onto the image. Through this, I learnt to stay calm and solve problems, step by step. 

private void picBoxLoad_Click(object sender, EventArgs e)
{
    picBoxToolPic.Image = picBoxLoad.Image;
    lblTexts.Text = "Loads image files from the library.";
    using (OpenFileDialog ofd = new OpenFileDialog())
    {
        ofd.Title = "Load Dialog";
        ofd.Filter = "JPEG files(*.jpeg)|*.jpeg| Image Files (*.BMP)|*.BMP| All files (*.*)|*.*";
        if (ofd.ShowDialog() == DialogResult.OK)
        try
        {
            Bitmap loadImage = new Bitmap(ofd.FileName);
            g = Graphics.FromImage(bm);
            g.DrawImage(loadImage, 0, 0, bm.Width, bm.Height);
            picBoxMain.Image = bm;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error loading image: " + ex.Message);
        }
    }
}

Undo and Redo

The undo and redo buttons are essential features in a drawing app because mistakes are common when drawing. They allow users to easily correct errors, helping them maintain accuracy and precision in their drawings. From this addition, I improved my skills on user experience and creativity, allowing users to have a better time using this drawing app.

private void picBoxUndo_Click(object sender, EventArgs e)
{
    lblTexts.Text = "Undo last drawing";
    if (undoStack.Count > 0)
    {
        redoStack.Push((Bitmap)bm.Clone());     // saves the current state for redo
        bm = (Bitmap)undoStack.Pop();       // restores previous state
        g = Graphics.FromImage(bm);
        picBoxMain.Image = bm;       // updates picBoxMain
    }
}

private void picBoxRedo_Click(object sender, EventArgs e)
{
    lblTexts.Text = "Reapplies last drawing";
    if (redoStack.Count > 0)
    {
        undoStack.Push((Bitmap)bm.Clone());
        bm = (Bitmap)redoStack.Pop();
        g = Graphics.FromImage(bm);
        picBoxMain.Image = bm;
    }
}

Pasting of shapes/emojis

The code below allows users to paste any shapes or emojis that they have selected onto the drawing board.

if (flagEmoji)
{
    g = Graphics.FromImage(bm);
    Font emojiFont = new Font("Segoe UI Emoji", scrollSize.Value * 5);
    SolidBrush emojiBrush = new SolidBrush(pen.Color);
    g.DrawString(emoji, emojiFont, emojiBrush, startP.X, startP.Y);
    g.Dispose();
    picBoxMain.Invalidate();
}
flagEmoji = false; // Reset so it doesn't draw again

if (flagShapes)
{
    g = Graphics.FromImage(bm);
    Font shapeSize = new Font("Segoe UI Shapes", scrollSize.Value);
    SolidBrush emojiBrush = new SolidBrush(pen.Color);
    g.DrawString(shapes, shapeSize, emojiBrush, startP.X, startP.Y);
    g.Dispose();
    picBoxMain.Invalidate();
}
flagShapes = false;
}

Save button

All efforts are wasted if users cannot save their work. To tackle this, I included a save button, allowing users to save their work as a bitmap and revisit or edit it later. A dialog box will appear after the file has been successfully saved. Implementing this reinforced my knowledge on file handling, event-driven programming, and user interface design.

private void picBoxSave_Click(object sender, EventArgs e)
{
    picBoxToolPic.Image = picBoxSave.Image;
    lblTexts.Text = "Saves the current drawing on the board.";

    paint = false;
    using (SaveFileDialog sfdlg = new SaveFileDialog())
    {
        sfdlg.Title = "Save Dialog";
        sfdlg.Filter = "Image Files (*.BMP)|*.BMP| JPEG files(*.jpeg)|*.jpeg| GIF files(*.GIF)|*.GIF| All files (*.*)|*.*";
        if (sfdlg.ShowDialog(this) == DialogResult.OK)
        {
            using (Bitmap bmp = new Bitmap(picBoxMain.Width, picBoxMain.Height))
            {
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                picBoxMain.DrawToBitmap(bmp, rect);
                bmp.Save(sfdlg.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                MessageBox.Show("File saved successfully");
            }
        }
    }
}

Equation

Final Thoughts

Lessons Learned and Insights Gained: Challenges, Skills, and Growth from This Project

Lessons learnt

Skills demonstrated