Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Drag & Drop in ListView problem

    QML and Qt Quick
    2
    6
    2485
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      ephe last edited by

      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()
                      }
                  }
              }
      
          }
      }
      

      }
      @

      1 Reply Last reply Reply Quote 0
      • p3c0
        p3c0 Moderators last edited by

        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.

        157

        1 Reply Last reply Reply Quote 0
        • E
          ephe last edited by

          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

          1 Reply Last reply Reply Quote 0
          • p3c0
            p3c0 Moderators last edited by

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

            157

            1 Reply Last reply Reply Quote 0
            • E
              ephe last edited by

              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

              1 Reply Last reply Reply Quote 0
              • E
                ephe last edited by

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

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post