|
@@ -21,19 +21,43 @@ namespace SketchAssistant
|
|
|
InitializeComponent();
|
|
|
}
|
|
|
|
|
|
+ /**********************************/
|
|
|
+ /*** CLASS VARIABLES START HERE ***/
|
|
|
+ /**********************************/
|
|
|
+
|
|
|
+ //Different Program States
|
|
|
+ public enum ProgramState
|
|
|
+ {
|
|
|
+ Idle,
|
|
|
+ Draw
|
|
|
+ }
|
|
|
+ //Current Program State
|
|
|
+ private ProgramState currentState;
|
|
|
//Dialog to select a file.
|
|
|
OpenFileDialog openFileDialogLeft = new OpenFileDialog();
|
|
|
//Image loaded on the left
|
|
|
Image leftImage = null;
|
|
|
//Image on the right
|
|
|
Image rightImage = null;
|
|
|
+ //Current Line being Drawn
|
|
|
+ List<Point> currentLine;
|
|
|
+ //All Lines in the current session
|
|
|
+ List<Tuple<bool,Line>> lineList = new List<Tuple<bool, Line>>();
|
|
|
+ //Whether the Mouse is currently pressed in the rightPictureBox
|
|
|
+ bool mousePressed = false;
|
|
|
+ //The Position of the Cursor in the right picture box
|
|
|
+ Point currentCursorPosition;
|
|
|
+ //The graphic representation of the right image
|
|
|
+ Graphics graph = null;
|
|
|
+
|
|
|
+ /******************************************/
|
|
|
+ /*** FORM SPECIFIC FUNCTIONS START HERE ***/
|
|
|
+ /******************************************/
|
|
|
|
|
|
private void Form1_Load(object sender, EventArgs e)
|
|
|
{
|
|
|
+ currentState = ProgramState.Idle;
|
|
|
this.DoubleBuffered = true;
|
|
|
- //Connect the Paint event of the left picture box to the event handler method.
|
|
|
- pictureBoxLeft.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBoxLeft_Paint);
|
|
|
- pictureBoxRight.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBoxRight_Paint);
|
|
|
}
|
|
|
|
|
|
//Resize Function connected to the form resize event, will refresh the form when it is resized
|
|
@@ -41,92 +65,194 @@ namespace SketchAssistant
|
|
|
{
|
|
|
this.Refresh();
|
|
|
}
|
|
|
-
|
|
|
- private void pictureBoxLeft_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
|
|
|
+
|
|
|
+ //Load button, will open an OpenFileDialog
|
|
|
+ private void loadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
- //Draw the left image
|
|
|
- if(leftImage != null)
|
|
|
+ openFileDialogLeft.Filter = "Image|*.jpg;*.png;*.jpeg";
|
|
|
+ if(openFileDialogLeft.ShowDialog() == DialogResult.OK)
|
|
|
{
|
|
|
+ toolStripLoadStatus.Text = openFileDialogLeft.SafeFileName;
|
|
|
+ leftImage = Image.FromFile(openFileDialogLeft.FileName);
|
|
|
pictureBoxLeft.Image = leftImage;
|
|
|
+ //Refresh the left image box when the content is changed
|
|
|
+ this.Refresh();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void pictureBoxRight_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
|
|
|
+ //Changes The State of the Program to drawing
|
|
|
+ private void drawButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
- //Draw the right image
|
|
|
- if (rightImage != null)
|
|
|
+ if(rightImage != null)
|
|
|
{
|
|
|
- pictureBoxRight.Image = rightImage;
|
|
|
+ if (currentState.Equals(ProgramState.Draw))
|
|
|
+ {
|
|
|
+ ChangeState(ProgramState.Idle);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ChangeState(ProgramState.Draw);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // A Table Layout with one row and two columns.
|
|
|
- // Columns are 50% so that the window is evenly split.
|
|
|
- // The size is manually set relative to the window size.
|
|
|
- // TODO: Maybe change this to automatically be the size of a parent container...
|
|
|
- private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
|
|
|
+ //get current Mouse positon within the right picture box
|
|
|
+ private void pictureBoxRight_MouseMove(object sender, MouseEventArgs e)
|
|
|
{
|
|
|
-
|
|
|
+ currentCursorPosition = ConvertCoordinates(new Point(e.X, e.Y));
|
|
|
}
|
|
|
|
|
|
- private void fileToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
+ //hold left mouse button to draw.
|
|
|
+ private void pictureBoxRight_MouseDown(object sender, MouseEventArgs e)
|
|
|
{
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //Load button, will open an OpenFileDialog
|
|
|
- private void loadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
- {
|
|
|
- openFileDialogLeft.Filter = "Image|*.jpg;*.png;*.jpeg";
|
|
|
- if(openFileDialogLeft.ShowDialog() == DialogResult.OK)
|
|
|
+ mousePressed = true;
|
|
|
+ if (currentState.Equals(ProgramState.Draw))
|
|
|
{
|
|
|
- toolStripLoadStatus.Text = openFileDialogLeft.SafeFileName;
|
|
|
- leftImage = Image.FromFile(openFileDialogLeft.FileName);
|
|
|
- //Refresh the left image box when the content is changed
|
|
|
- this.Refresh();
|
|
|
- pictureBoxLeft.Refresh();
|
|
|
+ currentLine = new List<Point>();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void toolStripStatusLabel1_Click(object sender, EventArgs e)
|
|
|
+ //Lift left mouse button to stop drawing.
|
|
|
+ private void pictureBoxRight_MouseUp(object sender, MouseEventArgs e)
|
|
|
{
|
|
|
-
|
|
|
+ mousePressed = false;
|
|
|
+ if (currentState.Equals(ProgramState.Draw))
|
|
|
+ {
|
|
|
+ lineList.Add(new Tuple<bool, Line>(true, new Line(currentLine)));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
|
|
|
+ //Button to create a new Canvas. Will create an empty image
|
|
|
+ //which is the size of the left image, if there is one.
|
|
|
+ //If there is no image loaded the canvas will be the size of the right picture box
|
|
|
+ private void canvasButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
-
|
|
|
+ DrawEmptyCanvas();
|
|
|
}
|
|
|
|
|
|
- private void pictureBoxLeft_Click(object sender, EventArgs e)
|
|
|
+ //add a Point on every tick to the Drawpath
|
|
|
+ private void drawTimer_Tick(object sender, EventArgs e)
|
|
|
{
|
|
|
-
|
|
|
+ if (currentState.Equals(ProgramState.Draw) && mousePressed)
|
|
|
+ {
|
|
|
+ currentLine.Add(currentCursorPosition);
|
|
|
+ Line drawline = new Line(currentLine);
|
|
|
+ drawline.DrawLine(graph);
|
|
|
+ pictureBoxRight.Image = rightImage;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- //Button to create a new Canvas. Will create an empty image
|
|
|
- //which is the size of the left image, if there is one.
|
|
|
- //If there is no image loaded the canvas will be the size of the right picture box
|
|
|
- private void toolStripButton1_Click(object sender, EventArgs e)
|
|
|
+ /***********************************/
|
|
|
+ /*** HELPER FUNCTIONS START HERE ***/
|
|
|
+ /***********************************/
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Creates an empty Canvas
|
|
|
+ /// </summary>
|
|
|
+ private void DrawEmptyCanvas()
|
|
|
{
|
|
|
if (leftImage == null)
|
|
|
{
|
|
|
rightImage = new Bitmap(pictureBoxRight.Width, pictureBoxRight.Height);
|
|
|
- using (Graphics grp = Graphics.FromImage(rightImage))
|
|
|
- {
|
|
|
- grp.FillRectangle(Brushes.White, 0, 0, pictureBoxRight.Width + 10, pictureBoxRight.Height + 10);
|
|
|
- }
|
|
|
+ graph = Graphics.FromImage(rightImage);
|
|
|
+ graph.FillRectangle(Brushes.White, 0, 0, pictureBoxRight.Width + 10, pictureBoxRight.Height + 10);
|
|
|
+ pictureBoxRight.Image = rightImage;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
rightImage = new Bitmap(leftImage.Width, leftImage.Height);
|
|
|
- using (Graphics grp = Graphics.FromImage(rightImage))
|
|
|
+ graph = Graphics.FromImage(rightImage);
|
|
|
+ graph.FillRectangle(Brushes.White, 0, 0, leftImage.Width + 10, leftImage.Height + 10);
|
|
|
+ pictureBoxRight.Image = rightImage;
|
|
|
+ }
|
|
|
+ this.Refresh();
|
|
|
+ pictureBoxRight.Refresh();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Redraws all lines in lineList, for which their associated boolean value equals true.
|
|
|
+ /// </summary>
|
|
|
+ private void RedrawRightImage()
|
|
|
+ {
|
|
|
+ DrawEmptyCanvas();
|
|
|
+ foreach (Tuple<bool, Line> lineBoolTuple in lineList)
|
|
|
+ {
|
|
|
+ if (lineBoolTuple.Item1)
|
|
|
{
|
|
|
- grp.FillRectangle(Brushes.White, 0, 0, leftImage.Width + 10, leftImage.Height + 10);
|
|
|
+ lineBoolTuple.Item2.DrawLine(graph);
|
|
|
}
|
|
|
}
|
|
|
- this.Refresh();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// A helper function which handles tasks associated witch changing states,
|
|
|
+ /// such as checking and unchecking buttons and changing the state.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="newState">The new state of the program</param>
|
|
|
+ private void ChangeState(ProgramState newState)
|
|
|
+ {
|
|
|
+ switch (currentState)
|
|
|
+ {
|
|
|
+ case ProgramState.Draw:
|
|
|
+ drawButton.CheckState = CheckState.Unchecked;
|
|
|
+ drawTimer.Enabled = false;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ switch (newState)
|
|
|
+ {
|
|
|
+ case ProgramState.Draw:
|
|
|
+ drawButton.CheckState = CheckState.Checked;
|
|
|
+ drawTimer.Enabled = true;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ currentState = newState;
|
|
|
pictureBoxRight.Refresh();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// A function that calculates the coordinates of a point on a zoomed in image.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="">The position of the mouse cursor</param>
|
|
|
+ /// <returns>The real coordinates of the mouse cursor on the image</returns>
|
|
|
+ private Point ConvertCoordinates(Point cursorPosition)
|
|
|
+ {
|
|
|
+ Point realCoordinates = new Point(5,3);
|
|
|
+ if(pictureBoxRight.Image == null)
|
|
|
+ {
|
|
|
+ return cursorPosition;
|
|
|
+ }
|
|
|
+
|
|
|
+ int widthImage = pictureBoxRight.Image.Width;
|
|
|
+ int heightImage = pictureBoxRight.Image.Height;
|
|
|
+ int widthBox = pictureBoxRight.Width;
|
|
|
+ int heightBox = pictureBoxRight.Height;
|
|
|
+
|
|
|
+ float imageRatio = (float)widthImage / (float)heightImage;
|
|
|
+ float containerRatio = (float)widthBox / (float)heightBox;
|
|
|
+
|
|
|
+ if (imageRatio >= containerRatio)
|
|
|
+ {
|
|
|
+ //Image is wider than it is high
|
|
|
+ float zoomFactor = (float)widthImage / (float)widthBox;
|
|
|
+ float scaledHeight = heightImage / zoomFactor;
|
|
|
+ float filler = (heightBox - scaledHeight) / 2;
|
|
|
+ realCoordinates.X = (int)(cursorPosition.X * zoomFactor);
|
|
|
+ realCoordinates.Y = (int)((cursorPosition.Y - filler) * zoomFactor);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //Image is higher than it is wide
|
|
|
+ float zoomFactor = (float)heightImage / (float)heightBox;
|
|
|
+ float scaledWidth = widthImage / zoomFactor;
|
|
|
+ float filler = (widthBox - scaledWidth) / 2;
|
|
|
+ realCoordinates.X = (int)((cursorPosition.X - filler) * zoomFactor);
|
|
|
+ realCoordinates.Y = (int)(cursorPosition.Y * zoomFactor);
|
|
|
+ }
|
|
|
+ return realCoordinates;
|
|
|
+ }
|
|
|
}
|
|
|
}
|