summaryrefslogtreecommitdiffstats
path: root/Cluster
diff options
context:
space:
mode:
Diffstat (limited to 'Cluster')
-rw-r--r--Cluster/Cluster.pro8
-rw-r--r--Cluster/images.qrc23
-rw-r--r--Cluster/images/BackgroundGradient.pngbin0 -> 18682 bytes
-rw-r--r--Cluster/images/BottomPanel.pngbin0 -> 27556 bytes
-rw-r--r--Cluster/images/Built_with_Qt_RGB_logo_white.pngbin0 -> 10082 bytes
-rw-r--r--Cluster/images/Cluster8Gauges.pngbin0 -> 691473 bytes
-rw-r--r--Cluster/images/Cluster8GaugesPlain.pngbin0 -> 656289 bytes
-rw-r--r--Cluster/images/ClusterGaugeCenters.pngbin0 -> 59985 bytes
-rw-r--r--Cluster/images/ClusterGaugeCentersPlain.pngbin0 -> 31938 bytes
-rw-r--r--Cluster/images/Gauges_normal.pngbin0 -> 473434 bytes
-rw-r--r--Cluster/images/Icon_Battery_OFF.pngbin0 -> 1307 bytes
-rw-r--r--Cluster/images/Icon_Battery_ON.pngbin0 -> 1933 bytes
-rw-r--r--Cluster/images/Icon_BulbFailure_OFF.pngbin0 -> 1940 bytes
-rw-r--r--Cluster/images/Icon_BulbFailure_ON.pngbin0 -> 2711 bytes
-rw-r--r--Cluster/images/Icon_Coolant_OFF.pngbin0 -> 1563 bytes
-rw-r--r--Cluster/images/Icon_Coolant_ON.pngbin0 -> 2024 bytes
-rw-r--r--Cluster/images/Icon_Fuel_OFF.pngbin0 -> 1485 bytes
-rw-r--r--Cluster/images/Icon_Fuel_ON.pngbin0 -> 1969 bytes
-rw-r--r--Cluster/images/Icon_LowBeam_OFF.pngbin0 -> 1853 bytes
-rw-r--r--Cluster/images/Icon_LowBeam_ON.pngbin0 -> 2323 bytes
-rw-r--r--Cluster/images/Icon_ParkingBrake_OFF.pngbin0 -> 1962 bytes
-rw-r--r--Cluster/images/Icon_ParkingBrake_ON.pngbin0 -> 2448 bytes
-rw-r--r--Cluster/images/Icon_PositionLights_OFF.pngbin0 -> 1617 bytes
-rw-r--r--Cluster/images/Icon_PositionLights_ON.pngbin0 -> 2085 bytes
-rw-r--r--Cluster/images/Icon_SeatBelt_OFF.pngbin0 -> 1539 bytes
-rw-r--r--Cluster/images/Icon_SeatBelt_ON.pngbin0 -> 1956 bytes
-rw-r--r--Cluster/images/Icon_TurnLeft_OFF.pngbin0 -> 1339 bytes
-rw-r--r--Cluster/images/Icon_TurnLeft_ON.pngbin0 -> 2119 bytes
-rw-r--r--Cluster/images/Icon_TyreMalfunction_OFF.pngbin0 -> 1584 bytes
-rw-r--r--Cluster/images/Icon_TyreMalfunction_ON.pngbin0 -> 2145 bytes
-rw-r--r--Cluster/images/SpeedometerNeedle.pngbin0 -> 280 bytes
-rw-r--r--Cluster/images/status_battery_highlight.pngbin0 -> 275 bytes
-rw-r--r--Cluster/images/status_battery_icon.pngbin0 -> 1425 bytes
-rw-r--r--Cluster/images/status_washer_fluid_highlight.pngbin0 -> 602 bytes
-rw-r--r--Cluster/images/status_washer_fluid_icon.pngbin0 -> 2128 bytes
-rw-r--r--Cluster/images/welcomeview_passenger_icon.pngbin0 -> 958 bytes
-rw-r--r--Cluster/images/welcomeview_status_icon.pngbin0 -> 1334 bytes
-rw-r--r--Cluster/images/welcomeview_trip_info_icon.pngbin0 -> 1336 bytes
-rw-r--r--Cluster/images/welcomeview_trip_route.pngbin0 -> 7123 bytes
-rw-r--r--Cluster/main.cpp130
-rw-r--r--Cluster/plugins/gaugefiller/gauge.cpp264
-rw-r--r--Cluster/plugins/gaugefiller/gauge.h138
-rw-r--r--Cluster/plugins/gaugefiller/gaugefiller.pro23
-rw-r--r--Cluster/plugins/gaugefiller/gaugenode.cpp306
-rw-r--r--Cluster/plugins/gaugefiller/gaugenode.h164
-rw-r--r--Cluster/plugins/gaugefiller/plugin.cpp52
-rw-r--r--Cluster/plugins/gaugefiller/qmldir2
-rw-r--r--Cluster/plugins/plugins.pro5
-rw-r--r--Cluster/plugins/scenehelper/plugin.cpp52
-rw-r--r--Cluster/plugins/scenehelper/qmldir2
-rw-r--r--Cluster/plugins/scenehelper/scenehelper.cpp194
-rw-r--r--Cluster/plugins/scenehelper/scenehelper.h65
-rw-r--r--Cluster/plugins/scenehelper/scenehelper.pro22
-rw-r--r--Cluster/qml/BottomPanel.qml134
-rw-r--r--Cluster/qml/CarModel.qml551
-rw-r--r--Cluster/qml/CenterView.qml152
-rw-r--r--Cluster/qml/Dashboard.qml289
-rw-r--r--Cluster/qml/DashboardFrame.qml121
-rw-r--r--Cluster/qml/DashboardView.qml49
-rw-r--r--Cluster/qml/FpsCounter.qml87
-rw-r--r--Cluster/qml/TurnIndicator.qml60
-rw-r--r--Cluster/qml/WelcomeDriver.qml105
-rw-r--r--Cluster/qml/WelcomeInfoNote.qml67
-rw-r--r--Cluster/qml/WelcomeStatus.qml118
-rw-r--r--Cluster/qml/WelcomeStatusNote.qml76
-rw-r--r--Cluster/qml/WelcomeTripSummary.qml113
-rw-r--r--Cluster/qml/WelcomeView.qml232
-rw-r--r--Cluster/qml/gauges/BatteryMeter.qml56
-rw-r--r--Cluster/qml/gauges/ConsumptionMeter.qml74
-rw-r--r--Cluster/qml/gauges/FpsMeter.qml72
-rw-r--r--Cluster/qml/gauges/FuelMeter.qml56
-rw-r--r--Cluster/qml/gauges/SpeedoMeter.qml138
-rw-r--r--Cluster/qml/gauges/TachoMeter.qml96
-rw-r--r--Cluster/qml/gauges/TemperatureMeter.qml75
-rw-r--r--Cluster/qml/gauges/TurboMeter.qml56
-rw-r--r--Cluster/qml/models/Map11.jpgbin0 -> 58551 bytes
-rw-r--r--Cluster/qml/models/sportscar.qgltfbin0 -> 59572 bytes
-rw-r--r--Cluster/qml/models/sportscar_1.binbin0 -> 2899794 bytes
-rw-r--r--Cluster/qtcluster.qrc13
-rw-r--r--Cluster/sportscar.qrc7
-rw-r--r--Cluster/sportscar_15k.qrc7
-rw-r--r--Cluster/sportsimages.qrc5
-rw-r--r--Cluster/sportsqml.qrc8
83 files changed, 4267 insertions, 0 deletions
diff --git a/Cluster/Cluster.pro b/Cluster/Cluster.pro
new file mode 100644
index 0000000..94871de
--- /dev/null
+++ b/Cluster/Cluster.pro
@@ -0,0 +1,8 @@
+include (../deployment.pri)
+TEMPLATE = subdirs
+
+SUBDIRS = plugins
+
+qml.files = qml images
+qml.path = $$TARGET_PATH_CLUSTER
+INSTALLS += qml
diff --git a/Cluster/images.qrc b/Cluster/images.qrc
new file mode 100644
index 0000000..29ff8df
--- /dev/null
+++ b/Cluster/images.qrc
@@ -0,0 +1,23 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/Icon_TurnLeft_OFF.png</file>
+ <file>images/Icon_TurnLeft_ON.png</file>
+ <file>images/MapLocation.png</file>
+ <file>images/Icon_LowBeam_OFF.png</file>
+ <file>images/Icon_LowBeam_ON.png</file>
+ <file>images/Icon_PositionLights_OFF.png</file>
+ <file>images/Icon_PositionLights_ON.png</file>
+ <file>images/Icon_SeatBelt_OFF.png</file>
+ <file>images/Icon_SeatBelt_ON.png</file>
+ <file>images/Icon_TyreMalfunction_OFF.png</file>
+ <file>images/Icon_TyreMalfunction_ON.png</file>
+ <file>images/Icon_Battery_OFF.png</file>
+ <file>images/Icon_Battery_ON.png</file>
+ <file>images/Icon_Coolant_OFF.png</file>
+ <file>images/Icon_Coolant_ON.png</file>
+ <file>images/Icon_Fuel_OFF.png</file>
+ <file>images/Icon_Fuel_ON.png</file>
+ <file>images/Icon_BulbFailure_OFF.png</file>
+ <file>images/Icon_BulbFailure_ON.png</file>
+ </qresource>
+</RCC>
diff --git a/Cluster/images/BackgroundGradient.png b/Cluster/images/BackgroundGradient.png
new file mode 100644
index 0000000..d7e3f8e
--- /dev/null
+++ b/Cluster/images/BackgroundGradient.png
Binary files differ
diff --git a/Cluster/images/BottomPanel.png b/Cluster/images/BottomPanel.png
new file mode 100644
index 0000000..7979b52
--- /dev/null
+++ b/Cluster/images/BottomPanel.png
Binary files differ
diff --git a/Cluster/images/Built_with_Qt_RGB_logo_white.png b/Cluster/images/Built_with_Qt_RGB_logo_white.png
new file mode 100644
index 0000000..5905362
--- /dev/null
+++ b/Cluster/images/Built_with_Qt_RGB_logo_white.png
Binary files differ
diff --git a/Cluster/images/Cluster8Gauges.png b/Cluster/images/Cluster8Gauges.png
new file mode 100644
index 0000000..2dd545d
--- /dev/null
+++ b/Cluster/images/Cluster8Gauges.png
Binary files differ
diff --git a/Cluster/images/Cluster8GaugesPlain.png b/Cluster/images/Cluster8GaugesPlain.png
new file mode 100644
index 0000000..314aeb4
--- /dev/null
+++ b/Cluster/images/Cluster8GaugesPlain.png
Binary files differ
diff --git a/Cluster/images/ClusterGaugeCenters.png b/Cluster/images/ClusterGaugeCenters.png
new file mode 100644
index 0000000..2d4720e
--- /dev/null
+++ b/Cluster/images/ClusterGaugeCenters.png
Binary files differ
diff --git a/Cluster/images/ClusterGaugeCentersPlain.png b/Cluster/images/ClusterGaugeCentersPlain.png
new file mode 100644
index 0000000..4cca83c
--- /dev/null
+++ b/Cluster/images/ClusterGaugeCentersPlain.png
Binary files differ
diff --git a/Cluster/images/Gauges_normal.png b/Cluster/images/Gauges_normal.png
new file mode 100644
index 0000000..43b6810
--- /dev/null
+++ b/Cluster/images/Gauges_normal.png
Binary files differ
diff --git a/Cluster/images/Icon_Battery_OFF.png b/Cluster/images/Icon_Battery_OFF.png
new file mode 100644
index 0000000..91b1bd1
--- /dev/null
+++ b/Cluster/images/Icon_Battery_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_Battery_ON.png b/Cluster/images/Icon_Battery_ON.png
new file mode 100644
index 0000000..576e48f
--- /dev/null
+++ b/Cluster/images/Icon_Battery_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_BulbFailure_OFF.png b/Cluster/images/Icon_BulbFailure_OFF.png
new file mode 100644
index 0000000..03a2f79
--- /dev/null
+++ b/Cluster/images/Icon_BulbFailure_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_BulbFailure_ON.png b/Cluster/images/Icon_BulbFailure_ON.png
new file mode 100644
index 0000000..fdfc866
--- /dev/null
+++ b/Cluster/images/Icon_BulbFailure_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_Coolant_OFF.png b/Cluster/images/Icon_Coolant_OFF.png
new file mode 100644
index 0000000..901933f
--- /dev/null
+++ b/Cluster/images/Icon_Coolant_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_Coolant_ON.png b/Cluster/images/Icon_Coolant_ON.png
new file mode 100644
index 0000000..c3d8f3e
--- /dev/null
+++ b/Cluster/images/Icon_Coolant_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_Fuel_OFF.png b/Cluster/images/Icon_Fuel_OFF.png
new file mode 100644
index 0000000..f278fd5
--- /dev/null
+++ b/Cluster/images/Icon_Fuel_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_Fuel_ON.png b/Cluster/images/Icon_Fuel_ON.png
new file mode 100644
index 0000000..43448a6
--- /dev/null
+++ b/Cluster/images/Icon_Fuel_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_LowBeam_OFF.png b/Cluster/images/Icon_LowBeam_OFF.png
new file mode 100644
index 0000000..e7dbed0
--- /dev/null
+++ b/Cluster/images/Icon_LowBeam_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_LowBeam_ON.png b/Cluster/images/Icon_LowBeam_ON.png
new file mode 100644
index 0000000..b949991
--- /dev/null
+++ b/Cluster/images/Icon_LowBeam_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_ParkingBrake_OFF.png b/Cluster/images/Icon_ParkingBrake_OFF.png
new file mode 100644
index 0000000..66940aa
--- /dev/null
+++ b/Cluster/images/Icon_ParkingBrake_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_ParkingBrake_ON.png b/Cluster/images/Icon_ParkingBrake_ON.png
new file mode 100644
index 0000000..d508c9b
--- /dev/null
+++ b/Cluster/images/Icon_ParkingBrake_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_PositionLights_OFF.png b/Cluster/images/Icon_PositionLights_OFF.png
new file mode 100644
index 0000000..b309832
--- /dev/null
+++ b/Cluster/images/Icon_PositionLights_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_PositionLights_ON.png b/Cluster/images/Icon_PositionLights_ON.png
new file mode 100644
index 0000000..8d77207
--- /dev/null
+++ b/Cluster/images/Icon_PositionLights_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_SeatBelt_OFF.png b/Cluster/images/Icon_SeatBelt_OFF.png
new file mode 100644
index 0000000..332e773
--- /dev/null
+++ b/Cluster/images/Icon_SeatBelt_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_SeatBelt_ON.png b/Cluster/images/Icon_SeatBelt_ON.png
new file mode 100644
index 0000000..1d33139
--- /dev/null
+++ b/Cluster/images/Icon_SeatBelt_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_TurnLeft_OFF.png b/Cluster/images/Icon_TurnLeft_OFF.png
new file mode 100644
index 0000000..e7812eb
--- /dev/null
+++ b/Cluster/images/Icon_TurnLeft_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_TurnLeft_ON.png b/Cluster/images/Icon_TurnLeft_ON.png
new file mode 100644
index 0000000..9b4d03e
--- /dev/null
+++ b/Cluster/images/Icon_TurnLeft_ON.png
Binary files differ
diff --git a/Cluster/images/Icon_TyreMalfunction_OFF.png b/Cluster/images/Icon_TyreMalfunction_OFF.png
new file mode 100644
index 0000000..3117bd7
--- /dev/null
+++ b/Cluster/images/Icon_TyreMalfunction_OFF.png
Binary files differ
diff --git a/Cluster/images/Icon_TyreMalfunction_ON.png b/Cluster/images/Icon_TyreMalfunction_ON.png
new file mode 100644
index 0000000..eee237d
--- /dev/null
+++ b/Cluster/images/Icon_TyreMalfunction_ON.png
Binary files differ
diff --git a/Cluster/images/SpeedometerNeedle.png b/Cluster/images/SpeedometerNeedle.png
new file mode 100644
index 0000000..90158b1
--- /dev/null
+++ b/Cluster/images/SpeedometerNeedle.png
Binary files differ
diff --git a/Cluster/images/status_battery_highlight.png b/Cluster/images/status_battery_highlight.png
new file mode 100644
index 0000000..62000d8
--- /dev/null
+++ b/Cluster/images/status_battery_highlight.png
Binary files differ
diff --git a/Cluster/images/status_battery_icon.png b/Cluster/images/status_battery_icon.png
new file mode 100644
index 0000000..ec2b397
--- /dev/null
+++ b/Cluster/images/status_battery_icon.png
Binary files differ
diff --git a/Cluster/images/status_washer_fluid_highlight.png b/Cluster/images/status_washer_fluid_highlight.png
new file mode 100644
index 0000000..8bbfe61
--- /dev/null
+++ b/Cluster/images/status_washer_fluid_highlight.png
Binary files differ
diff --git a/Cluster/images/status_washer_fluid_icon.png b/Cluster/images/status_washer_fluid_icon.png
new file mode 100644
index 0000000..4546977
--- /dev/null
+++ b/Cluster/images/status_washer_fluid_icon.png
Binary files differ
diff --git a/Cluster/images/welcomeview_passenger_icon.png b/Cluster/images/welcomeview_passenger_icon.png
new file mode 100644
index 0000000..e2f2078
--- /dev/null
+++ b/Cluster/images/welcomeview_passenger_icon.png
Binary files differ
diff --git a/Cluster/images/welcomeview_status_icon.png b/Cluster/images/welcomeview_status_icon.png
new file mode 100644
index 0000000..0a640ba
--- /dev/null
+++ b/Cluster/images/welcomeview_status_icon.png
Binary files differ
diff --git a/Cluster/images/welcomeview_trip_info_icon.png b/Cluster/images/welcomeview_trip_info_icon.png
new file mode 100644
index 0000000..32172f0
--- /dev/null
+++ b/Cluster/images/welcomeview_trip_info_icon.png
Binary files differ
diff --git a/Cluster/images/welcomeview_trip_route.png b/Cluster/images/welcomeview_trip_route.png
new file mode 100644
index 0000000..f7bafb9
--- /dev/null
+++ b/Cluster/images/welcomeview_trip_route.png
Binary files differ
diff --git a/Cluster/main.cpp b/Cluster/main.cpp
new file mode 100644
index 0000000..f02ea90
--- /dev/null
+++ b/Cluster/main.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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$
+**
+****************************************************************************/
+
+//#ifdef QT_3DCORE_LIB
+//#include "scenehelper.h"
+//#endif
+//#include "gauge.h"
+//#include "qtiviclusterdata.h"
+
+#include <QtQml/QQmlApplicationEngine>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickView>
+
+//#include "etcprovider.h"
+
+#ifdef STATIC
+#include <QtPlugin>
+#include <QQmlExtensionPlugin>
+
+Q_IMPORT_PLUGIN(QtQuick2Plugin)
+Q_IMPORT_PLUGIN(QtQuickScene3DPlugin)
+Q_IMPORT_PLUGIN(Qt3DQuick3DCorePlugin)
+Q_IMPORT_PLUGIN(Qt3DQuick3DRenderPlugin)
+Q_IMPORT_PLUGIN(QtIVIVehicleFunctionsPlugin)
+//Q_IMPORT_PLUGIN(QMultimediaDeclarativeModule)
+//Q_IMPORT_PLUGIN(QtIVIVehicleFunctionsPlugin)
+//Q_IMPORT_PLUGIN(QtIVICorePlugin)
+//Q_IMPROT_PLUGIN(QtMultimediaPlugin)
+#endif
+
+int main(int argc, char **argv)
+{
+ qputenv("QT_QPA_EGLFS_HIDECURSOR", "1");
+ qputenv("QT_QPA_EGLFS_DISABLE_INPUT","1");
+ qputenv("QT_QPA_EGLFS_INTEGRATION","eglfs_viv");
+ qputenv("FB_MULTI_BUFFER","2");
+ qputenv("QT_QPA_EGLFS_WIDTH","1280");
+ qputenv("QT_QPA_EGLFS_HEIGHT","480");
+ qputenv("QT_QPA_EGLFS_PHYSICAL_WIDTH","1280");
+ qputenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT","480");
+ qputenv("QT_QPA_FONTDIR",".");
+
+#ifdef STATIC
+ qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QtQuick2Plugin().instance())->registerTypes("QtQuick");
+ qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QtQuickScene3DPlugin().instance())->registerTypes("QtQuick.Scene3D");
+ qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_Qt3DQuick3DCorePlugin().instance())->registerTypes("Qt3D.Core");
+ qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_Qt3DQuick3DRenderPlugin().instance())->registerTypes("Qt3D.Render");
+ //qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QMultimediaDeclarativeModule().instance())->registerTypes("QtMultimedia");
+
+ //qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QtIVICorePlugin().instance())->registerTypes("QtIVICore");
+ qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QtIVIVehicleFunctionsPlugin().instance())->registerTypes("QtIVIVehicleFunctions");
+ //qobject_cast<QQmlExtensionPlugin*>(qt_static_plugin_QMultimediaDeclarativeModule().instance())->registerTypes("QtMultimedia");
+#endif
+ QGuiApplication app(argc, argv);
+
+ //QGuiApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
+ //QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
+
+ QFontDatabase::addApplicationFont(":/fonts/Lato-Bold.ttf");
+ QFontDatabase::addApplicationFont(":/fonts/Lato-Semibold.ttf");
+ int latoID = QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf");
+ QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(latoID);
+ if (!loadedFontFamilies.empty()) {
+ QString fontName = loadedFontFamilies.at(0);
+ QGuiApplication::setFont(QFont(fontName));
+ } else {
+ qWarning("Error: fail to load Open Sans font");
+ }
+
+#ifdef QT_3DCORE_LIB
+// qmlRegisterType<SceneHelper>("Qt3D.Examples", 2, 0, "SceneHelper");
+#endif
+// qmlRegisterType<QtIVIClusterData>("ClusterDemoData", 1, 0, "ClusterData");
+// qmlRegisterType<Gauge>("ClusterDemo", 1, 0, "GaugeFiller");
+// qmlRegisterSingletonType(QUrl("qrc:/qml/ValueSource.qml"), "ClusterDemo", 1, 0, "ValueSource");
+
+ QQuickView view;
+
+// EtcProvider *provider = new EtcProvider();
+// provider->setBaseUrl(QUrl("qrc:///images/"));
+// view.engine()->addImageProvider("etc", provider);
+
+ view.setColor(QColor(Qt::black));
+ view.setWidth(1280);
+ view.setHeight(480);
+ //view.setResizeMode(QQuickView::SizeRootObjectToView);
+
+ view.setSource(QUrl("qrc:/qml/DashboardFrame.qml"));
+ view.show();
+ return app.exec();
+}
diff --git a/Cluster/plugins/gaugefiller/gauge.cpp b/Cluster/plugins/gaugefiller/gauge.cpp
new file mode 100644
index 0000000..419196f
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gauge.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gauge.h"
+#include "gaugenode.h"
+
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgflatcolormaterial.h>
+#include <QtMath>
+
+Gauge::Gauge(QQuickItem *parent)
+ : QQuickItem(parent)
+ , m_value(0)
+ , m_angle(0)
+ , m_numVertices(128)
+ , m_fillWidth(10)
+ , m_radius(0)
+ , m_updateGeometry(true)
+ , m_lefttoright(true)
+ , m_minAngle(0)
+ , m_maxAngle(270)
+ , m_minValue(0)
+ , m_maxValue(240)
+ , m_doNotFill(false)
+ , m_color(QColor(255, 0, 0))
+ , arc_length(0)
+ , arc_dist_per_vertices(0)
+ , frontCutDeg(0.0)
+ , backCutDeg(0.0)
+ , frontCutRad(0.0)
+ , backCutRad(0.0)
+ , m_cutRad(0)
+{
+ setFlag(ItemHasContents, true);
+}
+
+Gauge::~Gauge()
+{
+}
+
+void Gauge::setValue(qreal value)
+{
+ if (m_value == value || value > m_maxValue || value < m_minValue)
+ return;
+
+ m_value = value;
+ updateValue();
+
+ emit valueChanged(value);
+ update();
+}
+
+void Gauge::setNumVertices(int numVertices)
+{
+ if (m_numVertices == numVertices)
+ return;
+
+ m_numVertices = numVertices;
+ emit numVerticesChanged(numVertices);
+ update();
+}
+
+void Gauge::setFillWidth(double fillWidth)
+{
+ if (m_fillWidth == fillWidth)
+ return;
+
+ m_fillWidth = fillWidth;
+ emit fillWidthChanged(m_fillWidth);
+ update();
+}
+
+void Gauge::setRadius(int radius)
+{
+ if (m_radius == radius)
+ return;
+
+ m_radius = radius;
+ emit radiusChanged(m_radius);
+ update();
+}
+
+void Gauge::setMinAngle(double minAngle)
+{
+ if (m_minAngle == minAngle)
+ return;
+
+ m_minAngle = minAngle;
+
+ backCutDeg = m_minAngle;
+ backCutRad = qDegreesToRadians(backCutDeg);
+
+ if (m_minAngle < m_maxAngle)
+ m_lefttoright = true;
+ else
+ m_lefttoright = false;
+
+ updateValue();
+
+ emit minAngleChanged(m_minAngle);
+ update();
+}
+
+void Gauge::setMaxAngle(double maxAngle)
+{
+ if (m_maxAngle == maxAngle)
+ return;
+
+ m_maxAngle = maxAngle;
+
+ if (m_minAngle < m_maxAngle)
+ m_lefttoright = true;
+ else
+ m_lefttoright = false;
+
+ updateValue();
+ emit maxAngleChanged(m_maxAngle);
+ update();
+}
+
+void Gauge::setMinValue(double minValue)
+{
+ if (m_minValue == minValue)
+ return;
+
+ m_minValue = minValue;
+ emit minValueChanged(m_minValue);
+ update();
+}
+
+void Gauge::setMaxValue(double maxValue)
+{
+ if (m_maxValue == maxValue)
+ return;
+
+ m_maxValue = maxValue;
+ emit maxValueChanged(m_maxValue);
+ update();
+}
+
+void Gauge::setDoNotFill(bool doNotFill)
+{
+ if (m_doNotFill == doNotFill)
+ return;
+
+ m_doNotFill = doNotFill;
+ emit doNotFillChanged(m_doNotFill);
+ update();
+}
+
+void Gauge::setColor(QColor color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ emit colorChanged(m_color);
+ update();
+}
+
+void Gauge::setUpdateGeometry(bool updateGeometry)
+{
+ if (m_updateGeometry == updateGeometry)
+ return;
+ m_updateGeometry = updateGeometry;
+
+ if (m_updateGeometry)
+ calcArc();
+ else
+ m_cutRad = calcValueAsRad(m_value);
+
+ update();
+}
+
+float Gauge::calcValueAsRad(qreal value)
+{
+ return qDegreesToRadians((m_minAngle + ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (value - m_minValue)) - 180.);
+}
+
+void Gauge::updateValue()
+{
+ if (m_updateGeometry)
+ calcArc();
+ else
+ m_cutRad = calcValueAsRad(m_value);
+}
+
+void Gauge::calcArc()
+{
+ backCutDeg = m_minAngle;
+ backCutRad = qDegreesToRadians(backCutDeg - 270);
+
+ if (m_updateGeometry) {
+ m_angle = ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (m_value - m_minValue);
+ } else {
+ m_angle = ((m_maxAngle - m_minAngle) / (m_maxValue - m_minValue))
+ * (m_maxValue - m_minValue);
+ }
+
+ arc_length = qDegreesToRadians(m_angle);
+ arc_dist_per_vertices = arc_length / m_numVertices;
+
+ emit angleChanged(m_angle);
+}
+
+QSGNode *Gauge::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ GaugeNode *n = static_cast<GaugeNode *>(oldNode);
+
+ if (!n)
+ n = new GaugeNode(m_numVertices, m_color, m_doNotFill);
+
+ n->setLeftToRight(m_lefttoright);
+ n->setColor(m_color);
+ n->setBoundingRect(boundingRect());
+ n->setUpdateGeometry(m_updateGeometry);
+ n->setDoNotFill(m_doNotFill);
+ n->setBackCutRad(backCutRad);
+ n->setRadius(m_radius);
+ n->setArcDistPerVert(arc_dist_per_vertices);
+ n->setNumVertices(m_numVertices);
+ n->setFillWidth(m_fillWidth);
+ if (!m_updateGeometry)
+ n->setCutRad(m_cutRad);
+ n->draw();
+ return n;
+}
+
+void Gauge::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ if (m_radius == 0)
+ setRadius(newGeometry.height() * 0.5);
+
+ calcArc();
+ update();
+}
diff --git a/Cluster/plugins/gaugefiller/gauge.h b/Cluster/plugins/gaugefiller/gauge.h
new file mode 100644
index 0000000..f75f23a
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gauge.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAUGE_H
+#define GAUGE_H
+
+#include <QQuickItem>
+
+class Gauge : public QQuickItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
+ Q_PROPERTY(int numVertices READ numVertices WRITE setNumVertices NOTIFY numVerticesChanged)
+
+ Q_PROPERTY(bool updateGeometry READ updateGeometry WRITE setUpdateGeometry NOTIFY updateGeometryChanged)
+ Q_PROPERTY(double fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged)
+ Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
+
+ Q_PROPERTY(double minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
+ Q_PROPERTY(double maxAngle READ maxAngle WRITE setMaxAngle NOTIFY maxAngleChanged)
+
+ Q_PROPERTY(double minValue READ minValue WRITE setMinValue NOTIFY minValueChanged)
+ Q_PROPERTY(double maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged)
+
+ Q_PROPERTY(bool doNotFill READ doNotFill WRITE setDoNotFill NOTIFY doNotFillChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+
+public:
+ Gauge(QQuickItem *parent = 0);
+ ~Gauge();
+
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+
+ qreal value() const { return m_value; }
+ qreal angle() const { return m_angle; }
+ bool updateGeometry() const { return m_updateGeometry; }
+ int numVertices() const { return m_numVertices; }
+ double fillWidth() const { return m_fillWidth; }
+ int radius() const { return m_radius; }
+ double minAngle() const { return m_minAngle; }
+ double maxAngle() const { return m_maxAngle; }
+ double minValue() const { return m_minValue; }
+ double maxValue() const { return m_maxValue; }
+ bool doNotFill() const { return m_doNotFill; }
+ QColor color() const { return m_color; }
+
+ void setValue(qreal value);
+ void setNumVertices(int numVertices);
+ void setFillWidth(double fillWidth);
+ void setRadius(int radius);
+ void setMinAngle(double minAngle);
+ void setMaxAngle(double maxAngle);
+ void setMinValue(double minValue);
+ void setMaxValue(double maxValue);
+ void setDoNotFill(bool doNotFill);
+ void setColor(QColor color);
+ void setUpdateGeometry(bool updateGeometry);
+
+signals:
+ void valueChanged(qreal value);
+ void angleChanged(qreal angle);
+ void numVerticesChanged(int numVertices);
+ void fillWidthChanged(double fillWidth);
+ void radiusChanged(int radius);
+ void minAngleChanged(double minAngle);
+ void maxAngleChanged(double maxAngle);
+ void minValueChanged(double minValue);
+ void maxValueChanged(double maxValue);
+ void doNotFillChanged(bool doNotFill);
+ void colorChanged(QColor color);
+ void updateGeometryChanged(bool updateGeometry);
+
+public slots:
+
+private:
+ void calcArc();
+ float calcValueAsRad(qreal value);
+ void updateValue();
+
+private:
+ qreal m_value;
+ double m_angle;
+ int m_numVertices;
+ double m_fillWidth;
+ int m_radius;
+ bool m_updateGeometry;
+ bool m_lefttoright;
+
+ double m_minAngle;
+ double m_maxAngle;
+ double m_minValue;
+ double m_maxValue;
+
+ bool m_doNotFill;
+ QColor m_color;
+
+ //Internal
+ double arc_length;
+ double arc_dist_per_vertices;
+
+ double frontCutDeg;
+ double backCutDeg;
+
+ double frontCutRad;
+ double backCutRad;
+
+ float m_cutRad;
+};
+
+#endif // GAUGE_H
diff --git a/Cluster/plugins/gaugefiller/gaugefiller.pro b/Cluster/plugins/gaugefiller/gaugefiller.pro
new file mode 100644
index 0000000..01165c0
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugefiller.pro
@@ -0,0 +1,23 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = clustergaugefillerplugin
+QT += qml quick
+CONFIG += qt plugin c++11
+
+TARGET = $$qtLibraryTarget($$TARGET)
+uri = com.qtcompany.clustergaugefiller
+
+SOURCES += \
+ plugin.cpp \
+ gauge.cpp \
+ gaugenode.cpp
+
+HEADERS += \
+ gauge.h
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/Cluster/plugins/gaugefiller/gaugenode.cpp b/Cluster/plugins/gaugefiller/gaugenode.cpp
new file mode 100644
index 0000000..8b9703d
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugenode.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gaugenode.h"
+
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgflatcolormaterial.h>
+#include <QtMath>
+
+#define EXTRAVERTICES 3
+
+GaugeNode::GaugeNode(const int &numVertices, const QColor &color = QColor(255, 0, 0),
+ const bool &doNotFill = false)
+ : QSGGeometryNode()
+ //Could be optimized more. If only geometry update used we do not need to map textured points.
+ //, m_geometry(QSGGeometry::defaultAttributes_Point2D(), numVertices+EXTRAVERTICES)
+ , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), numVertices+EXTRAVERTICES)
+ , m_material(nullptr)
+ , m_numVertices(numVertices)
+ , m_doNotFill(doNotFill)
+ , m_color(color)
+ , m_cutRad(0.0)
+ , m_updateGeometry(true)
+ , m_lefttoright(true)
+ , m_dirtyBits(0)
+{
+ initGeometry();
+}
+
+GaugeNode::~GaugeNode()
+{
+ if (m_material)
+ delete m_material;
+}
+
+void GaugeNode::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+ m_color = color;
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setCutRad(const float &cutRad)
+{
+ if (m_cutRad == cutRad)
+ return;
+
+ m_cutRad = cutRad;
+ if (!m_updateGeometry)
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setDoNotFill(const bool &doNotFill)
+{
+ if (m_doNotFill == doNotFill)
+ return;
+
+ m_doNotFill = doNotFill;
+
+ if (m_doNotFill)
+ m_geometry.setDrawingMode(GL_LINE_STRIP);
+ else
+ m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
+
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setBackCutRad(const double &backCutRad)
+{
+ if (backCutRad == m_backCutRad)
+ return;
+
+ m_backCutRad = backCutRad;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setRadius(const double &radius)
+{
+ if (m_radius == radius)
+ return;
+
+ m_radius = radius;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setArcDistPerVert(const double &dist)
+{
+ if (dist == m_arc_dist_per_vertices)
+ return;
+ m_arc_dist_per_vertices = dist;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setNumVertices(const int &numVertices)
+{
+ if (numVertices == m_numVertices)
+ return;
+
+ m_numVertices = numVertices;
+ m_geometry.allocate(m_numVertices + 3);
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setFillWidth(const double &fillWidth)
+{
+ if (m_fillWidth == fillWidth)
+ return;
+
+ m_fillWidth = fillWidth;
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setBoundingRect(const QRectF &rect)
+{
+ if (rect.width() == m_width && rect.height() == m_height)
+ return;
+
+ m_height = rect.height();
+ m_width = rect.width();
+ setCenterPoint(rect.center());
+ m_dirtyBits |= QSGNode::DirtyGeometry;
+}
+
+void GaugeNode::setCenterPoint(const QPointF &center)
+{
+ m_center_x = center.x();
+ m_center_y = center.y();
+}
+
+void GaugeNode::setUpdateGeometry(const bool &updateGeometry)
+{
+ if (m_updateGeometry == updateGeometry)
+ return;
+
+ m_updateGeometry = updateGeometry;
+
+ if (m_material)
+ delete m_material;
+
+ if (m_updateGeometry) {
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ m_material = static_cast<QSGMaterial *>(material);
+ material->setColor(m_color);
+ setMaterial(m_material);
+ } else {
+ QSGSimpleMaterial<GaugeState> *material = GaugeShader::createMaterial();
+ m_material = static_cast<QSGMaterial *>(material);
+ material->state()->color = m_color;
+ material->state()->cutRad = m_cutRad;
+ material->state()->leftToRight = m_lefttoright;
+ material->setFlag(QSGMaterial::Blending);
+ setMaterial(m_material);
+ }
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::setLeftToRight(const bool &ltr)
+{
+ if (m_lefttoright == ltr)
+ return;
+
+ m_lefttoright = ltr;
+ m_dirtyBits |= QSGNode::DirtyMaterial;
+}
+
+void GaugeNode::drawGeometryTexturePoint2D()
+{
+ QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D();
+
+ double current_angle_rad = 0.0;
+ double currentRadius = m_radius;
+ double d_arc_point_x = m_center_x + (currentRadius - m_fillWidth) * cos(m_backCutRad);
+ double d_arc_point_y = m_center_y + (currentRadius - m_fillWidth) * sin(m_backCutRad);
+
+ vertices[0].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ d_arc_point_x = m_center_x + currentRadius * cos(m_backCutRad);
+ d_arc_point_y = m_center_y + currentRadius * sin(m_backCutRad);
+ vertices[1].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ d_arc_point_x = 0;
+ d_arc_point_y = 0;
+
+ for (int i = 0; i < m_numVertices; ++i) {
+ current_angle_rad = m_backCutRad + i * m_arc_dist_per_vertices + m_arc_dist_per_vertices;
+
+ if (i % 2 == 0)
+ currentRadius -= m_fillWidth;
+ else
+ currentRadius += m_fillWidth;
+
+ d_arc_point_x = m_center_x + currentRadius * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + currentRadius * sin(current_angle_rad);
+ vertices[i + 2].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+ }
+ d_arc_point_x = m_center_x + (currentRadius - m_fillWidth) * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + (currentRadius - m_fillWidth) * sin(current_angle_rad);
+
+ vertices[m_numVertices + 2].set(d_arc_point_x, d_arc_point_y,
+ d_arc_point_x / m_width, d_arc_point_y / m_height);
+}
+
+void GaugeNode::drawMaterial()
+{
+ if (m_updateGeometry) {
+ static_cast<QSGFlatColorMaterial *>(m_material)->setColor(m_color);
+ } else {
+ GaugeState *s = static_cast<QSGSimpleMaterial<GaugeState> *>(m_material)->state();
+ s->color = m_color;
+ s->cutRad = m_cutRad;
+ s->leftToRight = m_lefttoright;
+ }
+}
+
+void GaugeNode::draw()
+{
+ if (m_dirtyBits == 0)
+ return;
+
+ if (m_dirtyBits.testFlag(QSGNode::DirtyGeometry))
+ drawGeometryTexturePoint2D();
+ if (m_dirtyBits.testFlag(QSGNode::DirtyMaterial))
+ drawMaterial();
+
+ markDirty(m_dirtyBits);
+ m_dirtyBits = 0;
+}
+
+//Could be used to optimize vertices if only geometry is changed
+void GaugeNode::drawGeometry()
+{
+ QSGGeometry::Point2D *vertices = m_geometry.vertexDataAsPoint2D();
+
+ double d_arc_point_x = 0.0;
+ double d_arc_point_y = 0.0;
+ double current_angle_rad = 0.0;
+ double currentRadius = m_radius;
+
+ vertices[0].set(m_center_x + (currentRadius - m_fillWidth) * cos(m_backCutRad), m_center_y
+ + (currentRadius - m_fillWidth) * sin(m_backCutRad));
+ vertices[1].set(m_center_x + currentRadius * cos(m_backCutRad), m_center_y
+ + currentRadius * sin(m_backCutRad));
+
+ for (int i = 0; i < m_numVertices; ++i) {
+ current_angle_rad = m_backCutRad + i * m_arc_dist_per_vertices + m_arc_dist_per_vertices;
+
+ if (i % 2 == 0)
+ currentRadius -= m_fillWidth;
+ else
+ currentRadius += m_fillWidth;
+
+ d_arc_point_x = m_center_x + currentRadius * cos(current_angle_rad);
+ d_arc_point_y = m_center_y + currentRadius * sin(current_angle_rad);
+ vertices[i + 2].set(d_arc_point_x, d_arc_point_y);
+ }
+
+ vertices[m_numVertices + 2].set(m_center_x + (currentRadius - m_fillWidth)
+ * cos(current_angle_rad), m_center_y
+ + (currentRadius - m_fillWidth) * sin(current_angle_rad));
+
+ markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
+}
+
+void GaugeNode::initGeometry()
+{
+ m_geometry.setLineWidth(1);
+ if (m_doNotFill)
+ m_geometry.setDrawingMode(GL_LINE_STRIP);
+ else
+ m_geometry.setDrawingMode(GL_TRIANGLE_STRIP);
+
+ setGeometry(&m_geometry);
+
+ QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
+ material->setColor(m_color);
+
+ m_material = static_cast<QSGMaterial *>(material);
+ setMaterial(m_material);
+}
diff --git a/Cluster/plugins/gaugefiller/gaugenode.h b/Cluster/plugins/gaugefiller/gaugenode.h
new file mode 100644
index 0000000..17e2a49
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/gaugenode.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAUGENODE_H
+#define GAUGENODE_H
+
+#include <QSGNode>
+#include <QSGSimpleMaterial>
+#include <QColor>
+
+struct GaugeState
+{
+ QColor color;
+ GLfloat cutRad;
+ bool leftToRight;
+
+ int compare(const GaugeState *other) const
+ {
+ const unsigned int c = color.rgba();
+ const unsigned int co = other->color.rgba();
+ return std::tie(c, cutRad) > std::tie(co, other->cutRad);
+ }
+};
+
+class GaugeShader : public QSGSimpleMaterialShader<GaugeState>
+{
+ QSG_DECLARE_SIMPLE_COMPARABLE_SHADER(GaugeShader, GaugeState)
+
+public:
+ const char *vertexShader() const {
+ return
+ "attribute highp vec4 aVertex; \n"
+ "attribute highp vec2 aTexCoord; \n"
+ "uniform highp mat4 qt_Matrix; \n"
+ "varying highp vec2 texCoord; \n"
+ "void main() { \n"
+ " gl_Position = qt_Matrix * aVertex; \n"
+ " texCoord = aTexCoord; \n"
+ "}";
+ }
+
+ const char *fragmentShader() const {
+ return
+ "uniform lowp float qt_Opacity; \n"
+ "uniform lowp vec4 color; \n"
+ "uniform highp float cutRad; \n"
+ "uniform lowp bool leftToRight; \n"
+ "varying highp vec2 texCoord; \n"
+ "void main() {\n"
+ " highp vec2 uv = vec2(.5 - texCoord.y, .5 - texCoord.x);\n"
+ " if (leftToRight ? (-atan(uv.y,uv.x) < cutRad) : (-atan(uv.y,uv.x) > cutRad)) {\n"
+ " gl_FragColor = color * qt_Opacity;\n"
+ " } else {\n"
+//debug color " gl_FragColor = vec4(0.,1.,0.,1.0);\n"
+ " gl_FragColor = vec4(0.,0.,0.,0.);\n"
+ " } \n"
+ "}\n";
+ }
+
+ QList<QByteArray> attributes() const
+ {
+ return QList<QByteArray>() << "aVertex" << "aTexCoord";
+ }
+
+ void updateState(const GaugeState *state, const GaugeState *)
+ {
+ program()->setUniformValue(id_color, state->color);
+ program()->setUniformValue(id_cutRad, state->cutRad);
+ program()->setUniformValue(id_leftToRight, state->leftToRight);
+ }
+
+ void resolveUniforms()
+ {
+ id_color = program()->uniformLocation("color");
+ id_cutRad = program()->uniformLocation("cutRad");
+ id_leftToRight = program()->uniformLocation("leftToRight");
+ }
+
+private:
+ int id_color;
+ int id_cutRad;
+ int id_leftToRight;
+};
+
+class GaugeNode : public QSGGeometryNode
+{
+public:
+ GaugeNode(const int &numVertices, const QColor &color, const bool &doNotFill);
+ ~GaugeNode();
+
+ void setColor(const QColor &color);
+ void setCutRad(const float &cutRad);
+
+ void setDoNotFill(const bool &doNotFill);
+
+ void setBackCutRad(const double &backCutRad);
+ void setRadius(const double &radius);
+ void setArcDistPerVert(const double &dist);
+ void setNumVertices(const int &numVertices);
+
+ void setFillWidth(const double &fillWidth);
+ void setBoundingRect(const QRectF &rect);
+ void setUpdateGeometry(const bool &updateGeometry);
+
+ void setLeftToRight(const bool &ltr);
+
+ void draw();
+
+private:
+ void initGeometry();
+ void setCenterPoint(const QPointF &center);
+
+ void drawGeometry();
+ void drawGeometryTexturePoint2D();
+ void drawMaterial();
+
+private:
+ QSGGeometry m_geometry;
+ QSGMaterial *m_material;
+ int m_numVertices;
+ bool m_doNotFill;
+ QColor m_color;
+ float m_cutRad;
+ double m_radius;
+ bool m_updateGeometry;
+ bool m_lefttoright;
+
+ qreal m_width;
+ qreal m_height;
+ double m_center_y;
+ double m_center_x;
+ double m_backCutRad;
+ double m_fillWidth;
+ double m_arc_dist_per_vertices;
+
+ DirtyState m_dirtyBits;
+};
+
+#endif // GAUGENODE_H
diff --git a/Cluster/plugins/gaugefiller/plugin.cpp b/Cluster/plugins/gaugefiller/plugin.cpp
new file mode 100644
index 0000000..e6732fd
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/plugin.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/qqmlextensionplugin.h>
+#include <qqml.h>
+#include "gauge.h"
+
+static QObject *clusterGaugeFillerSingletonFactory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(scriptEngine)
+ Q_UNUSED(engine)
+
+ return new Gauge();
+}
+
+class HoundPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("com.qtcompany.clustergaugefiller"));
+ qmlRegisterType<Gauge>(uri, 1, 0, "GaugeFiller");
+ }
+};
+
+#include "plugin.moc"
diff --git a/Cluster/plugins/gaugefiller/qmldir b/Cluster/plugins/gaugefiller/qmldir
new file mode 100644
index 0000000..1416273
--- /dev/null
+++ b/Cluster/plugins/gaugefiller/qmldir
@@ -0,0 +1,2 @@
+module com.qtcompany.clustergaugefiller
+plugin clustergaugefillerplugin
diff --git a/Cluster/plugins/plugins.pro b/Cluster/plugins/plugins.pro
new file mode 100644
index 0000000..805b714
--- /dev/null
+++ b/Cluster/plugins/plugins.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ scenehelper \
+ gaugefiller
diff --git a/Cluster/plugins/scenehelper/plugin.cpp b/Cluster/plugins/scenehelper/plugin.cpp
new file mode 100644
index 0000000..7432456
--- /dev/null
+++ b/Cluster/plugins/scenehelper/plugin.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/qqmlextensionplugin.h>
+#include <qqml.h>
+#include "scenehelper.h"
+
+static QObject *clusterSceneHelperSingletonFactory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(scriptEngine)
+ Q_UNUSED(engine)
+
+ return new SceneHelper();
+}
+
+class HoundPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("com.qtcompany.clusterscenehelper"));
+ qmlRegisterType<SceneHelper>(uri, 1, 0, "SceneHelper");
+ }
+};
+
+#include "plugin.moc"
diff --git a/Cluster/plugins/scenehelper/qmldir b/Cluster/plugins/scenehelper/qmldir
new file mode 100644
index 0000000..0c50858
--- /dev/null
+++ b/Cluster/plugins/scenehelper/qmldir
@@ -0,0 +1,2 @@
+module com.qtcompany.clusterscenehelper
+plugin clusterscenehelperplugin
diff --git a/Cluster/plugins/scenehelper/scenehelper.cpp b/Cluster/plugins/scenehelper/scenehelper.cpp
new file mode 100644
index 0000000..bd6291a
--- /dev/null
+++ b/Cluster/plugins/scenehelper/scenehelper.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scenehelper.h"
+
+QObject *SceneHelper::findEntity(Qt3DRender::QSceneLoader *loader, const QString &name)
+{
+ // The QSceneLoader instance is a component of an entity. The loaded scene
+ // tree is added under this entity.
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ if (entities.isEmpty())
+ return 0;
+
+ // Technically there could be multiple entities referencing the scene loader
+ // but sharing is discouraged, and in our case there will be one anyhow.
+ Qt3DCore::QEntity *root = entities[0];
+
+ // The scene structure and names always depend on the asset.
+ return root->findChild<Qt3DCore::QEntity *>(name);
+}
+
+void SceneHelper::removeFromScene(Qt3DRender::QSceneLoader *loader, const QStringList &names)
+{
+ //qDebug() << __FUNCTION__ << names;
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ if (entities.isEmpty())
+ return;
+
+ Qt3DCore::QEntity *root = entities[0];
+
+ foreach (QString name, names) {
+ QObject *entity = root->findChild<Qt3DCore::QEntity *>(name);
+ entity->setParent(Q_NULLPTR);
+ }
+}
+
+void SceneHelper::addMaterials(Qt3DRender::QSceneLoader *loader,
+ Qt3DRender::QMaterial *material, QStringList names)
+{
+ //qDebug() << __FUNCTION__ << material << names;
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ if (entities.isEmpty())
+ return;
+
+ Qt3DCore::QEntity *root = entities[0];
+
+ addComponents(names, root, material);
+}
+
+void SceneHelper::addMaterial(Qt3DRender::QSceneLoader *loader,
+ Qt3DRender::QMaterial *material, QString name)
+{
+ //qDebug() << __FUNCTION__ << material << name;
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ //qDebug() << entities;
+
+ if (entities.isEmpty())
+ return;
+
+ Qt3DCore::QEntity *root = entities[0];
+
+ addComponent(name, root, material);
+}
+
+void SceneHelper::replaceMaterial(Qt3DRender::QSceneLoader *loader, const QString &name,
+ Qt3DRender::QMaterial *material)
+{
+ //qDebug() << __FUNCTION__ << "Element " << name << " to " << material;
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ if (entities.isEmpty())
+ return;
+
+ Qt3DCore::QEntity *root = entities[0];
+ Qt3DCore::QEntity *entity = root->findChild<Qt3DCore::QEntity *>(name);
+ if (entity) {
+ QVector<Qt3DCore::QComponent *> components = entity->components();
+ //qDebug() << components;
+ foreach (Qt3DCore::QComponent *comp, components) {
+ if (qobject_cast<Qt3DRender::QMaterial *>(comp)) {
+ //qDebug() << "removing material";
+ entity->removeComponent(comp);
+ break;
+ }
+ }
+ //qDebug() << "adding" << material;
+ entity->addComponent(material);
+ } else {
+ qWarning() << __FUNCTION__ << "MISSING ELEMENT " << name;
+ }
+}
+
+void SceneHelper::addComponents(QStringList &names, Qt3DCore::QEntity *root,
+ Qt3DRender::QMaterial *material)
+{
+ //qDebug() << __FUNCTION__ << material;
+ foreach (QString name, names) {
+ Qt3DCore::QEntity *entity = root->findChild<Qt3DCore::QEntity *>(name);
+ //qDebug() << "entity = " << entity << " name " << name;
+ if (entity) {
+ QVector<Qt3DCore::QComponent *> components = entity->components();
+ foreach (Qt3DCore::QComponent *comp, components) {
+ //qDebug() << " comp = " << comp;
+ if (qobject_cast<Qt3DRender::QMaterial *>(comp)) {
+ //qDebug() << " removing " << comp;
+ entity->removeComponent(comp);
+ break;
+ }
+ }
+ //qDebug() << " adding " << material;
+ entity->addComponent(material);
+ } else {
+ qWarning() << __FUNCTION__ << "MISSING ELEMENT " << name;
+ }
+ }
+}
+
+/*void SceneHelper::searchCamera(Qt3DRender::QSceneLoader *loader, const QString &name)
+{
+ QVector<Qt3DCore::QEntity *> entities = loader->entities();
+
+ if (entities.isEmpty())
+ return;
+
+ Qt3DCore::QEntity *root = entities[0];
+ Qt3DCore::QEntity *entity = root->findChild<Qt3DCore::QEntity *>(name);
+ //qDebug() << "Found entity " << entity;
+ QVector<Qt3DCore::QComponent *> components = entity->components();
+ foreach (Qt3DCore::QComponent *comp, components) {
+ //qDebug() << " comp " << comp;
+ if (qobject_cast<Qt3DRender::QCameraLens *>(comp)) {
+ Qt3DRender::QCameraLens *lens = qobject_cast<Qt3DRender::QCameraLens *>(comp);
+ //qDebug() << " lens.left = " << lens->left() << lens->property("lookAt");
+ }
+ }
+}*/
+
+void SceneHelper::addComponent(QString &name, Qt3DCore::QEntity *root,
+ Qt3DRender::QMaterial *material)
+{
+ //qDebug() << __FUNCTION__ << material;
+ Qt3DCore::QEntity *entity = root->findChild<Qt3DCore::QEntity *>(name);
+ //qDebug() << "entity = " << entity << " name " << name;
+ if (entity) {
+ QVector<Qt3DCore::QComponent *> components = entity->components();
+ foreach (Qt3DCore::QComponent *comp, components) {
+ //qDebug() << " comp = " << comp;
+ if (qobject_cast<Qt3DRender::QMaterial *>(comp)) {
+ //qDebug() << " removing " << comp;
+ entity->removeComponent(comp);
+ break;
+ }
+ }
+ //qDebug() << " adding " << material;
+ entity->addComponent(material);
+ } else {
+ qWarning() << __FUNCTION__ << "MISSING ELEMENT " << name;
+ }
+}
+
+void SceneHelper::addListEntry(const QVariant &list, QObject *entry)
+{
+ QQmlListReference ref = list.value<QQmlListReference>();
+ ref.append(entry);
+}
diff --git a/Cluster/plugins/scenehelper/scenehelper.h b/Cluster/plugins/scenehelper/scenehelper.h
new file mode 100644
index 0000000..ec5ead7
--- /dev/null
+++ b/Cluster/plugins/scenehelper/scenehelper.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENEHELPER_H
+#define SCENEHELPER_H
+
+#include <QResource>
+
+#include <Qt3DRender/QRenderAspect>
+#include <Qt3DRender/QSceneLoader>
+#include <Qt3DCore/QEntity>
+//#include <Qt3DRender/QCameraLens>
+#include <Qt3DRender/QMaterial>
+#include <Qt3DQuick/QQmlAspectEngine>
+#include <Qt3DCore/QComponent>
+#include <QtQml>
+
+class SceneHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE QObject *findEntity(Qt3DRender::QSceneLoader *loader, const QString &name);
+ Q_INVOKABLE void addListEntry(const QVariant &list, QObject *entry);
+ Q_INVOKABLE void removeFromScene(Qt3DRender::QSceneLoader *loader, const QStringList &names);
+ Q_INVOKABLE void addMaterials(Qt3DRender::QSceneLoader *loader,
+ Qt3DRender::QMaterial *material, QStringList names);
+ Q_INVOKABLE void addMaterial(Qt3DRender::QSceneLoader *loader,
+ Qt3DRender::QMaterial *material, QString name);
+ Q_INVOKABLE void replaceMaterial(Qt3DRender::QSceneLoader *loader, const QString &name,
+ Qt3DRender::QMaterial *material);
+ //Q_INVOKABLE void searchCamera(Qt3DRender::QSceneLoader *loader, const QString &name);
+
+private:
+ void addComponents(QStringList &names, Qt3DCore::QEntity *root,
+ Qt3DRender::QMaterial *material);
+ void addComponent(QString &name, Qt3DCore::QEntity *root, Qt3DRender::QMaterial *material);
+};
+
+#endif // SCENEHELPER_H
diff --git a/Cluster/plugins/scenehelper/scenehelper.pro b/Cluster/plugins/scenehelper/scenehelper.pro
new file mode 100644
index 0000000..ca1cfde
--- /dev/null
+++ b/Cluster/plugins/scenehelper/scenehelper.pro
@@ -0,0 +1,22 @@
+include (../../../deployment.pri)
+TEMPLATE = lib
+TARGET = clusterscenehelperplugin
+QT += qml quick 3dcore 3dextras 3drender 3dquick 3dquick-private
+CONFIG += qt plugin c++11
+
+TARGET = $$qtLibraryTarget($$TARGET)
+uri = com.qtcompany.clusterscenehelper
+
+SOURCES += \
+ plugin.cpp \
+ scenehelper.cpp
+
+HEADERS += \
+ scenehelper.h
+
+OTHER_FILES = qmldir
+
+qmldir.files = qmldir
+qmldir.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+target.path = $$TARGET_PATH/qml/$$replace(uri, \\., /)
+INSTALLS += target qmldir
diff --git a/Cluster/qml/BottomPanel.qml b/Cluster/qml/BottomPanel.qml
new file mode 100644
index 0000000..c6c5681
--- /dev/null
+++ b/Cluster/qml/BottomPanel.qml
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+
+Item {
+ property int iconMargin: 10
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: bottomPanelImage.width
+ height: bottomPanelImage.height
+
+ Image {
+ id: bottomPanelImage
+ source: "../images/BottomPanel.png"
+ }
+
+ TurnIndicator {
+ direction: Qt.LeftArrow
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 250
+ active: ValueSource.turnSignal & Qt.LeftArrow
+ }
+
+ Image {
+ id: iconCoolant
+ source: ValueSource.engineTemperature >= 100.0 ? "../images/Icon_Coolant_ON.png"
+ : "../images/Icon_Coolant_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.right: iconBattery.left
+ }
+
+ Image {
+ id: iconBattery
+ source: ValueSource.batteryLevel <= 25.0 ? "../images/Icon_Battery_ON.png"
+ : "../images/Icon_Battery_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.right: iconFuel.left
+ }
+
+ Image {
+ id: iconFuel
+ source: ValueSource.fuelLevel <= 20.0 ? "../images/Icon_Fuel_ON.png"
+ : "../images/Icon_Fuel_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.right: iconParkingBrake.left
+ }
+
+ Image {
+ id: iconParkingBrake
+ source: ValueSource.parkingBrake ? "../images/Icon_ParkingBrake_ON.png"
+ : "../images/Icon_ParkingBrake_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.right: textTime.left
+ anchors.rightMargin: 5
+ }
+
+ Text {
+ id: textTime
+ text: ValueSource.time
+ font.pixelSize: 24 //18
+ color: "white"
+ anchors.centerIn: parent
+ }
+
+ Image {
+ id: iconLowbeam
+ source: ValueSource.lowBeam ? "../images/Icon_LowBeam_ON.png"
+ : "../images/Icon_LowBeam_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.left: textTime.right
+ anchors.leftMargin: iconMargin
+ }
+
+ Image {
+ id: iconTyre
+ source: ValueSource.flatTire ? "../images/Icon_TyreMalfunction_ON.png"
+ : "../images/Icon_TyreMalfunction_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.left: iconLowbeam.right
+ }
+
+ Image {
+ id: iconLamp
+ source: ValueSource.lightFailure ? "../images/Icon_BulbFailure_ON.png"
+ : "../images/Icon_BulbFailure_OFF.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.left: iconTyre.right
+ }
+
+ Image {
+ id: iconSeatbelt
+ //source: ValueSource.seatBelt ? "../images/Icon_SeatBelt_ON.png"
+ // : "../images/Icon_SeatBelt_OFF.png"
+ source: "../images/Icon_SeatBelt_ON.png"
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.left: iconLamp.right
+ }
+
+ TurnIndicator {
+ direction: Qt.RightArrow
+ anchors.verticalCenter: textTime.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: 250
+ active: ValueSource.turnSignal & Qt.RightArrow
+ }
+}
diff --git a/Cluster/qml/CarModel.qml b/Cluster/qml/CarModel.qml
new file mode 100644
index 0000000..b553461
--- /dev/null
+++ b/Cluster/qml/CarModel.qml
@@ -0,0 +1,551 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.0
+import Qt3D.Render 2.0
+import Qt3D.Extras 2.0
+import QtQuick 2.7 as Quick
+import com.qtcompany.clusterscenehelper 1.0
+
+Entity
+{
+ id: carModelEntity
+
+ property bool isReady: false
+ property bool hidden: true
+ property int width
+ property int height
+ property real carRotation: -30.0
+ property var previousComponent: undefined
+ property var previousMaterial
+ property vector3d defaultCameraPosition: Qt.vector3d(0.0, 5.0, 25.0)
+ property vector3d defaultLightPosition: Qt.vector3d(0.0, 20.0, 20.0)
+ property vector3d lightPosition: defaultLightPosition
+ property vector3d cameraPos: defaultCameraPosition
+ property vector3d lightPos: defaultLightPosition
+
+ property vector3d welcomeEndPosition: Qt.vector3d(-5.0, 5.0, 25.0)
+ property vector3d lightEndPosition: Qt.vector3d(20.0, 40.0, -10.0)
+ property vector3d statusEndPosition: Qt.vector3d(0.0, 40.0, 1.0)
+
+ property real lightPosMultiplier: 1.75
+
+ property int door_left: 1
+ property int door_right: 2
+ property int door_trunk: 4
+ property int door_hood: 8
+
+ property bool highlighting: false
+ property bool doorAction: false
+
+ property int highlightType: 0
+ property int defaultHighlight: 99
+
+ // Preset camera positions for highlights
+ // Light positions can use the same vectors, but with a multiplier to move it further or closer
+ // Lamp highlights
+ property vector3d positionFrontLeftHigh: Qt.vector3d(5.0, 4.0, 15.0) // Left headlight
+ property vector3d positionFrontRightHigh: Qt.vector3d(-5.0, 4.0, 15.0) // Right headlight
+ property vector3d positionFrontLeftLow: Qt.vector3d(3.0, 2.0, 15.0) // Left day light
+ property vector3d positionFrontRightLow: Qt.vector3d(-3.0, 2.0, 15.0) // Right day light
+ property vector3d positionRearLeft: Qt.vector3d(5.0, 5.0, -15.0) // Left tail light
+ property vector3d positionRearRight: Qt.vector3d(-5.0, 5.0, -15.0) // Right tail light
+ // Tire highlights
+ property vector3d positionLeftRear: Qt.vector3d(10.0, 2.0, -12.5)
+ property vector3d positionLeftFront: Qt.vector3d(10.0, 2.0, 12.5)
+ property vector3d positionRightRear: Qt.vector3d(-10.0, 2.0, -12.5)
+ property vector3d positionRightFront: Qt.vector3d(-10.0, 2.0, 12.5)
+ // Door highlights
+ property vector3d positionLeft: Qt.vector3d(35.0, 10.0, 0.0) // Doors on the left
+ property vector3d positionRight: Qt.vector3d(-35.0, 10.0, 0.0) // Doors on the right
+ property vector3d positionTop: Qt.vector3d(0.0, 40.0, 1.0) // Doors on both sides
+ property vector3d positionBack: Qt.vector3d(0.0, 20.0, -20.0) // Trunk
+ property vector3d positionFront: Qt.vector3d(0.0, 20.0, 20.0) // Hood
+
+ property color defaultBodyColor: "white"//Qt.rgba(0.5270588, 0.03137255, 0.03137255, 1.0)
+
+ property int topViewAnimationDuration: 2500
+
+ Camera {
+ id: cameraCar
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: carModelEntity.width / carModelEntity.height
+ nearPlane: 0.1
+ farPlane: 100.0
+ position: defaultCameraPosition
+ upVector: Qt.vector3d(0.0, 1.0, 0.0)
+ viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
+ }
+
+ Entity {
+ components: [
+ Transform {
+ translation: lightPosition
+ },
+ PointLight {
+ color: "white"
+ intensity: 1.0
+ }
+ ]
+ }
+
+ RenderSettings {
+ activeFrameGraph: TechniqueFilter {
+ matchAll: [ FilterKey { name: "renderingStyle"; value: "forward" } ]
+ id: carFramegraph
+
+ RenderSurfaceSelector {
+ id: surfaceSelector
+ Viewport {
+ normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
+
+ CameraSelector {
+ camera: cameraCar
+ NoDraw {
+ enabled: hidden
+ }
+ FrustumCulling {
+ ClearBuffers {
+ clearColor: "transparent"
+ buffers : ClearBuffers.ColorDepthBuffer
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Materials for the parts that need highlighting
+ PhongMaterial {
+ id: bodyMaterial
+ ambient: "black"
+ diffuse: defaultBodyColor
+ specular: Qt.rgba(0.7686275, 0.6196079, 0.3568628, 1.0)
+ shininess: 164
+ }
+
+ PhongMaterial {
+ id: bodyMaterialHighlight
+ ambient: "black"
+ diffuse: "orange"
+ shininess: 164
+ }
+
+ PhongMaterial {
+ id: tireMaterial
+ ambient: Qt.rgba(0.05, 0.05, 0.05, 1.0)
+ specular: Qt.rgba(0.594, 0.594, 0.594, 1.0)
+ diffuse: "black"
+ shininess: 51
+ }
+
+ PhongMaterial {
+ id: tireMaterialHighlight
+ ambient: "orange"
+ specular: Qt.rgba(0.594, 0.594, 0.594, 1.0)
+ diffuse: "black"
+ shininess: 51
+ }
+
+ DiffuseMapMaterial {
+ id: lampsMaterial
+ ambient: Qt.rgba(0.3, 0.3, 0.3, 1.0)
+ specular: Qt.rgba(0.279, 0.279, 0.279, 1.0)
+ diffuse: "models/Map11.jpg"
+ shininess: 31
+ }
+
+ // bodyMaterialHighlight is used for lamp highlight
+
+ // Materials for the parts that do not otherwise work correctly
+ Material {
+ id: transparentGlassMaterial
+
+ parameters: [
+ Parameter { name: "alpha"; value: 0.95 },
+ Parameter { name: "ka"; value: Qt.vector3d(0.0, 0.0, 0.0) },
+ Parameter { name: "kd"; value: Qt.vector3d(0.1608937, 0.16512, 0.154057) },
+ Parameter { name: "ks"; value: Qt.vector3d(1.0, 1.0, 1.0) },
+ Parameter { name: "shininess"; value: 33 }
+ ]
+
+ effect: DefaultAlphaEffect {
+ sourceRgbArg: BlendEquationArguments.SourceColor
+ destinationRgbArg: BlendEquationArguments.OneMinusSourceColor
+ }
+ }
+
+// PhongAlphaMaterial {
+// id: transparentGlassMaterial
+// diffuse: Qt.rgba(0.1608937, 0.16512, 0.154057, 1.0)
+// specular: Qt.rgba(1.0, 1.0, 1.0, 1.0)
+// alpha: 0.75
+// shininess: 33
+// }
+
+ PhongMaterial {
+ id: interiorMaterial
+ ambient: "black"
+ diffuse: Qt.rgba(0.17, 0.17, 0.18, 1.0)
+ shininess: 10
+ }
+
+ SceneHelper {
+ id: sceneHelper
+ }
+
+ Entity {
+ Transform {
+ id: scenePosition
+ matrix: {
+ var m = Qt.matrix4x4()
+ m.scale(1.15)
+ return m
+ }
+ }
+
+ Entity {
+ id: carModel
+
+ Transform {
+ id: carTransform
+ matrix: {
+ var m = Qt.matrix4x4()
+ m.rotate(carRotation, Qt.vector3d(0, 1, 0))
+ m.rotate(-90, Qt.vector3d(1, 0, 0))
+ return m
+ }
+ }
+
+ SceneLoader {
+ id: modelLoader
+ source: "models/sportscar.qgltf"
+ property var lampParts: [ "headlight_right", "headlight_left", "daylight_right",
+ "daylight_left", "taillight_left", "taillight_right" ]
+ property var bodyParts: [ "body", "door_left", "door_right",
+ "trunk", "hood" ]
+ property var transparentGlassParts: [ "d_glass" ]
+ property var tireParts: [ "tire_front_left", "tire_front_right",
+ "tire_rear_left", "tire_rear_right" ]
+ property var interiorParts: [ "interior" ]
+
+ // Note: If there are problems with transparent materials etc. check that you have
+ // exported the Collada file used to create the qgltf binary files using the following
+ // options in Blender (in Collada options category):
+ // - Triangulate (off)
+ // - Use Object Instances (on)
+ // - Sort by Object name (on)
+ // If just setting those is not enough, try changing the object names so that the
+ // object will be loaded in a different order.
+ // Use the following syntax for qgltf.exe:
+ // qgltf.exe file.dae -b -S
+
+ onStatusChanged: {
+ if (status === SceneLoader.Ready) {
+ sceneHelper.addMaterials(modelLoader, bodyMaterial, bodyParts)
+ sceneHelper.addMaterials(modelLoader, transparentGlassMaterial,
+ transparentGlassParts)
+ sceneHelper.addMaterials(modelLoader, interiorMaterial, interiorParts)
+ // Comment out if running standalone..
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[0])
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[1])
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[2])
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[3])
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[4])
+ sceneHelper.addMaterial(modelLoader, lampsMaterial, lampParts[5])
+ // ..Comment out if running standalone
+ sceneHelper.addMaterials(modelLoader, tireMaterial, tireParts)
+ //floorPlane.enabled = true // Disable floor for now
+ }
+ }
+ }
+
+ components: [carTransform, modelLoader]
+ }
+
+ Entity {
+ id: floorPlane
+ enabled: false
+
+ DiffuseMapMaterial {
+ id: planeMaterial
+ ambient: Qt.rgba(0, 0, 0, 1.0)
+ specular: Qt.rgba(0, 0, 0, 1.0)
+ diffuse: "../images-optimized/SportCarFloorShadow.png"
+ }
+
+ Transform {
+ id: planeRotation
+ matrix: {
+ var m = Qt.matrix4x4()
+ m.rotate(carRotation, Qt.vector3d(0, 1, 0))
+ return m
+ }
+ }
+
+ PlaneMesh {
+ id: planeMesh
+ width: 70
+ height: 70
+ }
+
+ components: [planeMesh, planeMaterial, planeRotation]
+ }
+
+ components: [ scenePosition ]
+ }
+
+ function highlightItem(idx) {
+ carRotationAnimation.stop()
+ carResetRotationAnimation.start()
+ highlighting = true
+ var highlightComponent
+ var highlightMaterial
+ var originalMaterial
+
+ switch (idx) {
+ case 1:
+ highlightComponent = "tire_front_left"
+ highlightMaterial = tireMaterialHighlight
+ originalMaterial = tireMaterial
+ lightPos = positionLeftFront.times(lightPosMultiplier)
+ cameraPos = positionLeftFront
+ break
+ case 2:
+ highlightComponent = "tire_front_right"
+ highlightMaterial = tireMaterialHighlight
+ originalMaterial = tireMaterial
+ lightPos = positionRightFront.times(lightPosMultiplier)
+ cameraPos = positionRightFront
+ break
+ case 3:
+ highlightComponent = "tire_rear_right"
+ highlightMaterial = tireMaterialHighlight
+ originalMaterial = tireMaterial
+ lightPos = positionRightRear.times(lightPosMultiplier)
+ cameraPos = positionRightRear
+ break
+ case 4:
+ highlightComponent = "tire_rear_left"
+ highlightMaterial = tireMaterialHighlight
+ originalMaterial = tireMaterial
+ lightPos = positionLeftRear.times(lightPosMultiplier)
+ cameraPos = positionLeftRear
+ break
+ case 5:
+ highlightComponent = "headlight_left"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionFrontLeftHigh.times(lightPosMultiplier)
+ cameraPos = positionFrontLeftHigh
+ break
+ case 6:
+ highlightComponent = "headlight_right"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionFrontRightHigh.times(lightPosMultiplier)
+ cameraPos = positionFrontRightHigh
+ break
+ case 7:
+ highlightComponent = "daylight_right"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionFrontRightLow.times(lightPosMultiplier)
+ cameraPos = positionFrontRightLow
+ break
+ case 8:
+ highlightComponent = "daylight_left"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionFrontLeftLow.times(lightPosMultiplier)
+ cameraPos = positionFrontLeftLow
+ break
+ case 9:
+ highlightComponent = "taillight_left"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionRearLeft.times(lightPosMultiplier)
+ cameraPos = positionRearLeft
+ break
+ case 10:
+ highlightComponent = "taillight_right"
+ highlightMaterial = bodyMaterialHighlight
+ originalMaterial = lampsMaterial
+ lightPos = positionRearRight.times(lightPosMultiplier)
+ cameraPos = positionRearRight
+ break
+ default:
+ lightPos = defaultLightPosition
+ cameraPos = defaultCameraPosition
+ }
+
+ if (previousComponent !== undefined)
+ sceneHelper.replaceMaterial(modelLoader, previousComponent, previousMaterial)
+
+ if (highlightComponent !== undefined)
+ sceneHelper.replaceMaterial(modelLoader, highlightComponent, highlightMaterial)
+
+ previousComponent = highlightComponent
+ previousMaterial = originalMaterial
+ }
+
+ function highlightOpenDoors(openDoors) {
+ carRotationAnimation.stop()
+ carResetRotationAnimation.start()
+ highlighting = true
+ var openLeft = false
+ var openRight = false
+ var openBack = false
+ var openFront = false
+
+ // Check with bitwise operators, as they can be open in any combination
+ if (openDoors & door_left) {
+ sceneHelper.replaceMaterial(modelLoader, "door_left", bodyMaterialHighlight)
+ openLeft = true
+ } else {
+ sceneHelper.replaceMaterial(modelLoader, "door_left", bodyMaterial)
+ }
+
+ if (openDoors & door_right) {
+ sceneHelper.replaceMaterial(modelLoader, "door_right", bodyMaterialHighlight)
+ openRight = true
+ } else {
+ sceneHelper.replaceMaterial(modelLoader, "door_right", bodyMaterial)
+ }
+
+ if (openDoors & door_trunk) {
+ sceneHelper.replaceMaterial(modelLoader, "trunk", bodyMaterialHighlight)
+ openBack = true
+ } else {
+ sceneHelper.replaceMaterial(modelLoader, "trunk", bodyMaterial)
+ }
+
+ if (openDoors & door_hood) {
+ openFront = true
+ sceneHelper.replaceMaterial(modelLoader, "hood", bodyMaterialHighlight)
+ } else {
+ sceneHelper.replaceMaterial(modelLoader, "hood", bodyMaterial)
+ }
+
+ if (openRight && openLeft || openBack && openFront) {
+ lightPos = positionTop.times(0.5)
+ cameraPos = positionTop
+ } else if (openRight) {
+ lightPos = positionRight.times(0.33)
+ lightPos.y += 15.0
+ cameraPos = positionRight
+ } else if (openLeft) {
+ lightPos = positionLeft.times(0.33)
+ lightPos.y += 15.0
+ cameraPos = positionLeft
+ } else if (openBack) {
+ lightPos = positionBack.times(0.75)
+ cameraPos = positionBack
+ } else if (openFront) {
+ lightPos = positionFront.times(1.0)
+ cameraPos = positionFront
+ } else {
+ lightPos = defaultLightPosition
+ cameraPos = defaultCameraPosition
+ }
+ }
+
+ onCameraPosChanged: {
+ // Update both camera and light positions
+ cameraAnimation.to = cameraPos
+ lightAnimation.to = lightPos
+ cameraAnimation.restart()
+ lightAnimation.restart()
+ }
+
+ Quick.PropertyAnimation {
+ running: false
+ id: cameraAnimation
+ target: cameraCar
+ property: "position"
+ duration: topViewAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ Quick.PropertyAnimation {
+ running: false
+ id: lightAnimation
+ target: carModelEntity
+ property: "lightPosition"
+ duration: topViewAnimationDuration * 4//1000
+ easing.type: Easing.Linear
+ }
+
+ Quick.RotationAnimation on carRotation {
+ id: carRotationAnimation
+ running: false
+ from: -30.0
+ to: 180.0
+ duration: topViewAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ function resetHighlight() {
+ if (doorAction)
+ highlightOpenDoors(0)
+ else
+ highlightItem(defaultHighlight)
+ doorAction = false
+ }
+
+ function highlightLamp() {
+ highlightType = Math.floor(Math.random() * 6) + 5
+ highlightItem(highlightType)
+ return highlightType
+ }
+
+ function highlightTire() {
+ highlightType = Math.floor(Math.random() * 4) + 1
+ highlightItem(highlightType)
+ return highlightType
+ }
+
+ function startWelcomeAnimation() {
+ cameraAnimation.duration = 1000
+ cameraPos = welcomeEndPosition
+ idleTimer.restart()
+ }
+
+ Quick.Timer {
+ id: idleTimer
+ interval: 2000
+ onTriggered: {
+ cameraAnimation.duration = topViewAnimationDuration
+ lightPos = lightEndPosition
+ cameraPos = statusEndPosition
+ carRotationAnimation.restart()
+ }
+ }
+}
diff --git a/Cluster/qml/CenterView.qml b/Cluster/qml/CenterView.qml
new file mode 100644
index 0000000..0f4edda
--- /dev/null
+++ b/Cluster/qml/CenterView.qml
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import models 1.0
+import controls 1.0
+import utils 1.0
+
+Item {
+ anchors.fill: parent
+ property real defaultScale: 1.0
+ property var previousView: initialView
+
+ Image {
+ id: initialView
+ source: Style.symbol("john")
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 400
+ }
+
+ Item {
+ id: musicContainer
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 270
+ width: 354
+ height: 354
+ default property alias content: musiccontainer.children
+
+ Item {
+ id: musiccontainer
+ anchors.fill: parent
+ }
+ }
+
+ Item {
+ id: contactContainer
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 350
+ width: 136
+ height: 250
+ default property alias content: contactcontainer.children
+
+ Item {
+ id: contactcontainer
+ anchors.fill: parent
+ }
+ }
+
+ Item {
+ id: carinfoContainer
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 340
+ width: 265
+ height: 250
+ default property alias content: carinfocontainer.children
+
+ Item {
+ id: carinfocontainer
+ anchors.fill: parent
+ }
+ }
+
+ Item {
+ id: calendarContainer
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 340
+ width: 220
+ height: 250
+ default property alias content: calendarcontainer.children
+
+ Item {
+ id: calendarcontainer
+ anchors.fill: parent
+ }
+ }
+
+ Connections {
+ target: ApplicationManagerInterface
+ onClusterWidgetReady: {
+ handleWidgetChange(category, item)
+ }
+ onClusterWidgetActivated: {
+ handleWidgetChange(category, item)
+ }
+ }
+
+ PropertyAnimation {
+ id: shrinkCenter
+ property: "scale"
+ to: 0.0
+ running: false
+ duration: 500
+ onStopped: {
+ target.visible = false
+ }
+ }
+
+ function handleWidgetChange(category, item) {
+ var container
+ if (category === "media")
+ container = musicContainer
+ else if (category === "contacts")
+ container = contactContainer
+ else if (category === "carinfo")
+ container = carinfoContainer
+ else if (category === "calendar")
+ container = calendarContainer
+ if (previousView !== container) {
+ // TODO: Find out why these commented-out animations cause flashing on HW, and fix it
+ //container.scale = defaultScale
+ container.visible = true
+ previousView.visible = false
+ //shrinkCenter.target = previousView
+ previousView = container
+ //shrinkCenter.start()
+ item.parent = container
+ container.content = item
+ item.width = container.width
+ item.height = container.height
+ }
+ }
+}
diff --git a/Cluster/qml/Dashboard.qml b/Cluster/qml/Dashboard.qml
new file mode 100644
index 0000000..260f989
--- /dev/null
+++ b/Cluster/qml/Dashboard.qml
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+import service.valuesource 1.0
+import "gauges"
+
+Image
+{
+ id: dashboardEntity
+ // for static dashboard
+ source: "../images/Cluster8Gauges.png"
+ // for 2.5D lighting effect
+ //source: "../images/Cluster8GaugesPlain.png"
+ anchors.fill: parent
+
+ property bool parentVisible: parent.visible
+
+ property real timeScaleMultiplier: 1.0
+ property bool startupAnimationsFinished: false
+
+ property alias bottomPanelY: bottompanel.y
+ property alias needleRotation: tachometer.tachometerNeedleRotation
+
+ onNeedleRotationChanged: speedometer.speedometerNeedleRotation = needleRotation / 40.
+
+ //
+ // Fuelmeter
+ //
+ FuelMeter {}
+
+ //
+ // Batterymeter
+ //
+ BatteryMeter {}
+
+ //
+ // Consumptionmeter
+ //
+ ConsumptionMeter {}
+
+ //
+ // Temperaturemeter
+ //
+ TemperatureMeter {}
+
+ //
+ // Turbometer
+ //
+ TurboMeter {}
+
+ //
+ // Fpsmeter
+ //
+ FpsMeter {}
+
+ //
+ // Bottom Panel
+ //
+ BottomPanel {
+ id: bottompanel
+ y: 720
+ }
+
+ //
+ // Gauge center pieces
+ //
+ Image {
+ // for static dashboard
+ source: "../images/ClusterGaugeCenters.png"
+ // for 2.5D lighting effect
+ // source: "../images/ClusterGaugeCentersPlain.png"
+ anchors.fill: parent
+ }
+
+ // These two must be after center pieces, as they print text on top of the image
+
+ //
+ // Speedometer
+ //
+ SpeedoMeter {
+ id: speedometer
+ }
+
+ //
+ // Tachometer
+ //
+ TachoMeter {
+ id: tachometer
+ }
+
+ //
+ // 2.5D illusion for the 2.5D dashboard
+ //
+
+ // for speed-based effect
+ //property real speed: ValueSource.kph
+ //property int xlight: speed * 5
+ // for animated effect
+// property int xlight: -960
+// property int ylight: 0
+// property real angle: -10
+
+// ShaderEffect {
+// id: bumpShader
+// anchors.fill: parent
+// //property vector3d lightPos: Qt.vector3d(xlight, ylight, 0) // If using speed-based effect
+// property vector3d lightPos: Qt.vector3d(xlight, ylight, 0) // If using the animations below
+// property var source: ShaderEffectSource {
+// sourceItem: dashboardEntity
+// }
+// property var bump: Image {
+// source: "../images/Gauges_normal.png"
+// }
+// property real angle: dashboardEntity.angle * Math.PI / 180.0
+// fragmentShader:
+// "
+// uniform sampler2D source;
+// uniform sampler2D bump;
+// varying vec2 qt_TexCoord0;
+// uniform float qt_Opacity;
+// uniform vec3 lightPos;
+// uniform float angle;
+
+// highp vec3 dbModel(const highp vec3 norm)
+// {
+// // Transform position, normal, and tangent to eye coords
+// vec3 normal = vec3(0, 1, 0);
+// vec3 tangent = vec3(1, 0, -1);
+// vec3 position = vec3(960, -4000, 540);
+
+// // Calculate binormal vector
+// vec3 binormal = normalize(cross(normal, tangent));
+
+// // Construct matrix to transform from eye coords to tangent space
+// mat3 tangentMatrix = mat3 (
+// tangent.x, binormal.x, normal.x,
+// tangent.y, binormal.y, normal.y,
+// tangent.z, binormal.z, normal.z);
+
+// // Transform light direction and view direction to tangent space
+// vec3 s = lightPos - position;
+// vec3 lightDir = normalize(tangentMatrix * s);
+
+// vec3 v = -position;
+// vec3 viewDir = normalize(tangentMatrix * v);
+
+// float oldX = lightDir.x;
+// lightDir.x = (lightDir.x * cos(angle) - lightDir.z * sin(angle));
+// lightDir.z = (oldX * sin(angle) + lightDir.z * cos(angle));
+
+// vec3 ka = vec3(1.0, 1.0, 1.0);
+// vec3 ks = vec3(0.25, 0.25, 0.25);
+// float shininess = 50.0;
+
+// // Reflection of light direction about normal
+// vec3 r = reflect(-lightDir, norm);
+
+// vec3 diffuseColor = texture2D(source, qt_TexCoord0).rgb;
+
+// // Calculate the ambient contribution
+// vec3 ambient = ka * diffuseColor;
+
+// // Calculate the diffuse contribution
+// float sDotN = max(dot(lightDir, norm), 0.0);
+// vec3 diffuse = diffuseColor * sDotN;
+
+// // Calculate the specular highlight contribution
+// vec3 specular = vec3(0.0);
+// if (sDotN > 0.0)
+// specular = ks * pow(max(dot(r, viewDir), 0.0), shininess);
+
+// //return specular;
+// //return ambient;
+// //return ambient + diffuse;
+// return diffuse + specular;
+// //return ambient + specular;
+// //return ambient + diffuse + specular;
+// }
+
+// void main()
+// {
+// vec4 normal = 2.0 * texture2D(bump, qt_TexCoord0) - vec4(1.0);
+// vec3 result = dbModel(normalize(normal.xyz));
+// gl_FragColor = qt_Opacity * vec4(result, 1.0);
+// }
+// "
+// }
+
+// SequentialAnimation {
+// running: true
+// loops: Animation.Infinite
+// PropertyAnimation {
+// target: dashboardEntity
+// property: "xlight"
+// from: -960
+// to: 1920
+// duration: 15000
+// easing.type: Easing.InOutQuad
+// }
+// PropertyAnimation {
+// target: dashboardEntity
+// property: "xlight"
+// from: 1920
+// to: -960
+// duration: 15000
+// easing.type: Easing.InOutQuad
+// }
+// }
+
+ //
+ // Startup animations
+ //
+ SequentialAnimation {
+ id: speedometerStartupAnimations
+ running: false
+
+ SmoothedAnimation {
+ target: dashboardEntity
+ property: "bottomPanelY"
+ from: 720
+ to: 603
+ duration: 1000 * timeScaleMultiplier
+ easing.type: Easing.InCirc
+ }
+
+ SmoothedAnimation {
+ target: dashboardEntity
+ property: "needleRotation"
+ from: 0.0
+ to: -8000.0
+ duration: 1000 * timeScaleMultiplier
+ easing.type: Easing.InCubic
+ }
+
+ SmoothedAnimation {
+ target: dashboardEntity
+ property: "needleRotation"
+ from: -8000.0
+ to: 0.0
+ duration: 1000 * timeScaleMultiplier
+ easing.type: Easing.OutCubic
+ }
+
+ ScriptAction {
+ script: {
+ startupAnimationsFinished = true
+ ValueSource.startAnimations = true
+ }
+ }
+ }
+
+ // Just a hack for now; wait for the fader to finish
+ onParentVisibleChanged: {
+ if (visible)
+ initTimer.start()
+ }
+
+ Timer {
+ id: initTimer
+ running: false
+ interval: 1000
+ onTriggered: speedometerStartupAnimations.start()
+ }
+}
diff --git a/Cluster/qml/DashboardFrame.qml b/Cluster/qml/DashboardFrame.qml
new file mode 100644
index 0000000..24fc94c
--- /dev/null
+++ b/Cluster/qml/DashboardFrame.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import Qt3D.Core 2.0
+
+Item {
+ id: root
+ width: 1920
+ height: 1080//720
+ anchors.top: parent.top
+
+ property real faderOpacity: 1.0
+
+ Loader {
+ id: welcomeLoader
+ source: "DashboardView.qml"
+ width: root.width
+ height: 720//root.height
+ onLoaded: {
+ initialFade.start()
+ }
+ }
+
+ property bool welcomeReady: welcomeLoader.status === Loader.Ready && welcomeLoader.item.isReady
+
+ onWelcomeReadyChanged: {
+ faderAnimation.start()
+ }
+
+ Loader {
+ id: dashLoader
+ source: "DashboardView.qml"
+ visible: false
+ active: true
+ width: root.width
+ height: 720//root.height
+ }
+
+ Rectangle {
+ id: fader
+ color: "black"
+ anchors.fill: root
+ opacity: faderOpacity
+ }
+
+ PropertyAnimation {
+ id: initialFade
+ target: root
+ property: "faderOpacity"
+ from: 1.0
+ to: 0.0
+ duration: 1000
+ }
+
+ SequentialAnimation {
+ id: faderAnimation
+ running: false
+
+ PropertyAnimation {
+ target: root
+ property: "faderOpacity"
+ from: 0.0
+ to: 1.0
+ duration: 500
+ }
+ ScriptAction {
+ script: {
+ welcomeLoader.visible = false
+ dashLoader.visible = true
+ }
+ }
+ PropertyAnimation {
+ target: root
+ property: "faderOpacity"
+ from: 1.0
+ to: 0.0
+ duration: 500
+ }
+ }
+
+ // Note: Use if cluster is displayed on 1080p screen
+ Rectangle {
+ color: "black"
+ anchors.bottom: parent.bottom
+ height: 360
+ width: 1920
+
+ Image {
+ source: "../images/Built_with_Qt_RGB_logo_white.png"
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.margins: 30
+ }
+ }
+}
diff --git a/Cluster/qml/DashboardView.qml b/Cluster/qml/DashboardView.qml
new file mode 100644
index 0000000..ced2387
--- /dev/null
+++ b/Cluster/qml/DashboardView.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import utils 1.0
+
+Image
+{
+ id: dashboardEntity
+ source: "../images/BackgroundGradient.png"
+ width: 1920
+ height: 720
+
+ Dashboard {
+ id: dash
+ anchors.fill: parent
+ }
+
+ CenterView {
+ id: centerview
+ }
+
+ Component.onCompleted: Style.clusterWidgetReady = true
+}
diff --git a/Cluster/qml/FpsCounter.qml b/Cluster/qml/FpsCounter.qml
new file mode 100644
index 0000000..a98550e
--- /dev/null
+++ b/Cluster/qml/FpsCounter.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+
+Item {
+ id: fpscounter
+ property real fpsNow: 0
+ property bool running: false
+ property alias fpsVisible: fpsLabel.visible
+ property int fpsInterval: 1000
+ property alias color: fpsLabel.color
+
+ Item {
+ id: swapTest
+ property real t
+ NumberAnimation on t {
+ running: fpscounter.running
+ from: 0
+ to: 1
+ duration: fpsInterval
+ loops: Animation.Infinite
+ }
+ onTChanged: {
+ ++fpsTimer.tick
+ }
+ }
+
+ Timer {
+ id: fpsTimer
+ running: fpscounter.running
+ repeat: true
+ interval: fpsInterval
+ property var lastFrameTime: new Date()
+ property int tick
+
+ onTriggered: {
+ var now = new Date()
+ var dt = now.getTime() - lastFrameTime.getTime()
+ lastFrameTime = now
+ var fps = (tick * fpsInterval) / dt
+ fpsNow = Math.round(fps * 10) / 10
+ tick = 0
+
+ if (fpsVisible)
+ fpsLabel.updateYerself()
+ }
+ }
+
+ Text {
+ id: fpsLabel
+ visible: false
+
+ anchors.centerIn: parent
+ font.pixelSize: 10
+ color: "white"
+
+ function updateYerself() {
+ text = Math.round(fpsNow)
+ }
+ }
+}
diff --git a/Cluster/qml/TurnIndicator.qml b/Cluster/qml/TurnIndicator.qml
new file mode 100644
index 0000000..71bba6d
--- /dev/null
+++ b/Cluster/qml/TurnIndicator.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.6
+
+Item {
+ property int direction: Qt.NoArrow
+ property bool active: false
+ property bool flashing: false
+
+ width: 47
+ height: 52
+
+ Timer {
+ id: flashTimer
+ interval: 500
+ running: (direction !== Qt.NoArrow)
+ repeat: true
+ onTriggered: flashing = !flashing
+ }
+
+ Image {
+ id: turnIndicatorImage
+ source: "../images/Icon_TurnLeft_ON.png"
+ anchors.fill: parent
+ mirror: direction === Qt.RightArrow
+ visible: active && flashing
+ }
+
+ Image {
+ source: "../images/Icon_TurnLeft_OFF.png"
+ anchors.fill: parent
+ mirror: direction === Qt.RightArrow
+ visible: !turnIndicatorImage.visible
+ }
+}
diff --git a/Cluster/qml/WelcomeDriver.qml b/Cluster/qml/WelcomeDriver.qml
new file mode 100644
index 0000000..7a4d601
--- /dev/null
+++ b/Cluster/qml/WelcomeDriver.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import controls 1.0
+import utils 1.0
+
+Item {
+ anchors.fill: parent
+
+ property string welcomeText: "GOOD MORNING"
+
+ Column {
+ anchors.centerIn: parent
+ spacing: 10
+
+ Image {
+ id: driverImage
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: Style.symbol("john")
+ opacity: 0.0
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ }
+
+ Text {
+ id: driverText
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: welcomeText
+ font.bold: true
+ font.pixelSize: 20
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ opacity: 0.0
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ }
+
+ Text {
+ id: driverSecondRowText
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "John"
+ font.pixelSize: 30
+ color: "#EF2973"
+ horizontalAlignment: Text.AlignHCenter
+ opacity: 0.0
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ var currentDate = new Date()
+ var hours = currentDate.getHours()
+ if (hours > 0 && hours < 3)
+ welcomeText = "GOOD LATE EVENING"
+ else if (hours >= 3 && hours < 12)
+ welcomeText = "GOOD MORNING"
+ else if (hours >= 12 && hours < 18)
+ welcomeText = "GOOD AFTERNOON"
+ else if (hours >= 18 && hours < 24)
+ welcomeText = "GOOD EVENING"
+
+ driverText.opacity = 1.0
+ driverRecognition.start()
+ }
+
+ Timer {
+ id: driverRecognition
+ running: false
+ interval: 1000
+ onTriggered: {
+ driverImage.opacity = 1.0
+ driverSecondRowText.opacity = 1.0
+ }
+ }
+}
diff --git a/Cluster/qml/WelcomeInfoNote.qml b/Cluster/qml/WelcomeInfoNote.qml
new file mode 100644
index 0000000..0d63b9b
--- /dev/null
+++ b/Cluster/qml/WelcomeInfoNote.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+
+Column {
+ property alias firstline: tripInfoAmount.text
+ property alias firstlineunit: tripInfoUnit.text
+ property alias secondline: tripInfoText.text
+
+ spacing: 3
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 3
+
+ Text {
+ id: tripInfoAmount
+ text: "9:40"
+ font.pixelSize: 18
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Text {
+ id: tripInfoUnit
+ text: "km"
+ font.pixelSize: 12
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignTop
+ }
+ }
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ id: tripInfoText
+ text: "Start time"
+ font.pixelSize: 12
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ }
+}
diff --git a/Cluster/qml/WelcomeStatus.qml b/Cluster/qml/WelcomeStatus.qml
new file mode 100644
index 0000000..379387d
--- /dev/null
+++ b/Cluster/qml/WelcomeStatus.qml
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+
+Item {
+ anchors.fill: parent
+
+ Column {
+ anchors.centerIn: parent
+ spacing: 20
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Image {
+ id: statusImage
+ source: "../images/welcomeview_status_icon.png"
+ }
+
+ Text {
+ id: statusText
+ anchors.verticalCenter: statusImage.verticalCenter
+ text: "READY FOR THE ROAD"
+ font.pixelSize: 18
+ color: "white"
+ }
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 20
+
+ Rectangle {
+ id: line
+ height: 2
+ width: 205
+ color: "gray"
+ }
+
+ Text {
+ text: "Status"
+ font.pixelSize: 18
+ color: "white"
+ anchors.verticalCenter: line.verticalCenter
+ }
+
+ Rectangle {
+ height: 2
+ width: 205
+ color: "gray"
+ }
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 50
+
+ WelcomeInfoNote {
+ firstline: ValueSource.totalDistance.toString()
+ firstlineunit: "KM"
+ secondline: "Total\ndistance"
+ }
+
+ WelcomeInfoNote {
+ firstline: ValueSource.kmSinceCharge.toString()
+ firstlineunit: "KM"
+ secondline: "Since last\ncharge"
+ }
+
+ WelcomeInfoNote {
+ firstline: ValueSource.avRangePerCharge.toString()
+ firstlineunit: "KM"
+ secondline: "Average\nrange/charge"
+ }
+
+ WelcomeInfoNote {
+ firstline: ValueSource.energyPerKm.toString()
+ firstlineunit: "WH"
+ secondline: "energy/km"
+ }
+ }
+
+ Rectangle {
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: 2
+ width: 500
+ color: "gray"
+ }
+ }
+}
diff --git a/Cluster/qml/WelcomeStatusNote.qml b/Cluster/qml/WelcomeStatusNote.qml
new file mode 100644
index 0000000..042f89b
--- /dev/null
+++ b/Cluster/qml/WelcomeStatusNote.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+
+Item {
+ property string position: "right"
+ property alias text: statusNoteText.text
+ property string icon
+ property string highlight
+
+ Column {
+ spacing: 5
+
+ Row {
+ id: statusNoteRow
+ spacing: 5
+
+ Image {
+ id: statusNotePointerImage
+ height: 66
+ fillMode: Image.Pad
+ source: position === "left" ? icon : highlight
+ anchors.verticalCenter: statusNoteImage.verticalCenter
+ }
+
+ Rectangle {
+ id: statusNoteLineImage
+ height: 2
+ width: 100
+ color: "gray"
+ anchors.verticalCenter: statusNoteImage.verticalCenter
+ }
+
+ Image {
+ id: statusNoteImage
+ height: 66
+ fillMode: Image.Pad
+ source: position === "right" ? icon : highlight
+ }
+ }
+
+ Text {
+ id: statusNoteText
+ anchors.right: position === "right" ? statusNoteRow.right : undefined
+ anchors.left: position === "left" ? statusNoteRow.left : undefined
+ style: Text.RichText
+ font.pixelSize: 14
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+}
diff --git a/Cluster/qml/WelcomeTripSummary.qml b/Cluster/qml/WelcomeTripSummary.qml
new file mode 100644
index 0000000..b9bb647
--- /dev/null
+++ b/Cluster/qml/WelcomeTripSummary.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+
+Item {
+ anchors.fill: parent
+
+ Column {
+ anchors.centerIn: parent
+ spacing: 20
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Image {
+ id: tripSummaryImage
+ source: "../images/welcomeview_trip_info_icon.png"
+ }
+
+ Text {
+ id: tripSummaryText
+ anchors.verticalCenter: tripSummaryImage.verticalCenter
+ text: "TRIP SUMMARY"
+ font.pixelSize: 18
+ color: "white"
+ }
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 50
+
+ WelcomeInfoNote {
+ firstline: "9:40"
+ secondline: "Start time"
+ }
+
+ WelcomeInfoNote {
+ firstline: "0:38"
+ secondline: "Duration"
+ }
+
+ WelcomeInfoNote {
+ firstline: "58"
+ firstlineunit: "KM"
+ secondline: "Distance"
+ }
+ }
+
+ Rectangle {
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: 2
+ width: 400
+ color: "gray"
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 50
+
+ WelcomeInfoNote {
+ firstline: "324"
+ firstlineunit: "WH"
+ secondline: "Average\nenergy/km"
+ }
+
+ WelcomeInfoNote {
+ firstline: "18.7"
+ firstlineunit: "KWH"
+ secondline: "Total energy"
+ }
+
+ WelcomeInfoNote {
+ firstline: "60"
+ firstlineunit: "KMH"
+ secondline: "Average\nspeed"
+ }
+ }
+
+ Image {
+ // TODO: Image from route?
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: "../images/welcomeview_trip_route.png"
+ }
+ }
+}
diff --git a/Cluster/qml/WelcomeView.qml b/Cluster/qml/WelcomeView.qml
new file mode 100644
index 0000000..c1ade20
--- /dev/null
+++ b/Cluster/qml/WelcomeView.qml
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtQuick.Scene3D 2.0
+
+Image
+{
+ id: welcomeView
+ source: "../images/BackgroundGradient.png"
+ width: 1920
+ height: 720
+
+ property alias hidden: carModel.hidden
+ property bool isReady: false
+
+ Scene3D {
+ id: welcomeScene
+ width: welcomeView.width / 2
+ height: welcomeView.height
+ multisample: true
+
+ CarModel {
+ id: carModel
+ width: welcomeView.width
+ height: welcomeView.height
+ }
+ }
+
+ Rectangle {
+ id: infoPane
+ anchors.top: welcomeView.top
+ anchors.bottom: welcomeView.bottom
+ anchors.right: welcomeView.right
+ anchors.left: welcomeScene.right
+ color: "transparent"
+
+ Loader {
+ id: infoPaneLoader
+ anchors.fill: parent
+ source: "WelcomeDriver.qml"
+ active: true
+ }
+ }
+
+ Image {
+ id: passengerDriver
+ source: "../images/welcomeview_passenger_icon.png"
+ opacity: 0.0
+ scale: 2.0
+ x: 410
+ y: 330
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ Behavior on scale {
+ PropertyAnimation {
+ duration: 1000
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+
+ Image {
+ id: passengerShotgun
+ source: "../images/welcomeview_passenger_icon.png"
+ opacity: 0.0
+ scale: 2.0
+ x: 500
+ y: 330
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ Behavior on scale {
+ PropertyAnimation {
+ duration: 1000
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+
+ Image {
+ id: passengerRearLeft
+ source: "../images/welcomeview_passenger_icon.png"
+ opacity: 0.0
+ scale: 2.0
+ x: 415
+ y: 430
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ Behavior on scale {
+ PropertyAnimation {
+ duration: 1000
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+
+ Image {
+ id: passengerRearRight
+ source: "../images/welcomeview_passenger_icon.png"
+ opacity: 0.0
+ scale: 2.0
+ x: 495
+ y: 430
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ Behavior on scale {
+ PropertyAnimation {
+ duration: 1000
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+
+ WelcomeStatusNote {
+ id: washerFluidNote
+ text: "<center><font color=\"#FFFFFF\">Washer fluid<br>Low <font color=\"#EF2973\">10%"
+ icon: "../images/status_washer_fluid_icon.png"
+ highlight: "../images/status_washer_fluid_highlight.png"
+ position: "right"
+ opacity: 0.0
+ x: 535
+ y: 200
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ }
+
+ WelcomeStatusNote {
+ id: batteryLowNote
+ text: "<center><font color=\"#FFFFFF\">Battery low<br>Range <font color=\"#EF2973\">35KM"
+ icon: "../images/status_battery_icon.png"
+ highlight: "../images/status_battery_highlight.png"
+ position: "left"
+ opacity: 0.0
+ x: 205
+ y: 497
+ Behavior on opacity {
+ PropertyAnimation { duration: 1000 }
+ }
+ }
+
+ // Functions to control highlights from dashboard
+ function highlightLamp() {
+ var type = carModel.highlightLamp()
+ carModel.toggleIdleTimer(true)
+ resetModelTimer.restart()
+ return type
+ }
+
+ function highlightDoors(doors) {
+ doorAction = true
+ carModel.doorAction = true
+ carModel.highlightOpenDoors(doors)
+ carModel.toggleIdleTimer(true)
+ resetModelTimer.restart()
+ }
+
+ function highlightTire() {
+ var type = carModel.highlightTire()
+ carModel.toggleIdleTimer(true)
+ resetModelTimer.restart()
+ return type
+ }
+
+ Timer {
+ running: true
+ interval: 6000
+ onTriggered: {
+ infoPaneLoader.source = "WelcomeTripSummary.qml"
+ statusCheckTimer.start()
+ passengerDriver.opacity = 1.0
+ passengerRearRight.opacity = 1.0
+ passengerDriver.scale = 1.0
+ passengerRearRight.scale = 1.0
+ washerFluidNote.opacity = 1.0
+ batteryLowNote.opacity = 1.0
+ }
+ }
+
+ Timer {
+ id: statusCheckTimer
+ running: false
+ interval: 5000
+ onTriggered: {
+ infoPaneLoader.source = "WelcomeStatus.qml"
+ batteryLowNote.opacity = 0.0
+ readyTimer.start()
+ }
+ }
+
+ Component.onCompleted: {
+ carModel.startWelcomeAnimation()
+ }
+
+ Timer {
+ id: readyTimer
+ running: false
+ interval: 5000
+ onTriggered: {
+ isReady = true
+ }
+ }
+}
diff --git a/Cluster/qml/gauges/BatteryMeter.qml b/Cluster/qml/gauges/BatteryMeter.qml
new file mode 100644
index 0000000..d6380a9
--- /dev/null
+++ b/Cluster/qml/gauges/BatteryMeter.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+
+Item {
+ property real batterymeterNeedleRotation: -batteryValue * batteryDegreesPerValue
+ property real batteryValue: ValueSource.batteryLevel
+ property real maxValueAngle: 317
+ property real minValueAngle: 225
+ property real maximumValue: 100
+ property real batteryDegreesPerValue: Math.abs((maxValueAngle - minValueAngle) / maximumValue)
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.rightMargin: 654
+ anchors.topMargin: 140
+ width: 162
+ height: 10
+ rotation: batterymeterNeedleRotation - 135
+
+ Image {
+ width: 54
+ height: 5
+ //opacity: 0.75
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+}
diff --git a/Cluster/qml/gauges/ConsumptionMeter.qml b/Cluster/qml/gauges/ConsumptionMeter.qml
new file mode 100644
index 0000000..f2cbf39
--- /dev/null
+++ b/Cluster/qml/gauges/ConsumptionMeter.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.7
+import service.valuesource 1.0
+import com.qtcompany.clustergaugefiller 1.0
+
+Item {
+ property real consumptionValue: 2.0 + ValueSource.rpm / 444.45
+ property real minValueAngle: 378
+ property real maxValueAngle: 291
+ property real minimumValue: 0
+ property real maximumValue: 20
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: 365
+ anchors.rightMargin: 413
+
+ GaugeFiller {
+ id: consumptionFiller
+ value: consumptionValue
+ anchors.fill: parent
+ numVertices: 64
+ radius: 233
+ fillWidth: 30
+ color: "#EF2973"
+ opacity: 0.3
+ minAngle: minValueAngle
+ maxAngle: maxValueAngle
+ minValue: minimumValue
+ maxValue: maximumValue
+ }
+
+ Item {
+ width: 465
+ height: 10
+ rotation: consumptionFiller.angle - 72
+ anchors.centerIn: parent
+
+ Image {
+ width: 144
+ height: 5
+ //opacity: 0.75
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+ }
+}
diff --git a/Cluster/qml/gauges/FpsMeter.qml b/Cluster/qml/gauges/FpsMeter.qml
new file mode 100644
index 0000000..b56739f
--- /dev/null
+++ b/Cluster/qml/gauges/FpsMeter.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+import ".."
+
+Item {
+ id: fpsmeterNeedle
+
+ property real fpsmeterNeedleRotation: fpsValue * fpsDegreesPerValue
+ property real fpsValue: Math.min(fpscounter.fpsNow, 60) // Limit to 60, as that's where the gauge ends
+ property real maxValueAngle: 314
+ property real minValueAngle: 45
+ property real maximumValue: 60
+ property real fpsDegreesPerValue: Math.abs((maxValueAngle - minValueAngle) / maximumValue)
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.rightMargin: 887
+ anchors.topMargin: 125
+ width: 161
+ height: 10
+ rotation: fpsmeterNeedleRotation - 45
+
+ Image {
+ width: 56
+ height: 5
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+
+ FpsCounter {
+ id: fpscounter
+ rotation: fpsVisible ? -fpsmeterNeedle.rotation : 0
+ anchors.top: parent.top
+ anchors.topMargin: 50
+ anchors.horizontalCenter: parent.horizontalCenter
+ fpsVisible: false // Setting this to true prints fps on screen
+ running: startupAnimationsFinished
+ }
+ Behavior on fpsValue {
+ enabled: startupAnimationsFinished
+ PropertyAnimation { duration: fpscounter.fpsInterval }
+ }
+}
diff --git a/Cluster/qml/gauges/FuelMeter.qml b/Cluster/qml/gauges/FuelMeter.qml
new file mode 100644
index 0000000..3393e4f
--- /dev/null
+++ b/Cluster/qml/gauges/FuelMeter.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+
+Item {
+ property real fuelmeterNeedleRotation: fuelValue * fuelDegreesPerValue
+ property real fuelValue: ValueSource.fuelLevel
+ property real maxValueAngle: 170
+ property real minValueAngle: 10
+ property real maximumValue: 100
+ property real fuelDegreesPerValue: Math.abs((maxValueAngle - minValueAngle) / maximumValue)
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.rightMargin: 654
+ anchors.topMargin: 140
+ width: 158
+ height: 10
+ rotation: fuelmeterNeedleRotation - 80
+
+ Image {
+ width: 56
+ height: 5
+ //opacity: 0.75
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+}
diff --git a/Cluster/qml/gauges/SpeedoMeter.qml b/Cluster/qml/gauges/SpeedoMeter.qml
new file mode 100644
index 0000000..67d43de
--- /dev/null
+++ b/Cluster/qml/gauges/SpeedoMeter.qml
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+import com.qtcompany.clustergaugefiller 1.0
+
+Item {
+ anchors.fill: parent
+
+ property real speedometerNeedleRotation: 0.0
+ property string speed: actualSpeed.toFixed().toString()
+ property real actualSpeed: startupAnimationsFinished
+ ? ValueSource.kph : -speedometerNeedleRotation
+ property real maxValueAngle: 305
+ property real minValueAngle: 55
+ property real minimumSpeed: 0
+ property real maximumSpeed: 200
+
+ Item {
+ anchors.left: parent.left
+ anchors.leftMargin: 30
+ width: 720
+ height: 720
+
+ GaugeFiller {
+ id: speedFiller
+ value: actualSpeed
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.topMargin: 366
+ anchors.leftMargin: 382
+ radius: 232
+ fillWidth: 8
+ color: "#EF2973"
+ opacity: 0.6
+ maxAngle: maxValueAngle
+ minAngle: minValueAngle
+ minValue: minimumSpeed
+ maxValue: maximumSpeed
+ }
+ }
+
+ Item {
+ id: speedometerNeedle
+ width: 464
+ height: 10
+ rotation: speedFiller.angle - 35
+ x: 180
+ y: 361
+
+ Image {
+ opacity: 0.75
+ width: 146
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+ }
+
+ Row {
+ anchors.top: speedometerNeedle.bottom
+ anchors.topMargin: 120
+ anchors.horizontalCenter: speedometerNeedle.horizontalCenter
+ spacing: 10
+
+ Text {
+ font.pixelSize: 24
+ color:(ValueSource.gear === 0 && ValueSource.parkingBrake) ? "white" : "gray"
+ text: "P"
+ }
+
+ Text {
+ font.pixelSize: 24
+ //font.bold: ValueSource.gear === -1
+ color: ValueSource.gear === -1 ? "white" : "gray"
+ text: "R"
+ }
+
+ Text {
+ font.pixelSize: 24
+ //font.bold: ValueSource.gear === 0
+ color: (ValueSource.gear === 0 && !ValueSource.parkingBrake) ? "white" : "gray"
+ text: "N"
+ }
+
+ Text {
+ font.pixelSize: 24
+ //font.bold: ValueSource.gear === 1
+ color: ValueSource.gear === 1 ? "white" : "gray"
+ text: "D"
+ }
+ }
+
+ Text {
+ id: speedText
+ anchors.top: speedometerNeedle.top
+ anchors.topMargin: -40
+ anchors.horizontalCenter: speedometerNeedle.horizontalCenter
+ font.pixelSize: 60
+ color: "lightGray"
+ text: speed
+ }
+
+ Text {
+ id: speedUnitText
+ anchors.top: speedText.bottom
+ anchors.horizontalCenter: speedometerNeedle.horizontalCenter
+ font.pixelSize: 24
+ color: "lightGray"
+ text: "KM/H"
+ }
+}
diff --git a/Cluster/qml/gauges/TachoMeter.qml b/Cluster/qml/gauges/TachoMeter.qml
new file mode 100644
index 0000000..3fbd2c1
--- /dev/null
+++ b/Cluster/qml/gauges/TachoMeter.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+import com.qtcompany.clustergaugefiller 1.0
+
+Item {
+ anchors.fill: parent
+
+ property real tachometerNeedleRotation: 0.0
+ property string rpm: actualRPM.toFixed().toString()
+ property real actualRPM: startupAnimationsFinished
+ ? ValueSource.rpm : -tachometerNeedleRotation
+ property real minValueAngle: 55
+ property real maxValueAngle: 255
+ property real minimumRPM: 0
+ property real maximumRPM: 8000
+
+ Item {
+ anchors.right: parent.right
+ anchors.rightMargin: 30
+ width: 720
+ height: 720
+
+ GaugeFiller {
+ id: rpmFiller
+ value: actualRPM
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: 369
+ anchors.rightMargin: 380
+ radius: 232
+ fillWidth: 8
+ color: "#EF2973"
+ opacity: 0.6
+ minAngle: minValueAngle
+ maxAngle: maxValueAngle
+ minValue: minimumRPM
+ maxValue: maximumRPM
+ }
+ }
+
+ Item {
+ id: tachometerNeedle
+ width: 468
+ height: 10
+ rotation: rpmFiller.angle - 35
+ x: 1275
+ y: 363
+
+ Image {
+ opacity: 0.75
+ width: 147
+ anchors.left: parent.left
+ anchors.leftMargin: 2
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+ }
+
+ Text {
+ id: textEco
+ anchors.top: tachometerNeedle.top
+ anchors.topMargin: -10
+ anchors.horizontalCenter: tachometerNeedle.horizontalCenter
+ text: actualRPM > 4000 ? "POWER" : "ECO"
+ font.pixelSize: 24
+ color: actualRPM <= 4000 ? "white" : "red"
+ }
+}
diff --git a/Cluster/qml/gauges/TemperatureMeter.qml b/Cluster/qml/gauges/TemperatureMeter.qml
new file mode 100644
index 0000000..67c2a8a
--- /dev/null
+++ b/Cluster/qml/gauges/TemperatureMeter.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+import com.qtcompany.clustergaugefiller 1.0
+
+Item {
+ property real temperatureValue: ValueSource.engineTemperature
+ property real minValueAngle: 42.5
+ property real maxValueAngle: -42.5
+ property real minimumValue: 40
+ property real maximumValue: 120
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.rightMargin: 965
+ anchors.topMargin: 90
+
+ GaugeFiller {
+ id: temperatureFiller
+ value: temperatureValue
+ anchors.fill: parent
+ numVertices: 64
+ radius: 210
+ fillWidth: 38
+ color: "#EF2973"
+ opacity: 0.3
+ minAngle: minValueAngle
+ maxAngle: maxValueAngle
+ minValue: minimumValue
+ maxValue: maximumValue
+ }
+
+ Item {
+ width: 420
+ height: 10
+ rotation: temperatureFiller.angle - 47.5
+ anchors.centerIn: parent
+
+ Image {
+ width: 38
+ height: 5
+ //opacity: 0.75
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+ }
+}
diff --git a/Cluster/qml/gauges/TurboMeter.qml b/Cluster/qml/gauges/TurboMeter.qml
new file mode 100644
index 0000000..c1a37cc
--- /dev/null
+++ b/Cluster/qml/gauges/TurboMeter.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt multiscreen demo application.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import service.valuesource 1.0
+
+Item {
+ property real turbometerNeedleRotation: turboValue * turboDegreesPerValue
+ property real turboValue: ValueSource.rpm / 2000.
+ property real maxValueAngle: 270
+ property real minValueAngle: 0
+ property real maximumValue: 4.0
+ property real turboDegreesPerValue: Math.abs((maxValueAngle - minValueAngle) / maximumValue)
+
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.leftMargin: 639
+ anchors.topMargin: 140
+ width: 164
+ height: 10
+ rotation: turbometerNeedleRotation - 90
+
+ Image {
+ width: 57
+ height: 5
+ //opacity: 0.75
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../images/SpeedometerNeedle.png"
+ }
+}
diff --git a/Cluster/qml/models/Map11.jpg b/Cluster/qml/models/Map11.jpg
new file mode 100644
index 0000000..5b81424
--- /dev/null
+++ b/Cluster/qml/models/Map11.jpg
Binary files differ
diff --git a/Cluster/qml/models/sportscar.qgltf b/Cluster/qml/models/sportscar.qgltf
new file mode 100644
index 0000000..7b30a0d
--- /dev/null
+++ b/Cluster/qml/models/sportscar.qgltf
Binary files differ
diff --git a/Cluster/qml/models/sportscar_1.bin b/Cluster/qml/models/sportscar_1.bin
new file mode 100644
index 0000000..bf5f16d
--- /dev/null
+++ b/Cluster/qml/models/sportscar_1.bin
Binary files differ
diff --git a/Cluster/qtcluster.qrc b/Cluster/qtcluster.qrc
new file mode 100644
index 0000000..cc1c63b
--- /dev/null
+++ b/Cluster/qtcluster.qrc
@@ -0,0 +1,13 @@
+<RCC>
+ <qresource prefix="/">
+ <file>../demo-assets/fonts/Lato-Bold.ttf</file>
+ <file>../demo-assets/fonts/Lato-Regular.ttf</file>
+ <file>../demo-assets/fonts/Lato-Semibold.ttf</file>
+ <file>qml/FpsCounter.qml</file>
+ <file>qml/Dashboard.qml</file>
+ <file>qml/DashboardFrame.qml</file>
+ <file>qml/DashboardView.qml</file>
+ <file>qml/CarModel.qml</file>
+ <file>qml/WelcomeView.qml</file>
+ </qresource>
+</RCC>
diff --git a/Cluster/sportscar.qrc b/Cluster/sportscar.qrc
new file mode 100644
index 0000000..feb6358
--- /dev/null
+++ b/Cluster/sportscar.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="Map11.jpg">qml/models/Map11.jpg</file>
+ <file alias="sportscar.qgltf">qml/models/sportscar.qgltf</file>
+ <file alias="sportscar_1.bin">qml/models/sportscar_1.bin</file>
+ </qresource>
+</RCC>
diff --git a/Cluster/sportscar_15k.qrc b/Cluster/sportscar_15k.qrc
new file mode 100644
index 0000000..c0a1df9
--- /dev/null
+++ b/Cluster/sportscar_15k.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="Map11.jpg">qml/models/Map11.jpg</file>
+ <file alias="sportscar.qgltf">qml/models/sportscar_15k.qgltf</file>
+ <file alias="sportscar_15k_1.bin">qml/models/sportscar_15k_1.bin</file>
+ </qresource>
+</RCC>
diff --git a/Cluster/sportsimages.qrc b/Cluster/sportsimages.qrc
new file mode 100644
index 0000000..641ae9b
--- /dev/null
+++ b/Cluster/sportsimages.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/MapLocationSport.png</file>
+ </qresource>
+</RCC>
diff --git a/Cluster/sportsqml.qrc b/Cluster/sportsqml.qrc
new file mode 100644
index 0000000..020b33a
--- /dev/null
+++ b/Cluster/sportsqml.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/Dashboard.qml</file>
+ <file>qml/DashboardFrame.qml</file>
+ <file>qml/CarModel.qml</file>
+ <file>qml/DashboardView.qml</file>
+ </qresource>
+</RCC>