From bfd197a016e8a7aa8abdb022b33172ba1d612313 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 15 Mar 2018 22:50:11 +0100 Subject: [PATCH] some more work on rules and the main view --- mea/basicconfiguration.cpp | 2 +- mea/discovery/zeroconfdiscovery.cpp | 2 +- mea/interfacesmodel.cpp | 21 ++-- mea/interfacesmodel.h | 2 + mea/jsonrpc/jsonrpcclient.cpp | 2 +- mea/resources.qrc | 1 + mea/rulemanager.cpp | 4 +- mea/ui/DevicesPage.qml | 3 +- mea/ui/EditDevicesPage.qml | 2 +- mea/ui/MainPage.qml | 139 +++++++++++++++------ mea/ui/NewDeviceWizard.qml | 3 +- mea/ui/images/select-none.svg | 17 +++ mea/ui/main.qml | 15 +++ mea/ui/paramdelegates-ng/ParamDelegate.qml | 5 +- 14 files changed, 161 insertions(+), 57 deletions(-) create mode 100644 mea/ui/images/select-none.svg diff --git a/mea/basicconfiguration.cpp b/mea/basicconfiguration.cpp index 49aa393e..ccc4da0c 100644 --- a/mea/basicconfiguration.cpp +++ b/mea/basicconfiguration.cpp @@ -40,7 +40,7 @@ void BasicConfiguration::init() void BasicConfiguration::getConfigurationsResponse(const QVariantMap ¶ms) { - qDebug() << "have config reply" << params; +// qDebug() << "have config reply" << params; QVariantMap basicConfig = params.value("params").toMap().value("basicConfiguration").toMap(); m_debugServerEnabled = basicConfig.value("debugServerEnabled").toBool(); m_serverName = basicConfig.value("serverName").toString(); diff --git a/mea/discovery/zeroconfdiscovery.cpp b/mea/discovery/zeroconfdiscovery.cpp index 4bd4eb0b..a6a5b25c 100644 --- a/mea/discovery/zeroconfdiscovery.cpp +++ b/mea/discovery/zeroconfdiscovery.cpp @@ -34,7 +34,7 @@ void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry) if (!entry.name().startsWith("nymea") || entry.serviceType() != "_jsonrpc._tcp") { return; } - qDebug() << "avahi service entry added" << entry.name() << entry.hostAddress() << entry.port() << entry.txt() << entry.serviceType(); +// qDebug() << "avahi service entry added" << entry.name() << entry.hostAddress() << entry.port() << entry.txt() << entry.serviceType(); QString uuid; bool sslEnabled = false; diff --git a/mea/interfacesmodel.cpp b/mea/interfacesmodel.cpp index 93211f43..c58967b2 100644 --- a/mea/interfacesmodel.cpp +++ b/mea/interfacesmodel.cpp @@ -83,23 +83,26 @@ void InterfacesModel::syncInterfaces() } } QStringList interfacesToAdd = interfacesInSource; + QStringList interfacesToRemove; - for (QStringList::iterator i = m_interfaces.begin(); i != m_interfaces.end();) { - if (!interfacesInSource.contains(*i)) { - int idx = m_interfaces.indexOf(*i); - beginRemoveRows(QModelIndex(), idx, idx); - m_interfaces.takeAt(idx); - endRemoveRows(); - continue; + foreach (const QString &interface, m_interfaces) { + if (!interfacesInSource.contains(interface)) { + interfacesToRemove.append(interface); } - interfacesToAdd.removeAll(*i); - ++i; + interfacesToAdd.removeAll(interface); + } + foreach (const QString &interface, interfacesToRemove) { + int idx = m_interfaces.indexOf(interface); + beginRemoveRows(QModelIndex(), idx, idx); + m_interfaces.takeAt(idx); + endRemoveRows(); } if (!interfacesToAdd.isEmpty()) { beginInsertRows(QModelIndex(), m_interfaces.count(), m_interfaces.count() + interfacesToAdd.count() - 1); m_interfaces.append(interfacesToAdd); endInsertRows(); } + emit countChanged(); } void InterfacesModel::rowsChanged(const QModelIndex &index, int first, int last) diff --git a/mea/interfacesmodel.h b/mea/interfacesmodel.h index 1ef34535..b216816d 100644 --- a/mea/interfacesmodel.h +++ b/mea/interfacesmodel.h @@ -9,6 +9,7 @@ class InterfacesModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(Devices* devices READ devices WRITE setDevices NOTIFY devicesChanged) Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged) @@ -31,6 +32,7 @@ public: void setShownInterfaces(const QStringList &shownInterfaces); signals: + void countChanged(); void devicesChanged(); void shownInterfacesChanged(); diff --git a/mea/jsonrpc/jsonrpcclient.cpp b/mea/jsonrpc/jsonrpcclient.cpp index 95237477..39849eed 100644 --- a/mea/jsonrpc/jsonrpcclient.cpp +++ b/mea/jsonrpc/jsonrpcclient.cpp @@ -158,7 +158,7 @@ void JsonRpcClient::sendRequest(const QVariantMap &request) { QVariantMap newRequest = request; newRequest.insert("token", m_token); - qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); +// qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); m_connection->sendData(QJsonDocument::fromVariant(newRequest).toJson()); } diff --git a/mea/resources.qrc b/mea/resources.qrc index ea513aa6..a032b7b2 100644 --- a/mea/resources.qrc +++ b/mea/resources.qrc @@ -140,5 +140,6 @@ ui/magic/SimpleStateEvaluatorDelegate.qml ui/magic/SelectStateDescriptorParamsPage.qml ui/magic/SelectStateDescriptorPage.qml + ui/images/select-none.svg diff --git a/mea/rulemanager.cpp b/mea/rulemanager.cpp index 208a7ffa..99f51980 100644 --- a/mea/rulemanager.cpp +++ b/mea/rulemanager.cpp @@ -112,7 +112,7 @@ void RuleManager::getRulesReply(const QVariantMap ¶ms) qWarning() << "Error getting rules:" << params.value("error").toString(); return; } - qDebug() << "Get Rules reply" << params; +// qDebug() << "Get Rules reply" << params; foreach (const QVariant &ruleDescriptionVariant, params.value("params").toMap().value("ruleDescriptions").toList()) { QUuid ruleId = ruleDescriptionVariant.toMap().value("id").toUuid(); QString name = ruleDescriptionVariant.toMap().value("name").toString(); @@ -139,7 +139,7 @@ void RuleManager::getRuleDetailsReply(const QVariantMap ¶ms) qDebug() << "Got rule details for a rule we don't know"; return; } - qDebug() << "got rule details for rule" << ruleMap; +// qDebug() << "got rule details for rule" << ruleMap; parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule); parseRuleActions(ruleMap.value("actions").toList(), rule); parseRuleExitActions(ruleMap.value("exitActions").toList(), rule); diff --git a/mea/ui/DevicesPage.qml b/mea/ui/DevicesPage.qml index aa11ac6a..846d034e 100644 --- a/mea/ui/DevicesPage.qml +++ b/mea/ui/DevicesPage.qml @@ -8,13 +8,12 @@ GridView { id: interfacesGridView property alias shownInterfaces: interfacesModel.shownInterfaces + property int tilesPerRow: Math.ceil(Math.sqrt(interfacesGridView.count)) model: InterfacesModel { id: interfacesModel devices: Engine.deviceManager.devices } - - property int tilesPerRow: Math.ceil(Math.sqrt(interfacesGridView.count)) cellWidth: width / tilesPerRow cellHeight: height / tilesPerRow delegate: Item { diff --git a/mea/ui/EditDevicesPage.qml b/mea/ui/EditDevicesPage.qml index 66f4e696..71bb0ffd 100644 --- a/mea/ui/EditDevicesPage.qml +++ b/mea/ui/EditDevicesPage.qml @@ -21,7 +21,7 @@ Page { ColorIcon { height: app.iconSize width: height - name: app.interfaceToIcon(model.interfaces[0]) + name: app.interfacesToIcon(model.interfaces) color: app.guhAccent } diff --git a/mea/ui/MainPage.qml b/mea/ui/MainPage.qml index 23b8a101..ae1a1624 100644 --- a/mea/ui/MainPage.qml +++ b/mea/ui/MainPage.qml @@ -48,6 +48,107 @@ Page { } } + InterfacesModel { + id: page1Model + devices: Engine.deviceManager.devices + shownInterfaces: ["light", "weather", "sensor", "media", "garagegate"] + property var view: null + onCountChanged: buildView() + } + InterfacesModel { + id: page2Model + devices: Engine.deviceManager.devices + shownInterfaces: ["gateway", "button", "notifications"] + property var view: null + onCountChanged: buildView() + } + + Component { + id: devicePageComponent + DevicesPage { + width: swipeView.width + height: swipeView.height + visible: count > 0 + shownInterfaces: ["light", "weather", "sensor", "media", "garagegate"] + } + } + + Component { + id: allDevicesComponent + ListView { + width: swipeView.width + height: swipeView.height + model: Engine.deviceManager.devices + delegate: ItemDelegate { + width: parent.width + contentItem: RowLayout { + spacing: app.margins + ColorIcon { + height: app.iconSize + width: height + name: app.interfacesToIcon(model.interfaces) + color: app.guhAccent + } + + Label { + Layout.fillWidth: true + text: model.name + } + } + onClicked: { + pageStack.push(Qt.resolvedUrl("devicepages/GenericDevicePage.qml"), {device: Engine.deviceManager.devices.get(index)}) + } + } + + ColumnLayout { + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins } + spacing: app.margins + visible: Engine.deviceManager.devices.count === 0 + Label { + text: "Welcome to nymea!" + font.pixelSize: app.largeFont + Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + color: app.guhAccent + } + Label { + text: "There are no things set up yet. You can start with adding your things by using the menu on the upper left and selecting \"Add a new thing\"." + Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + } + } + } + } + + function buildView() { + var shownViews = [] + if (page1Model.count > 0) { + shownViews.push(0) + } + if (page2Model.count > 0) { + shownViews.push(1) + } + shownViews.push(2) + + if (swipeView.count === shownViews.length) { + return; + } + + while (swipeView.count > 0) { + swipeView.removeItem(0) + } + if (shownViews.indexOf(0) >= 0) { + swipeView.addItem(devicePageComponent.createObject(swipeView, {model: page1Model})) + } + if (shownViews.indexOf(1) >= 0) { + swipeView.addItem(devicePageComponent.createObject(swipeView, {model: page2Model})) + } + swipeView.addItem(allDevicesComponent.createObject(swipeView)) + } + + ColumnLayout { anchors.fill: parent @@ -57,44 +158,6 @@ Page { Layout.fillHeight: true currentIndex: pageIndicator.currentIndex clip: true - - DevicesPage { - width: parent.view.width - height: parent.view.height - shownInterfaces: ["light", "weather", "sensor", "media", "garagegate"] - } - - DevicesPage { - width: parent.view.width - height: parent.view.height - shownInterfaces: ["gateway", "button", "notifications"] - } - - ListView { - width: parent.view.width - height: parent.view.height - model: Engine.deviceManager.devices - delegate: ItemDelegate { - width: parent.width - contentItem: RowLayout { - spacing: app.margins - ColorIcon { - height: app.iconSize - width: height - name: app.interfaceToIcon(model.interfaces[0]) - color: app.guhAccent - } - - Label { - Layout.fillWidth: true - text: model.name - } - } - onClicked: { - pageStack.push(Qt.resolvedUrl("devicepages/GenericDevicePage.qml"), {device: Engine.deviceManager.devices.get(index)}) - } - } - } } PageIndicator { diff --git a/mea/ui/NewDeviceWizard.qml b/mea/ui/NewDeviceWizard.qml index 55b756d2..bb5cacab 100644 --- a/mea/ui/NewDeviceWizard.qml +++ b/mea/ui/NewDeviceWizard.qml @@ -3,7 +3,7 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 import Mea 1.0 import "components" -import "paramdelegates" +import "paramdelegates-ng" Page { id: root @@ -334,6 +334,7 @@ Page { var param = {} param.paramTypeId = paramRepeater.itemAt(i).paramType.id param.value = paramRepeater.itemAt(i).value + print("adding param", param.paramTypeId, param.value) params.push(param) } diff --git a/mea/ui/images/select-none.svg b/mea/ui/images/select-none.svg new file mode 100644 index 00000000..49b983c7 --- /dev/null +++ b/mea/ui/images/select-none.svg @@ -0,0 +1,17 @@ + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/mea/ui/main.qml b/mea/ui/main.qml index e628fce3..abf9a689 100644 --- a/mea/ui/main.qml +++ b/mea/ui/main.qml @@ -129,6 +129,16 @@ ApplicationWindow { } } + function interfacesToIcon(interfaces) { + for (var i = 0; i < interfaces.length; i++) { + var icon = interfaceToIcon(interfaces[i]); + if (icon !== "") { + return icon; + } + } + return Qt.resolvedUrl("images/select-none.svg") + } + function interfaceToIcon(name) { switch (name) { case "light": @@ -136,6 +146,8 @@ ApplicationWindow { case "dimmablelight": return Qt.resolvedUrl("images/torch-on.svg") case "sensor": + case "temperaturesensor": + case "humiditysensor": return Qt.resolvedUrl("images/sensors.svg") case "media": case "mediacontroller": @@ -155,7 +167,10 @@ ApplicationWindow { return Qt.resolvedUrl("images/network-wired-symbolic.svg") case "notifications": return Qt.resolvedUrl("images/notification.svg") + case "connectable": + return Qt.resolvedUrl("images/stock_link.svg") } + return ""; } function interfaceToColor(name) { diff --git a/mea/ui/paramdelegates-ng/ParamDelegate.qml b/mea/ui/paramdelegates-ng/ParamDelegate.qml index f93f69ae..6474b478 100644 --- a/mea/ui/paramdelegates-ng/ParamDelegate.qml +++ b/mea/ui/paramdelegates-ng/ParamDelegate.qml @@ -36,7 +36,10 @@ ItemDelegate { case "bool": return boolComponent; case "int": - return stringComponent; + if (root.paramType.minimumValue !== undefined && root.paramType.maximumValue !== undefined) { + return sliderComponent; + } + return textFieldComponent; case "string": case "qstring": if (root.paramType.allowedValues.length > 0) {