How to draw straight line to the mouse coordinates? - c#

When user press the left button and move the mouse it should appears a straight line(not permanent line) from previous point to the current mouse moving position. Finally a real straight line will appear when the user releases the left mouse. please help me ..how do i do it?
List<Point> points = new List<Point>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
points.Add(e.Location);
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (points.Count > 1)
e.Graphics.DrawLines(Pens.Black, points.ToArray());
}

This is what you're looking for
private Stack<Point> points = new Stack<Point>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
points.Clear();
points.Push(e.Location);
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (points.Count > 1)
{
points.Pop();
}
if (points.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
points.Push(e.Location);
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (points.Count > 1)
e.Graphics.DrawLines(Pens.Black, points.ToArray());
}
I used Stack for ease of use, you are free to change to whatever collection of your choice.
To draw several line you can do something like this
private Stack<Line> lines = new Stack<Line>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
lines.Push(new Line { Start = e.Location });
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lines.Count > 0 && e.Button == System.Windows.Forms.MouseButtons.Left)
{
lines.Peek().End = e.Location;
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (var line in lines)
{
e.Graphics.DrawLine(Pens.Black, line.Start, line.End);
}
}
class Line
{
public Point Start { get; set; }
public Point End { get; set; }
}

you can use mentioned code
Point currentPoint = new Point();
private void Canvas_MouseDown_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ButtonState == MouseButtonState.Pressed)
currentPoint = e.GetPosition(this);
}
private void Canvas_MouseMove_1(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Line line = new Line();
line.Stroke = SystemColors.WindowFrameBrush;
line.X1 = currentPoint.X;
line.Y1 = currentPoint.Y;
line.X2 = e.GetPosition(this).X;
line.Y2 = e.GetPosition(this).Y;
currentPoint = e.GetPosition(this);
paintSurface.Children.Add(line);
}
}

Related

Custom scrollbar for panel does not scroll smoothly

customBtn1 is the custom scrollbar. The below code sample works, but the scrolling action is jittery and stuttery. It does not scroll smoothly. Any idea why this could be happening and how to fix it?
int PreviousBarLoc;
private void MainForm_Load(object sender, EventArgs e)
{
PreviousBarLoc= customBtn1.Location.Y;
}
//move the scrollbar up and down when the user drags it
private void customBtn1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{ MouseDownLocation = e.Location; }
}
private Point MouseDownLocation;
private void customBtn1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
customBtn1.Top = e.Y + customBtn1.Top - MouseDownLocation.Y;
}
}
//scroll the panel
private void customBtn1_LocationChanged(object sender, EventArgs e)
{
int locDifference = customBtn1.Location.Y - PreviousBarLoc;
if (steamSrvListPnl.VerticalScroll.Value + locDifference <= 255 && steamSrvListPnl.VerticalScroll.Value + locDifference >= 0)
{
steamSrvListPnl.VerticalScroll.Value += locDifference;
}
PreviousBarLoc= customBtn1.Location.Y;
}
Your deltas are not quite right. The way it is currently written, if you drag the mouse down and then start dragging back up, it will not scroll back up because your current e.Y is still below the original MouseDownLocation.Y. I'm not entirely sure of your setup, but below is an example of how to get smooth scrolling to work when the left mouse button is pressed and dragged on a button:
private int _prevY = 0;
private bool _mouseDown = false;
private void button1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_mouseDown = true;
_prevY = e.Y;
}
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (_mouseDown)
{
panel1.VerticalScroll.Value = Math.Max(panel1.VerticalScroll.Minimum, Math.Min(panel1.VerticalScroll.Maximum, panel1.VerticalScroll.Value + e.Y - _prevY));
_prevY = e.Y;
}
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
if (_mouseDown)
{
_mouseDown = false;
_prevY = 0;
}
}

What is best way to write in windows forms with pen-tablet like wacom intuos in C#

i have a problem.
I'm writing a program that writes on it with a stylus.
First, i create a windows form with a panel.
second, this code:
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.Drawing.Drawing2D;
namespace testWrite
{
public partial class Form1 : Form
{
Graphics g;
int x = -1;
int y = -1;
bool moving = false;
Pen pen;
public Form1()
{
InitializeComponent();
g = panel1.CreateGraphics();
pen = new Pen(Color.Black, 5);
pen.SetLineCap(System.Drawing.Drawing2D.LineCap.Round, System.Drawing.Drawing2D.LineCap.Round, System.Drawing.Drawing2D.DashCap.Round);
pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
g.DrawLine(pen, new Point(x, y), e.Location);
x = e.X;
y = e.Y;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
x = -1;
y = -1;
moving = false;
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
moving = true;
}
}
}
I use this app with a Wacom intuos
But the result is not so good because a few words are lost...haizzz
toi tên la trần
quang hieu
hello heloo
especially, when i write fast or the text is small.
when i write in Microsoft Paint, it is very good
What is best way to to write in windows forms with pen-tablet like wacom intuos?
UPDATE 1:
With cmt from TaW.
Thanks for your help. But, that's not what I need...
i was change my code to:
public partial class Form1 : Form
{
List<Point> curPoints = new List<Point>();
List<List<Point>> allPoints = new List<List<Point>>();
public Form1()
{
InitializeComponent();
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// here we should check if the distance is more than a minimum!
curPoints.Add(e.Location);
// let it show
panel1.Invalidate();
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// ToList creates a copy
allPoints.Add(curPoints.ToList());
curPoints.Clear();
}
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// begin fresh line or curve
curPoints.Clear();
// startpoint
curPoints.Add(e.Location);
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
// here you can use DrawLines or DrawCurve
// current line
if (curPoints.Count > 1) e.Graphics.DrawCurve(Pens.Red, curPoints.ToArray());
// other lines or curves
foreach (List<Point> points in allPoints)
if (points.Count > 1) e.Graphics.DrawCurve(Pens.Red, points.ToArray());
}
}
But nothing better. The result is worse...
I tried to write: "Hello my name is Hieu", but is not run...
Looks like a pen-tablet differs from a mouse when use to write. Because, with mouse i feel that is better in this code...
UPDATE 2:
With code by Idle_Mind. It will be fine if i set pen-tablet:
With setting "Click", it is not OK
How to fix it, i don't want to set "Double Click" to my pen !
Here's my version...worked great for me. You might need to adjust your tablet settings so that it picks up everything correctly:
public partial class FormTablet : Form
{
private Point lastPoint;
private GraphicsPath GP = null;
private List<GraphicsPath> GPs = new List<GraphicsPath>();
public FormTablet()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
lastPoint = new Point(e.X, e.Y);
GP = new GraphicsPath();
GP.AddLine(lastPoint, lastPoint);
GPs.Add(GP);
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point pt = new Point(e.X, e.Y);
GP.AddLine(lastPoint, pt);
lastPoint = pt;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
GP = null;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (checkBox1.Checked)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
}
using(Pen p = new Pen(Color.Black, (int)numericUpDown1.Value))
{
p.LineJoin = LineJoin.Round;
p.MiterLimit = p.Width / 2;
foreach (GraphicsPath path in GPs)
{
if (path.PathPoints.Count() > 2)
{
// draw the path
e.Graphics.DrawPath(p, path);
}
else
{
// just draw a single dot
Rectangle rc = new Rectangle(Point.Round(path.PathPoints[0]), new Size(1, 1));
rc.Inflate((int)numericUpDown1.Value, (int)numericUpDown1.Value);
e.Graphics.FillEllipse(Brushes.Black, rc);
}
}
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
GPs.Clear();
pictureBox1.Invalidate();
}
}

Visual Studio Drawimage drag and drop image

I want to know how i can move a image that i create with System.DrawImage() with mouse. I try with this but dont work:
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt))
{
isImageClicked = false;
}
}
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt))
{
isImageClicked = true;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Point mousePt = new Point(e.X, e.Y);
if (rectA.Contains(mousePt) && isImageClicked)
{
rectA.X = mousePt.X;
rectA.Y = mousePt.Y;
this.Invalidate();
}
}
I think that have some way to refresh that, but i dont know!

Drag and drop in winforms

I need to drag 6 images, which are in PictureBoxes, to 6 answer panels, one at a time and if the correct image is dragged to the correct spot it adds 1 to the score which is in a class called 'score'. There is code below to show one of the pcitures working but the form lags alot and if the image is dragged anywhere above the panel, it will snap into place. is there a way to stop this?
namespace DragAndDropQuiz
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void pcBxLiverpool_MouseEnter(object sender, EventArgs e)
{
this.Cursor = Cursors.Hand;
}
private void pcBxLiverpool_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Default;
}
private int xPos;
private int yPos;
private void pcBxGeneral_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
xPos = e.X;
yPos = e.Y;
}
}
private void pcBxGeneral_MouseMove(object sender, MouseEventArgs e)
{
if (sender != null && sender.GetType() == typeof(PictureBox))
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
((PictureBox)sender).Top += (e.Y - yPos);
((PictureBox)sender).Left += (e.X - xPos);
this.Refresh();
}
}
}
private void pcBxGeneral_MouseUp(object sender, MouseEventArgs e)
{
if (sender != null && sender.GetType() == typeof(PictureBox))
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
PictureBox answer = (PictureBox)sender;
if (answer.Location.X < pnlAnswer.Location.X)
{
if (answer.Location.X + answer.Width > pnlAnswer.Location.X)
{
if ((answer.Location.X + answer.Width) < pnlAnswer.Location.X + pnlAnswer.Width)
{
answer.Location = pnlAnswer.Location;
}
}
}
else if (answer.Location.X > pnlAnswer.Location.X)
{
if (answer.Location.X < (pnlAnswer.Location.X + pnlAnswer.Width))
{
answer.Location = pnlAnswer.Location;
}
}
}
}
}
private void Form2_Paint(object sender, PaintEventArgs e)
{
}
private void groupBox2_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawRectangle(new Pen(Color.Red), pnlAnswer.Location.X, pnlAnswer.Location.Y, pnlAnswer.Width, pnlAnswer.Height);
}
}
}

Drawing lines in a PictureBox

First I need to make some color scribbles (the picture below is taken from M. Yang article's on Still Image Colorization) on an monochrome input image which is loaded into a PictureBox control.
I'm trying to use this to get the effect:
private void PictureBoxOnMouseDown(Object sender, MouseEventArgs e)
{
if((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
this.MouseInitialPosition = e.Location;
}
}
private void PictureBoxOnMouseMove(Object sender, MouseEventArgs e)
{
if((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
this.MouseLastPosition = e.Location;
}
this._PictureBox.Invalidate();
}
private void PictureBoxOnPaint(Object sender, PaintEventArgs e)
{
using(var pen = new Pen(Color.Red, 3.0F))
{
e.Graphics.DrawLine(pen, this.MouseInitialPosition, this.MouseLastPosition);
}
}
But that's giving me not quite I've been waiting for:
I can't put several lines. Lines are not stored;
I'm overwriting line with line;
Second. I need to get all pixels from an image I've been drawing onto and filter them in some way (i.e. extract special ones). How do I store lines/scribbles onto image and then read the image efficiently?
A simple solution would be to store lines when a mouseMove event occurs on a picturebox control and then invalidate to redraw:
public class Lines
{
public Point startPoint = new Point();
public Point endPoint = new Point();
}
Lines l = new Lines();
List<Lines> allLines = new List<Lines>();
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
// Collect endPoint when mouse moved
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
l.endPoint = e.Location;
//Line completed
allLines.Add(l);
this.pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// Collect startPoint when left mouse clicked
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
l = new Lines();
l.startPoint = e.Location;
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (var aLine in allLines)
{
e.Graphics.DrawLine(Pens.Blue, aLine.startPoint, aLine.endPoint);
}
}
Just keep a list of lines. Then when OnPaint is called draw all the lines.
The Line class would be something like:
public class Line
{
public List<Point> Points = new List<Point>();
public DrawLine(Pen pen, Grphics g)
{
for (int i = 0; i < Points.Count - 1; ++i)
g.DrawLine(pen, Points[i], Points[i+1];
}
}
private void PictureBoxOnMouseDown(Object sender, MouseEventArgs e)
{
if((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
var newLine = new Line();
newLine.Points.Add(e.Location);
lines.Add(newLine);
}
}
PictureBoxOnMouseMove(Object sender, MouseEventArgs e)
{
if((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
lines[lines.Count-1].Points.Add(e.Location);
}
}
private void PictureBoxOnPaint(Object sender, PaintEventArgs e)
{
using(var pen = new Pen(Color.Red, 3.0F))
{
foreach (var line in lines)
DrawLine(pen, e.Graphics)
}
}

Categories

Resources