import QtQuick 2.8 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.1 import QtQuick.Controls.Material 2.1 import Nymea 1.0 import "../components" ItemDelegate { id: root property var actionType: null property var actionState: null signal executeAction(var params) readonly property bool multiParam: actionType.paramTypes.count > 1 contentItem: ColumnLayout { RowLayout { Label { Layout.fillWidth: true text: root.actionType.displayName elide: Text.ElideRight visible: loader.sourceComponent != buttonComponent } Loader { id: loader Layout.fillWidth: sourceComponent == textFieldComponent || sourceComponent == buttonComponent sourceComponent: { if (root.multiParam || root.actionType.paramTypes.count === 0) { return buttonComponent } var paramType = root.actionType.paramTypes.get(0); switch (paramType.type.toLowerCase()) { case "bool": return boolComponent; case "double": case "int": if (paramType.minValue === undefined || paramType.maxValue === undefined) { return textFieldComponent } return stringComponent; case "string": case "qstring": if (paramType.allowedValues.length > 0) { return comboBoxComponent; } return buttonComponent; // return textFieldComponent; case "color": return colorPreviewComponent; } console.warn("Param Delegate: Fallback to stringComponent", paramType.name, paramType.type) return stringComponent; } } Binding { target: loader.item when: loader.item property: "paramType" value: root.actionType.paramTypes.get(0) } Binding { target: loader.item when: loader.item property: "value" value: root.actionState } } Repeater { id: paramRepeater model: root.actionType.paramTypes delegate: Loader { id: bottomLoader property var paramType: root.actionType.paramTypes.get(index) Layout.fillWidth: true sourceComponent: { switch (paramType.type.toLowerCase()) { case "int": case "double": if (paramType.minValue !== undefined && paramType.maxValue !== undefined) { if (root.multiParam) { return labelledSpinnerComponent; } return sliderComponent } return textFieldComponent; case "color": return colorPickerComponent case "string": return paramType.allowedValues.length === 0 ? textFieldComponent : root.actionType.paramTypes.count === 1 ? null : comboBoxComponent case "bool": if (root.multiParam) { return labeledBoolComponent; } return null } console.warn("WARNING", paramType.name, "of type", paramType.type, "not implemented") return null; } Binding { target: bottomLoader.item when: bottomLoader.item property: "paramType" value: bottomLoader.paramType } Binding { target: bottomLoader.item when: bottomLoader.item property: "value" value: (root.actionState && index == 0) ? root.actionState : root.actionType.paramTypes.get(index).defaultValue } } } } Component { id: stringComponent Label { property var paramType: null property var value: null text: { switch (paramType.type.toLowerCase()) { case "int": return Math.round(value); } return value; } } } Component { id: boolComponent Switch { checked: root.actionState === true onClicked: { var params = []; var param1 = {}; param1["paramTypeId"] = root.actionType.paramTypes.get(0).id; param1["value"] = checked; params.push(param1) root.executeAction(params) } } } Component { id: labeledBoolComponent RowLayout { id: switchRow property var paramType: null property var value Label { text: paramType.displayName Layout.fillWidth: true } Switch { checked: paramType.defaultValue onClicked: { switchRow.value = checked; } } } } Component { id: sliderComponent RowLayout { id: sliderRow spacing: app.margins property var paramType: null property var value: null Label { text: sliderRow.paramType.minValue } ThrottledSlider { Layout.fillWidth: true from: sliderRow.paramType.minValue to: sliderRow.paramType.maxValue value: sliderRow.value stepSize: { switch (sliderRow.paramType.type) { case "Int": return 1; } return 0.01; } onMoved: { var params = []; var param1 = new Object(); param1["paramTypeId"] = sliderRow.paramType.id; param1["value"] = value; params.push(param1) root.executeAction(params) } } Label { text: sliderRow.paramType.maxValue } } } Component { id: labelledSpinnerComponent RowLayout { id: sliderRow property var paramType: null property var value: null Label { text: sliderRow.paramType.displayName Layout.fillWidth: true } SpinBox { from: sliderRow.paramType.minValue to: sliderRow.paramType.maxValue value: sliderRow.value editable: true onValueModified: { sliderRow.value = value } } } } Component { id: textFieldComponent RowLayout { id: textFieldRow property alias value: textField.text property var paramType: null spacing: app.margins Label { text: paramType.displayName } TextField { id: textField Layout.fillWidth: true onAccepted: value = text } } } Component { id: comboBoxComponent ComboBox { id: box model: paramType.allowedValues currentIndex: paramType.allowedValues.indexOf(value) property var paramType: null property var value: null onActivated: { value = paramType.allowedValues[index] var params = []; var param1 = new Object(); param1["paramTypeId"] = paramType.id; param1["value"] = currentText; params.push(param1) root.executeAction(params) } } } Component { id: colorPickerComponent ColorPicker { id: colorPicker implicitHeight: 200 // color: root.param.value Binding { target: colorPicker property: "color" value: root.actionState when: !colorPicker.pressed } property var lastSentTime: new Date() onColorChanged: { var currentTime = new Date(); if (pressed && currentTime - lastSentTime > 200) { var params = []; var param1 = new Object(); param1["paramTypeId"] = paramType.id; param1["value"] = color; params.push(param1) root.executeAction(params) } } } } Component { id: colorPreviewComponent Rectangle { property var paramType: null property var value: null implicitHeight: app.mediumFont implicitWidth: implicitHeight color: value radius: width / 4 } } Component { id: buttonComponent Button { // just to suppress some warnings property var paramType: null property var value: null text: root.actionType.displayName onClicked: { print("ActionDelegate: Button clicked") var params = []; print("fooo", root.actionType.paramTypes.count) for (var i = 0; i < root.actionType.paramTypes.count; i++) { var param = {}; param["paramTypeId"] = root.actionType.paramTypes.get(i).id; print("bla", paramRepeater.itemAt(i), paramRepeater.itemAt(i).item, paramRepeater.itemAt(i).item.value) param["value"] = paramRepeater.itemAt(i).item.value; params.push(param) } root.executeAction(params) } } } }