Drag & Drop in ListView problem



  • I have created a ListView and I want to drag & drop the items within it. As long as I do not move the items out of the view, everything works fine.
    To scroll the view while the mouse is pressed, I have animated the ListView. During the animations, the DropArea entered is not called.
    If I then drag an item out of the view (the space of the item is not visible anymore), the x of the items is shifted for 80 pixels (width of an item) to the right. I am not sure if this is the desired behaviour, for me it causes some problems as it is not possible anymore to move the items to the very right.
    I have already tried to set the cacheBuffer higher and also tried to move the items into the persistedItems.

    The best way to reproduce it is to drag the first item, move the mouse underneath the list and to the very right and wait until the list has scrolled to the end. Then move the item to the left of the last item (also underneath the list) and drop it.

    Has anyone had the same problem or are there any suggestions on how to implement this scrolling while dragging & dropping?

    Thank you in advance!

    @
    import QtQuick 2.0
    import QtQml.Models 2.1
    Item
    {
    width: 800
    height: 150

    ListView {
        id: root
        width: 800; height: 150
        orientation: ListView.Horizontal
        displaced: Transition {
            NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }
        }
        PropertyAnimation
        {
            id: ani
            property bool bForward: false
            target: root
            property: "contentX"
            from: root.contentX
            to: bForward ? root.contentWidth-root.width : 0
            duration: bForward ? (root.contentWidth-root.width-root.contentX)*2 : root.contentX*2
        }
        cacheBuffer: model.count*1000
        property bool forward: false
        spacing: 10
        property bool dragActive: false
        model: DelegateModel {
            id: visualModel
    
            model: ListModel {
                id: colorModel
                ListElement { color: "yellow" }
                ListElement { color: "orange" }
                ListElement { color: "red" }
                ListElement { color: "darkred" }
                ListElement { color: "pink" }
                ListElement { color: "purple" }
                ListElement { color: "lightblue" }
                ListElement { color: "blue" }
                ListElement { color: "darkblue" }
                ListElement { color: "lightgreen" }
                ListElement { color: "green" }
                ListElement { color: "darkgreen" }
                ListElement { color: "lightgrey" }
                ListElement { color: "darkgrey" }
                ListElement { color: "grey" }
                ListElement { color: "black" }
            }
            delegate: MouseArea {
                id: delegateRoot
    
                property int visualIndex: DelegateModel.itemsIndex
                width: 80; height: 80
                drag.target: icon
                onXChanged: if(visualIndex == 0) console.log("x: " + x)
                Rectangle {
                    id: icon
                    width: 80; height: 80
                    opacity: root.currentIndex == delegateRoot.DelegateModel.itemsIndex ? 1 : 0.2
                    anchors {
                        horizontalCenter: parent.horizontalCenter;
                        verticalCenter: parent.verticalCenter
                    }
                    color: model.color
                    radius: 3
    
                    Drag.active: delegateRoot.drag.active
                    Drag.source: delegateRoot
                    Drag.hotSpot.x: 36
                    Drag.hotSpot.y: 36
    
                    states: [
                        State {
                            when: icon.Drag.active
                            ParentChange {
                                target: icon
                                parent: root
                            }
    
                            AnchorChanges {
                                target: icon;
                                anchors.horizontalCenter: undefined;
                                anchors.verticalCenter: undefined
                            }
                        }
                    ]
                }
                Text
                {
                    anchors.centerIn: parent
                    text: index + " " + delegateRoot.DelegateModel.itemsIndex
                }
    
                DropArea {
                    id:dropArea
                    anchors { fill: parent; margins: 15 }
                    onEntered:
                    {
                        visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)
                    }
                }
    
                onReleased:
                {
                    ani.stop()
                }
    
                onMouseXChanged:
                {
                    root.dragActive = true
                    if(mapToItem(root, mouseX, mouseY).x > 750)
                    {
                        if(!root.atXEnd)
                        {
                            ani.bForward = true
                            ani.start()
                        }
                    }
                    else if(mapToItem(root, mouseX, mouseY).x < 50)
                    {
                        if(!root.atXBeginning)
                        {
                            ani.bForward = false
                            ani.start()
                        }
                    }
                    else if (mapToItem(root, mouseX, mouseY).x >= 50 && mapToItem(root, mouseX, mouseY).x <= 750)
                    {
                        ani.stop()
                    }
                }
            }
    
        }
    }
    

    }
    @


  • Moderators

    Hi,

    If i understood correctly, the DropArea doesn’t gets called as per your explanation. Is it ? If So, then you can increase the height of DropArea.



  • do you mean the z value? I have just tried to set the z value of the MouseArea to 90 and the z value of the DropArea to 100, but sadly it still does not work.
    Whenever I move the mouse, the DropArea gets called, but if I just leave the mouse at the very right or left, I do not get the onEntered event


  • Moderators

    No, the height of DropArea. Something like this,
    @
    DropArea {
    id:dropArea
    //anchors { fill: parent; margins: 15 }
    width: parent.width
    height: parent.width*2
    }
    @



  • Thank you for your quick answers!
    I also just tried, but it does not work. The DropArea does react while I move the mouse, but while I execute the animation to scroll the list, it does not react anymore



  • I just checked the qt code, it seems that the DropArea.entered() signal is only sent when the mouse moves


Log in to reply
 

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