I am trying to implement a functionality in my application to snap cursor to edge of a grid in my scene. As it stands I do have the framework to take the current MouseMove provided e.Location and converting to my world coordinates and back to screen - and the values match. See below basic code overview.
public void Scene_MouseMove(object sender, MouseEventArgs e)
{
Vector2 world = ScreenToWorld(e.Location);
---> Check here to make sure the world coordinates returned
fall inside my grid scene edges.
if (world.X < Grid.Left) world.x = Grid.Left;
Point target = WorldToScreen(world);
// set cursr desired position
Cursor.Position = (sender as PictureBox).PointToScreen( target );
}
The problem I am having is the fact that MouseMove is getting called AFTER the fact that mouse has moved, so when I hit the edges of my grid I see the mouse overshoot for a frame, and then correct itself. This causes the cursor to jitter past the edges as I move the mouse. I want to make it so when I hit the edge the cursor stops dead in its tracks, but I do not know how to capture the data prior to the mouse moving!
Perhaps I am going about this wrong, so any suggestions would be greatly appreciated.
FYI - This is the first part of a SnapToGrid functionality I am trying to implement.
EDIT : A simpler example:
You can see my problem running the simple example below. Notice how the cursor flickers every frame as you move it around?
bool g_Set = false;
public void Scene_MouseMove(object sender, MouseEventArgs e)
{
// stop MouseMove from flooding the control recursively
if(g_Set) { g_Set = false; return; }
g_Set = true;
Cursor.Position = new Point(400,400);
}
Does C# support anything in the API to capture MouseMove before it actually moves the Cursor, or should I just be looking into implementing my own Cursor class to hide the Form.Cursor and just render mine (something else I would need to look into as I have no clue on that functionality either).
To snap to edge's give a little room for the snap, eg 2 pixels:
To confine the cursor within the rectangle of a control, eg: aButton
To free the cursor: