Files
GenericQMLApp/ExpandableItemDelegate.qml

277 lines
7.4 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
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
required property string type
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
Image {
id: icon
width: 50
height: 50
source: "icons/software-application.png"
}
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("Description")
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
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
topMargin: 5
}
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
}
SpinBox {
value: item.amount
width: 80
height: 25
onValueModified: item.amount = value
}
Text {
id: factorText
text: "Factor: " + item.factor
wrapMode: Text.WordWrap
width: details.width
}
SpinBox {
id: spinBox
from: 0
value: decimalToInt(item.factor)
to: decimalToInt(100)
stepSize: decimalFactor
editable: true
property int decimals: 2
property real realValue: value / decimalFactor
readonly property int decimalFactor: Math.pow(10, decimals)
function decimalToInt(decimal) {
return decimal * decimalFactor
}
onValueModified: item.factor = value / decimalFactor
validator: DoubleValidator {
bottom: Math.min(spinBox.from, spinBox.to)
top: Math.max(spinBox.from, spinBox.to)
decimals: spinBox.decimals
notation: DoubleValidator.StandardNotation
}
textFromValue: function (value, locale) {
return Number(value / decimalFactor).toLocaleString(
locale, 'f', spinBox.decimals)
}
valueFromText: function (text, locale) {
return Math.round(Number.fromLocaleString(
locale, text) * decimalFactor)
}
}
Text {
id: typeText
text: "Type: " + item.type
wrapMode: Text.WordWrap
}
ComboBox {
// TODO use model from metadata.h (in some way)
model: ["A", "B", "C", ""]
// BUG type is not been updated due to undo/redo step
currentIndex: find(item.type)
Component.onCompleted: currentIndex = find(item.type)
onCurrentTextChanged: {
item.type = currentText
}
width: 80
height: 25
}
}
}
Image {
anchors {
right: flick.right
top: flick.top
}
source: "icons/moreUp.png"
opacity: flick.atYBeginning ? 0 : 1
}
Image {
anchors {
right: flick.right
bottom: flick.bottom
}
source: "icons/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"
}
}
}
}