Hi. I am having problems in the invalidate and onpaint method. I used lists to store the details of the shapes for redrawing in onpaint method but there is some problem due to which the shapes are not being redrawn. At the moment i have commented out the code which is causing trouble due to which multiple drawings are generated when i uncomment the invalidate() the drawings are corrected but they vanish once i release the mouse button. Please someone tell me whats the problem with my lists and the onpaint method.
Here is my code.
CODE
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
// This is the main form
namespace paint
{
public partial class Form1 : Form
{
//Main form(canvas)
Point startPoint = new Point(); // stores the starting point of the object to be drawn
Point currentPoint = new Point(); // stores the current position of the mouse cursor
bool drag = false; // drag identifies whether the mouse button is pressed or not
List<int> drawingshape = new List<int>(); //list to hold the shapes that have to be redrawn in onpaint
List<Point> startLocation = new List<Point>(); //list of starting points of shapes for onpaint
List<Point> endLocation = new List<Point>(); //list of end points of shapes for onpaint
List<Color> shapecolor = new List<Color>(); //list of colors holding the colors of the shapes for onPaint
List<float> brushwidth = new List<float>(); //list of brushwidth of shapes for onPaint
Color color; //Color type variable to determine the color of the shape to be drawn
// enum for determining which tool is selected by assigning a value to the tool instance of this enum
// and for determining which shape to be drawn in onpaint by assigning a value to drawingshape list
enum ToolSelect
{
eLine, eFreeHand, eRectangle, eElipse,
eSlinky, eSelectionRectangle, eABC, eErarser, eBrush, eTextureBrush
};
ToolSelect tool; // instance of toolselect enum
// enum to determine which color is selectedfor onpaint by assigning a value to shapecolor list
enum shapeColor
{
eBlack, eFireBrick, eRed, eBlue, eYellow, eGreen, eGray,
eBrown, eOrange, eAqua, eMaroon, eViolet, eLime, eOlive, eKhake
};
//shapeColor shpCol; // instance of shapecolor enum
// enum to determine which shape is drawn for onpaint by assigning its value to the drawing shape list
enum shapeList { e_Rectangle, e_Line, e_Ellipse };
//shapeList shpLst;
public Form1()
{
InitializeComponent();
color = Color.Black; //default color of pen
}
private void Form1_Load(object sender, EventArgs e)
{
}
// mouse down event of drawing area
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
// set the position of startPoint to the point where mouse is clicked
startPoint.X = e.X;
startPoint.Y = e.Y;
drag = true; // sets the value of drag to true to tell that the mouse button is pressed
}
// mouse up event of drawing area
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
//try
//{ // set drag to false to tell the program that mouse button is released
drag = false;
//storing the position,colors,brushwidth and the shapes to be redrawn in onpaint maethod using lists
switch (tool)
{
// switch is used to identify which tool is being used and hence which shape has to be redrawn
case ToolSelect.eLine:
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
case ToolSelect.eRectangle:
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
case ToolSelect.eElipse:
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
case ToolSelect.eErarser:
startLocation.Add(startPoint);/////////////////////////
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
case ToolSelect.eBrush:
startLocation.Add(startPoint);//////////////////////////
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add((float)brushWidth.Value);
break;
case ToolSelect.eFreeHand:
startLocation.Add(startPoint);///////////////////////////
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
}
//}
//catch (System.NullReferenceException eaa)
//{
//}
}
// mouse move handler for drawing area
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
label1.Text = e.X.ToString();
label2.Text = e.Y.ToString();
//sets the position of the currentPoint to the mouse position
currentPoint.X = e.X;
currentPoint.Y = e.Y;
//Point ptOriginal = new Point(x, y);
//Point ptLast = new Point(newX, newY);
if (drag == true) // checks whether the mouse button is pressed or not
{
// if it is then create a grphics object for panel
Graphics g = this.panel1.CreateGraphics();
// switch to determin which tool is selected and hence which shape is to be drawn
switch (tool)
{
case ToolSelect.eLine: //if the tool is line
line l = new line(); //create an object of class line
Pen Pn = new Pen(color); //create an object of user specified color from pallete
//call the drawline function of class line and pass it the graphics object,pen and starting and ending point
l.drawLine(g, Pn, startPoint, currentPoint);
//currentPoint.X=e.X;
//currentPoint.Y=e.Y;
// even though i have made onpaint and i am storing the shapes and theri atribs in lists i am unable
// to figure out why it is not working
//uncomment out this and onpaaint to see that the lines are being drawn but vanish once mouse is release
//this.panel1.Invalidate(); //call invalidate so that multiple lines are not generated
break;
case ToolSelect.eRectangle: //if the tool is rectangle
rectangle r = new rectangle(); // create an object of class rectangle
Brush brr = new SolidBrush(color); // create a brush of specified color from pallete
Pen Penn = new Pen(brr); // create the pen of specified brush and width
// call the drawrectangle function of class rectangle and pass it graphics object,pen and start and endpoints
r.drawRectangle(g, Penn, startPoint, currentPoint);
// even though i have made onpaint and i am storing the shapes and theri atribs in lists i am unable
// to figure out why it is not working
//uncomment out this and onpaint to see that the lines are being drawn but vanish once mouse is release
//this.panel1.Invalidate(); //call invalidate so that multiple rectangles are not generated
break;
case ToolSelect.eElipse: //if the tool is ellipse
ellipse e1 = new ellipse(); //then create an ellipse object
Pen pn = new Pen(color); //create a pen with specified color
e1.drawEllipse(g, pn, startPoint, currentPoint);
// even though i have made onpaint and i am storing the shapes and theri atribs in lists i am unable
// to figure out why it is not working
// the only difference between slinky and ellipses is that ellipses call the onpaint but slinky does not
//uncomment out and onpaint to see that the lines are being drawn but vanish once mouse is released
//this.panel1.Invalidate(); //call invalidate so that multiple ellipses are not generated
break;
case ToolSelect.eFreeHand: // if the tool is freehand
freeHand fh = new freeHand(); // create its object
Pen pnn = new Pen(color); // create a pen of specified color
//calls the draw function of freehand and passes it graphic obj,pen and start and end points
fh.drawFreeHand(g, pnn, startPoint, currentPoint);
//sets the new start points as the current points of mouse since freehand is a no of lines joined together
startPoint.X = currentPoint.X;
startPoint.Y = currentPoint.Y;
//since multiple lines are drawn here they need to be stored simultaneously in the list for use in onpaint
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add(1);
break;
case ToolSelect.eABC: //if tool is ABC(text)
textLabel tL = new textLabel(); // then create textLabels obj
// call the objects function to draw the text box passing necessary arguments
tL.drawTextBox(g, textBox.Text, startPoint, currentPoint);
break;
case ToolSelect.eErarser: // if tool is erasr
eraser er = new eraser(); // create its object
//call the erase function passing graphics object,width specified of eraser and start and endpoints
er.erase(g, (float)brushWidth.Value, startPoint, currentPoint);
//sets the new start points as the current points of mouse since freehand is a no of lines joined together
startPoint.X = currentPoint.X;
startPoint.Y = currentPoint.Y;
//since multiple lines are drawn here they need to be stored simultaneously in the list for use in onpaint
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add((float)brushWidth.Value);
break;
case ToolSelect.eBrush: //if the tool is brush
//create its object passing its width and color to the constructor as specified by the user
brush br = new brush((float)(brushWidth.Value), color);
//call its draw function passing required arguments
br.paintBrush(g, startPoint, currentPoint);
//sets the new start points as the current points of mouse since freehand is a no of lines joined together
startPoint.X = currentPoint.X;
startPoint.Y = currentPoint.Y;
//since multiple lines are drawn here they need to be stored simultaneously in the list for use in onpaint
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Line);
brushwidth.Add((float)brushWidth.Value);
break;
case ToolSelect.eTextureBrush:
//short of time and too tired
break;
case ToolSelect.eSelectionRectangle:
// short of time and too tired
break;
case ToolSelect.eSlinky:
ellipse s1 = new ellipse(); //then create an ellipse object
Pen spn = new Pen(color); //create a pen with specified color
s1.drawEllipse(g, spn, startPoint, currentPoint);
//since multiple ellipses are drawn here they need to be stored simultaneously in the list for use in onpaint
startLocation.Add(startPoint);
endLocation.Add(currentPoint);
shapecolor.Add(color);
drawingshape.Add((int)shapeList.e_Ellipse);
brushwidth.Add(1);
break;
}
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// click events of the toolbar to select the tool and assign it to the tool (instance) of toolselct enum
private void bLine_Click(object sender, EventArgs e)
{
tool = ToolSelect.eLine;
}
private void bBrush_Click(object sender, EventArgs e)
{
tool = ToolSelect.eBrush;
}
private void bTextureBrush_Click(object sender, EventArgs e)
{
tool = ToolSelect.eTextureBrush;
}
private void bFreeHand_Click(object sender, EventArgs e)
{
tool = ToolSelect.eFreeHand;
}
private void bRectangle_Click(object sender, EventArgs e)
{
tool = ToolSelect.eRectangle;
}
private void bElispse_Click(object sender, EventArgs e)
{
tool = ToolSelect.eElipse;
}
private void bSlinky_Click(object sender, EventArgs e)
{
tool = ToolSelect.eSlinky;
}
private void bText_Click(object sender, EventArgs e)
{
tool = ToolSelect.eABC;
textBox.Enabled = true;
}
private void bEraser_Click(object sender, EventArgs e)
{
tool = ToolSelect.eErarser;
}
private void bSelection_Click(object sender, EventArgs e)
{
tool = ToolSelect.eSelectionRectangle;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//sets the background color as specified by the user in the pallete
private void bBackColor_Click(object sender, EventArgs e)
{
panel1.BackColor = color;
}
//clears the text box
private void textBox_MouseDown(object sender, MouseEventArgs e)
{
textBox.Text = "";
}
// uncomment out onpaint and invalidate calls to see the effect
/*protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e); // calls the base onpaint method
Graphics g = this.panel1.CreateGraphics(); //creates graphics object
int count; // count to store the no of objects to be drawn
count = drawingshape.Count; // gets the no of shapes to be drawn and stores them in count
for (int i = 0; i < count; i++) // loop as many times as the no of shapes
{
if (drawingshape[i] == (int)(shapeList.e_Ellipse)) //if shape is ellipse
{
ellipse elp = new ellipse(); // create graphics object
//call its drawing function and pass it graphics object,pen color and drawing points
elp.drawEllipse(g, new Pen(shapecolor[i]), startLocation[i], endLocation[i]);
}
if (drawingshape[i] == (int)shapeList.e_Line) // if shape is line
{
line l1 = new line(); // create graphics object
//call its drawing function and pass it graphics object,pen color and drawing points
//l1.drawLine(g, new Pen(shapecolor[i], brushwidth[i]), startLocation[i], endLocation[i]);
}
if (drawingshape[i] == (int)shapeList.e_Rectangle) // if shape is rectangle
{
rectangle rc = new rectangle(); // create graphics object
//call its drawing function and pass it graphics object,pen color and drawing points
rc.drawRectangle(g, new Pen(shapecolor[i]), startLocation[i], endLocation[i]);
}
}
}*/
// refreshes the canvas
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
panel1.Refresh();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
Graphics g = this.panel1.CreateGraphics(); // Create a graphics object
OpenFileDialog dlgFile = new OpenFileDialog(); // Open a dialog box to open files
Stream stm; // Variable of type stream to read file
String strImgName; // Variable to read File Name
dlgFile.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"; // Filter to specify file types
dlgFile.FilterIndex = 2; // which are to be opened
if (dlgFile.ShowDialog() == DialogResult.OK) // if dialog box is opened correctly
{
if ((stm = dlgFile.OpenFile()) != null) // and a file is opened
{
strImgName = dlgFile.FileName; // get the file name
stm.Close(); // Close file
Point pt1 = new Point(0, 0);
g.DrawImage(Image.FromFile(strImgName), pt1); // draw image from file on to the panel
}
}
}
// says it all!!!!!!!!
private void aboutCanvasToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Canvas 2008.\n\nVersion 0.3 Beta.\n\nA feeble attempt, of C# beginners, at making a professional software in just five days.\nHoping against hope that our efforts will outweigh the bugs in the program.\n\nHowever, all rights reserved!!!", "About Canvas");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// click events of colorpallete assigns the chosen color to the variable color
private void Black_Click(object sender, EventArgs e)
{
color = Color.Black;
}
private void Red_Click(object sender, EventArgs e)
{
color = Color.Red;
}
private void Blue_Click(object sender, EventArgs e)
{
color = Color.Blue;
}
private void Yellow_Click(object sender, EventArgs e)
{
color = Color.Yellow;
}
private void Green_Click(object sender, EventArgs e)
{
color = Color.Green;
}
private void Gray_Click(object sender, EventArgs e)
{
color = Color.Gray;
}
private void Brown_Click(object sender, EventArgs e)
{
color = Color.Brown;
}
private void Orange_Click(object sender, EventArgs e)
{
color = Color.Orange;
}
private void White_Click(object sender, EventArgs e)
{
color = Color.White;
}
private void Navy_Click(object sender, EventArgs e)
{
color = Color.Navy;
}
private void Maroon_Click(object sender, EventArgs e)
{
color = Color.Maroon;
}
private void Violet_Click(object sender, EventArgs e)
{
color = Color.Violet;
}
private void Lime_Click(object sender, EventArgs e)
{
color = Color.Lime;
}
private void Khaki_Click(object sender, EventArgs e)
{
color = Color.Khaki;
}
private void Olive_Click(object sender, EventArgs e)
{
color = Color.Olive;
}
private void FireBrick_Click(object sender, EventArgs e)
{
color = Color.Firebrick;
}
}
}