Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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