How do I drag my widgets without dragging other widgets?
- by Cypher
I have a bunch of drag-able widgets on screen. When I am dragging one of the widgets around, if I drag the mouse over another widget, that widget then gets "snagged" and is also dragged around.
While this is kind of a neat thing and I can think of a few game ideas based on that alone, that was not intended. :-P
Background Info
I have a Widget class that is the basis for my user interface controls. It has a bunch of properties that define it's size, position, image information, etc. It also defines some events, OnMouseOver, OnMouseOut, OnMouseClick, etc. All of the event handler functions are virtual, so that child objects can override them and make use of their implementation without duplicating code.
Widgets are not aware of each other. They cannot tell each other, "Hey, I'm dragging so bugger off!"
Source Code
Here's where the widget gets updated (every frame):
public virtual void Update( MouseComponent mouse, KeyboardComponent keyboard ) {
// update position if the widget is being dragged
if ( this.IsDragging ) {
this.Left -= (int)( mouse.LastPosition.X - mouse.Position.X );
this.Top -= (int)( mouse.LastPosition.Y - mouse.Position.Y );
}
... // define and throw other events
if ( !this.WasMouseOver && this.IsMouseOver && mouse.IsButtonDown( MouseButton.Left ) ) {
this.IsMouseDown = true;
this.MouseDown( mouse, new EventArgs() );
}
... // define and throw other events
}
And here's the OnMouseDown event where the IsDraggable property gets set:
public virtual void OnMouseDown( object sender, EventArgs args ) {
if ( this.IsDraggable ) {
this.IsDragging = true;
}
}
Problem
Looking at the source code, it's obvious why this is happening. The OnMouseDown event gets fired whenever the mouse is hovered over the Widget and when the left mouse button is "down" (but not necessarily in that order!). That means that even if I hold the mouse down somewhere else on screen, and simply move it over anything that IsDraggable, it will "hook" onto the mouse and go for a ride.
So, now that it's obvious that I'm Doing It Wrong™, how do I do this correctly?