I'v been making a program where the user clicks, and wherever they drag their mouse, it draws a line to. It works, but it draws the lines in the wrong place. I think its because I am getting the x y of the whole form, not my panel. Heres the code:
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
vars.x = MousePosition.X;
vars.y = MousePosition.Y;
label1.Text = vars.x + ", " + vars.y;
vars.isDrawing = true;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (vars.isDrawing == true)
{
if (e.Button == MouseButtons.Left)
{
int x2 = MousePosition.X;
int y2 = MousePosition.Y;
Random randomGen = new Random();
Color randomColor = Color.FromArgb(randomGen.Next(255), randomGen.Next(255), randomGen.Next(255));
Pen line = new Pen(randomColor, 1);
System.Drawing.Graphics formGraphics = panel2.CreateGraphics();
formGraphics.DrawLine(line, vars.x, vars.y, x2, y2);
}
}
}
Use e.X and e.Y instead of MousePosition.X and MousePosition.Y
Related
How to move a pictureBox inside a Panel by Mouse.
Visual Studio 2015 C# Winsows Forms Application.
I've made a primitive slider to control the volume of my WindowsMediaPlayer.
A panel as the background and a pictureBox inside as the slider-knopf.
And it works well.
But purely visually it does not work that good.
I'v searched all around, but can't I find an answer to this little funny problem.
Here is my code:
int posY;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
posY = e.Y; ;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PictureBox box = sender as PictureBox;
if (e.Button == MouseButtons.Left)
{
box.Top += e.Y - posY;
}
if (box.Top < 0)
{
box.Top = 0;
}
if (box.Top > 100)
{
box.Top = 100;
}
int n = box.Top;
n = n * - 1 + 100;
label1.Text = n.ToString();
}
When I move the pictureBox out of the edge of the little panel, the pictureBox somehow 'shrinks' in the panel.
But when I release the mouse, the pictureBox restore its size.
Slider.gif
Why is that.?
And how can I avoid it.?
Thanks.
I found a solution.
It's not optimal, but it can be used.
I changed the code to:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragging = true;
startPoint = e.Location;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Debug.WriteLine("mousemove X: " + e.X + " Y: " + e.Y);
pictureBox1.Location = new Point(0, pictureBox1.Top + e.Location.Y - startPoint.Y);
if (pictureBox1.Location.Y < 0)
{
pictureBox1.Location = new Point(0, 0);
dragging = false;
}
if (pictureBox1.Location.Y > 100)
{
pictureBox1.Location = new Point(0, 100);
dragging = false;
}
this.Refresh();
}
int n = pictureBox1.Location.Y;
n = n * -1 + 100;
label1.Text = n.ToString();
mediaPlayer1.settings.volume = n;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
gif
I still need to put an 'if' to correct, when the pictureBox1 is pulled out of the panel.
And to avoid flicker, I have had to put a 'dragging = false'.
However, it results in the pictureBox1 is getting frozen to the edge, so I have to release the mouse, and re-click to continue.
But well - it's to live with.
Thanks.
How to receive a path of relocation of a mouse between the 1st clicking and the 2nd?
private void OnMouseDown(object sender, MouseEventArgs e)
{
Log(string.Format("MouseDown \t\t {0}\n", e.Button));
LogMousePosition(string.Format("\n\nx={0:0000}\ny={1:0000}", e.X, e.Y));
if (lastX != -100 && lastY != -100)
{
shortestDistanse = Convert.ToInt64(Math.Sqrt((Math.Pow(e.X - lastX, 2)) + (Math.Pow(e.Y - lastY, 2))));
LogMousePosition(string.Format("\nshortDistanse\t\t {0}\n", shortestDistanse));
}
lastX = e.X;
lastY = e.Y;
}
If you just want the distance between the two points use pythagora.
Example:
private double GetDistance(Point p1, Point p2) {
int x = Math.Abs(p1.X - p2.X);
int y = Math.Abs(p1.Y - p2.Y);
return Math.Sqrt( Math.Pow(x, 2) + Math.Pow(y, 2));
}
You may try something like
// form fields
bool pressed;
List<Point> path;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (!pressed)
{
pressed = true;
path = new List<Point>();
path.Add(e.Location);
}
else
{
pressed = false;
// calculate distance from List
// log distance
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (pressed)
{
path.Add(e.Location);
}
}
However, the MouseMove event will be triggered only above the form. If the mouse is outside of it - distance is not taken into account. It also doesn't work when moving over other controls, but we can add to them MouseMove handlers too.
I could make
string pathMList = "C:\\logs/testMList.txt";`
private void HookManager_MouseMove(object sender, MouseEventArgs e)
{
labelMousePosition.Text = string.Format("x={0:0000}; y={1:0000}", e.X, e.Y);
if (mouseDownMove == 2)
{
LogMList(string.Format("\nx={0:0000} y={1:0000}", e.X, e.Y));
}
}
private void OnMouseDown(object sender, MouseEventArgs e)
{
Log(string.Format("MouseDown \t\t {0}\n", e.Button));
LogMousePosition(string.Format("\n\nx={0:0000}\ny={1:0000}", e.X, e.Y));
if (lastX != -100 && lastY != -100)
{
shortestDistanse = Convert.ToInt64(Math.Sqrt((Math.Pow(e.X - lastX, 2)) + (Math.Pow(e.Y - lastY, 2))));
LogMousePosition(string.Format("\nshortDistanse\t\t {0}\n", shortestDistanse));
LogMList(string.Format("\n\n NEW CLICK\n\nx={0:0000} y={1:0000}", e.X, e.Y));
}
lastX = e.X;
lastY = e.Y;
mouseDownMove = 2;
}
I have a mainPicture box that contains Two picture boxes (_pic1 , _pic2) .
I can drag _pic1 and drag _pic2 too.
But I want to when I do mouse down on intersection of two picture boxes, I could drag two lines together.
So I should get intersection position . by below code I could not.
_pic2.MouseUp += new MouseEventHandler(_pic1_MouseUp);
_pic2.MouseDown += new MouseEventHandler(_pic1_MouseDown);
Point p = new Point();
bool interSection;
private void _pic1_MouseDown(object sender, MouseEventArgs e)
{
p = e.Location;
dragging = true;
dragPoint = new Point(e.X, e.Y);
this.Cursor = Cursors.SizeAll;
Rectangle p1 = this._pic1.ClientRectangle;
p1.Offset(this._pic1.Location);
Rectangle p2 = this._pic2.ClientRectangle;
p2.Offset(this._pic2.Location);
//bool z = p1.Contains(p) it returns false
//bool zz = p2.Contains(p) it returns false too
if (p1.Contains(p) && p2.Contains(p))
{
interSection = true;
}
}
private void _pic_MouseMove(object sender, MouseEventArgs e)
{
if (interSection)
{
//drag two lines together
_pic1.Location = new Point(_pic1.Location.X + e.X - dragPoint.X, _pic1.Location.Y + e.Y - dragPoint.Y);
_pic2.Location = new Point(_pic2.Location.X + e.X - dragPoint.X, _pic2.Location.Y + e.Y - dragPoint.Y);
return;
}
if (dragging)
{
_pic_1.Location = new Point(_pic1.Location.X + e.X - dragPoint.X, _pic1.Location.Y + e.Y - dragPoint.Y);
}
}
private void _pic1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
this.Cursor = Cursors.Default;
}
private void _pic2_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
_pic2.Location = new Point(_pic2.Location.X + e.X - dragPoint.X, _pic2.Location.Y + e.Y - dragPoint.Y);
}
}
image :
http://tinypic.com/view.php?pic=ix8bab&s=8
You can test two Rectangles for Intersection like this:
if (_pic1.Bounds.IntersectsWith(_pic2.Bounds) ) // do stuff
And you can get the intersection like this:
Rectangle R = _pic1.Bounds;
R.Intersect(_pic2.Bounds);
Now you can test it again:
if (R != Rectangle.Empty)
Or find the Center:
Point center = new Point(R.X + R.Width / 2, R.Y + R.Height / 2);
Or test whether the Mouse was clicked on the intersection:
if (R.Contains(e.Location) // ..
i got the picture box to move. But when i click down on the picture box it jumps all over the place. Can anyone help me with this at all?
namespace Move_Shapes
{
public partial class Form1 : Form
{
int X = 0;
int Y = 0;
int mX = 0;
int mY = 0;
bool Move = false;
public Form1()
{
InitializeComponent();
}
private void pic_TL_Click(object sender, EventArgs e)
{
//X = MousePosition.X - this.Location.X - 8 - pic_TL.Location.X; // loc of cursor in picture
//Y = MousePosition.Y - this.Location.Y - 30 - pic_TL.Location.Y;
//label1.Text = X.ToString();
//label2.Text = Y.ToString();
//X = MousePosition.X - this.Location.X - 8;
//Y = MousePosition.Y - this.Location.Y - 30;
//label3.Text = X.ToString();
//label4.Text = Y.ToString();
}
private void pic_TL_MouseDown(object sender, MouseEventArgs e)
{
X = MousePosition.X - this.Location.X - 8 - pic_TL.Location.X; // loc of cursor in picture
Y = MousePosition.Y - this.Location.Y - 30 - pic_TL.Location.Y;
label1.Text = X.ToString();
label2.Text = Y.ToString();
Move = true;
}
private void pic_TL_MouseMove(object sender, MouseEventArgs e)
{
mX = MousePosition.X - this.Location.X - 8 - pic_TL.Location.X; // loc of cursor in picture
mY = MousePosition.Y - this.Location.Y - 30 - pic_TL.Location.Y;
if (Move)
{
pic_TL.Location = new Point(mX - X, mY - Y);
}
}
private void pic_TL_MouseUp(object sender, MouseEventArgs e)
{
Move = false;
}
}
}
On MoseMove you set location to difference of current mouse position and initial mouse position.
pic_TL.Location = new Point(mX - X, mY - Y);
I case mouse moved over one pixel, picture will move to left-top corner.
I wrote this code:
private struct MovePoint
{
public int X;
public int Y;
}
private void Image_MouseDown(object sender, MouseEventArgs e)
{
FirstPoint = new MovePoint();
FirstPoint.X = e.X;
FirstPoint.Y = e.Y;
}
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
if(FirstPoint.X > e.X)
{
Rectangle.X = FirstPoint.X - e.X;
//Rectangle.Width -= FirstPoint.X - e.X;
} else
{
Rectangle.X = FirstPoint.X + e.X;
//Rectangle.Width += FirstPoint.X + e.X;
}
if(FirstPoint.Y > e.Y)
{
Rectangle.Y = FirstPoint.Y - e.Y;
//Rectangle.Height -= FirstPoint.Y - e.Y;
} else
{
Rectangle.Y = FirstPoint.Y + e.Y;
//Rectangle.Height += FirstPoint.Y + e.Y;
}
Image.Invalidate();
}
}
private void Image_Paint(object sender, PaintEventArgs e)
{
if(Pen != null) e.Graphics.DrawRectangle(Pen, Rectangle);
}
Rectangle moves, but with inversion (it should not be). Can you help?
The mathematics in your mouse-move handler for moving the rectangle based on the mouse-movements seems quite off; I think you want something like this:
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int initialX = 0, initialY = 0; // for example.
Rectangle.X = (e.X - FirstPoint.X) + initialX;
Rectangle.Y = (e.Y - FirstPoint.Y) + initialY;
Image.Invalidate();
}
}
This way, the rectangle's upper left corner will follow the mouse by tracking the delta between the initial mouse-down location and the current mouse location. Note however that each time you re-click and drag, the rectangle will move back to its original location.
If, instead, you want the Rectangle to 'remember' its position across multiple click-and-drag operations (i.e. not to be reinitialized to its initial location on mouse-down) you can do:
private void Image_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Increment rectangle-location by mouse-location delta.
Rectangle.X += e.X - FirstPoint.X;
Rectangle.Y += e.Y - FirstPoint.Y;
// Re-calibrate on each move operation.
FirstPoint = new MovePoint { X = e.X, Y = e.Y };
Image.Invalidate();
}
}
One other suggestion: There's no need to create your own MovePoint type when there's already the System.Drawing.Point type. Also, in general, try not to create mutable structs.