Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the drop effect of a DragArea to animate towards the DropArea that received it?

Tags:

qt

qml

Hope this makes some sense as a question. In my app, I have a DragArea defined which I use to start dragging things over top of various Rectangles that each contain a DropArea. Everything is working fine in my code except for a cosmetic effect that I would like to change.

In QML, when you start dragging from a DragArea and eventually drop, the animation effect is such that the thing you're dragging animates (while fading out) back to the spot from which you started dragging. This happens even when you drop over a DropArea that successfully captures the drop.

What I would like to do is have the drop effect animate towards the DropArea that received the drop - so that it appears I am dragging-and-dropping things into the Rectangle. Is there any way to do this?

I'm guessing that this in some way involves the .source and .target properties of these areas, but no luck so far in having any effect on where the drop animation goes.

like image 481
MusiGenesis Avatar asked Aug 07 '16 19:08

MusiGenesis


1 Answers

By default, QML will give you no cosmetic behavior for drag and drop whatsoever. The drag target will begin at the drag start location, and will end wherever it is dropped, regardless of whether the drag is accepted or not.

Thus I assume the behavior you describe is implemented in your user code, which you have not disclosed. Regardless, what you want to do is quite easy, it involves tracking the position the drag originates at and it ends at, so you can use the two coordinates to animate the position.

In the following example the red rectangle can be dragged, and if dropped outside of a drop area it will animate from its current to its initial position, whereas if dropped in the yellow rectangle, it will animate from its initial to its drop position.

Window {
  width: 600
  height: 600
  visible: true

  Rectangle {
    width: 200
    height: 200
    color: "yellow"
    DropArea {
      anchors.fill: parent
      onEntered: drag.source.accepted = true
      onExited: drag.source.accepted = false
    }
  }

  Rectangle {
    id: rect
    width: 50
    height: 50
    color: "red"
    x: parent.width * 0.5
    y: parent.height * 0.5
    Drag.active: mouseArea.drag.active

    property point begin
    property point end
    property bool accepted : false

    MouseArea {
      id: mouseArea
      anchors.fill: parent
      drag.target: parent
      onPressed: rect.begin = Qt.point(rect.x, rect.y)
      onReleased: {
        rect.end = Qt.point(rect.x, rect.y)
        aX.from = rect.accepted ? rect.begin.x : rect.end.x
        aX.to = rect.accepted ? rect.end.x : rect.begin.x
        aY.from = rect.accepted ? rect.begin.y : rect.end.y
        aY.to = rect.accepted ? rect.end.y : rect.begin.y
        anim.start()
      }
      ParallelAnimation {
        id: anim
        NumberAnimation { id: aX; target: rect; property: "x"; duration: 200 }
        NumberAnimation { id: aY; target: rect; property: "y"; duration: 200 }
      }
    }
  }
}
like image 120
dtech Avatar answered Nov 03 '22 05:11

dtech