From a7cfbd0ee09ad6e1aade1cc2b201026b3ee725be Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 6 Aug 2020 16:17:22 +0200 Subject: [PATCH] Fixes in garage door and barcode scanner related UIs --- nymea-app/ui/Nymea.qml | 14 +-- .../devicepages/BarcodeScannerThingPage.qml | 22 +++- .../ui/mainviews/DevicesPageDelegate.qml | 105 +++++++++++++++--- .../thingconfiguration/ConfigureThingPage.qml | 50 ++++++--- 4 files changed, 150 insertions(+), 41 deletions(-) diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 9b5227e3..2b2918bb 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -108,25 +108,25 @@ ApplicationWindow { property var supportedInterfaces: [ "light", - "weather", "media", - "garagedoor", "awning", "shutter", "blind", + "garagedoor", "powersocket", "heating", + "smartlock", "doorbell", - "sensor", "irrigation", "ventilation", - "smartmeter", + "sensor", + "weather", "evcharger", + "smartmeter", "fingerprintreader", - "smartlock", - "button", - "barcodescanner", "notifications", + "barcodescanner", + "button", "inputtrigger", "outputtrigger", "gateway", diff --git a/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml b/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml index 9a53c42f..87c31d5d 100644 --- a/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml +++ b/nymea-app/ui/devicepages/BarcodeScannerThingPage.qml @@ -38,6 +38,17 @@ import "../customviews" DevicePageBase { id: root + EmptyViewPlaceholder { + anchors { left: parent.left; right: parent.right; margins: app.margins } + anchors.verticalCenter: parent.verticalCenter + + title: qsTr("No codes have been scanned yet.") + text: qsTr("Scan a code to see it appearing here.") + visible: logView.logsModel.count === 0 + buttonVisible: false + imageSource: "../images/qrcode.svg" + } + Connections { target: logsModelNg onCountChanged: { @@ -49,7 +60,7 @@ DevicePageBase { ColumnLayout { anchors.fill: parent spacing: app.margins - + visible: logView.logsModel.count > 0 Label { Layout.fillWidth: true @@ -58,11 +69,17 @@ DevicePageBase { text: qsTr("Last scan") } + FontMetrics { + id: fontMetrics + font.pixelSize: app.largeFont + } + Label { id: codeLabel Layout.fillWidth: true - font.pixelSize: app.largeFont * 2 + font.pixelSize: fontMetrics.boundingRect(text).width < root.width ? app.largeFont * 2 : app.mediumFont horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WrapAtWordBoundaryOrAnywhere } Label { @@ -105,6 +122,7 @@ DevicePageBase { var rulePage = pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device}); rulePage.addRule(rule); } + } } diff --git a/nymea-app/ui/mainviews/DevicesPageDelegate.qml b/nymea-app/ui/mainviews/DevicesPageDelegate.qml index 82356c93..1b6cdd36 100644 --- a/nymea-app/ui/mainviews/DevicesPageDelegate.qml +++ b/nymea-app/ui/mainviews/DevicesPageDelegate.qml @@ -143,6 +143,10 @@ MainPageTile { // return labelComponent; case "light": + case "garagedoor": + case "impulsegaragedoor": + case "statefulgaragedoor": + case "extendedstatefulgaragedoor": case "garagegate": case "blind": case "extendedblind": @@ -255,17 +259,23 @@ MainPageTile { } } return count === 0 ? qsTr("All off") : qsTr("%1 on").arg(count) - case "garagegate": + case "garagedoor": + var statefulCount = 0; var count = 0; for (var i = 0; i < devicesProxy.count; i++) { - var device = devicesProxy.get(i); - var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId); - var stateType = deviceClass.stateTypes.findByName("state"); - if (device.states.getState(stateType.id).value !== "closed") { - count++; + var thing = devicesProxy.get(i); + if (thing.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 || thing.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 || thing.thingClass.interfaces.indexOf("garagegate") >= 0) { + statefulCount++; + var stateType = thing.thingClass.stateTypes.findByName("state"); + if (stateType && device.states.getState(stateType.id).value !== "closed") { + count++; + } } } - return count === 0 ? qsTr("All closed") : qsTr("%1 open").arg(count) + if (statefulCount > 0) { + return count === 0 ? qsTr("All closed") : qsTr("%1 open").arg(count) + } + return ""; case "blind": case "extendedblind": case "awning": @@ -302,7 +312,15 @@ MainPageTile { case "irrigation": case "ventilation": return "" - case "garagegate": + case "garagedoor": + var dev = devicesProxy.get(0) + if (dev.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("garagegate") >= 0) { + return "../images/up.svg" + } + return "" case "blind": case "extendedblind": case "awning": @@ -324,7 +342,19 @@ MainPageTile { case "irrigation": case "ventilation": break; - case "garagegate": + case "garagedoor": + for (var i = 0; i < devicesProxy.count; i++) { + var thing = devicesProxy.get(i); + if (thing.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("garagegate") >= 0) { + + var actionType = thing.thingClass.actionTypes.findByName("open"); + engine.deviceManager.executeAction(thing.id, actionType.id) + } + } + break; case "shutter": case "extendedshutter": case "blind": @@ -362,7 +392,15 @@ MainPageTile { case "irrigation": case "ventilation": return "" - case "garagegate": + case "garagedoor": + var dev = devicesProxy.get(0) + if (dev.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("garagegate") >= 0) { + return "../images/media-playback-stop.svg" + } + return "" case "blind": case "awning": case "shutter": @@ -384,7 +422,19 @@ MainPageTile { case "irrigation": case "ventilation": break; - case "garagegate": + case "garagedoor": + for (var i = 0; i < devicesProxy.count; i++) { + var thing = devicesProxy.get(i); + if (thing.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("garagegate") >= 0) { + + var actionType = thing.thingClass.actionTypes.findByName("stop"); + engine.thingManager.executeAction(thing.id, actionType.id) + } + } + break; case "shutter": case "extendedshutter": case "blind": @@ -398,7 +448,7 @@ MainPageTile { var actionType = deviceClass.actionTypes.findByName("stop"); engine.deviceManager.executeAction(device.id, actionType.id) } - + break; default: console.warn("DevicesPageDelegate, inlineButtonControl clicked: Unhandled interface", iface.name) } @@ -430,7 +480,18 @@ MainPageTile { case "irrigation": case "ventilation": return "../images/system-shutdown.svg" - case "garagegate": + case "garagedoor": + var dev = devicesProxy.get(0) + if (dev.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || dev.thingClass.interfaces.indexOf("garagegate") >= 0) { + return "../images/down.svg" + } + if (dev.thingClass.interfaces.indexOf("impulsegaragedoor") >= 0) { + return "../images/closable-move.svg" + } + return "" case "blind": case "extendedblind": case "awning": @@ -492,7 +553,23 @@ MainPageTile { print("executing", device, device.id, actionTypeId, actionName, deviceClass.actionTypes) engine.deviceManager.executeAction(device.id, actionTypeId) - case "garagegate": + case "garagedoor": + for (var i = 0; i < devicesProxy.count; i++) { + var thing = devicesProxy.get(i); + if (thing.thingClass.interfaces.indexOf("simplegaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("statefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("extendedstatefulgaragedoor") >= 0 + || thing.thingClass.interfaces.indexOf("garagegate") >= 0) { + + var actionType = thing.thingClass.actionTypes.findByName("close"); + engine.deviceManager.executeAction(thing.id, actionType.id) + } + if (thing.thingClass.interfaces.indexOf("impulsegaragedoor") >= 0) { + var actionType = thing.thingClass.actionTypes.findByName("triggerImpulse"); + engine.deviceManager.executeAction(thing.id, actionType.id) + } + } + break; case "shutter": case "extendedshutter": case "blind": diff --git a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml index 72d38f11..323bbc84 100644 --- a/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml +++ b/nymea-app/ui/thingconfiguration/ConfigureThingPage.qml @@ -330,15 +330,15 @@ SettingsPageBase { text: qsTr("Connect \"%1\" to:").arg(ioConnectionDialog.ioStateType.displayName) wrapMode: Text.WordWrap } - Label { text: "\n" } // Fake in some spacing +// Label { text: "\n" } // Fake in some spacing GridLayout { columns: (ioConnectionDialog.width / 400) * 2 - Label { - Layout.fillWidth: true - text: qsTr("Thing") - } +// Label { +// Layout.fillWidth: true +// text: qsTr("Thing") +// } ComboBox { id: ioThingComboBox @@ -369,10 +369,10 @@ SettingsPageBase { } } - Label { - Layout.fillWidth: true - text: (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) ? qsTr("Output") : qsTr("Input") - } +// Label { +// Layout.fillWidth: true +// text: (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput || ioConnectionDialog.ioStateType.ioType == Types.IOTypeAnalogInput) ? qsTr("Output") : qsTr("Input") +// } ComboBox { id: ioStateComboBox @@ -405,29 +405,41 @@ SettingsPageBase { } } - Label { - text: qsTr("Inverted") - Layout.fillWidth: true + RowLayout { + + Label { + text: qsTr("Inverted") + Layout.fillWidth: true + } + + CheckBox { + id: invertCheckBox + checked: ioConnectionDialog.isInput ? ioConnectionDialog.inputWatcher.ioConnection.inverted : ioConnectionDialog.outputWatcher.ioConnection.inverted + } + } } - CheckBox { - id: invertCheckBox - checked: ioConnectionDialog.isInput ? ioConnectionDialog.inputWatcher.ioConnection.inverted : ioConnectionDialog.outputWatcher.ioConnection.inverted - } - } - RowLayout { + GridLayout { + id: buttonGrid + columns: width > (cancelButton.implicitWidth + disconnectButton.implicitWidth + connectButton.implicitWidth) + ? 4 : 1 + layoutDirection: columns == 1 ? Qt.RightToLeft : Qt.LeftToRight Item { Layout.fillWidth: true } Button { + id: cancelButton text: qsTr("Cancel") + Layout.fillWidth: buttonGrid.columns === 1 onClicked: ioConnectionDialog.reject(); } Button { + id: disconnectButton text: qsTr("Disconnect") enabled: ioConnectionDialog.isInput ? ioConnectionDialog.inputWatcher.ioConnection != null : ioConnectionDialog.outputWatcher.ioConnection != null + Layout.fillWidth: buttonGrid.columns === 1 onClicked: { if (ioConnectionDialog.ioStateType.ioType == Types.IOTypeDigitalInput @@ -441,8 +453,10 @@ SettingsPageBase { } } Button { + id: connectButton text: qsTr("Connect") enabled: ioThingComboBox.currentIndex >= 0 && ioStateComboBox.currentIndex >= 0 + Layout.fillWidth: buttonGrid.columns === 1 onClicked: { var inputThingId;