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.



  • Is there any possible way to do that? or not?

    --Attach--

    I've got a Idea, so currently working on it.

    --Attach--

    First testings are working pretty fine.



  • 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.0

    Rectangle {
    property int mainWidth: 1440
    property int mainHeight: 810
    property double reScale: 1.0

    readonly 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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.