views:

129

answers:

1

I want to modify the fridge magnets example provided with Qt in a way that when I drag a label and drop it over another, it will push the label beneath the dragged label to the side, so they will never overlap one another.

I've seen how collision is detected in the colliding mice example, where it uses a QGraphicsScene to draw the QGraphicsItem mice on, and scene()->collidingItems(this) to see which mice are colliding.

The problem is that the fridge magnets example uses a class that inherits QWidget in place of QGraphicsScene, so there's no collidingItems() method to check when we have a collision.

How do I go about doing that?

+1  A: 

You can get the location and size of each QWidget from geometry(), which returns a QRect. QRect has function intersects(), which will tell you if it intersects another QRect. After the drop is complete, iterate through all of the labels and check if any of them do intersect the new position.

(This will be easier if you modify dragwidget to keep a QList<DragLabel*> of each label on the dragwidget.)

QRect droppedRect = newLabel->geometry();
foreach(DragLabel* label, dragLabelList)
{
  if (droppedRect.intersects(label->geometry())
  {
    // Add to the list of covered labels that need to be moved.
  }
}

The harder part: If there is an intersection, move the old label out of the way.

Maybe try the following algorithm: Move the offending label out of the way in the direction that takes the least movement. Now check it against all the other labels. Any of those that are covered should be moved in the same direction. Repeat until all the labels are uncovered.

Bill