title: QML: GridView with movable cells (drag and drop)
body: <p>I am following the approach given on <a href="http://qt-project.org/wiki/Drag_and_Drop_within_a_GridView" rel="nofollow">http://qt-project.org/wiki/Drag_and_Drop_within_a_GridView</a> .</p>
  
  <p>I have the presented program. Drag and drop is working, but after the drop I get
  empty space in my grid. How can I improve this?</p>
  
  <p>Moreover, I have also noticed that function indexAt() in line 46 not working correctly during the drag operation. Thus I had to add explicit calculation of gridArea.index.</p>
  
  <p>(EDITED) I seems to me that the empty space appears because after droping the element it is returned to its original position (it is below the visible element). GridView is not updated and finish in an irregular state. </p>
  
  <pre><code>import QtQuick 1.1
  
  GridView {
      id: mainGrid
      cellWidth: 165; cellHeight: 95
      width: 5*cellWidth; height: 4*cellHeight
      model: myModel
      delegate: myButton
  
      ListModel {
          id: myModel
          function createModel() {
              for (var i=1; i&lt;=20; i++) {
                  myModel.append({"display": i, "uid": i})
              }
          }
          Component.onCompleted: {createModel()}
      }
  
      Component {
          id: myButton
          Rectangle {
              id: item
              width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5;
              border.width: 1
              property int uid: (index &gt;= 0) ? myModel.get(index).uid : -1
              Text {
                  anchors.centerIn: parent
                  text: display
                  font.pixelSize: 48
              }
              states: [
                  State {
                      name: "active"; when: gridArea.activeId == item.uid
                      PropertyChanges {target: item; x: gridArea.mouseX-80; y: gridArea.mouseY-45; z: 10; smooth: false}
                  }
              ]
          }
      }
  
      MouseArea {
          id: gridArea
          anchors.fill: parent
          hoverEnabled: true
          preventStealing : true
          //property int index: mainGrid.indexAt(mouseX, mouseY) //WHY IS THIS NOT WORKING RELIABLE?
          property int mX: (mouseX &lt; 0) ? 0 : ((mouseX &lt; mainGrid.width - mainGrid.cellWidth) ? mouseX : mainGrid.width - mainGrid.cellWidth)
          property int mY: (mouseY &lt; 0) ? 0 : ((mouseY &lt; mainGrid.height - mainGrid.cellHeight) ? mouseY : mainGrid.height - mainGrid.cellHeight)
          property int index: parseInt(mX/mainGrid.cellWidth) + 5*parseInt(mY/mainGrid.cellHeight)  //item underneath cursor
          property int activeId: -1 //uid of active item
          property int activeIndex //current position of active item
          onPressAndHold: {
              activeId = mainGrid.model.get(activeIndex=index).uid
          }
          onReleased: {
              activeId = -1
          }
          onPositionChanged: {
              if (activeId != -1 &amp;&amp; index != -1 &amp;&amp; index != activeIndex) {
                  mainGrid.model.move(activeIndex, activeIndex = index, 1)
              }
          }
      }
  }
  </code></pre>