summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/CMakeLists.txt50
-rw-r--r--app/DashboardGaugeStyle.qml175
-rw-r--r--app/IconGaugeStyle.qml135
-rw-r--r--app/TachometerStyle.qml127
-rw-r--r--app/TurnIndicator.qml111
-rw-r--r--app/ValueSource.qml385
-rw-r--r--app/cluster-gauges.qml364
-rw-r--r--app/cluster-gauges.qrc10
-rw-r--r--app/images/Utility_Logo_Grey-01.svg84
-rw-r--r--app/images/agl_title_793x211.pngbin0 -> 55357 bytes
-rw-r--r--app/images/fuel-icon.pngbin0 -> 409 bytes
-rw-r--r--app/images/images.qrc8
-rw-r--r--app/images/temperature-icon.pngbin0 -> 3302 bytes
-rw-r--r--app/main.cpp91
14 files changed, 1540 insertions, 0 deletions
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
new file mode 100644
index 0000000..07c60c4
--- /dev/null
+++ b/app/CMakeLists.txt
@@ -0,0 +1,50 @@
+###########################################################################
+# Copyright 2018 Konsulko Group
+#
+# Author: Scott Murray <scott.murray@konsulko.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+###########################################################################
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_CXX_STANDARD 14)
+
+find_package(Qt5 COMPONENTS Core Gui QuickControls2 WebSockets QuickWidgets REQUIRED)
+find_package(PkgConfig REQUIRED)
+
+qt5_add_resources(RESOURCES cluster-gauges.qrc images/images.qrc)
+
+PROJECT_TARGET_ADD(cluster-gauges)
+
+add_executable(${TARGET_NAME}
+ main.cpp
+ ${RESOURCES}
+)
+
+pkg_check_modules(QLIBWINMGR REQUIRED qlibwindowmanager)
+
+set_target_properties(${TARGET_NAME} PROPERTIES
+ LABELS "EXECUTABLE"
+ PREFIX ""
+ COMPILE_FLAGS "${QLIBWINMGR_FLAGS} ${EXTRAS_CFLAGS} -DFOR_AFB_BINDING"
+ LINK_FLAGS "${BINDINGS_LINK_FLAG}"
+ LINK_LIBRARIES "${EXTRAS_LIBRARIES}"
+ OUTPUT_NAME "${TARGET_NAME}"
+)
+
+target_link_libraries(${TARGET_NAME}
+ Qt5::QuickControls2
+ Qt5::QuickWidgets
+ ${QLIBWINMGR_LIBRARIES}
+)
diff --git a/app/DashboardGaugeStyle.qml b/app/DashboardGaugeStyle.qml
new file mode 100644
index 0000000..d765a70
--- /dev/null
+++ b/app/DashboardGaugeStyle.qml
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.4
+
+CircularGaugeStyle {
+ tickmarkInset: toPixels(0.04)
+ minorTickmarkInset: tickmarkInset
+ labelStepSize: 20
+ labelInset: toPixels(0.23)
+
+ property real xCenter: outerRadius
+ property real yCenter: outerRadius
+ property real needleLength: outerRadius - tickmarkInset * 1.25
+ property real needleTipWidth: toPixels(0.02)
+ property real needleBaseWidth: toPixels(0.06)
+ property bool halfGauge: false
+
+ function toPixels(percentage) {
+ return percentage * outerRadius;
+ }
+
+ function degToRad(degrees) {
+ return degrees * (Math.PI / 180);
+ }
+
+ function radToDeg(radians) {
+ return radians * (180 / Math.PI);
+ }
+
+ function paintBackground(ctx) {
+ if (halfGauge) {
+ ctx.beginPath();
+ ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height / 2);
+ ctx.clip();
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = "black";
+ ctx.ellipse(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset;
+ ctx.strokeStyle = "black";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset / 2;
+ ctx.strokeStyle = "#222";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ var gradient = ctx.createRadialGradient(xCenter, yCenter, 0, xCenter, yCenter, outerRadius * 1.5);
+ gradient.addColorStop(0, Qt.rgba(1, 1, 1, 0));
+ gradient.addColorStop(0.7, Qt.rgba(1, 1, 1, 0.13));
+ gradient.addColorStop(1, Qt.rgba(1, 1, 1, 1));
+ ctx.fillStyle = gradient;
+ ctx.arc(xCenter, yCenter, outerRadius - tickmarkInset, outerRadius - tickmarkInset, 0, Math.PI * 2);
+ ctx.fill();
+ }
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ paintBackground(ctx);
+ }
+
+ Text {
+ id: speedText
+ font.pixelSize: toPixels(0.3)
+ text: kphInt
+ color: "white"
+ horizontalAlignment: Text.AlignRight
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.verticalCenter
+ anchors.topMargin: toPixels(0.1)
+
+ readonly property int kphInt: control.value
+ }
+ Text {
+ text: "km/h"
+ color: "white"
+ font.pixelSize: toPixels(0.09)
+ anchors.top: speedText.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ needle: Canvas {
+ implicitWidth: needleBaseWidth
+ implicitHeight: needleLength
+
+ property real xCenter: width / 2
+ property real yCenter: height / 2
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height);
+ ctx.lineTo(xCenter - needleBaseWidth / 2, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter - needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, yCenter - needleLength);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.rgba(0.66, 0, 0, 0.66);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height)
+ ctx.lineTo(width, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter + needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.lighter(Qt.rgba(0.66, 0, 0, 0.66));
+ ctx.fill();
+ }
+ }
+
+ foreground: null
+}
diff --git a/app/IconGaugeStyle.qml b/app/IconGaugeStyle.qml
new file mode 100644
index 0000000..6247076
--- /dev/null
+++ b/app/IconGaugeStyle.qml
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Extras 1.4
+
+DashboardGaugeStyle {
+ id: fuelGaugeStyle
+ minimumValueAngle: -60
+ maximumValueAngle: 60
+ tickmarkStepSize: 1
+ labelStepSize: 1
+ labelInset: toPixels(-0.25)
+ minorTickmarkCount: 3
+
+ needleLength: toPixels(0.85)
+ needleBaseWidth: toPixels(0.08)
+ needleTipWidth: toPixels(0.03)
+
+ halfGauge: true
+
+ property string icon: ""
+ property color minWarningColor: "transparent"
+ property color maxWarningColor: "transparent"
+ readonly property real minWarningStartAngle: minimumValueAngle - 90
+ readonly property real maxWarningStartAngle: maximumValueAngle - 90
+
+ tickmark: Rectangle {
+ implicitWidth: toPixels(0.06)
+ antialiasing: true
+ implicitHeight: toPixels(0.2)
+ color: "#c8c8c8"
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: toPixels(0.03)
+ antialiasing: true
+ implicitHeight: toPixels(0.15)
+ color: "#c8c8c8"
+ }
+
+ background: Item {
+ Canvas {
+ anchors.fill: parent
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintBackground(ctx);
+
+ if (minWarningColor != "transparent") {
+ ctx.beginPath();
+ ctx.lineWidth = fuelGaugeStyle.toPixels(0.08);
+ ctx.strokeStyle = minWarningColor;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(minWarningStartAngle),
+ degToRad(minWarningStartAngle + angleRange / (minorTickmarkCount + 1)), false);
+ ctx.stroke();
+ }
+ if (maxWarningColor != "transparent") {
+ ctx.beginPath();
+ ctx.lineWidth = fuelGaugeStyle.toPixels(0.08);
+ ctx.strokeStyle = maxWarningColor;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(maxWarningStartAngle - angleRange / (minorTickmarkCount + 1)),
+ degToRad(maxWarningStartAngle), false);
+ ctx.stroke();
+ }
+ }
+ }
+
+ Image {
+ source: icon
+ anchors.bottom: parent.verticalCenter
+ anchors.bottomMargin: toPixels(0.3)
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: toPixels(0.3)
+ height: width
+ fillMode: Image.PreserveAspectFit
+ }
+ }
+}
diff --git a/app/TachometerStyle.qml b/app/TachometerStyle.qml
new file mode 100644
index 0000000..a632eab
--- /dev/null
+++ b/app/TachometerStyle.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Extras 1.4
+
+DashboardGaugeStyle {
+ id: tachometerStyle
+ tickmarkStepSize: 1
+ labelStepSize: 1
+ needleLength: toPixels(0.85)
+ needleBaseWidth: toPixels(0.08)
+ needleTipWidth: toPixels(0.03)
+
+ tickmark: Rectangle {
+ implicitWidth: toPixels(0.03)
+ antialiasing: true
+ implicitHeight: toPixels(0.08)
+ color: styleData.index === 7 || styleData.index === 8 ? Qt.rgba(0.5, 0, 0, 1) : "#c8c8c8"
+ }
+
+ minorTickmark: null
+
+ tickmarkLabel: Text {
+ font.pixelSize: Math.max(6, toPixels(0.12))
+ text: styleData.value
+ color: styleData.index === 7 || styleData.index === 8 ? Qt.rgba(0.5, 0, 0, 1) : "#c8c8c8"
+ antialiasing: true
+ }
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ paintBackground(ctx);
+
+ ctx.beginPath();
+ ctx.lineWidth = tachometerStyle.toPixels(0.08);
+ ctx.strokeStyle = Qt.rgba(0.5, 0, 0, 1);
+ var warningCircumference = maximumValueAngle - minimumValueAngle * 0.1;
+ var startAngle = maximumValueAngle - 90;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(startAngle - angleRange / 8 + angleRange * 0.015),
+ degToRad(startAngle - angleRange * 0.015), false);
+ ctx.stroke();
+ }
+
+ Text {
+ id: rpmText
+ font.pixelSize: tachometerStyle.toPixels(0.3)
+ text: rpmInt
+ color: "white"
+ horizontalAlignment: Text.AlignRight
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.verticalCenter
+ anchors.topMargin: 20
+
+ readonly property int rpmInt: valueSource.rpm
+ }
+ Text {
+ text: "x1000"
+ color: "white"
+ font.pixelSize: tachometerStyle.toPixels(0.1)
+ anchors.top: parent.top
+ anchors.topMargin: parent.height / 4
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ Text {
+ text: "RPM"
+ color: "white"
+ font.pixelSize: tachometerStyle.toPixels(0.1)
+ anchors.top: rpmText.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+}
diff --git a/app/TurnIndicator.qml b/app/TurnIndicator.qml
new file mode 100644
index 0000000..3bc4c0e
--- /dev/null
+++ b/app/TurnIndicator.qml
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.2
+
+Item {
+ // This enum is actually keyboard-related, but it serves its purpose
+ // as an indication of direction for us.
+ property int direction: Qt.LeftArrow
+ property bool on: false
+
+ property bool flashing: false
+
+ scale: direction === Qt.LeftArrow ? 1 : -1
+ Timer {
+ id: flashTimer
+ interval: 500
+ running: on
+ repeat: true
+ onTriggered: flashing = !flashing
+ }
+ function paintOutlinePath(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(0, height * 0.5);
+ ctx.lineTo(0.6 * width, 0);
+ ctx.lineTo(0.6 * width, height * 0.28);
+ ctx.lineTo(width, height * 0.28);
+ ctx.lineTo(width, height * 0.72);
+ ctx.lineTo(0.6 * width, height * 0.72);
+ ctx.lineTo(0.6 * width, height);
+ ctx.lineTo(0, height * 0.5);
+ }
+ Canvas {
+ id: backgroundCanvas
+ anchors.fill: parent
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintOutlinePath(ctx);
+
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = "lightgrey";
+ ctx.stroke();
+ }
+ }
+ Canvas {
+ id: foregroundCanvas
+ anchors.fill: parent
+ visible: on && flashing
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintOutlinePath(ctx);
+
+ ctx.fillStyle = "green";
+ ctx.fill();
+ }
+ }
+}
diff --git a/app/ValueSource.qml b/app/ValueSource.qml
new file mode 100644
index 0000000..41d0f96
--- /dev/null
+++ b/app/ValueSource.qml
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Konsulko Group
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+Item {
+ id: valueSource
+ property real kph: 0
+ property real rpm: 1
+ property real fuel: 0.85
+ property string gear: {
+ var g;
+ if (kph < 30) {
+ return "1";
+ }
+ if (kph < 50) {
+ return "2";
+ }
+ if (kph < 80) {
+ return "3";
+ }
+ if (kph < 120) {
+ return "4";
+ }
+ if (kph < 160) {
+ return "5";
+ }
+ }
+ property string prindle: {
+ var g;
+ if (kph > 0) {
+ return "D";
+ }
+ return "P";
+ }
+ property int turnSignal: prindle == "P" && !start ? randomDirection() : -1
+ property real temperature: 0.6
+ property bool start: true
+
+ function randomDirection() {
+ return Math.random() > 0.5 ? Qt.LeftArrow : Qt.RightArrow;
+ }
+
+ SequentialAnimation {
+ running: true
+ loops: 1
+
+ // We want a small pause at the beginning, but we only want it to happen once.
+ PauseAnimation {
+ duration: 1000
+ }
+
+ PropertyAction {
+ target: valueSource
+ property: "start"
+ value: false
+ }
+
+ SequentialAnimation {
+ loops: Animation.Infinite
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ from: 0
+ to: 30
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ from: 1
+ to: 6.1
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ from: 30
+ to: 26
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ from: 6
+ to: 2.4
+ duration: 600
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 60
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.6
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 56
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.3
+ duration: 600
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 100
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.1
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 96
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.2
+ duration: 600
+ }
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 140
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.2
+ duration: 3000
+ }
+ }
+
+ // Slow down a bit
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 115
+ duration: 6000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.5
+ duration: 6000
+ }
+ }
+
+ // Cruise for a while
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 110
+ duration: 10000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.2
+ duration: 10000
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 115
+ duration: 10000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.5
+ duration: 10000
+ }
+ }
+
+ // Start downshifting.
+
+ // Fifth to fourth gear.
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.Linear
+ to: 100
+ duration: 5000
+ }
+
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 3.1
+ duration: 5000
+ }
+ }
+
+ // Fourth to third gear.
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.5
+ duration: 600
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 60
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.6
+ duration: 5000
+ }
+ }
+
+ // Third to second gear.
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.3
+ duration: 600
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 30
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.6
+ duration: 5000
+ }
+ }
+
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.5
+ duration: 600
+ }
+
+ // Second to first gear.
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 0
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 1
+ duration: 4500
+ }
+ }
+
+ PauseAnimation {
+ duration: 5000
+ }
+ }
+ }
+}
diff --git a/app/cluster-gauges.qml b/app/cluster-gauges.qml
new file mode 100644
index 0000000..013a0c1
--- /dev/null
+++ b/app/cluster-gauges.qml
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Konsulko Group
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * NOTE: Originally written from scratch, but enough code was eventually
+ * pasted in from the Qt dashboard.qml example that its license text
+ * has been adopted.
+ */
+
+import QtQuick 2.2
+import QtQuick.Window 2.1
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Extras 1.4
+
+ApplicationWindow {
+ id: root
+ width: 1920
+ height: 1080
+ visible: true
+ flags: Qt.FramelessWindowHint
+ style: ApplicationWindowStyle {
+ background: Rectangle {
+ color: "black"
+ }
+ }
+
+ ValueSource {
+ id: valueSource
+ }
+
+ Rectangle {
+ id: statusFrame
+ x: (parent.width - width) / 2
+ y: 80
+ width: 960
+ height: 96
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+
+ Row {
+ width: parent.width
+ height: parent.height * 0.75
+ spacing: (parent.width - (10 * parent.height * 0.75)) / 11
+
+ anchors.fill: parent
+ anchors.topMargin: (parent.height - height) /2
+ anchors.bottomMargin: (parent.height - height) /2
+ anchors.leftMargin: (parent.width - (10 * parent.height * 0.75)) / 11
+ anchors.rightMargin: (parent.width - (10 * parent.height * 0.75)) / 11
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+
+ TurnIndicator {
+ id: leftIndicator
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: height
+ height: parent.height * 0.75
+
+ direction: Qt.LeftArrow
+ on: valueSource.turnSignal == Qt.LeftArrow
+ }
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+
+ Text {
+ id: prindle
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ horizontalAlignment: Text.AlignCenter
+
+ text: valueSource.prindle
+ color: "white"
+ font.pixelSize: parent.height * 0.85
+ }
+ }
+
+ Rectangle {
+ id: gearIndicatior
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+
+ Text {
+ id: gear
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ horizontalAlignment: Text.AlignCenter
+
+ text: valueSource.gear
+ color: "white"
+ font.pixelSize: parent.height * 0.85
+ }
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+ }
+
+ Rectangle {
+ width: height
+ height: parent.height
+ radius: height / 5
+
+ color: "black"
+ border.width: 2
+ border.color: "grey"
+
+ TurnIndicator {
+ id: rightIndicator
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: height
+ height: parent.height * 0.75
+
+ direction: Qt.RightArrow
+ on: valueSource.turnSignal == Qt.RightArrow
+ }
+ }
+ }
+ }
+
+ Item {
+ x: 36
+ y: 240
+ width: 600
+ height: width
+
+ CircularGauge {
+ id: accelerometer
+ x: (parent.width - width) / 2
+ //y: (parent.height - height) / 2
+ width: parent.width * 0.9
+ height: width
+
+ maximumValue: 220
+ value: valueSource.kph
+
+ style: DashboardGaugeStyle {}
+ }
+ }
+
+ Item {
+ x: 1284
+ y: 240
+ width: 600
+ height: width
+
+ CircularGauge {
+ id: tachometer
+ x: (parent.width - width) / 2
+ width: parent.width * 0.9
+ height: width
+
+ maximumValue: 8
+ value: valueSource.rpm
+
+ style: TachometerStyle {}
+ }
+
+ CircularGauge {
+ id: fuelGauge
+ value: valueSource.fuel
+ maximumValue: 1
+ y: parent.width * 0.85
+ width: parent.width * 0.45
+ height: parent.height * 0.25
+
+ style: IconGaugeStyle {
+ id: fuelGaugeStyle
+
+ icon: "./images/fuel-icon.png"
+ minWarningColor: Qt.rgba(0.5, 0, 0, 1)
+
+ tickmarkLabel: Text {
+ color: "white"
+ visible: styleData.value === 0 || styleData.value === 1
+ font.pixelSize: fuelGaugeStyle.toPixels(0.225)
+ text: styleData.value === 0 ? "E" : (styleData.value === 1 ? "F" : "")
+ }
+ }
+ }
+
+ CircularGauge {
+ id: tempGauge
+ value: valueSource.temperature
+ maximumValue: 1
+ x: parent.width * 0.55
+ y: parent.width * 0.85
+ width: parent.width * 0.45
+ height: parent.height * 0.25
+
+ style: IconGaugeStyle {
+ id: tempGaugeStyle
+
+ icon: "./images/temperature-icon.png"
+ maxWarningColor: Qt.rgba(0.5, 0, 0, 1)
+
+ tickmarkLabel: Text {
+ color: "white"
+ visible: styleData.value === 0 || styleData.value === 1
+ font.pixelSize: tempGaugeStyle.toPixels(0.225)
+ text: styleData.value === 0 ? "C" : (styleData.value === 1 ? "H" : "")
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: frame
+ x: 672
+ y: 264
+ width: 576
+ height: 552
+
+ color: "black"
+ border.width: 4
+ border.color: "grey"
+
+ Image {
+ source: './images/Utility_Logo_Grey-01.svg'
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ width: parent.width / 2
+ height: width
+ }
+ }
+
+ Image {
+ source: './images/agl_title_793x211.png'
+ //x: 772
+ x: (parent.width - width) / 2
+ y: 898
+ width: 376
+ height: 100
+ }
+}
diff --git a/app/cluster-gauges.qrc b/app/cluster-gauges.qrc
new file mode 100644
index 0000000..22f7528
--- /dev/null
+++ b/app/cluster-gauges.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/">
+ <file>cluster-gauges.qml</file>
+ <file>DashboardGaugeStyle.qml</file>
+ <file>IconGaugeStyle.qml</file>
+ <file>TachometerStyle.qml</file>
+ <file>TurnIndicator.qml</file>
+ <file>ValueSource.qml</file>
+ </qresource>
+</RCC>
diff --git a/app/images/Utility_Logo_Grey-01.svg b/app/images/Utility_Logo_Grey-01.svg
new file mode 100644
index 0000000..16ac88c
--- /dev/null
+++ b/app/images/Utility_Logo_Grey-01.svg
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 215 215"
+ style="enable-background:new 0 0 215 215;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#525252;}
+</style>
+<switch>
+ <g i:extraneous="self">
+ <g>
+ <path class="st0" d="M113.8,150.3h4.2v15.3h9.5v3.8h-13.7V150.3z"/>
+ <path class="st0" d="M130.9,150.3h4.2v19.1h-4.2V150.3z"/>
+ <path class="st0" d="M139.9,150.3h3.9l9,11.8v-11.8h4.2v19.1h-3.6l-9.3-12.2v12.2h-4.2V150.3z"/>
+ <path class="st0" d="M169.4,169.7c-2.6,0-4.6-0.7-6.1-2.1c-1.5-1.4-2.2-3.5-2.2-6.4v-10.9h4.2v10.8c0,1.6,0.4,2.7,1.1,3.5
+ c0.7,0.8,1.7,1.2,3,1.2c1.3,0,2.3-0.4,3-1.1c0.7-0.8,1.1-1.9,1.1-3.4v-11h4.2v10.8c0,1.5-0.2,2.7-0.6,3.8c-0.4,1.1-1,2-1.7,2.7
+ c-0.7,0.7-1.6,1.3-2.7,1.6C171.9,169.5,170.7,169.7,169.4,169.7z"/>
+ <path class="st0" d="M187.3,159.7l-6.4-9.4h4.9l4,6.2l4-6.2h4.8l-6.4,9.3l6.7,9.8H194l-4.3-6.6l-4.3,6.6h-4.8L187.3,159.7z"/>
+ <path class="st0" d="M24.6,126.9h2l8.4,18.6h-2.2l-2.2-4.9H20.5l-2.2,4.9h-2.1L24.6,126.9z M29.7,138.7l-4.2-9.4l-4.2,9.4H29.7z"
+ />
+ <path class="st0" d="M37.7,137.7V127h2.1v10.6c0,4,2.1,6.2,5.6,6.2c3.4,0,5.6-2.1,5.6-6.1V127H53v10.6c0,5.4-3.1,8.2-7.7,8.2
+ C40.8,145.7,37.7,142.9,37.7,137.7z"/>
+ <path class="st0" d="M62.9,128.9h-6.2V127h14.5v1.9H65v16.5h-2.1V128.9z"/>
+ <path class="st0" d="M73,136.3L73,136.3c0-5.1,3.8-9.6,9.4-9.6c5.6,0,9.4,4.4,9.4,9.5c0,0,0,0,0,0.1c0,5.1-3.8,9.5-9.4,9.5
+ C76.8,145.8,73,141.4,73,136.3z M89.7,136.3L89.7,136.3c0-4.2-3.1-7.7-7.3-7.7c-4.2,0-7.2,3.4-7.2,7.6v0.1c0,4.2,3.1,7.6,7.3,7.6
+ C86.6,143.8,89.7,140.5,89.7,136.3z"/>
+ <path class="st0" d="M96.2,127h2.1l6.7,10.1l6.7-10.1h2.1v18.5h-2.1v-15l-6.7,9.9H105l-6.7-9.9v14.9h-2V127z"/>
+ <path class="st0" d="M145.2,128.9H139V127h14.5v1.9h-6.2v16.5h-2.1V128.9z"/>
+ <path class="st0" d="M157.6,127h2.1v18.5h-2.1V127z"/>
+ <path class="st0" d="M163.5,127h2.3l6.6,15.9L179,127h2.2l-7.9,18.6h-1.8L163.5,127z"/>
+ <path class="st0" d="M184.8,127h13.3v1.9h-11.3v6.3H197v1.9h-10.1v6.5h11.4v1.9h-13.5V127z"/>
+ <rect x="105.6" y="55.1" class="st0" width="3.8" height="16.8"/>
+
+ <rect x="69.3" y="69.6" transform="matrix(0.707 -0.7072 0.7072 0.707 -34.2747 73.1702)" class="st0" width="3.8" height="16.8"/>
+ <rect x="155.1" y="104.5" class="st0" width="16.8" height="3.8"/>
+ <rect x="47.4" y="104.5" class="st0" width="16.8" height="3.8"/>
+ <path class="st0" d="M43.7,113.9c2.1-34.7,31-62.4,66.2-62.4c35.2,0,64.2,27.6,66.2,62.4h6.4c-2.1-38.3-33.8-68.8-72.6-68.8
+ s-70.5,30.5-72.6,68.8H43.7z"/>
+ <circle class="st0" cx="107.5" cy="114.9" r="6.7"/>
+
+ <rect x="107.1" y="88.5" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -24.9453 120.6025)" class="st0" width="52" height="3.8"/>
+ <rect x="86.9" y="78" class="st0" width="9.2" height="9.2"/>
+ <rect x="97.6" y="78" class="st0" width="9.2" height="9.2"/>
+ <rect x="108.3" y="78" class="st0" width="9.2" height="9.2"/>
+ <rect x="118.9" y="78" class="st0" width="9.2" height="9.2"/>
+ <g>
+ <g>
+ <path class="st0" d="M35.1,153.7l-1.5,1.4c-1.1-1-2.2-1.8-3.5-2.4c-1.3-0.5-2.5-0.8-3.7-0.8c-1.5,0-2.9,0.4-4.2,1.1
+ c-1.3,0.7-2.4,1.7-3.1,3c-0.7,1.2-1.1,2.6-1.1,4c0,1.4,0.4,2.8,1.1,4.1c0.8,1.3,1.8,2.3,3.2,3c1.3,0.7,2.8,1.1,4.4,1.1
+ c1.9,0,3.6-0.5,4.9-1.6c1.3-1.1,2.1-2.5,2.4-4.3h-6v-1.8h8.2c0,2.9-0.9,5.2-2.6,7c-1.7,1.7-4,2.6-6.9,2.6
+ c-3.5,0-6.3-1.2-8.3-3.6c-1.6-1.8-2.4-4-2.4-6.4c0-1.8,0.5-3.5,1.4-5c0.9-1.5,2.1-2.8,3.7-3.6c1.6-0.9,3.3-1.3,5.3-1.3
+ c1.6,0,3.1,0.3,4.5,0.9C32.4,151.5,33.8,152.4,35.1,153.7z"/>
+ <path class="st0" d="M39.9,150.5h3.8c2.1,0,3.5,0.1,4.3,0.3c1.1,0.3,2,0.8,2.7,1.7c0.7,0.8,1.1,1.9,1.1,3.1
+ c0,1-0.2,1.9-0.7,2.7c-0.5,0.8-1.2,1.4-2.1,1.8c-0.9,0.4-2.1,0.6-3.7,0.6l6.8,8.8h-2.3l-6.8-8.8h-1.1v8.8h-1.9V150.5z
+ M41.8,152.3v6.4l3.3,0c1.3,0,2.2-0.1,2.8-0.4c0.6-0.2,1.1-0.6,1.4-1.2c0.3-0.5,0.5-1.1,0.5-1.8c0-0.6-0.2-1.2-0.5-1.7
+ s-0.8-0.9-1.4-1.1c-0.6-0.2-1.5-0.3-2.8-0.3H41.8z"/>
+ <path class="st0" d="M63.6,150.5l8.8,18.9h-2l-3-6.2h-8.2l-2.9,6.2h-2.1l8.9-18.9H63.6z M63.3,154.5l-3.2,6.9h6.5L63.3,154.5z"
+ />
+ <path class="st0" d="M75.3,169.4v-18.9h3.9c2.8,0,4.9,0.2,6.2,0.7c1.8,0.6,3.3,1.8,4.3,3.3c1,1.6,1.6,3.5,1.6,5.7
+ c0,1.9-0.4,3.6-1.2,5c-0.8,1.4-1.9,2.5-3.2,3.2c-1.3,0.7-3.1,1-5.5,1H75.3z M77.1,167.6h2.2c2.6,0,4.4-0.2,5.4-0.5
+ c1.4-0.5,2.5-1.3,3.4-2.5c0.8-1.2,1.2-2.7,1.2-4.4c0-1.8-0.4-3.4-1.3-4.7c-0.9-1.3-2.1-2.2-3.7-2.7c-1.2-0.4-3.1-0.5-5.9-0.5
+ h-1.3V167.6z"/>
+ <path class="st0" d="M95,150.5h10.9v1.9h-9v5.9h8.9v1.9h-8.9v7.4h8.9v1.9H95V150.5z"/>
+ </g>
+ </g>
+ <g>
+ <polygon class="st0" points="121.4,141.8 121.4,134.4 117.7,134.4 117.7,145.4 128.7,145.4 128.7,141.8 "/>
+ <polygon class="st0" points="136.1,127 117.7,127 117.7,132.6 121.4,132.6 121.4,130.7 132.4,130.7 132.4,141.8 130.6,141.8
+ 130.6,145.4 136.1,145.4 "/>
+ </g>
+ </g>
+ </g>
+</switch>
+</svg>
diff --git a/app/images/agl_title_793x211.png b/app/images/agl_title_793x211.png
new file mode 100644
index 0000000..5a183d2
--- /dev/null
+++ b/app/images/agl_title_793x211.png
Binary files differ
diff --git a/app/images/fuel-icon.png b/app/images/fuel-icon.png
new file mode 100644
index 0000000..70da758
--- /dev/null
+++ b/app/images/fuel-icon.png
Binary files differ
diff --git a/app/images/images.qrc b/app/images/images.qrc
new file mode 100644
index 0000000..8767add
--- /dev/null
+++ b/app/images/images.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/images">
+ <file>agl_title_793x211.png</file>
+ <file>Utility_Logo_Grey-01.svg</file>
+ <file>fuel-icon.png</file>
+ <file>temperature-icon.png</file>
+ </qresource>
+</RCC>
diff --git a/app/images/temperature-icon.png b/app/images/temperature-icon.png
new file mode 100644
index 0000000..5a4334e
--- /dev/null
+++ b/app/images/temperature-icon.png
Binary files differ
diff --git a/app/main.cpp b/app/main.cpp
new file mode 100644
index 0000000..4f36ef7
--- /dev/null
+++ b/app/main.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Qt Company Ltd.
+ * Copyright (C) 2018 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QtCore/QDebug>
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QUrlQuery>
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QtQml/qqml.h>
+#include <QQuickWindow>
+#include <QtQuickControls2/QQuickStyle>
+
+#include <qlibwindowmanager.h>
+
+int main(int argc, char *argv[])
+{
+ // Slight hack, using the homescreen role greatly simplifies things wrt
+ // the windowmanager
+ QString myname = QString("homescreen");
+
+ QGuiApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ parser.addPositionalArgument("port", app.translate("main", "port for binding"));
+ parser.addPositionalArgument("secret", app.translate("main", "secret for binding"));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.process(app);
+ QStringList positionalArguments = parser.positionalArguments();
+
+ QQmlApplicationEngine engine;
+
+ if (positionalArguments.length() == 2) {
+ int port = positionalArguments.takeFirst().toInt();
+ QString secret = positionalArguments.takeFirst();
+ QUrl bindingAddress;
+ bindingAddress.setScheme(QStringLiteral("ws"));
+ bindingAddress.setHost(QStringLiteral("localhost"));
+ bindingAddress.setPort(port);
+ bindingAddress.setPath(QStringLiteral("/api"));
+ QUrlQuery query;
+ query.addQueryItem(QStringLiteral("token"), secret);
+ bindingAddress.setQuery(query);
+ QQmlContext *context = engine.rootContext();
+ context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress);
+
+ std::string token = secret.toStdString();
+ QLibWindowmanager* qwm = new QLibWindowmanager();
+
+ // WindowManager
+ if(qwm->init(port, secret) != 0){
+ exit(EXIT_FAILURE);
+ }
+
+ // Request a surface as described in layers.json windowmanager’s file
+ if (qwm->requestSurface(myname) != 0) {
+ exit(EXIT_FAILURE);
+ }
+
+ // Create an event callback against an event type. Here a lambda is called when SyncDraw event occurs
+ qwm->set_event_handler(QLibWindowmanager::Event_SyncDraw, [qwm, myname](json_object*) {
+ fprintf(stderr, "Surface got syncDraw!\n");
+ qwm->endDraw(myname);
+ });
+
+ engine.load(QUrl(QStringLiteral("qrc:/cluster-gauges.qml")));
+
+ // Find the instantiated model QObject and connect the signals/slots
+ QList<QObject *> mobjs = engine.rootObjects();
+
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(mobjs.first());
+ QObject::connect(window, SIGNAL(frameSwapped()), qwm, SLOT(slotActivateSurface()));
+ }
+
+ return app.exec();
+}