From 256149c5dee39e70f3941ff6fd4bbb3fd08c0ca1 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 25 May 2018 11:48:21 +0200 Subject: [PATCH] add a styleController to have better control over styles --- mea/main.cpp | 15 +- mea/mea.pro | 6 +- mea/stylecontroller.cpp | 38 +++++ mea/stylecontroller.h | 25 +++ mea/ui/BluetoothDiscoveryPage.qml | 3 +- mea/ui/ConnectPage.qml | 244 ++++++++++++++++-------------- mea/ui/SettingsPage.qml | 50 ++++-- mea/ui/main.qml | 13 +- 8 files changed, 256 insertions(+), 138 deletions(-) create mode 100644 mea/stylecontroller.cpp create mode 100644 mea/stylecontroller.h diff --git a/mea/main.cpp b/mea/main.cpp index ad6bc048..f99dad3a 100644 --- a/mea/main.cpp +++ b/mea/main.cpp @@ -53,6 +53,7 @@ #include "models/eventdescriptorparamsfiltermodel.h" #include "basicconfiguration.h" #include "wifisetup/networkmanagercontroler.h" +#include "stylecontroller.h" static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEngine) { @@ -166,15 +167,17 @@ int main(int argc, char *argv[]) Engine::instance(); - QQmlApplicationEngine engine; + QQmlApplicationEngine *engine = new QQmlApplicationEngine(); #ifdef BRANDING - engine.rootContext()->setContextProperty("appBranding", BRANDING); - QQuickStyle::setStyle(QString(":/styles/%1").arg(BRANDING)); + engine->rootContext()->setContextProperty("appBranding", BRANDING); #else - QSettings settings; - QQuickStyle::setStyle(":/styles/" + settings.value("style", "light").toString()); + engine->rootContext()->setContextProperty("appBranding", ""); #endif - engine.load(QUrl(QLatin1String("qrc:/ui/main.qml"))); + + StyleController styleController; + engine->rootContext()->setContextProperty("styleController", &styleController); + + engine->load(QUrl(QLatin1String("qrc:/ui/main.qml"))); return application.exec(); } diff --git a/mea/mea.pro b/mea/mea.pro index 98cdac20..585b941e 100644 --- a/mea/mea.pro +++ b/mea/mea.pro @@ -45,7 +45,8 @@ HEADERS += engine.h \ wifisetup/wirelessaccesspoint.h \ wifisetup/wirelessaccesspoints.h \ wifisetup/wirelesssetupmanager.h \ - wifisetup/networkmanagercontroler.h + wifisetup/networkmanagercontroler.h \ + stylecontroller.h SOURCES += main.cpp \ @@ -87,7 +88,8 @@ SOURCES += main.cpp \ wifisetup/wirelessaccesspoint.cpp \ wifisetup/wirelessaccesspoints.cpp \ wifisetup/wirelesssetupmanager.cpp \ - wifisetup/networkmanagercontroler.cpp + wifisetup/networkmanagercontroler.cpp \ + stylecontroller.cpp withavahi { DEFINES += WITH_AVAHI diff --git a/mea/stylecontroller.cpp b/mea/stylecontroller.cpp new file mode 100644 index 00000000..ff765fd9 --- /dev/null +++ b/mea/stylecontroller.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +#include "stylecontroller.h" + +StyleController::StyleController(QObject *parent) : QObject(parent) +{ +#ifdef BRANDING + QQuickStyle::setStyle(QString(":/styles/%1").arg(BRANDING)); +#else + QQuickStyle::setStyle(QString(":/styles/%1").arg(currentStyle())); +#endif +} + +QString StyleController::currentStyle() const +{ +#ifdef BRANDING + return BRANDING; +#endif + QSettings settings; + return settings.value("style", "light").toString(); +} + +void StyleController::setCurrentStyle(const QString ¤tStyle) +{ + QSettings settings; + if (settings.value("style").toString() != currentStyle) { + settings.setValue("style", currentStyle); + emit currentStyleChanged(); + } +} + +QStringList StyleController::allStyles() const +{ + QDir dir(":/styles/"); + return dir.entryList(QDir::Dirs); +} diff --git a/mea/stylecontroller.h b/mea/stylecontroller.h new file mode 100644 index 00000000..4c34ae36 --- /dev/null +++ b/mea/stylecontroller.h @@ -0,0 +1,25 @@ +#ifndef STYLECONTROLLER_H +#define STYLECONTROLLER_H + +#include + +class StyleController : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString currentStyle READ currentStyle WRITE setCurrentStyle NOTIFY currentStyleChanged) + Q_PROPERTY(QStringList allStyles READ allStyles CONSTANT) + +public: + explicit StyleController(QObject *parent = nullptr); + + QString currentStyle() const; + void setCurrentStyle(const QString ¤tStyle); + + QStringList allStyles() const; + +signals: + void currentStyleChanged(); + +}; + +#endif // STYLECONTROLLER_H diff --git a/mea/ui/BluetoothDiscoveryPage.qml b/mea/ui/BluetoothDiscoveryPage.qml index 3b13e4e5..7d484d10 100644 --- a/mea/ui/BluetoothDiscoveryPage.qml +++ b/mea/ui/BluetoothDiscoveryPage.qml @@ -1,7 +1,6 @@ import QtQuick 2.4 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.2 - import "components" import Mea 1.0 @@ -22,6 +21,7 @@ Page { ColumnLayout { anchors.fill: parent + spacing: app.margins BusyIndicator { Layout.alignment: Qt.AlignHCenter @@ -77,5 +77,4 @@ Page { } } } - } diff --git a/mea/ui/ConnectPage.qml b/mea/ui/ConnectPage.qml index 7ff1e5ef..e83a8743 100644 --- a/mea/ui/ConnectPage.qml +++ b/mea/ui/ConnectPage.qml @@ -10,40 +10,13 @@ Page { readonly property bool haveHosts: discovery.discoveryModel.count > 0 - header: GuhHeader { - text: qsTr("Connect nymea") - backButtonVisible: false - menuButtonVisible: true - onMenuPressed: connectionMenu.open() - } - - Menu { - id: connectionMenu - width: implicitWidth + app.margins - - IconMenuItem { - iconSource: "../images/network-vpn.svg" - text: qsTr("Manual connect") - onTriggered: pageStack.push(manualConnectPage) - } - - MenuSeparator {} - - IconMenuItem { - iconSource: "../images/bluetooth.svg" - text: qsTr("Wireless setup") - onTriggered: pageStack.push(Qt.resolvedUrl("BluetoothDiscoveryPage.qml")) - } - - - - } - Component.onCompleted: { print("completed connectPage. last connected host:", settings.lastConnectedHost) if (settings.lastConnectedHost.length > 0) { pageStack.push(connectingPage) Engine.connection.connect(settings.lastConnectedHost) + } else { + pageStack.push(discoveryPage) } } @@ -57,130 +30,170 @@ Page { } onConnectionError: { pageStack.pop(root) + pageStack.push(discoveryPage) } } - ColumnLayout { - anchors.fill: parent - anchors.topMargin: app.bigMargins - spacing: app.margins + Component { + id: discoveryPage - ColumnLayout { - Layout.fillWidth: true - Layout.margins: app.margins - spacing: app.margins - - Label { - Layout.fillWidth: true - text: root.haveHosts ? qsTr("Oh, look!") : qsTr("Uh oh") - //color: "black" - font.pixelSize: app.largeFont + Page { + header: GuhHeader { + text: qsTr("Connect nymea") + backButtonVisible: false + menuButtonVisible: true + onMenuPressed: connectionMenu.open() } - Label { - Layout.fillWidth: true - text: root.haveHosts ? - qsTr("There are %1 nymea boxes in your network! Which one would you like to use?").arg(discovery.discoveryModel.count) - : qsTr("There doesn't seem to be a nymea box installed in your network. Please make sure your nymea box is correctly set up and connected.") - wrapMode: Text.WordWrap + Timer { + id: startupTimer + interval: 5000 + repeat: false + running: true } - } - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 1 - color: Material.accent - } + Menu { + id: connectionMenu + width: implicitWidth + app.margins - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - model: discovery.discoveryModel - clip: true - - delegate: ItemDelegate { - width: parent.width - height: app.delegateHeight - ColumnLayout { - anchors.fill: parent - anchors.margins: app.margins - Label { - text: model.name - } - Label { - text: model.hostAddress - font.pixelSize: app.smallFont - } + IconMenuItem { + iconSource: "../images/network-vpn.svg" + text: qsTr("Manual connect") + onTriggered: pageStack.push(manualConnectPage) } - onClicked: { - print("Should connect to", model.nymeaRpcUrl) - Engine.connection.connect(model.nymeaRpcUrl) - pageStack.push(connectingPage) + + MenuSeparator {} + + IconMenuItem { + iconSource: "../images/bluetooth.svg" + text: qsTr("Wireless setup") + onTriggered: pageStack.push(Qt.resolvedUrl("BluetoothDiscoveryPage.qml")) } } - Column { - anchors.centerIn: parent + ColumnLayout { + anchors.fill: parent spacing: app.margins - visible: !root.haveHosts - Label { - text: qsTr("Searching for nymea boxes...") + ColumnLayout { + Layout.fillWidth: true + Layout.margins: app.margins + spacing: app.margins + + Label { + Layout.fillWidth: true + text: root.haveHosts ? qsTr("Oh, look!") : startupTimer.running ? qsTr("Just a moment...") : qsTr("Uh oh") + //color: "black" + font.pixelSize: app.largeFont + } + + Label { + Layout.fillWidth: true + text: root.haveHosts ? + qsTr("There are %1 nymea boxes in your network! Which one would you like to use?").arg(discovery.discoveryModel.count) + : startupTimer.running ? qsTr("We haven't found any nymea boxes in your network yet.") + : qsTr("There doesn't seem to be a nymea box installed in your network. Please make sure your nymea box is correctly set up and connected.") + wrapMode: Text.WordWrap + } } - BusyIndicator { - running: visible - anchors.horizontalCenter: parent.horizontalCenter + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 1 + color: Material.accent + } + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + model: discovery.discoveryModel + clip: true + + delegate: ItemDelegate { + width: parent.width + height: app.delegateHeight + ColumnLayout { + anchors.fill: parent + anchors.margins: app.margins + Label { + text: model.name + } + Label { + text: model.hostAddress + font.pixelSize: app.smallFont + } + } + onClicked: { + print("Should connect to", model.nymeaRpcUrl) + Engine.connection.connect(model.nymeaRpcUrl) + pageStack.push(connectingPage) + } + } + + Column { + anchors.centerIn: parent + spacing: app.margins + visible: !root.haveHosts + + Label { + text: qsTr("Searching for nymea boxes...") + } + + BusyIndicator { + running: visible + anchors.horizontalCenter: parent.horizontalCenter + } + } + + } + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 1 + color: Material.accent + } + + RowLayout { + Layout.fillWidth: true + Layout.margins: app.margins + visible: root.haveHosts + Label { + Layout.fillWidth: true + text: qsTr("Not the ones you're looking for? We're looking for more!") + wrapMode: Text.WordWrap + } + + BusyIndicator { } } } - - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 1 - color: Material.accent - } - - RowLayout { - Layout.fillWidth: true - Layout.margins: app.margins - visible: root.haveHosts - Label { - Layout.fillWidth: true - text: qsTr("Not the ones you're looking for? We're looking for more!") - wrapMode: Text.WordWrap - } - - BusyIndicator { } } } + Component { id: manualConnectPage Page { - header: GuhHeader { - text: qsTr("Manual connect to nymea") + text: qsTr("Manual connection") onBackPressed: pageStack.pop() } ColumnLayout { - anchors.fill: parent + anchors { left: parent.left; top: parent.top; right: parent.right } anchors.margins: app.margins spacing: app.margins GridLayout { - Layout.fillHeight: true - Layout.fillWidth: true - columns: 2 + Label { + text: qsTr("Protocol") + } + ComboBox { id: connectionTypeComboBox Layout.fillWidth: true - Layout.columnSpan: 2 model: [ qsTr("TCP"), qsTr("Websocket") ] } @@ -264,7 +277,7 @@ Page { spacing: app.margins Label { - text: qsTr("Connecting to your nymea box...") + text: qsTr("Trying to connect...") wrapMode: Text.WordWrap font.pixelSize: app.largeFont Layout.fillWidth: true @@ -275,7 +288,8 @@ Page { Layout.fillWidth: true onClicked: { Engine.connection.disconnect() - pageStack.pop(); + pageStack.pop(root); + pageStack.push(discoveryPage); } } } diff --git a/mea/ui/SettingsPage.qml b/mea/ui/SettingsPage.qml index 5290cac6..463c587a 100644 --- a/mea/ui/SettingsPage.qml +++ b/mea/ui/SettingsPage.qml @@ -68,20 +68,19 @@ Page { text: "Style" } ComboBox { - model: ["light", "dark", "maveo"] - currentIndex: { - switch (settings.style) { - case "light": - return 0; - case "dark": - return 1; - case "maveo": - return 2; - } - } + model: styleController.allStyles + currentIndex: styleController.allStyles.indexOf(styleController.currentStyle) onActivated: { - settings.style = model[index] + styleController.currentStyle = model[index] + } + } + + Connections { + target: styleController + onCurrentStyleChanged: { + var popup = styleChangedDialog.createObject(root) + popup.open() } } } @@ -167,6 +166,7 @@ Page { Button { id: debugServerButton Layout.fillWidth: true + Layout.margins: app.margins visible: debugServerEnabledSwitch.checked text: qsTr("Open debug interface") onClicked: Qt.openUrlExternally("http://" + Engine.connection.hostAddress + "/debug") @@ -192,4 +192,30 @@ Page { } } } + + Component { + id: styleChangedDialog + Dialog { + width: Math.min(parent.width * .8, contentLabel.implicitWidth) + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + modal: true + + title: qsTr("Style changed") + + standardButtons: Dialog.Ok + + ColumnLayout { + id: content + anchors { left: parent.left; top: parent.top; right: parent.right } + + Label { + id: contentLabel + Layout.fillWidth: true + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + text: qsTr("The application needs to be restarted for style changes to take effect.") + } + } + } + } } diff --git a/mea/ui/main.qml b/mea/ui/main.qml index 2972c499..88e81454 100644 --- a/mea/ui/main.qml +++ b/mea/ui/main.qml @@ -12,6 +12,14 @@ ApplicationWindow { height: 580 visibility: settings.viewMode font: Qt.application.font + title: { + switch (appBranding) { + case "maveo": + return qsTr("Maveo Pro Box Dashboard") + default: + return "Mea"; + } + } property int margins: 14 property int bigMargins: 20 @@ -109,7 +117,10 @@ ApplicationWindow { onClosing: { if (Qt.platform.os == "android") { - if (pageStack.depth > 1) { + // If we're connected, allow going back up to MainPage + if ((Engine.jsonRpcClient.connected && pageStack.depth > 1) + // if we're not connected, only allow using the back button in wizards + || (!Engine.jsonRpcClient.connected && pageStack.depth > 3)) { close.accepted = false; pageStack.pop(); }