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;


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?


2 Answers 2


It seems that you need some kind of a boolean variable telling you whether you are dragging something at this exact time, or not. Assuming that you can only drag one widget at a time, just check if draggingSomething is true, and if so, don't "hook" any new widgets on.

  • 1
    \$\begingroup\$ I thought about adding a flag to the MouseComponent. Problem is that it creates this strange dependency between objects. I would rather the objects be more independent and handle their own states. Maybe I'm over-thinking things... +1 for the straight-forward solution. \$\endgroup\$
    – Cypher
    Commented Sep 18, 2012 at 20:28
  • \$\begingroup\$ I smell YAGNI. I don't see why, if you have an object already managing the widgets, you couldn't just include a flag... But well, it's your code, this is how I'd do it. It's just communication between objects, if you already have something implemented, then go for it I guess. \$\endgroup\$
    – jcora
    Commented Sep 18, 2012 at 20:47

Only trigger the OnMouseDown event if the mouse was up before and is now down (all over the same element). Meaning you only trigger when the mouse is clicked on the current widget, and not by dragging a clicked mouse across multiple widgets. Means you need to keep track of the mouse state.

Keeping track of which widget the mouse is currently over would likely be very useful to you if you're not doing it already. When a mouse press is detected it can be picked up by whatever your GUI controller class is. The GUI controller will then send the event to the currently selected widget.

The currently selected widget gets updated something like so (this code is run by your GUI controller):

poll mouse position
walk tree into children and find bottom most child widget mouse is in
if underMouseWidget is different than the currentWidget
   currentWidget = underMouseWidget

Now that you have the current widget your GUI controller can handle events much easier. Like, a mouse click:

currentWidget.mouseClick(Button, Position)

This also means you always know where your mouse is, and your widgets know if they were the ones currently under the mouse when it was pressed.

  • \$\begingroup\$ The mouse state is tracked via the MouseComponent. \$\endgroup\$
    – Cypher
    Commented Sep 18, 2012 at 21:11
  • \$\begingroup\$ How can the Widget track if the mouse went down while hovering over it and then somehow not set the same flag when hovering over other Widgets that it does not know about? I can't use your logic of !this.WasMouseDown && this.IsMouseDown because that will be true by simply rolling over all elements with the mouse held down... hence the question. :) \$\endgroup\$
    – Cypher
    Commented Sep 18, 2012 at 21:13
  • \$\begingroup\$ I guess I can only suggest a slightly different way of doing things. Please see my edits. \$\endgroup\$
    – House
    Commented Sep 18, 2012 at 22:13
  • \$\begingroup\$ "Slightly different way of doing things" is why I'm here. :) It sounds like you're advocating the use of a manager class for the widgets. That's a good idea. \$\endgroup\$
    – Cypher
    Commented Sep 18, 2012 at 22:22
  • \$\begingroup\$ Indeed, a manager class has lots of nice features and centralizing the input controls is one of the really good ones. \$\endgroup\$
    – House
    Commented Sep 18, 2012 at 22:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .