diff --git a/mea/main.cpp b/mea/main.cpp index f457cd8d..a9fe502e 100644 --- a/mea/main.cpp +++ b/mea/main.cpp @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) applicationFont.setWeight(QFont::Normal); QGuiApplication::setFont(applicationFont); - QTranslator qtTranslator; + QTranslator qtTranslator; qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); application.installTranslator(&qtTranslator); diff --git a/mea/resources.qrc b/mea/resources.qrc index 132b7305..b344b4a6 100644 --- a/mea/resources.qrc +++ b/mea/resources.qrc @@ -67,7 +67,6 @@ ui/images/settings.svg ui/images/stock_link.svg ui/images/share.svg - ui/SystemInfoPage.qml ui/devicepages/SensorDevicePage.qml ui/components/Graph.qml ui/images/sensors.svg @@ -162,5 +161,8 @@ ui/images/network-vpn.svg translations/mea-de_DE.qm translations/mea-en_US.qm + ui/AppSettingsPage.qml + ui/images/stock_application.svg + ui/delegates/ThingDelegate.qml diff --git a/mea/ui/AppSettingsPage.qml b/mea/ui/AppSettingsPage.qml new file mode 100644 index 00000000..a17ee5b9 --- /dev/null +++ b/mea/ui/AppSettingsPage.qml @@ -0,0 +1,140 @@ +import QtQuick 2.5 +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 +import QtQuick.Layouts 1.1 +import Mea 1.0 +import "components" + +Page { + id: root + header: GuhHeader { + text: qsTr("App Settings") + backButtonVisible: true + onBackPressed: pageStack.pop() + } + + ColumnLayout { + anchors { left: parent.left; right: parent.right; top: parent.top } + + ColumnLayout { + Layout.fillWidth: true + Layout.margins: app.margins + + RowLayout { + Layout.fillWidth: true + Label { + Layout.fillWidth: true + text: qsTr("View mode") + } + ComboBox { + model: [qsTr("Windowed"), qsTr("Maximized"), qsTr("Fullscreen")] + currentIndex: { + switch (settings.viewMode) { + case ApplicationWindow.Windowed: + return 0; + case ApplicationWindow.Maximized: + return 1; + case ApplicationWindow.FullScreen: + return 2; + } + } + + onCurrentIndexChanged: { + switch (currentIndex) { + case 0: + settings.viewMode = ApplicationWindow.Windowed; + break; + case 1: + settings.viewMode = ApplicationWindow.Maximized; + break; + case 2: + settings.viewMode = ApplicationWindow.FullScreen; + } + } + } + } + + RowLayout { + Layout.fillWidth: true + visible: appBranding.length === 0 + Label { + Layout.fillWidth: true + text: "Style" + } + ComboBox { + model: styleController.allStyles + currentIndex: styleController.allStyles.indexOf(styleController.currentStyle) + + onActivated: { + styleController.currentStyle = model[index] + } + } + + Connections { + target: styleController + onCurrentStyleChanged: { + var popup = styleChangedDialog.createObject(root) + popup.open() + } + } + } + + RowLayout { + Layout.fillWidth: true + Label { + Layout.fillWidth: true + text: qsTr("Return to home on idle") + } + CheckBox { + checked: settings.returnToHome + onClicked: settings.returnToHome = checked + } + } + RowLayout { + Layout.fillWidth: true + Label { + Layout.fillWidth: true + text: qsTr("Graph style") + } + RadioButton { + checked: settings.graphStyle === "bars" + text: qsTr("Bars") + onClicked: settings.graphStyle = "bars" + } + RadioButton { + checked: settings.graphStyle === "bezier" + text: qsTr("Lines") + onClicked: settings.graphStyle = "bezier" + } + + } + } + } + + + 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/ConnectPage.qml b/mea/ui/ConnectPage.qml index 1cd727cb..3367aaff 100644 --- a/mea/ui/ConnectPage.qml +++ b/mea/ui/ConnectPage.qml @@ -61,17 +61,23 @@ Page { IconMenuItem { objectName: "manualConnectMenuItem" iconSource: "../images/network-vpn.svg" - text: qsTr("Manual connect") + text: qsTr("Manual connection") onTriggered: pageStack.push(manualConnectPage) } - MenuSeparator {} - IconMenuItem { iconSource: "../images/bluetooth.svg" text: qsTr("Wireless setup") onTriggered: pageStack.push(Qt.resolvedUrl("BluetoothDiscoveryPage.qml")) } + + MenuSeparator {} + + IconMenuItem { + iconSource: "../images/stock_application.svg" + text: qsTr("App settings") + onTriggered: pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml")) + } } ColumnLayout { diff --git a/mea/ui/DevicesPage.qml b/mea/ui/DevicesPage.qml index e3412864..97bd2b79 100644 --- a/mea/ui/DevicesPage.qml +++ b/mea/ui/DevicesPage.qml @@ -50,7 +50,7 @@ Item { text: interfaceToString(model.name).toUpperCase() width: parent.width horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap + wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } diff --git a/mea/ui/EditDevicesPage.qml b/mea/ui/EditDevicesPage.qml index d19fa71e..fef87da6 100644 --- a/mea/ui/EditDevicesPage.qml +++ b/mea/ui/EditDevicesPage.qml @@ -2,6 +2,7 @@ import QtQuick 2.4 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.2 import "components" +import "delegates" import Mea 1.0 Page { @@ -14,22 +15,9 @@ Page { ListView { anchors.fill: parent 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 - } - } + delegate: ThingDelegate { + interfaces:model.interfaces + name: model.name onClicked: { pageStack.push(Qt.resolvedUrl("devicepages/ConfigureThingPage.qml"), {device: Engine.deviceManager.devices.get(index)}) } diff --git a/mea/ui/MagicPage.qml b/mea/ui/MagicPage.qml index 7a947b1c..daacbe57 100644 --- a/mea/ui/MagicPage.qml +++ b/mea/ui/MagicPage.qml @@ -7,7 +7,7 @@ import Mea 1.0 Page { id: root header: GuhHeader { - text: "Magic" + text: qsTr("Magic") onBackPressed: pageStack.pop() HeaderButton { diff --git a/mea/ui/MainPage.qml b/mea/ui/MainPage.qml index 38dc9e80..1744679a 100644 --- a/mea/ui/MainPage.qml +++ b/mea/ui/MainPage.qml @@ -4,6 +4,7 @@ import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.2 import Mea 1.0 import "components" +import "delegates" Page { id: root @@ -17,23 +18,23 @@ Page { // FIXME: Currently we don't have any feedback for executeAction // we don't want all the results, e.g. on looped calls like "all off" -// Connections { -// target: Engine.deviceManager -// onExecuteActionReply: { -// var text = params["deviceError"] -// switch(text) { -// case "DeviceErrorNoError": -// return; -// case "DeviceErrorHardwareNotAvailable": -// text = qsTr("Could not execute action. The thing is not available"); -// break; -// } + // Connections { + // target: Engine.deviceManager + // onExecuteActionReply: { + // var text = params["deviceError"] + // switch(text) { + // case "DeviceErrorNoError": + // return; + // case "DeviceErrorHardwareNotAvailable": + // text = qsTr("Could not execute action. The thing is not available"); + // break; + // } -// var errorDialog = Qt.createComponent(Qt.resolvedUrl("components/ErrorDialog.qml")) -// var popup = errorDialog.createObject(root, {text: text}) -// popup.open() -// } -// } + // var errorDialog = Qt.createComponent(Qt.resolvedUrl("components/ErrorDialog.qml")) + // var popup = errorDialog.createObject(root, {text: text}) + // popup.open() + // } + // } Menu { id: mainMenu @@ -57,14 +58,14 @@ Page { MenuSeparator {} IconMenuItem { iconSource: "../images/settings.svg" - text: qsTr("Settings") + text: qsTr("System settings") onTriggered: pageStack.push(Qt.resolvedUrl("SettingsPage.qml")) } MenuSeparator {} IconMenuItem { - iconSource: "../images/info.svg" - text: qsTr("System information") - onTriggered: pageStack.push(Qt.resolvedUrl("SystemInfoPage.qml")) + iconSource: "../images/stock_application.svg" + text: qsTr("App settings") + onTriggered: pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml")) } } @@ -101,28 +102,9 @@ Page { id: devicesProxy devices: Engine.deviceManager.devices } - delegate: ItemDelegate { - width: parent.width - property string mainInterface: app.interfacesToIcon(model.interfaces) - 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 - } - Image { - source: "images/next.svg" - Layout.preferredHeight: parent.height - Layout.preferredWidth: height - } - } + delegate: ThingDelegate { + interfaces: model.interfaces + name: model.name onClicked: { pageStack.push(Qt.resolvedUrl("devicepages/GenericDevicePage.qml"), {device: devicesProxy.get(index)}) } diff --git a/mea/ui/SettingsPage.qml b/mea/ui/SettingsPage.qml index 463c587a..4a928968 100644 --- a/mea/ui/SettingsPage.qml +++ b/mea/ui/SettingsPage.qml @@ -8,7 +8,7 @@ import "components" Page { id: root header: GuhHeader { - text: qsTr("Settings") + text: qsTr("System settings") backButtonVisible: true onBackPressed: pageStack.pop() } @@ -21,114 +21,29 @@ Page { Layout.margins: app.margins Label { - text: qsTr("Application").toUpperCase() - color: app.guhAccent Layout.fillWidth: true - } - - RowLayout { - Layout.fillWidth: true - Label { - Layout.fillWidth: true - text: qsTr("View mode") - } - ComboBox { - model: [qsTr("Windowed"), qsTr("Maximized"), qsTr("Fullscreen")] - currentIndex: { - switch (settings.viewMode) { - case ApplicationWindow.Windowed: - return 0; - case ApplicationWindow.Maximized: - return 1; - case ApplicationWindow.FullScreen: - return 2; - } - } - - onCurrentIndexChanged: { - switch (currentIndex) { - case 0: - settings.viewMode = ApplicationWindow.Windowed; - break; - case 1: - settings.viewMode = ApplicationWindow.Maximized; - break; - case 2: - settings.viewMode = ApplicationWindow.FullScreen; - } - } - } - } - - RowLayout { - Layout.fillWidth: true - visible: appBranding.length === 0 - Label { - Layout.fillWidth: true - text: "Style" - } - ComboBox { - model: styleController.allStyles - currentIndex: styleController.allStyles.indexOf(styleController.currentStyle) - - onActivated: { - styleController.currentStyle = model[index] - } - } - - Connections { - target: styleController - onCurrentStyleChanged: { - var popup = styleChangedDialog.createObject(root) - popup.open() - } - } - } - - RowLayout { - Layout.fillWidth: true - Label { - Layout.fillWidth: true - text: qsTr("Return to home on idle") - } - CheckBox { - checked: settings.returnToHome - onClicked: settings.returnToHome = checked - } + text: qsTr("Connected to:") + color: Material.accent } RowLayout { Layout.fillWidth: true + Label { Layout.fillWidth: true - text: qsTr("Graph style") + text: Engine.connection.url } - RadioButton { - checked: settings.graphStyle === "bars" - text: qsTr("Bars") - onClicked: settings.graphStyle = "bars" + Button { + text: qsTr("Disconnect") + onClicked: { + settings.lastConnectedHost = ""; + Engine.connection.disconnect(); + } } - RadioButton { - checked: settings.graphStyle === "bezier" - text: qsTr("Lines") - onClicked: settings.graphStyle = "bezier" - } - } } - ThinDivider {} - Label { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - Layout.topMargin: app.margins - text: qsTr("System").toUpperCase() - color: app.guhAccent - } - - RowLayout { Layout.fillWidth: true Layout.leftMargin: app.margins @@ -191,6 +106,24 @@ Page { pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml")) } } + + ItemDelegate { + Layout.fillWidth: true + contentItem: RowLayout { + Label { + text: qsTr("Log viewer") + Layout.fillWidth: true + } + Image { + source: "images/next.svg" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height + } + } + + onClicked: pageStack.push(Qt.resolvedUrl("system/LogViewerPage.qml")) + } + } Component { diff --git a/mea/ui/SystemInfoPage.qml b/mea/ui/SystemInfoPage.qml deleted file mode 100644 index 1c8fab13..00000000 --- a/mea/ui/SystemInfoPage.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick 2.8 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.1 -import QtQuick.Layouts 1.3 -import "components" -import Mea 1.0 - -Page { - id: root - header: GuhHeader { - text: qsTr("System information") - backButtonVisible: true - onBackPressed: pageStack.pop() - } - - ColumnLayout { - anchors.fill: parent - - ColumnLayout { - Layout.fillWidth: true - Layout.margins: app.margins - - Label { - Layout.fillWidth: true - text: qsTr("Connected to:") - color: Material.accent - } - RowLayout { - Layout.fillWidth: true - - Label { - Layout.fillWidth: true - text: Engine.connection.url - } - Button { - text: qsTr("Disconnect") - onClicked: { - settings.lastConnectedHost = ""; - Engine.connection.disconnect(); - } - } - } - } - - ThinDivider {} - - ItemDelegate { - Layout.fillWidth: true - contentItem: RowLayout { - Label { - text: qsTr("Log viewer") - Layout.fillWidth: true - } - Image { - source: "images/next.svg" - Layout.preferredHeight: parent.height - Layout.preferredWidth: height - } - } - - onClicked: pageStack.push(Qt.resolvedUrl("system/LogViewerPage.qml")) - } - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - } - - } -} diff --git a/mea/ui/components/Graph.qml b/mea/ui/components/Graph.qml index f0725e17..5a3dd0e7 100644 --- a/mea/ui/components/Graph.qml +++ b/mea/ui/components/Graph.qml @@ -1,6 +1,7 @@ import QtQuick 2.4 import QtQuick.Controls 2.1 import Mea 1.0 +import QtQuick.Controls.Material 2.2 Item { id: root @@ -116,7 +117,7 @@ Item { function paintGrid(ctx) { ctx.strokeStyle = canvas.gridColor; - ctx.fillStyle = "black" + ctx.fillStyle = Material.foreground ctx.lineWidth = 1; ctx.beginPath(); @@ -139,8 +140,8 @@ Item { ctx.beginPath(); var label = maxTemp - (tempInterval * i).toFixed(0) var textSize = ctx.measureText(label) - ctx.strokeStyle = "black" - ctx.fillStyle = "black" + ctx.strokeStyle = Material.foreground + ctx.fillStyle = Material.foreground ctx.lineWidth = 0; ctx.text(label, -textSize.width - app.margins, i * pps + 5) // ctx.stroke(); @@ -149,8 +150,8 @@ Item { } ctx.beginPath(); - ctx.strokeStyle = "black" - ctx.fillStyle = "black" + ctx.strokeStyle = Material.foreground + ctx.fillStyle = Material.foreground ctx.lineWidth = 0; var label = "°C" var textSize = ctx.measureText(label) @@ -165,8 +166,8 @@ Item { // enumate x axis ctx.beginPath(); ctx.globalAlpha = 1; - ctx.strokeStyle = "black" - ctx.fillStyle = "black" + ctx.strokeStyle = Material.foreground + ctx.fillStyle = Material.foreground ctx.lineWidth = 0; // enumerate Y axis diff --git a/mea/ui/components/IconMenuItem.qml b/mea/ui/components/IconMenuItem.qml index 3545b9e0..3c57eb63 100644 --- a/mea/ui/components/IconMenuItem.qml +++ b/mea/ui/components/IconMenuItem.qml @@ -14,9 +14,11 @@ MenuItem { width: height } Label { + id: label text: root.text Layout.fillWidth: true font.pixelSize: app.mediumFont + elide: Text.ElideRight } } } diff --git a/mea/ui/delegates/ThingDelegate.qml b/mea/ui/delegates/ThingDelegate.qml new file mode 100644 index 00000000..608653a9 --- /dev/null +++ b/mea/ui/delegates/ThingDelegate.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.2 +import "../components" + +ItemDelegate { + id: root + width: parent.width + + property var interfaces: [] + property var name: "" + + contentItem: RowLayout { + spacing: app.margins + ColorIcon { + height: app.iconSize + width: height + name: app.interfacesToIcon(root.interfaces) + color: app.guhAccent + } + + Label { + Layout.fillWidth: true + text: root.name + } + Image { + source: "../images/next.svg" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height + } + } +} diff --git a/mea/ui/images/magic.svg b/mea/ui/images/magic.svg index 94043003..b3336bcf 100644 --- a/mea/ui/images/magic.svg +++ b/mea/ui/images/magic.svg @@ -25,9 +25,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="5.6568543" - inkscape:cx="115.91572" - inkscape:cy="46.722217" + inkscape:zoom="22.627417" + inkscape:cx="54.176835" + inkscape:cy="72.222857" inkscape:document-units="px" inkscape:current-layer="g4780" showgrid="false" @@ -139,7 +139,7 @@ image/svg+xml - + @@ -174,24 +174,13 @@ - - + inkscape:connector-curvature="0" + sodipodi:nodetypes="scccccccsssccccccsccccccccccccccc" /> + style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 67.513672 10.917969 C 66.493152 10.917305 65.434004 10.953809 64.369141 10.996094 L 63.826172 12.373047 L 65.064453 14.210938 C 65.438421 14.244894 65.830087 14.264111 66.193359 14.306641 C 69.750679 14.723066 72.787297 15.544697 75.117188 16.794922 C 77.447076 18.045147 79.094458 19.763523 79.673828 21.923828 C 80.253028 24.084403 79.685229 26.394797 78.292969 28.642578 C 76.900689 30.890369 74.681094 33.122225 71.808594 35.261719 C 66.063594 39.540696 57.688946 43.452776 47.978516 46.054688 C 38.262796 48.657997 28.345412 49.532279 20.576172 48.769531 C 16.691562 48.388152 13.343288 47.602974 10.798828 46.375 C 8.2543682 45.147036 6.4596556 43.424899 5.9785156 41.189453 C 5.5911256 39.389645 6.2567856 37.391466 7.3847656 35.351562 C 8.5127356 33.31166 10.146742 31.211204 11.919922 29.259766 C 13.049542 28.016587 14.196023 27.034758 15.345703 25.978516 C 14.198123 26.64999 13.202239 27.096549 11.849609 28.130859 C 8.3114598 30.836369 5.6074594 33.583556 3.9746094 36.195312 C 2.3417594 38.80707 1.78282 41.231781 2.375 43.441406 C 2.96752 45.653121 4.6644394 47.502933 7.3808594 48.960938 C 10.097289 50.418941 13.808222 51.447488 18.226562 51.964844 C 27.063252 52.999564 38.717849 52.005538 51.005859 48.712891 C 63.293889 45.420372 73.884061 40.453139 81.019531 35.138672 C 84.587271 32.481433 87.286616 29.736177 88.910156 27.115234 C 90.533686 24.494281 91.079048 22.043686 90.486328 19.832031 C 89.893818 17.620326 88.196889 15.770503 85.480469 14.3125 C 82.764049 12.854487 79.053106 11.827912 74.634766 11.310547 C 72.425596 11.051864 70.041501 10.919613 67.513672 10.917969 z M 62.724609 11.078125 C 61.674769 11.140476 60.621418 11.20698 59.537109 11.310547 C 56.933931 11.559183 54.230913 11.939605 51.466797 12.429688 L 54.220703 15.048828 L 54.150391 14.304688 C 57.352761 13.998794 60.375476 13.925484 63.158203 14.064453 L 62.142578 12.558594 L 62.724609 11.078125 z " + transform="matrix(0,-1,-1.0003957,0,438.00245,441.36222)" + id="path1945" /> + transform="matrix(0,-0.87442092,-0.87476693,0,429.6294,425.38564)" + inkscape:transform-center-x="0.72060319" + inkscape:transform-center-y="0.38571588" /> diff --git a/mea/ui/images/stock_application.svg b/mea/ui/images/stock_application.svg new file mode 100644 index 00000000..9b311bf6 --- /dev/null +++ b/mea/ui/images/stock_application.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/mea/ui/magic/SelectEventDescriptorParamsPage.qml b/mea/ui/magic/SelectEventDescriptorParamsPage.qml index 3c2aac9e..6f4ac5e8 100644 --- a/mea/ui/magic/SelectEventDescriptorParamsPage.qml +++ b/mea/ui/magic/SelectEventDescriptorParamsPage.qml @@ -2,7 +2,7 @@ import QtQuick 2.8 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.2 import "../components" -import "../paramdescriptordelegates" +import "../delegates" import Mea 1.0 Page { diff --git a/mea/ui/magic/SelectThingPage.qml b/mea/ui/magic/SelectThingPage.qml index f5e0a935..7cfeacac 100644 --- a/mea/ui/magic/SelectThingPage.qml +++ b/mea/ui/magic/SelectThingPage.qml @@ -2,6 +2,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.1 import "../components" +import "../delegates" import Mea 1.0 Page { @@ -20,6 +21,8 @@ Page { RowLayout { Layout.fillWidth: true + // TODO: unfinished, disabled for now + visible: false RadioButton { id: thingButton text: qsTr("A specific thing") @@ -36,9 +39,9 @@ Page { Layout.fillHeight: true model: thingButton.checked ? Engine.deviceManager.devices : Interfaces clip: true - delegate: ItemDelegate { - text: thingButton.checked ? model.name : model.displayName - width: parent.width + delegate: ThingDelegate { + name: thingButton.checked ? model.name : model.displayName + interfaces: model.interfaces onClicked: { if (thingButton.checked) { root.thingSelected(Engine.deviceManager.devices.get(index))