Update rule editor to not use generated events for states any more
This commit is contained in:
parent
43b447d0af
commit
efe51b33e4
@ -116,7 +116,10 @@ QList<int> ThingDiscovery::discoverThingsByInterface(const QString &interfaceNam
|
|||||||
|
|
||||||
for (int i = 0; i < m_engine->thingManager()->thingClasses()->rowCount(); i++) {
|
for (int i = 0; i < m_engine->thingManager()->thingClasses()->rowCount(); i++) {
|
||||||
ThingClass *thingClass = m_engine->thingManager()->thingClasses()->get(i);
|
ThingClass *thingClass = m_engine->thingManager()->thingClasses()->get(i);
|
||||||
if (!thingClass->interfaces().contains(interfaceName)) {
|
if (!thingClass->interfaces().contains(interfaceName) && !thingClass->providedInterfaces().contains(interfaceName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!thingClass->createMethods().contains("CreateMethodDiscovery")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pendingCommands.append(discoverThingsInternal(thingClass->id()));
|
pendingCommands.append(discoverThingsInternal(thingClass->id()));
|
||||||
|
|||||||
@ -274,5 +274,6 @@
|
|||||||
<file>ui/components/SettingsTile.qml</file>
|
<file>ui/components/SettingsTile.qml</file>
|
||||||
<file>ui/components/NymeaTextField.qml</file>
|
<file>ui/components/NymeaTextField.qml</file>
|
||||||
<file>ui/system/TunnelProxyServerConfigurationDialog.qml</file>
|
<file>ui/system/TunnelProxyServerConfigurationDialog.qml</file>
|
||||||
|
<file>ui/delegates/StateDelegate.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -106,48 +106,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "Automatic night mode",
|
|
||||||
"ruleNameTemplate": "Automatic night mode on %0",
|
|
||||||
"timeDescriptorTemplate": {
|
|
||||||
"calendarItemTemplates": [
|
|
||||||
{
|
|
||||||
"startTime": "22:00",
|
|
||||||
"duration": 600,
|
|
||||||
"repeatingOption": {
|
|
||||||
"repeatingMode": "RepeatingModeDaily"
|
|
||||||
},
|
|
||||||
"editable": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ruleActionTemplates": [
|
|
||||||
{
|
|
||||||
"interfaceName": "mediacontroller",
|
|
||||||
"interfaceAction": "nightMode",
|
|
||||||
"selectionId": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"name": "nightMode",
|
|
||||||
"value": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ruleExitActionTemplates": [
|
|
||||||
{
|
|
||||||
"interfaceName": "mediacontroller",
|
|
||||||
"interfaceAction": "nightMode",
|
|
||||||
"selectionId": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"name": "nightMode",
|
|
||||||
"value": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Play/pause music by button press",
|
"description": "Play/pause music by button press",
|
||||||
"ruleNameTemplate": "%1 toggles play/pause on %0",
|
"ruleNameTemplate": "%1 toggles play/pause on %0",
|
||||||
|
|||||||
@ -39,6 +39,7 @@ SwipeDelegate {
|
|||||||
implicitWidth: 200
|
implicitWidth: 200
|
||||||
implicitHeight: Style.smallDelegateHeight
|
implicitHeight: Style.smallDelegateHeight
|
||||||
|
|
||||||
|
|
||||||
property string subText
|
property string subText
|
||||||
property bool progressive: true
|
property bool progressive: true
|
||||||
property bool canDelete: false
|
property bool canDelete: false
|
||||||
@ -199,6 +200,15 @@ SwipeDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swipe.enabled: {
|
||||||
|
for (var i = 0; i < d.finalContextOptions.length; i++) {
|
||||||
|
if (d.finalContextOptions[i].visible) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
swipe.right: swipeComponent
|
swipe.right: swipeComponent
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|||||||
@ -37,14 +37,20 @@ import "../components"
|
|||||||
ItemDelegate {
|
ItemDelegate {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var paramType: null
|
property ParamType paramType: null
|
||||||
|
property StateType stateType: null
|
||||||
property var value: null
|
property var value: null
|
||||||
property int operatorType: ParamDescriptors.ValueOperatorEquals
|
property int operatorType: ParamDescriptors.ValueOperatorEquals
|
||||||
|
|
||||||
|
readonly property string type: paramType ? paramType.type.toLowerCase() : stateType ? stateType.type.toLowerCase() : ""
|
||||||
|
readonly property var minValue: paramType ? paramType.minValue : stateType ? stateType.minValue : undefined
|
||||||
|
readonly property var maxValue: paramType ? paramType.maxValue : stateType ? stateType.maxValue : undefined
|
||||||
|
readonly property var allowedValues: paramType ? paramType.allowedValues : stateType ? stateType.allowedValues : undefined
|
||||||
|
readonly property int unit: paramType ? root.paramType.unit : root.stateType.unit
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: paramType.displayName
|
text: root.paramType ? root.paramType.displayName : root.stateType.displayName
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@ -64,7 +70,7 @@ ItemDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property bool isNumeric: {
|
property bool isNumeric: {
|
||||||
switch (paramType.type.toLowerCase()) {
|
switch (root.type) {
|
||||||
case "bool":
|
case "bool":
|
||||||
case "string":
|
case "string":
|
||||||
case "qstring":
|
case "qstring":
|
||||||
@ -75,7 +81,7 @@ ItemDelegate {
|
|||||||
case "double":
|
case "double":
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
console.warn("ParamDescriptorDelegate: Unhandled data type:", paramType.type.toLowerCase());
|
console.warn("ParamDescriptorDelegate: Unhandled data type:", root.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,44 +120,45 @@ ItemDelegate {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
print("Datatye is:", paramType.name, paramType.type, paramType.minValue, paramType.maxValue, paramType.allowedValues)
|
print("Datatye is:", root.type, root.minValue, root.maxValue, root.allowedValues)
|
||||||
switch (paramType.type.toLowerCase()) {
|
switch (root.type) {
|
||||||
case "bool":
|
case "bool":
|
||||||
return boolComponent;
|
return boolComponent;
|
||||||
case "uint":
|
case "uint":
|
||||||
case "int":
|
case "int":
|
||||||
case "double":
|
case "double":
|
||||||
if (paramType.minValue !== undefined && paramType.maxValue !== undefined) {
|
if (root.minValue !== undefined && root.maxValue !== undefined) {
|
||||||
return labelComponent;
|
return labelComponent;
|
||||||
}
|
}
|
||||||
return spinboxComponent;
|
return spinboxComponent;
|
||||||
case "string":
|
case "string":
|
||||||
case "qstring":
|
case "qstring":
|
||||||
case "color":
|
case "color":
|
||||||
if (paramType.allowedValues.length > 0) {
|
if (root.allowedValues.length > 0) {
|
||||||
return comboBoxComponent
|
return comboBoxComponent
|
||||||
}
|
}
|
||||||
return textFieldComponent;
|
return textFieldComponent;
|
||||||
}
|
}
|
||||||
console.warn("ParamDescriptorDelegate: Type delegate not implemented", paramType.type)
|
console.warn("ParamDescriptorDelegate: Type delegate not implemented", root.type)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: Types.toUiUnit(paramType.unit)
|
text: Types.toUiUnit(root.unit)
|
||||||
visible: paramType.unit !== Types.UnitNone
|
visible: root.unit !== Types.UnitNone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
print("***********+ loading", paramType.type)
|
print("***********+ loading", root.type)
|
||||||
switch (paramType.type.toLowerCase()) {
|
switch (root.type) {
|
||||||
|
case "uint":
|
||||||
case "int":
|
case "int":
|
||||||
case "double":
|
case "double":
|
||||||
if (paramType.minValue !== undefined && paramType.maxValue !== undefined) {
|
if (root.minValue !== undefined && root.maxValue !== undefined) {
|
||||||
return sliderComponent
|
return sliderComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +173,11 @@ ItemDelegate {
|
|||||||
id: labelComponent
|
id: labelComponent
|
||||||
Label {
|
Label {
|
||||||
text: {
|
text: {
|
||||||
switch (root.paramType.type.toLowerCase()) {
|
switch (root.type.toLowerCase()) {
|
||||||
case "double":
|
case "double":
|
||||||
return Math.round(Types.toUiValue(root.value, root.paramType.unit) * 10) / 10
|
return Math.round(Types.toUiValue(root.value, root.unit) * 10) / 10
|
||||||
}
|
}
|
||||||
return Types.toUiValue(root.value, root.paramType.unit)
|
return Types.toUiValue(root.value, root.unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,13 +196,13 @@ ItemDelegate {
|
|||||||
id: sliderComponent
|
id: sliderComponent
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: app.margins
|
spacing: app.margins
|
||||||
Label { text: Types.toUiValue(root.paramType.minValue, root.paramType.unit) }
|
Label { text: Types.toUiValue(root.minValue, root.unit) }
|
||||||
Slider {
|
Slider {
|
||||||
from: paramType.minValue
|
from: root.minValue
|
||||||
to: paramType.maxValue
|
to: root.maxValue
|
||||||
value: root.value
|
value: root.value
|
||||||
stepSize: {
|
stepSize: {
|
||||||
switch (root.paramType.type.toLowerCase()) {
|
switch (root.type.toLowerCase()) {
|
||||||
case "double":
|
case "double":
|
||||||
return 0.1
|
return 0.1
|
||||||
}
|
}
|
||||||
@ -206,7 +213,7 @@ ItemDelegate {
|
|||||||
root.value = value;
|
root.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label { text: Types.toUiValue(root.paramType.maxValue, root.paramType.unit) }
|
Label { text: Types.toUiValue(root.maxValue, root.unit) }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -214,11 +221,11 @@ ItemDelegate {
|
|||||||
Component {
|
Component {
|
||||||
id: spinboxComponent
|
id: spinboxComponent
|
||||||
NymeaSpinBox {
|
NymeaSpinBox {
|
||||||
from: paramType.minValue
|
from: root.minValue
|
||||||
to: paramType.maxValue
|
to: root.maxValue
|
||||||
value: root.value != undefined ? root.value : 0
|
value: root.value != undefined ? root.value : 0
|
||||||
onValueModified: root.value = value
|
onValueModified: root.value = value
|
||||||
floatingPoint: root.paramType.type.toLowerCase() === "double"
|
floatingPoint: root.type === "double"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +245,9 @@ ItemDelegate {
|
|||||||
Component {
|
Component {
|
||||||
id: comboBoxComponent
|
id: comboBoxComponent
|
||||||
ComboBox {
|
ComboBox {
|
||||||
model: paramType.allowedValues
|
model: root.allowedValues
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
root.value = paramType.allowedValues[currentIndex]
|
root.value = root.allowedValues[currentIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
362
nymea-app/ui/delegates/StateDelegate.qml
Normal file
362
nymea-app/ui/delegates/StateDelegate.qml
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
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 StateType stateType: null
|
||||||
|
property alias value: d.value
|
||||||
|
property Param param: Param {
|
||||||
|
id: d
|
||||||
|
paramTypeId: stateType.id
|
||||||
|
value: stateType.defaultValue
|
||||||
|
}
|
||||||
|
property bool writable: true
|
||||||
|
property alias nameVisible: nameLabel.visible
|
||||||
|
property string placeholderText: ""
|
||||||
|
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
id: contentItemColumn
|
||||||
|
RowLayout {
|
||||||
|
spacing: app.margins
|
||||||
|
property bool labelFillsWidth: loader.sourceComponent !== textFieldComponent
|
||||||
|
&& loader.sourceComponent !== stringComponent
|
||||||
|
Label {
|
||||||
|
id: nameLabel
|
||||||
|
Layout.fillWidth: parent.labelFillsWidth
|
||||||
|
// Layout.minimumWidth: parent.width / 2
|
||||||
|
text: root.stateType.displayName
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
Layout.fillWidth: !parent.labelFillsWidth
|
||||||
|
sourceComponent: {
|
||||||
|
print("Loading ParamDelegate");
|
||||||
|
print("Writable:", root.writable, "type:", root.stateType.type, "min:", root.stateType.minValue, "max:", root.stateType.maxValue, "value:", root.param.value)
|
||||||
|
if (!root.writable) {
|
||||||
|
return stringComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (root.stateType.type.toLowerCase()) {
|
||||||
|
case "bool":
|
||||||
|
return boolComponent;
|
||||||
|
case "uint":
|
||||||
|
case "int":
|
||||||
|
if (root.stateType.name == "colorTemperature") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case "double":
|
||||||
|
if (root.stateType.allowedValues.length > 0) {
|
||||||
|
return comboBoxComponent;
|
||||||
|
} else if (root.stateType.minValue !== undefined && root.stateType.maxValue !== undefined
|
||||||
|
&& (root.stateType.maxValue - root.stateType.minValue <= 100)) {
|
||||||
|
return sliderComponent;
|
||||||
|
} else {
|
||||||
|
return spinnerComponent;
|
||||||
|
}
|
||||||
|
case "string":
|
||||||
|
case "qstring":
|
||||||
|
if (root.stateType.allowedValues.length > 0) {
|
||||||
|
return comboBoxComponent;
|
||||||
|
}
|
||||||
|
return textFieldComponent;
|
||||||
|
case "color":
|
||||||
|
return colorPreviewComponent;
|
||||||
|
}
|
||||||
|
console.warn("Param Delegate: Fallback to stringComponent", root.stateType.name, root.stateType.type)
|
||||||
|
return stringComponent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
sourceComponent: {
|
||||||
|
if (root.stateType.name == "colorTemperature") {
|
||||||
|
return colorTemperaturePickerComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (root.stateType.type.toLowerCase()) {
|
||||||
|
case "color":
|
||||||
|
return colorPickerComponent
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: stringComponent
|
||||||
|
Label {
|
||||||
|
text: {
|
||||||
|
switch (root.stateType.type.toLowerCase()) {
|
||||||
|
case "int":
|
||||||
|
return Math.round(root.param.value);
|
||||||
|
}
|
||||||
|
return root.param.value;
|
||||||
|
}
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component {
|
||||||
|
id: boolComponent
|
||||||
|
Item {
|
||||||
|
implicitHeight: theSwitch.implicitHeight
|
||||||
|
implicitWidth: theSwitch.implicitWidth
|
||||||
|
Switch {
|
||||||
|
id: theSwitch
|
||||||
|
anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
|
||||||
|
width: Math.min(parent.width, implicitiWidth)
|
||||||
|
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.stateType.minValue
|
||||||
|
to: root.stateType.maxValue
|
||||||
|
value: root.param.value
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (root.param.value === undefined) {
|
||||||
|
if (root.stateType.defaultValue !== undefined) {
|
||||||
|
root.param.value = root.stateType.defaultValue
|
||||||
|
} else {
|
||||||
|
root.param.value = root.stateType.minValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stepSize: {
|
||||||
|
var ret = 1
|
||||||
|
for (var i = 0; i < decimals; i++) {
|
||||||
|
ret /= 10;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
property int decimals: root.stateType.type.toLocaleLowerCase() === "double" ? 1 : 0
|
||||||
|
|
||||||
|
onMoved: {
|
||||||
|
var newValue
|
||||||
|
switch (root.stateType.type.toLowerCase()) {
|
||||||
|
case "int":
|
||||||
|
newValue = Math.round(value)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newValue = Math.round(value * 10) / 10
|
||||||
|
}
|
||||||
|
root.param.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: Types.toUiValue(root.param.value, root.stateType.unit).toFixed(slider.decimals) + Types.toUiUnit(root.stateType.unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: spinnerComponent
|
||||||
|
RowLayout {
|
||||||
|
spacing: app.margins
|
||||||
|
|
||||||
|
NymeaSpinBox {
|
||||||
|
id: spinbox
|
||||||
|
value: root.param.value ? root.param.value : 0
|
||||||
|
from: root.stateType.minValue !== undefined
|
||||||
|
? root.stateType.minValue
|
||||||
|
: root.stateType.type.toLowerCase() === "uint"
|
||||||
|
? 0
|
||||||
|
: -2000000000
|
||||||
|
to: root.stateType.maxValue !== undefined
|
||||||
|
? root.stateType.maxValue
|
||||||
|
: 2000000000
|
||||||
|
editable: true
|
||||||
|
width: 150
|
||||||
|
onValueModified: root.param.value = value
|
||||||
|
|
||||||
|
floatingPoint: root.stateType.type.toLowerCase() == "double"
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
print("from:", from, "min", root.stateType.minValue)
|
||||||
|
if (root.value === undefined) {
|
||||||
|
root.value = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: Types.toUiUnit(root.stateType.unit)
|
||||||
|
visible: text.length > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: textFieldComponent
|
||||||
|
TextField {
|
||||||
|
text: root.param.value !== undefined
|
||||||
|
? root.param.value
|
||||||
|
: root.stateType.defaultValue
|
||||||
|
? root.stateType.defaultValue
|
||||||
|
: ""
|
||||||
|
onEditingFinished: {
|
||||||
|
root.param.value = text
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (root.param.value === undefined) {
|
||||||
|
root.param.value = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
placeholderText: root.placeholderText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: comboBoxComponent
|
||||||
|
ComboBox {
|
||||||
|
id: control
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: root.stateType.allowedValues
|
||||||
|
displayText: currentText + ( root.stateType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.stateType.unit) : "")
|
||||||
|
currentIndex: root.stateType.allowedValues.indexOf(root.param.value !== undefined ? root.param.value : root.stateType.defaultValue)
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
width: control.width
|
||||||
|
text: Types.toUiValue(modelData, root.stateType.unit) + ( root.stateType.unit != Types.UnitNone ? " " + Types.toUiUnit(root.stateType.unit) : "")
|
||||||
|
highlighted: control.highlightedIndex === index
|
||||||
|
}
|
||||||
|
onActivated: {
|
||||||
|
root.param.value = root.stateType.allowedValues[index]
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (root.value === undefined) {
|
||||||
|
root.value = model[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: colorPickerComponent
|
||||||
|
ColorPickerPre510 {
|
||||||
|
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: colorTemperaturePickerComponent
|
||||||
|
ColorPickerCt {
|
||||||
|
id: colorPickerCt
|
||||||
|
implicitHeight: 50
|
||||||
|
minCt: root.stateType.minValue
|
||||||
|
maxCt: root.stateType.maxValue
|
||||||
|
ct: root.param.value !== undefined
|
||||||
|
? root.param.value
|
||||||
|
: root.stateType.defaultValue
|
||||||
|
? root.stateType.defaultValue
|
||||||
|
: root.stateType.minValue
|
||||||
|
|
||||||
|
onCtChanged: {
|
||||||
|
root.param.value = ct
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
touchDelegate: Rectangle {
|
||||||
|
height: colorPickerCt.height
|
||||||
|
width: 5
|
||||||
|
color: Style.accentColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: colorPreviewComponent
|
||||||
|
Rectangle {
|
||||||
|
implicitHeight: app.mediumFont
|
||||||
|
implicitWidth: implicitHeight
|
||||||
|
color: root.param.value
|
||||||
|
radius: width / 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -298,6 +298,7 @@ Page {
|
|||||||
Flickable {
|
Flickable {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
contentHeight: contentColumn.implicitHeight + app.margins
|
contentHeight: contentColumn.implicitHeight + app.margins
|
||||||
|
clip: true
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
@ -554,7 +555,7 @@ Page {
|
|||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
font.pixelSize: app.smallFont
|
font.pixelSize: app.smallFont
|
||||||
font.italic: true
|
font.italic: true
|
||||||
text: qsTr("Examples:\n• While I'm at home...\n• When the temperature is below 0...\n• Between 9 am and 6 pm...")
|
text: qsTr("Examples:\n• While I'm at home...\n• While the TV is on...\n• Between 9 am and 6 pm...")
|
||||||
visible: root.isEmpty
|
visible: root.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,7 +751,7 @@ Page {
|
|||||||
minimumJsonRpcVersion: "1.0"
|
minimumJsonRpcVersion: "1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate: NymeaSwipeDelegate {
|
delegate: NymeaItemDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Style.largeDelegateHeight
|
Layout.preferredHeight: Style.largeDelegateHeight
|
||||||
iconName: model.iconName
|
iconName: model.iconName
|
||||||
@ -801,7 +802,7 @@ Page {
|
|||||||
minimumJsonRpcVersion: "1.0"
|
minimumJsonRpcVersion: "1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate: NymeaSwipeDelegate {
|
delegate: NymeaItemDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: Style.largeDelegateHeight
|
Layout.preferredHeight: Style.largeDelegateHeight
|
||||||
iconName: model.iconName
|
iconName: model.iconName
|
||||||
|
|||||||
@ -46,13 +46,16 @@ NymeaSwipeDelegate {
|
|||||||
readonly property Interface iface: eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
readonly property Interface iface: eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
||||||
readonly property EventType eventType: thingClass ? thingClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
readonly property EventType eventType: thingClass ? thingClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
||||||
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||||
|
readonly property StateType stateType: thingClass ? thingClass.stateTypes.getStateType(eventDescriptor.eventTypeId)
|
||||||
|
: iface ? iface.stateTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||||
|
readonly property var actualEventType: eventType || stateType
|
||||||
|
|
||||||
signal removeEventDescriptor()
|
signal removeEventDescriptor()
|
||||||
|
|
||||||
onDeleteClicked: root.removeEventDescriptor()
|
onDeleteClicked: root.removeEventDescriptor()
|
||||||
|
|
||||||
iconName: root.thing ? "../images/event.svg" : "../images/event-interface.svg"
|
iconName: root.thing ? "../images/event.svg" : "../images/event-interface.svg"
|
||||||
text: qsTr("%1 - %2").arg(root.thing ? root.thing.name : root.iface.displayName).arg(root.eventType.displayName)
|
text: "%1 - %2".arg(root.thing ? root.thing.name : root.iface.displayName).arg(root.actualEventType.displayName)
|
||||||
subText: {
|
subText: {
|
||||||
var ret = qsTr("anytime");
|
var ret = qsTr("anytime");
|
||||||
for (var i = 0; i < root.eventDescriptor.paramDescriptors.count; i++) {
|
for (var i = 0; i < root.eventDescriptor.paramDescriptors.count; i++) {
|
||||||
@ -81,9 +84,10 @@ NymeaSwipeDelegate {
|
|||||||
operatorString = " ? ";
|
operatorString = " ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
var paramType = paramDescriptor.paramName
|
print("**", root.eventType, root.stateType, paramDescriptor.paramName, paramDescriptor.paramTypeId)
|
||||||
? root.eventType.paramTypes.findByName(paramDescriptor.paramName)
|
var paramType = root.eventType ?
|
||||||
: root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId)
|
(paramDescriptor.paramName ? root.eventType.paramTypes.findByName(paramDescriptor.paramName) : root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId) )
|
||||||
|
: root.stateType
|
||||||
|
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
// TRANSLATORS: example: "only if temperature > 5"
|
// TRANSLATORS: example: "only if temperature > 5"
|
||||||
|
|||||||
@ -378,13 +378,29 @@ Page {
|
|||||||
function createEventDescriptor(rule, ruleTemplate, thing, eventDescriptorTemplate) {
|
function createEventDescriptor(rule, ruleTemplate, thing, eventDescriptorTemplate) {
|
||||||
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
|
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
|
||||||
eventDescriptor.thingId = thing.id;
|
eventDescriptor.thingId = thing.id;
|
||||||
eventDescriptor.eventTypeId = thing.thingClass.eventTypes.findByName(eventDescriptorTemplate.eventName).id
|
var eventType = thing.thingClass.eventTypes.findByName(eventDescriptorTemplate.eventName)
|
||||||
|
var stateType = thing.thingClass.stateTypes.findByName(eventDescriptorTemplate.eventName)
|
||||||
var needsParams = false;
|
var needsParams = false;
|
||||||
|
print("Creating event descriptor from template:", eventDescriptorTemplate.interfaceName, eventDescriptorTemplate.eventName, thing.name, eventType, stateType)
|
||||||
|
if (eventType) {
|
||||||
|
eventDescriptor.eventTypeId = eventType.id
|
||||||
|
|
||||||
var eventType = thing.thingClass.eventTypes.getEventType(eventDescriptor.eventTypeId);
|
for (var j = 0; j < eventType.paramTypes.count; j++) {
|
||||||
for (var j = 0; j < eventType.paramTypes.count; j++) {
|
var paramType = eventType.paramTypes.get(j);
|
||||||
var paramType = eventType.paramTypes.get(j);
|
var paramDescriptorTemplate = eventDescriptorTemplate.paramDescriptors.getParamDescriptorByName(paramType.name)
|
||||||
var paramDescriptorTemplate = eventDescriptorTemplate.paramDescriptors.getParamDescriptorByName(paramType.name)
|
// has the template a value for this? If so, set it, otherwise flag as needsParams
|
||||||
|
print("template:", paramType.id, eventDescriptorTemplate.paramDescriptors.count)
|
||||||
|
if (paramDescriptorTemplate && paramDescriptorTemplate.value !== undefined) {
|
||||||
|
print("filling in param descriptor:", paramDescriptorTemplate.value)
|
||||||
|
eventDescriptor.paramDescriptors.setParamDescriptorByName(paramDescriptorTemplate.paramName, paramDescriptorTemplate.value, paramDescriptorTemplate.operatorType);
|
||||||
|
} else {
|
||||||
|
needsParams = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (stateType) {
|
||||||
|
eventDescriptor.eventTypeId = stateType.id
|
||||||
|
var paramType = stateType.id
|
||||||
|
var paramDescriptorTemplate = eventDescriptorTemplate.paramDescriptors.getParamDescriptorByName(stateType.name)
|
||||||
// has the template a value for this? If so, set it, otherwise flag as needsParams
|
// has the template a value for this? If so, set it, otherwise flag as needsParams
|
||||||
print("template:", paramType.id, eventDescriptorTemplate.paramDescriptors.count)
|
print("template:", paramType.id, eventDescriptorTemplate.paramDescriptors.count)
|
||||||
if (paramDescriptorTemplate && paramDescriptorTemplate.value !== undefined) {
|
if (paramDescriptorTemplate && paramDescriptorTemplate.value !== undefined) {
|
||||||
|
|||||||
@ -1,157 +1,187 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
* This project including source code and documentation is protected by
|
* This project including source code and documentation is protected by
|
||||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
* reproduction, publication, editing and translation, are reserved. The use of
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
* this project is subject to the terms of a license agreement to be concluded
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
* under https://nymea.io/license
|
* under https://nymea.io/license
|
||||||
*
|
*
|
||||||
* GNU General Public License Usage
|
* GNU General Public License Usage
|
||||||
* Alternatively, this project may be redistributed and/or modified under the
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
* terms of the GNU General Public License as published by the Free Software
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
* Public License for more details.
|
* Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* For any further details and any questions please contact us under
|
* For any further details and any questions please contact us under
|
||||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
* https://nymea.io/license/faq
|
* https://nymea.io/license/faq
|
||||||
*
|
*
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
import QtQuick.Controls 2.1
|
import QtQuick.Controls 2.1
|
||||||
import "../components"
|
import QtQuick.Layouts 1.2
|
||||||
import Nymea 1.0
|
import "../components"
|
||||||
|
import Nymea 1.0
|
||||||
Page {
|
|
||||||
id: root
|
Page {
|
||||||
property alias text: header.text
|
id: root
|
||||||
|
property alias text: header.text
|
||||||
// an eventDescriptor object needs to be set and prefilled with either thingId or interfaceName
|
|
||||||
property var eventDescriptor: null
|
// an eventDescriptor object needs to be set and prefilled with either thingId or interfaceName
|
||||||
|
property var eventDescriptor: null
|
||||||
readonly property Thing thing: eventDescriptor && eventDescriptor.thingId ? engine.thingManager.things.getThing(eventDescriptor.thingId) : null
|
|
||||||
|
readonly property Thing thing: eventDescriptor && eventDescriptor.thingId ? engine.thingManager.things.getThing(eventDescriptor.thingId) : null
|
||||||
signal backPressed();
|
|
||||||
signal done();
|
signal backPressed();
|
||||||
|
signal done();
|
||||||
onEventDescriptorChanged: buildInterface()
|
|
||||||
Component.onCompleted: buildInterface()
|
onEventDescriptorChanged: buildInterface()
|
||||||
|
Component.onCompleted: buildInterface()
|
||||||
header: NymeaHeader {
|
|
||||||
id: header
|
header: NymeaHeader {
|
||||||
onBackPressed: root.backPressed();
|
id: header
|
||||||
|
onBackPressed: root.backPressed();
|
||||||
property bool interfacesMode: root.eventDescriptor.interfaceName !== ""
|
|
||||||
onInterfacesModeChanged: root.buildInterface()
|
property bool interfacesMode: root.eventDescriptor.interfaceName !== ""
|
||||||
|
onInterfacesModeChanged: root.buildInterface()
|
||||||
HeaderButton {
|
|
||||||
imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
// HeaderButton {
|
||||||
visible: root.eventDescriptor.interfaceName === ""
|
// imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
||||||
onClicked: header.interfacesMode = !header.interfacesMode
|
// visible: root.eventDescriptor.interfaceName === ""
|
||||||
}
|
// onClicked: header.interfacesMode = !header.interfacesMode
|
||||||
}
|
// }
|
||||||
|
}
|
||||||
ListModel {
|
|
||||||
id: generatedModel
|
ListModel {
|
||||||
ListElement { displayName: ""; eventTypeId: "" }
|
id: generatedModel
|
||||||
}
|
ListElement { displayName: ""; eventTypeId: "" }
|
||||||
|
}
|
||||||
function buildInterface() {
|
|
||||||
if (header.interfacesMode) {
|
function buildInterface() {
|
||||||
if (root.thing) {
|
if (header.interfacesMode) {
|
||||||
generatedModel.clear();
|
if (root.thing) {
|
||||||
for (var i = 0; i < Interfaces.count; i++) {
|
generatedModel.clear();
|
||||||
var iface = Interfaces.get(i);
|
for (var i = 0; i < Interfaces.count; i++) {
|
||||||
if (root.thing.thingClass.interfaces.indexOf(iface.name) >= 0) {
|
var iface = Interfaces.get(i);
|
||||||
for (var j = 0; j < iface.eventTypes.count; j++) {
|
if (root.thing.thingClass.interfaces.indexOf(iface.name) >= 0) {
|
||||||
var ifaceEt = iface.eventTypes.get(j);
|
for (var j = 0; j < iface.eventTypes.count; j++) {
|
||||||
var dcEt = root.thing.thingClass.eventTypes.findByName(ifaceEt.name)
|
var ifaceEt = iface.eventTypes.get(j);
|
||||||
generatedModel.append({displayName: ifaceEt.displayName, eventTypeId: dcEt.id})
|
var dcEt = root.thing.thingClass.eventTypes.findByName(ifaceEt.name)
|
||||||
}
|
if (!dcEt) {
|
||||||
}
|
dcEt = root.thing.thingClass.stateTypes.findByName(ifaceEt.name)
|
||||||
}
|
}
|
||||||
listView.model = generatedModel
|
|
||||||
} else if (root.eventDescriptor.interfaceName !== "") {
|
generatedModel.append({displayName: ifaceEt.displayName, eventTypeId: dcEt.id})
|
||||||
listView.model = Interfaces.findByName(root.eventDescriptor.interfaceName).eventTypes
|
}
|
||||||
} else {
|
}
|
||||||
console.warn("You need to set thing or interfaceName");
|
}
|
||||||
}
|
listView.model = generatedModel
|
||||||
} else {
|
} else if (root.eventDescriptor.interfaceName !== "") {
|
||||||
if (root.thing) {
|
listView.model = Interfaces.findByName(root.eventDescriptor.interfaceName).eventTypes
|
||||||
listView.model = root.thing.thingClass.eventTypes;
|
} else {
|
||||||
}
|
console.warn("You need to set thing or interfaceName");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
if (root.thing) {
|
||||||
ListView {
|
generatedModel.clear();
|
||||||
id: listView
|
for (var i = 0; i < root.thing.thingClass.stateTypes.count; i++) {
|
||||||
anchors.fill: parent
|
var stateType = root.thing.thingClass.stateTypes.get(i)
|
||||||
|
generatedModel.append({displayName: stateType.displayName, id: stateType.id.toString(), type: "state"})
|
||||||
delegate: ItemDelegate {
|
}
|
||||||
width: parent.width
|
for (var i = 0; i < root.thing.thingClass.eventTypes.count; i++) {
|
||||||
text: model.displayName
|
var eventType = root.thing.thingClass.eventTypes.get(i)
|
||||||
onClicked: {
|
generatedModel.append({displayName: eventType.displayName, id: eventType.id.toString(), type: "event"})
|
||||||
if (header.interfacesMode) {
|
}
|
||||||
if (root.thing) {
|
|
||||||
root.eventDescriptor.eventTypeId = model.eventTypeId;
|
listView.model = generatedModel;
|
||||||
var eventType = root.thing.thingClass.eventTypes.getEventType(model.eventTypeId)
|
}
|
||||||
if (eventType.paramTypes.count > 0) {
|
}
|
||||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
}
|
||||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
|
||||||
paramsPage.onCompleted.connect(function() {
|
ListView {
|
||||||
pageStack.pop();
|
id: listView
|
||||||
root.done();
|
anchors.fill: parent
|
||||||
})
|
clip: true
|
||||||
} else {
|
|
||||||
root.done();
|
section.property: "type"
|
||||||
}
|
section.delegate: ListSectionHeader {
|
||||||
} else if (root.eventDescriptor.interfaceName !== "") {
|
text: section === "state" ? qsTr("State change") : qsTr("Event")
|
||||||
root.eventDescriptor.interfaceEvent = model.name;
|
}
|
||||||
if (listView.model.get(index).paramTypes.count > 0) {
|
|
||||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
delegate: ItemDelegate {
|
||||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
width: parent.width
|
||||||
paramsPage.onCompleted.connect(function() {
|
text: model.displayName
|
||||||
pageStack.pop();
|
onClicked: {
|
||||||
root.done();
|
if (header.interfacesMode) {
|
||||||
})
|
if (root.thing) {
|
||||||
} else {
|
root.eventDescriptor.eventTypeId = model.eventTypeId;
|
||||||
root.done();
|
var eventType = root.thing.thingClass.eventTypes.getEventType(model.eventTypeId)
|
||||||
}
|
if (eventType.paramTypes.count > 0) {
|
||||||
} else {
|
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
||||||
console.warn("Neither thingId not interfaceName set. Cannot continue...");
|
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||||
}
|
paramsPage.onCompleted.connect(function() {
|
||||||
} else {
|
pageStack.pop();
|
||||||
if (root.thing) {
|
root.done();
|
||||||
var eventType = root.thing.thingClass.eventTypes.getEventType(model.id);
|
})
|
||||||
root.eventDescriptor.eventTypeId = model.id;
|
} else {
|
||||||
if (eventType.paramTypes.count > 0) {
|
root.done();
|
||||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
}
|
||||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
} else if (root.eventDescriptor.interfaceName !== "") {
|
||||||
paramsPage.onCompleted.connect(function() {
|
root.eventDescriptor.interfaceEvent = model.name;
|
||||||
pageStack.pop();
|
if (listView.model.get(index).paramTypes.count > 0) {
|
||||||
root.done();
|
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
||||||
})
|
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||||
} else {
|
paramsPage.onCompleted.connect(function() {
|
||||||
root.done();
|
pageStack.pop();
|
||||||
}
|
root.done();
|
||||||
|
})
|
||||||
print("have type", eventType.id)
|
} else {
|
||||||
} else {
|
root.done();
|
||||||
console.warn("FIXME: not implemented yet");
|
}
|
||||||
}
|
} else {
|
||||||
}
|
console.warn("Neither thingId not interfaceName set. Cannot continue...");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (root.thing) {
|
||||||
}
|
root.eventDescriptor.eventTypeId = model.id;
|
||||||
|
|
||||||
|
if (model.type === "state") {
|
||||||
|
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
||||||
|
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||||
|
paramsPage.onCompleted.connect(function() {
|
||||||
|
pageStack.pop();
|
||||||
|
root.done();
|
||||||
|
})
|
||||||
|
|
||||||
|
} else if (model.type === "event") {
|
||||||
|
var eventType = root.thing.thingClass.eventTypes.getEventType(model.id);
|
||||||
|
if (eventType.paramTypes.count > 0) {
|
||||||
|
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
||||||
|
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||||
|
paramsPage.onCompleted.connect(function() {
|
||||||
|
pageStack.pop();
|
||||||
|
root.done();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
root.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn("FIXME: not implemented yet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -42,7 +42,9 @@ Page {
|
|||||||
|
|
||||||
readonly property Thing thing: eventDescriptor && eventDescriptor.thingId ? engine.thingManager.things.getThing(eventDescriptor.thingId) : null
|
readonly property Thing thing: eventDescriptor && eventDescriptor.thingId ? engine.thingManager.things.getThing(eventDescriptor.thingId) : null
|
||||||
readonly property var iface: eventDescriptor && eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
readonly property var iface: eventDescriptor && eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
||||||
readonly property var eventType: thing ? thing.thingClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
readonly property EventType eventType: thing ? thing.thingClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
||||||
|
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||||
|
readonly property StateType stateType: thing ? thing.thingClass.stateTypes.getStateType(eventDescriptor.eventTypeId)
|
||||||
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||||
|
|
||||||
signal backPressed();
|
signal backPressed();
|
||||||
@ -57,16 +59,17 @@ Page {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Repeater {
|
Repeater {
|
||||||
id: delegateRepeater
|
id: delegateRepeater
|
||||||
model: root.eventType.paramTypes
|
model: root.eventType ? root.eventType.paramTypes : 1
|
||||||
delegate: ColumnLayout {
|
delegate: ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
property alias paramType: paramDescriptorDelegate.paramType
|
property alias paramType: paramDescriptorDelegate.paramType
|
||||||
|
property alias stateType: paramDescriptorDelegate.stateType
|
||||||
property alias value: paramDescriptorDelegate.value
|
property alias value: paramDescriptorDelegate.value
|
||||||
property alias considerParam: paramCheckBox.checked
|
property alias considerParam: paramCheckBox.checked
|
||||||
property alias operatorType: paramDescriptorDelegate.operatorType
|
property alias operatorType: paramDescriptorDelegate.operatorType
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: paramCheckBox
|
id: paramCheckBox
|
||||||
text: qsTr("Only consider event if")
|
text: root.eventType ? qsTr("Only consider event if") : qsTr("Only consider state change if")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: app.margins
|
Layout.leftMargin: app.margins
|
||||||
Layout.rightMargin: app.margins
|
Layout.rightMargin: app.margins
|
||||||
@ -76,8 +79,9 @@ Page {
|
|||||||
id: paramDescriptorDelegate
|
id: paramDescriptorDelegate
|
||||||
enabled: paramCheckBox.checked
|
enabled: paramCheckBox.checked
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
paramType: root.eventType.paramTypes.get(index)
|
paramType: root.eventType ? root.eventType.paramTypes.get(index) : null
|
||||||
value: paramType.defaultValue
|
stateType: root.stateType
|
||||||
|
value: paramType ? paramType.defaultValue : stateType.defaultValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,10 +99,13 @@ Page {
|
|||||||
var paramDelegate = delegateRepeater.itemAt(i);
|
var paramDelegate = delegateRepeater.itemAt(i);
|
||||||
if (paramDelegate.considerParam) {
|
if (paramDelegate.considerParam) {
|
||||||
if (root.thing) {
|
if (root.thing) {
|
||||||
root.eventDescriptor.paramDescriptors.setParamDescriptor(paramDelegate.paramType.id, paramDelegate.value, paramDelegate.operatorType)
|
var paramTypeId = paramDelegate.paramType ? paramDelegate.paramType.id : paramDelegate.stateType.id
|
||||||
|
print("setting param descriptor by id:", paramTypeId, paramDelegate.value)
|
||||||
|
root.eventDescriptor.paramDescriptors.setParamDescriptor(paramTypeId, paramDelegate.value, paramDelegate.operatorType)
|
||||||
} else if (root.iface) {
|
} else if (root.iface) {
|
||||||
print("setting param descriptors by name", root.eventType.paramTypes.get(i), root.eventType.paramTypes.get(i).name)
|
var name = root.eventType ? root.eventType.paramTypes.get(i).name : root.stateType.name
|
||||||
root.eventDescriptor.paramDescriptors.setParamDescriptorByName(root.eventType.paramTypes.get(i).name, paramDelegate.value, paramDelegate.operatorType)
|
print("setting param descriptors by name", name, paramDelegate.value)
|
||||||
|
root.eventDescriptor.paramDescriptors.setParamDescriptorByName(name, paramDelegate.value, paramDelegate.operatorType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,15 +117,14 @@ Page {
|
|||||||
|
|
||||||
ThinDivider { Layout.columnSpan: parent.columns }
|
ThinDivider { Layout.columnSpan: parent.columns }
|
||||||
|
|
||||||
ParamDelegate {
|
StateDelegate {
|
||||||
id: staticValueParamDelegate
|
id: staticValueParamDelegate
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
hoverEnabled: false
|
hoverEnabled: false
|
||||||
padding: 0
|
padding: 0
|
||||||
paramType: root.thing.thingClass.eventTypes.getEventType(root.stateType.id).paramTypes.getParamType(root.stateType.id)
|
stateType: root.stateType
|
||||||
enabled: staticValueRadioButton.checked
|
enabled: staticValueRadioButton.checked
|
||||||
nameVisible: false
|
nameVisible: false
|
||||||
value: root.stateType.defaultValue
|
|
||||||
visible: staticValueRadioButton.checked
|
visible: staticValueRadioButton.checked
|
||||||
placeholderText: qsTr("Insert value here")
|
placeholderText: qsTr("Insert value here")
|
||||||
}
|
}
|
||||||
|
|||||||
101
nymea-app/ui/magic/SelectStateEventDescriptorParamPage.qml
Normal file
101
nymea-app/ui/magic/SelectStateEventDescriptorParamPage.qml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2022, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
import QtQuick 2.8
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import "../components"
|
||||||
|
import "../delegates"
|
||||||
|
import Nymea 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: root
|
||||||
|
// Needs to be set and filled in with thingId and eventTypeId
|
||||||
|
property var eventDescriptor: null
|
||||||
|
|
||||||
|
readonly property Thing thing: eventDescriptor && eventDescriptor.thingId ? engine.thingManager.things.getThing(eventDescriptor.thingId) : null
|
||||||
|
readonly property var iface: eventDescriptor && eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
||||||
|
readonly property var stateType: thing ? thing.thingClass.stateTypes.getStateType(eventDescriptor.eventTypeId)
|
||||||
|
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||||
|
|
||||||
|
signal backPressed();
|
||||||
|
signal completed();
|
||||||
|
|
||||||
|
header: NymeaHeader {
|
||||||
|
text: "Options"
|
||||||
|
onBackPressed: root.backPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property alias paramType: paramDescriptorDelegate.paramType
|
||||||
|
property alias value: paramDescriptorDelegate.value
|
||||||
|
property alias considerParam: paramCheckBox.checked
|
||||||
|
property alias operatorType: paramDescriptorDelegate.operatorType
|
||||||
|
CheckBox {
|
||||||
|
id: paramCheckBox
|
||||||
|
text: qsTr("Only consider state change if")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins
|
||||||
|
Layout.rightMargin: app.margins
|
||||||
|
}
|
||||||
|
|
||||||
|
ParamDescriptorDelegate {
|
||||||
|
id: paramDescriptorDelegate
|
||||||
|
enabled: paramCheckBox.checked
|
||||||
|
Layout.fillWidth: true
|
||||||
|
stateType: root.stateType
|
||||||
|
value: stateType.defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "OK"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: app.margins
|
||||||
|
onClicked: {
|
||||||
|
root.eventDescriptor.paramDescriptors.clear();
|
||||||
|
if (paramDelegate.considerParam) {
|
||||||
|
if (root.thing) {
|
||||||
|
root.eventDescriptor.paramDescriptors.setParamDescriptor(root.stateType.id, paramDescriptorDelegate.value, paramDescriptorDelegate.operatorType)
|
||||||
|
} else if (root.iface) {
|
||||||
|
root.eventDescriptor.paramDescriptors.setParamDescriptorByName(root.stateType.name, paramDescriptorDelegate.value, paramDescriptorDelegate.operatorType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -119,7 +119,7 @@ Page {
|
|||||||
print("new checked state;", newCache[thingId])
|
print("new checked state;", newCache[thingId])
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: NymeaSwipeDelegate {
|
delegate: NymeaItemDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.selectInterface ? model.displayName : model.name
|
text: root.selectInterface ? model.displayName : model.name
|
||||||
iconName: root.selectInterface ? app.interfaceToIcon(model.name) : app.interfacesToIcon(model.interfaces)
|
iconName: root.selectInterface ? app.interfaceToIcon(model.name) : app.interfacesToIcon(model.interfaces)
|
||||||
|
|||||||
Reference in New Issue
Block a user