Skip to content

Instantly share code, notes, and snippets.

@oKcerG
Last active September 24, 2018 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oKcerG/bd0813e16f48b3316010a1799163b44c to your computer and use it in GitHub Desktop.
Save oKcerG/bd0813e16f48b3316010a1799163b44c to your computer and use it in GitHub Desktop.
import QtQuick 2.0
MouseArea {
id: root
property Item draggedParent: parent ? parent.parent || parent : null
property var modelIndex: typeof model !== "undefined" ? model.index : undefined
signal move(int from, int to)
property bool dropEnabled: true
property bool dropBlocked: false
property bool dragEnabled: true
default property alias contentData: container.data
readonly property Item contentItem: container.children.length > 0 ? container.children[0] : null
property bool _held: false
readonly property alias held: root._held
drag {
target: _held ? container : undefined
axis: Drag.XandYAxis
threshold: 0
minimumX: 0
maximumX: draggedParent.width - width
minimumY: 0
maximumY: draggedParent.height - height
}
onPressAndHold: {
if (dragEnabled)
_held = true;
else
shakeAnimation.start();
}
onReleased: _held = false
onCanceled: _held = false
Binding on width {
when: contentItem
value: contentItem ? contentItem.width : undefined
}
Binding on height {
when: contentItem
value: contentItem ? contentItem.height : undefined
}
Item {
id: container
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
horizontalCenterOffset: -5 * Math.sin(shakeDegree * Math.PI / 180)
}
property real shakeDegree: 0
width: root.width
height: root.height
Drag.active: root._held
Drag.source: root
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
states: State {
name: "_held"
when: root._held
ParentChange {
target: container
parent: root.draggedParent
}
AnchorChanges {
target: container
anchors {
horizontalCenter: undefined
verticalCenter: undefined
}
}
}
transitions: Transition {
from: "_held"
ParentAnimation {
AnchorAnimation { easing.type: Easing.InOutQuad }
}
}
RotationAnimation on shakeDegree {
id: shakeAnimation
running: false
from: 0
to: 360
loops: 2
duration: 110
}
}
DropArea {
id: dropArea
enabled: dropEnabled && !dropBlocked
anchors.fill: parent
onEntered: {
if (drag.source.parent !== root.parent || drag.source.modelIndex === root.modelIndex)
drag.accepted = false
else
root.move(drag.source.modelIndex, root.modelIndex)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment