From 609f777d1390375bd5e4676b458c45ec1f851b7a Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Mon, 9 Mar 2026 07:51:16 +0100 Subject: [PATCH] Added an editable item delegate. Only Factor plus/minus button are working for now. (based on https://doc.qt.io/qt-6/qtquick-views-example.html as well) --- CMakeLists.txt | 10 +- EditableItemDelegate.qml | 163 ++++++++++++++++++++++++++++++++ ExpandableItemDelegate.qml | 6 +- ListPage.qml | 4 +- controls/PressAndHoldButton.qml | 45 +++++++++ icons/arrow-down.png | Bin 0 -> 594 bytes icons/arrow-up.png | Bin 0 -> 692 bytes icons/list-delete.png | Bin 0 -> 831 bytes icons/minus-sign.png | Bin 0 -> 250 bytes icons/plus-sign.png | Bin 0 -> 462 bytes 10 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 EditableItemDelegate.qml create mode 100644 controls/PressAndHoldButton.qml create mode 100644 icons/arrow-down.png create mode 100644 icons/arrow-up.png create mode 100644 icons/list-delete.png create mode 100644 icons/minus-sign.png create mode 100644 icons/plus-sign.png diff --git a/CMakeLists.txt b/CMakeLists.txt index b055edc..d713665 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,10 +20,14 @@ qt_add_qml_module(${TARGET_APP} ListPage.qml ListItemDelegate.qml ExpandableItemDelegate.qml + EditableItemDelegate.qml + controls/PressAndHoldButton.qml RESOURCES - "icons/software-application.png" - "icons/moreUp.png" - "icons/moreDown.png" + icons/software-application.png + icons/moreUp.png icons/moreDown.png + icons/arrow-down.png icons/arrow-up.png + icons/list-delete.png + icons/minus-sign.png icons/plus-sign.png ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. diff --git a/EditableItemDelegate.qml b/EditableItemDelegate.qml new file mode 100644 index 0000000..7885f49 --- /dev/null +++ b/EditableItemDelegate.qml @@ -0,0 +1,163 @@ +import QtQuick + +import "controls" + +Item { + //! [0] + id: delegateItem + width: listView.width + height: 80 + clip: true + + required property int index + + // required property string edit + // required property QtObject model + required property string name + required property string description + required property string info + required property int amount + required property real factor + + 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 + } + + Column { + id: arrows + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + } + Image { + source: "icons/arrow-up.png" + MouseArea { + anchors.fill: parent + // onClicked: fruitModel.move(delegateItem.index, + // delegateItem.index - 1, 1) + } + } + Image { + source: "icons/arrow-down.png" + MouseArea { + anchors.fill: parent + // onClicked: fruitModel.move(delegateItem.index, + // delegateItem.index + 1, 1) + } + } + } + + Column { + anchors { + left: arrows.right + horizontalCenter: parent.horizontalCenter + bottom: parent.verticalCenter + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: delegateItem.name + font.pixelSize: 15 + color: "white" + } + Text { + text: delegateItem.description + color: "White" + } + } + + Item { + anchors { + left: arrows.right + horizontalCenter: parent.horizontalCenter + top: parent.verticalCenter + bottom: parent.bottom + } + + Row { + anchors.centerIn: parent + spacing: 10 + + PressAndHoldButton { + anchors.verticalCenter: parent.verticalCenter + source: "icons/plus-sign.png" + onClicked: delegateItem.factor = delegateItem.factor + 0.25 + } + + Text { + id: factorText + anchors.verticalCenter: parent.verticalCenter + text: 'Factor: ' + Number(delegateItem.factor).toFixed(2) + font.pixelSize: 15 + color: "white" + font.bold: true + } + + PressAndHoldButton { + anchors.verticalCenter: parent.verticalCenter + source: "icons/minus-sign.png" + onClicked: delegateItem.factor = Math.max( + 0, delegateItem.factor - 0.25) + } + + Image { + source: "icons/list-delete.png" + MouseArea { + anchors.fill: parent + onClicked: fruitModel.remove(delegateItem.index) + } + } + } + } + + // Animate adding and removing of items: + //! [1] + SequentialAnimation { + id: addAnimation + PropertyAction { + target: delegateItem + property: "height" + value: 0 + } + NumberAnimation { + target: delegateItem + property: "height" + to: 80 + duration: 250 + easing.type: Easing.InOutQuad + } + } + ListView.onAdd: addAnimation.start() + + SequentialAnimation { + id: removeAnimation + PropertyAction { + target: delegateItem + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: delegateItem + property: "height" + to: 0 + duration: 250 + easing.type: Easing.InOutQuad + } + + // Make sure delayRemove is set back to false so that the item can be destroyed + PropertyAction { + target: delegateItem + property: "ListView.delayRemove" + value: false + } + } + ListView.onRemove: removeAnimation.start() +} diff --git a/ExpandableItemDelegate.qml b/ExpandableItemDelegate.qml index aa2e210..a321fe2 100644 --- a/ExpandableItemDelegate.qml +++ b/ExpandableItemDelegate.qml @@ -1,8 +1,7 @@ import QtQuick -import QtQuick.Controls.Material +import QtQuick.Controls import QtQuick.Layouts -//! [0] Item { id: item @@ -95,7 +94,6 @@ Item { bottomMargin: 10 } opacity: item.detailsOpacity - //! [2] Text { id: moreInfoTitle anchors.top: parent.top @@ -213,4 +211,4 @@ Item { } } } -} //! [3] +} diff --git a/ListPage.qml b/ListPage.qml index 6c728ac..81b4f35 100644 --- a/ListPage.qml +++ b/ListPage.qml @@ -12,9 +12,11 @@ Page { clip: true model: mainModel + delegateModelAccess: DelegateModel.ReadWrite // delegate: ListItemDelegate {} - delegate: ExpandableItemDelegate {} + // delegate: ExpandableItemDelegate {} + delegate: EditableItemDelegate {} header: bannercomponent footer: Rectangle { diff --git a/controls/PressAndHoldButton.qml b/controls/PressAndHoldButton.qml new file mode 100644 index 0000000..51ab943 --- /dev/null +++ b/controls/PressAndHoldButton.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick + +Image { + id: container + + property int repeatDelay: 300 + property int repeatDuration: 75 + property bool pressed + + signal clicked + + scale: pressed ? 0.9 : 1 + + function release() { + autoRepeatClicks.stop() + container.pressed = false + } + + SequentialAnimation on pressed { + id: autoRepeatClicks + running: false + + PropertyAction { target: container; property: "pressed"; value: true } + ScriptAction { script: container.clicked() } + PauseAnimation { duration: container.repeatDelay } + + SequentialAnimation { + loops: Animation.Infinite + ScriptAction { script: container.clicked() } + PauseAnimation { duration: container.repeatDuration } + } + } + + MouseArea { + anchors.fill: parent + + onPressed: autoRepeatClicks.start() + onReleased: container.release() + onCanceled: container.release() + } +} + diff --git a/icons/arrow-down.png b/icons/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..29d1d4439a139c662aecca94b6f43a465cfb9cc6 GIT binary patch literal 594 zcmV-Y0j z)Xz`TU>wKswOeUBH_Vo3LZ*V4p&U4v;LVFDq!ObUNJtQHC_UYOy}c$4_Z z287Mpy&>Gkk3$;%;XTGD)-SARcb^V+y#l_lys$a@k{nD+qgKLE+C6xLudGK{sd70w zcE71nDjtqr6rQslcH!s21HbzIZLG4Ku(F%O+U^xp_O4>4nBl-LJ{^?W2788E7ww3c$dW3qz>Ki(HSZqJlD~5#;x#SD}gQ7 zgv0(;bxhbL9Yezjn5K`uZiTiRwq2=|ckJ6DkxX7Tsy45p8>IMse%D zf;Vqf6vh<#P(J!fv{R}3IKcTOvuzkL=(>--JPth;j^KP+u2DCF7oBg1O2Gjh4p2raNh0iv$(l~TMx4kdC6q9nEA|`**D{}k#dX8|6LB>7#;)I^Ped=4Hzs5}YJfl=IMqVOwV3TOn<`fg+FtutHTOl+p4ItW@S@UCRT$s#e2Vdg=lo5D}~>p3$197_jRp z=YhPc7Gm8z$3=Kf7AcnG)$Gyx5pjP)J5;=W_SftyqWmZ>V+N`!8lA3I}LdVVyM axbX+reAIe(fQ}9T0000R5;6h zl}l(-K@^6Q=FtdACA#^NDs^{Lp)6)L zgDB5eX;UdG_4H6F7*yIgXmIAu0!5NyOCtSU7G=!;6%|3j{gliox-!pOK?G(o&X({YLK$5)lC7F{VZbo703UCXA=&? zO>Nu>w#%A8Rp;5oKacEBBT*BGX+{#I_yE%2i8f!~SeeejbP6SvLH5VQ-~o6A-hwe1 z-+)oOG3-#N-p|7H3rxph%DcJ`E`ihFDtIo2X&L#)9#wa!-__Ey=>18UreVqnx(m*O z14e_~1JA$~|`2HhU^Ra!WRl)GgiU zYU$BXh#q3R4$gpm?mF#|Br$YH!gK>%1c$VCx82fBJaI+hxwpFb)g=^Dbv{zQc<7+k z9t8>W67osVx3S=)K2n#oseNr$I`ov*vgsc2h}xyrpv>h+JHeJUF8ZjWkj` zH1UE>PMpf&iLCQ!iioCJ)~Hi?YjvJaK8_pg59Au!plIt&?SDO~mzDzYD;xj-002ov JPDHLkV1h`%ho%4k literal 0 HcmV?d00001 diff --git a/icons/minus-sign.png b/icons/minus-sign.png new file mode 100644 index 0000000000000000000000000000000000000000..d6f233d7399c4c07c6c66775f7806acac84b1870 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6P60k4u0Wb3;FYqWamwl0TmSYg zzPEV)f9L4=uDMg50*&A=3GxeOV9U{Bm1EIh)b!)dNY8G|=4l2>MR>Y6hE&9zJ@3ia zpuppBkxMsqLg3#2p{{ow4y^sCTR&@AtNcZ-!c0XiUIF(fS@*p4-Mvkxubuwr)McGB zHm7G5zmh%w<-tAQYwQ=f{_Q#i|$63?4Gdn(WDhGy5?S*zvKV>UH^L*-tUX z$Jv{I&ffC7bM{5Qj4e}Ezbj}vVjnSc;_|19_y1onFfAQuu24ykUoZnB3o9G9teS?7 zt9NpGMrLu#@0UVzfU@^IT^vIy;%X<}%xf{=arHKHYQL~@ZfotgwYUG*$MH^!I&%2V z@)sJL`rl4pesV%`$+ja*^=&3!b{Hmgs`72G$lh?~sgSmhV3T|L)#5pvnp5W$R3F&x zq^-&N)%9FO2FOm@bA*rKR&a{^p(h(SexKRzobg)f!S5Tb z0(ReeejodN_$Ob%pPGvI-{X5McZ=;}w|{;sE!Zmj;a8K;+WTSWrcUlO+qsq1zw`F> zL$~g{I69@}|MDjqpAy@zuKLv`b1gzCeQUnq?;S;@b8|k;l-+S#KOj|nW)fHH0-#SB NJYD@<);T3K0RYVY#HauO literal 0 HcmV?d00001