From dc8a4683db6adfb2772dea558431cb3b3d6e5280 Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Sat, 7 Mar 2026 11:02:35 +0100 Subject: [PATCH] Using a expandable list item as delegate. (adapted Qt example: https://doc.qt.io/qt-6/qtquick-views-example.html) Icons not working yet! --- CMakeLists.txt | 5 +- ExpandableItemDelegate.qml | 215 +++++++++++++++++++++++++++++++++++++ ListPage.qml | 7 +- 3 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 ExpandableItemDelegate.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b71f15..39c2158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,9 @@ qt_add_qml_module(${TARGET_APP} URI GenericQML QML_FILES Main.qml - QML_FILES ListPage.qml - QML_FILES ListItemDelegate.qml + ListPage.qml + ListItemDelegate.qml + ExpandableItemDelegate.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. diff --git a/ExpandableItemDelegate.qml b/ExpandableItemDelegate.qml new file mode 100644 index 0000000..65fbcaa --- /dev/null +++ b/ExpandableItemDelegate.qml @@ -0,0 +1,215 @@ +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Layouts + +//! [0] +Item { + id: item + + required property int index + required property string name + required property string description + required property string info + required property int amount + required property real factor + + property real detailsOpacity: 0 + width: ListView.view.width + height: 70 + + Rectangle { + id: background + x: 2 + y: 2 + width: parent.width - x * 2 + height: parent.height - y * 2 + color: wccDarkLight + border.color: index === listView.currentIndex ? "blue" : wccDarkDefault + border.width: 3 + radius: 5 + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: mouse => { + parent.ListView.view.currentIndex = parent.index + if (mouse.button === Qt.RightButton) { + item.state = 'Details' + } + } + } + + Row { + id: topLayout + x: 10 + y: 10 + height: icon.height + width: parent.width + spacing: 10 + + Rectangle { + id: icon + width: 50 + height: 50 + color: wccLavenderDark + } + Column { + width: background.width - icon.width - 20 + height: icon.height + spacing: 5 + + Text { + text: item.name + font.bold: true + font.pointSize: 16 + } + + Text { + text: qsTr("Details") + font.bold: true + font.pointSize: 9 + opacity: item.detailsOpacity + } + + Text { + text: item.description + wrapMode: Text.WordWrap + width: parent.width + font.pointSize: 9 + opacity: item.detailsOpacity + } + } + } + + Item { + id: details + x: 10 + width: parent.width - 20 + + anchors { + top: topLayout.bottom + topMargin: 10 + bottom: parent.bottom + bottomMargin: 10 + } + opacity: item.detailsOpacity + //! [2] + Text { + id: moreInfoTitle + anchors.top: parent.top + text: qsTr("Further information") + font.pointSize: 9 + font.bold: true + } + + Flickable { + id: flick + width: parent.width + anchors { + top: moreInfoTitle.bottom + bottom: parent.bottom + } + contentHeight: infoText.height + clip: true + + ColumnLayout { + Text { + id: infoText + text: item.info + wrapMode: Text.WordWrap + width: details.width + } + Text { + id: amountText + text: "Amount: " + item.amount + wrapMode: Text.WordWrap + width: details.width + } + Text { + id: factorText + text: "Factor: " + item.factor + wrapMode: Text.WordWrap + width: details.width + } + } + } + + Image { + anchors { + right: flick.right + top: flick.top + } + source: ":/moreUp.png" + opacity: flick.atYBeginning ? 0 : 1 + } + + Image { + anchors { + right: flick.right + bottom: flick.bottom + } + + source: ":/moreDown.png" + opacity: flick.atYEnd ? 0 : 1 + } + } + + Button { + y: 10 + anchors { + right: background.right + rightMargin: 10 + } + opacity: item.detailsOpacity + text: qsTr("Close") + + onClicked: item.state = '' + } + + states: State { + name: "Details" + + PropertyChanges { + background.color: "white" + icon { + // Make picture bigger + width: 130 + height: 130 + } + item { + // Make details visible + detailsOpacity: 1 + x: 0 + + // Fill the entire list area with the detailed view + height: listView.height + } + } + + // Move the list so that this item is at the top. + PropertyChanges { + item.ListView.view.contentY: item.y + explicit: true + } + + // Disallow flicking while we're in detailed view + PropertyChanges { + item.ListView.view.interactive: false + } + } + + transitions: Transition { + // Make the state changes smooth + ParallelAnimation { + ColorAnimation { + property: "color" + duration: 500 + } + NumberAnimation { + duration: 300 + properties: "detailsOpacity,x,contentY,height,width" + } + } + } +} //! [3] diff --git a/ListPage.qml b/ListPage.qml index 79fd490..6c728ac 100644 --- a/ListPage.qml +++ b/ListPage.qml @@ -13,11 +13,8 @@ Page { model: mainModel - delegate: ListItemDelegate {} - highlight: Rectangle { - color: wccLavenderDefault - radius: 5 - } + // delegate: ListItemDelegate {} + delegate: ExpandableItemDelegate {} header: bannercomponent footer: Rectangle {