import QtQuick 2.8 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.2 import QtQuick.Controls.Material 2.1 import Nymea 1.0 import "../components" ItemDelegate { id: root property ParamType paramType: null property alias value: d.value property Param param: Param { id: d paramTypeId: paramType.id value: paramType.defaultValue } property bool writable: true property alias nameVisible: nameLabel.visible property string placeholderText: "" topPadding: 0 bottomPadding: 0 contentItem: ColumnLayout { id: contentItemColumn RowLayout { Label { id: nameLabel Layout.fillWidth: true Layout.minimumWidth: parent.width / 2 text: root.paramType.displayName elide: Text.ElideRight } Loader { id: loader Layout.fillWidth: true// sourceComponent === textFieldComponent || sourceComponent === stringComponent sourceComponent: { print("loading paramdelegate:", root.writable, root.paramType.type) if (!root.writable) { return stringComponent; } switch (root.paramType.type.toLowerCase()) { case "bool": return boolComponent; case "uint": case "int": case "double": if (root.paramType.minValue && root.paramType.maxValue) { return sliderComponent; } else { return spinnerComponent; } case "string": case "qstring": if (root.paramType.allowedValues.length > 0) { return comboBoxComponent; } return textFieldComponent; case "color": return colorPreviewComponent; } console.warn("Param Delegate: Fallback to stringComponent", root.paramType.name, root.paramType.type) return stringComponent; } } } Loader { Layout.fillWidth: true sourceComponent: { switch (root.paramType.type.toLowerCase()) { // case "int": // case "double": // if (root.paramType.minValue !== undefined && root.paramType.maxValue !== undefined) { // return sliderComponent // } // break; case "color": return colorPickerComponent } return null; } } } Component { id: stringComponent Label { text: { switch (root.paramType.type.toLowerCase()) { case "int": return Math.round(root.param.value); } return root.param.value; } horizontalAlignment: Text.AlignRight elide: Text.ElideRight } } Component { id: boolComponent Switch { checked: root.param.value === true Component.onCompleted: { if (root.param.value === undefined) { root.param.value = checked; } } onClicked: { root.param.value = checked; } } } Component { id: sliderComponent RowLayout { spacing: app.margins Slider { id: slider Layout.fillWidth: true from: root.paramType.minValue to: root.paramType.maxValue value: root.param.value stepSize: { var ret = 1 for (var i = 0; i < decimals; i++) { ret /= 10; } return ret; } property int decimals: root.paramType.type.toLocaleLowerCase() === "int" ? 0 : 1 onMoved: { var newValue switch (root.paramType.type.toLowerCase()) { case "int": newValue = Math.round(value) break; default: newValue = Math.round(value * 10) / 10 } root.param.value = newValue; } } Label { text: root.param.value.toFixed(slider.decimals) + root.paramType.unitString } } } Component { id: spinnerComponent RowLayout { spacing: app.margins SpinBox { value: root.param.value ? root.param.value : 0 from: root.paramType.minValue ? root.paramType.minValue : root.paramType.type.toLowerCase() === "uint" ? 0 : -2000000000 to: root.paramType.maxValue ? root.paramType.maxValue : 2000000000 editable: true width: 150 onValueModified: root.param.value = value textFromValue: function(value) { return value } Component.onCompleted: { if (root.value === undefined) { root.value = value } } } Label { text: root.paramType.unitString visible: text.length > 0 } } } Component { id: textFieldComponent TextField { text: root.param.value !== undefined ? root.param.value : root.paramType.defaultValue ? root.paramType.defaultValue : "" onEditingFinished: { root.param.value = text } Component.onCompleted: { if (root.param.value === undefined) { root.param.value = text; } } placeholderText: root.placeholderText } } Component { id: comboBoxComponent ComboBox { model: root.paramType.allowedValues currentIndex: root.paramType.allowedValues.indexOf(root.param.value) onActivated: { root.param.value = root.paramType.allowedValues[index] print("setting value to", root.param.value) } Component.onCompleted: { if (root.value === undefined) { root.value = model[0] } } } } Component { id: colorPickerComponent ColorPicker { id: colorPicker implicitHeight: 200 // color: root.param.value Binding { target: colorPicker property: "color" value: root.param.value when: !colorPicker.pressed } onColorChanged: { root.param.value = color; } touchDelegate: Rectangle { height: 15 width: height radius: height / 2 color: Material.accent Rectangle { color: colorPicker.hovered || colorPicker.pressed ? "#11000000" : "transparent" anchors.centerIn: parent height: 30 width: height radius: width / 2 Behavior on color { ColorAnimation { duration: 200 } } } } } } Component { id: colorPreviewComponent Rectangle { implicitHeight: app.mediumFont implicitWidth: implicitHeight color: root.param.value radius: width / 4 } } }