I have prepared a simple example of a dynamic list view where items can be dynamically added, deleted by swiping to the left and moved by pressing and holding. For this last feature, I followed this example, http://doc.qt.io/qt-5/qtquick-tutorials-dynamicview-dynamicview3-example.html.
It works as expected, but is there a better way to do it?. Since SimpleRow does not propagate events I had to include a new MouseArea (holdMouseArea), where I have to manage all the events of SimpleRow. I tried to set propagateComposedEvents to true, but it does not work unless I set mouse.accepted = true in onPressed signal. If I do that, then I cannot listen to the onPressAndHold signal needed for the drag and drop. So, I would like to know if there a way to propagate events to SimpleRow, another option would be that SimpleRow propagates events to its parent.
This example works fine in the Felgo live client, but there an error in the Felgo web editor indicating that QtQml.Models is not installed.
import Felgo 3.0
import QtQuick 2.9
import QtQml.Models 2.2
App {
Item{
id: root
anchors.fill: parent
Column{
anchors.fill: parent
Rectangle{
id: header
width: parent.width
height: dp(40)
color: Theme.secondaryBackgroundColor
AppText{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("List view")
}
IconButton{
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: dp(5)
icon: IconType.plus
onClicked: addItem()
}
}
AppListView{
id: listView
height: parent.height - header.height
model: visualModel
emptyText.text: qsTr("No items, add a new one")
}
}
DelegateModel {
id: visualModel
model: listModel
delegate: listDelegate
}
ListModel{
id: listModel
Component.onCompleted: {
for(var i=1;i<=10; i++)
listModel.append(rowModel(i))
}
}
Component {
id: listDelegate
Item {
id: dragArea
property bool held: false
anchors { left: parent.left; right: parent.right }
height: container.height
DropArea {
anchors { fill: parent; margins: 10 }
onEntered: visualModel.items.move(drag.source.DelegateModel.itemsIndex,
dragArea.DelegateModel.itemsIndex)
}
SwipeOptionsContainer {
id: container
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
width: dragArea.width;
rightOption: SwipeButton {
text: qsTr("Delete")
icon: IconType.remove
height: dragArea.height
backgroundColor: "indianred"
onClicked: listModel.remove(index,1)
}
SimpleRow {
id: row
property bool pressed
anchors.fill: parent
text: name
style.backgroundColor: dragArea.held ? Qt.lighter(Theme.tintColor) :
row.pressed ? Theme.listSection.selectedBackgroundColor : Theme.backgroundColor
//onSelected: console.log("Selected item: " + name)
MouseArea{
id: holdMouseArea
anchors.fill: parent
pressAndHoldInterval: 500
//propagateComposedEvents: true
drag.target: held ? container : undefined
drag.axis: Drag.YAxis
onPressed: row.pressed = true
onPressAndHold: dragArea.held = true
onReleased: {
row.pressed = false
dragArea.held = false
}
onCanceled: {
row.pressed = false
dragArea.held = false
}
onClicked: console.log("Selected item: " + name)
//onClicked: mouse.accepted = false
//onPressed: mouse.accepted = false
}
}
Drag.active: dragArea.held
Drag.source: dragArea
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
states: State {
when: dragArea.held
ParentChange { target: container; parent: root }
AnchorChanges {
target: container
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
}
}
}
}
function rowModel(i)
{
return {name: qsTr("Item ") + i, value: i}
}
function addItem()
{
var max = 0
for(var i=0; i<listModel.count;i++)
if (listModel.get(i).value > max) max = listModel.get(i).value
listModel.append(rowModel(max+1))
}
}