Drag and Drop with custom Drop-positions
-
Is there any good way of doing a Smartphone/Tablet-like Positioning with draging QML Components around which snap to position and move other Components away, a customized positioning, that means not a default grid of like 100100 for each Component, but like 300200, 300200, then 20020 and so on... ? A drag and drop with different cellsizes.
-
Alright after a little bit of work a simple Concept is "done". It has got still a few bugs which i didn't try to resolve yet, also the code is not that beautiful but i think the "main-idea" is visible.
@import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Window 2.0
import QtQuick.Layouts 1.0Rectangle {
property int mainWidth: 1440
property int mainHeight: 810
property double reScale: 1.0readonly property var customGridXStart: [0, 0, 0, 0, 345] readonly property var customGridWidth: [345, 345, 345, 345, 1350] readonly property var customGridYStart: [0, 210, 405, 600, 0] readonly property var customGridHeight: [210, 195, 195, 210, mainHeight] readonly property var customPosX: [30, 30, 30, 30, 360] readonly property var customPosWidth: [300, 300, 300, 300, 720] readonly property var customPosY: [30, 225, 420, 615, 30] readonly property var customPosHeight: [165, 165, 165, 165, 750] property var setPos: [0, 0] property var setSize: [0, 0] property bool gridRecDebug: true function moveComponent(x, y){ for(var i = 0; i < dragItem.children.length; i++){ if(dragItem.children[i].children[0].x == x){ if(dragItem.children[i].children[0].y == y){ console.log(setPos[0] + " " + setPos[1]) dragItem.children[i].children[0].x = setPos[0] dragItem.children[i].children[0].y = setPos[1] dragItem.children[i].children[0].width = setSize[0] dragItem.children[i].children[0].height = setSize[1] } } } } Component { id: dragHeightWidthResize MouseArea { anchors.fill: mainFrame drag.minimumX: 0 drag.minimumY: 0 drag.maximumX: parent.parent.parent.parent.width - parent.parent.width drag.maximumY: parent.parent.parent.parent.height - parent.parent.height drag.target: parent.parent drag.axis: Drag.XAndYAxis onPositionChanged: { parent.parent.parent.z = 1 } onPressed: { setPos[0] = parent.parent.x setPos[1] = parent.parent.y setSize[0] = parent.parent.width setSize[1] = parent.parent.height } onReleased: { parent.parent.parent.z = 0 var rectX = parent.parent.x+(parent.parent.width/2) var rectY = parent.parent.y+(parent.parent.height/2) if((customGridXStart.length != customGridYStart.length) || (customGridWidth.length != customGridHeight.length) || (customPosX.length != customPosY.length)){ console.log("Wrong lenght in GridParam.") return } for(var i = 0; i < customGridXStart.length; i++){ if(rectX >= customGridXStart[i] && rectX <= customGridXStart[i]+customGridWidth[i]){ if(rectY >= customGridYStart[i] && rectY <= customGridYStart[i]+customGridHeight[i]){ moveComponent(customPosX[i], customPosY[i]) parent.parent.width = customPosWidth[i] * reScale parent.parent.height = customPosHeight[i] * reScale parent.parent.x = customPosX[i] parent.parent.y = customPosY[i] break } } } } } } Component { id: left1 Rectangle { x: 30; y: 30 width: 300; height: 165 opacity: 0.5 color: "lightgray"; border.width: 2 border.color: "#000000" radius: 5 antialiasing: true Loader { sourceComponent: dragHeightWidthResize; anchors.fill: parent } } } Component { id: left2 Rectangle { x: 30; y: 225 width: 300; height: 165 opacity: 0.5 color: "blue"; border.width: 2 border.color: "#000000" radius: 5 antialiasing: true Loader { sourceComponent: dragHeightWidthResize; anchors.fill: parent } } } id: mainFrame width: mainWidth height: mainHeight color: "#FFFFFF" Item { id: dragItem anchors.fill: parent Loader { sourceComponent: left1 } Loader { sourceComponent: left2 } }
}@
Yet it's also pretty dynamic. You just need a Component which has got any visible Item in it which Loads the dragHeightWidthResize Component
@Loader { sourceComponent: dragHeightWidthResize; anchors.fill: parent }@Im Loading all Components which are Drag and Dropable here:
@Item {
id: dragItem
anchors.fill: parent
Loader { sourceComponent: left1 }
Loader { sourceComponent: left2 }
}@The "look-up table" for the Grid is on top as a property array
@readonly property var customGridXStart: [0, 0, 0, 0, 345]
...
readonly property var customPosHeight: [165, 165, 165, 165, 750]@The most important math-part is in the function moveComponent(x, y) and in the onReleased slot in the dragHeightWidthResize Mousearea.
It still is pretty basic without much visual stuff. Does someone have a better Idea or Code which this person could provide? Thanks in advance.