Finish implementing new C++ dashboard model

This commit is contained in:
Alex Spataru 2021-09-25 01:26:05 -05:00
parent a5bee32c74
commit 230e8809f0
21 changed files with 817 additions and 120 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><g><path d="M3,7h2v7H3V7z M0,10h2v7H0V10z M22,7h2v7h-2V7z M19,10h2v7h-2V10z M16,2.01L8,2C6.9,2,6,2.9,6,4v16c0,1.1,0.9,2,2,2h8 c1.1,0,2-0.9,2-2V4C18,2.9,17.1,2.01,16,2.01z M16,20H8v-1h8V20z M16,17H8V7h8V17z M8,5V4h8v1H8z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 421 B

1
assets/icons/bar.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M5 9.2h3V19H5V9.2zM10.6 5h2.8v14h-2.8V5zm5.6 8H19v6h-2.8v-6z"/></svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z"/></svg>

Before

Width:  |  Height:  |  Size: 189 B

View File

Before

Width:  |  Height:  |  Size: 214 B

After

Width:  |  Height:  |  Size: 214 B

View File

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 230 B

View File

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 364 B

1
assets/icons/map.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z"/></svg>

After

Width:  |  Height:  |  Size: 414 B

1
assets/icons/plot.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><g><path d="M14.06,9.94L12,9l2.06-0.94L15,6l0.94,2.06L18,9l-2.06,0.94L15,12L14.06,9.94z M4,14l0.94-2.06L7,11l-2.06-0.94L4,8 l-0.94,2.06L1,11l2.06,0.94L4,14z M8.5,9l1.09-2.41L12,5.5L9.59,4.41L8.5,2L7.41,4.41L5,5.5l2.41,1.09L8.5,9z M4.5,20.5l6-6.01l4,4 L23,8.93l-1.41-1.41l-7.09,7.97l-4-4L3,19L4.5,20.5z"/></g></svg>

After

Width:  |  Height:  |  Size: 492 B

View File

@ -1,18 +1,20 @@
<RCC>
<qresource prefix="/icons">
<file>ac-power.svg</file>
<file>accelerometer.svg</file>
<file>add.svg</file>
<file>apply.svg</file>
<file>arrow-right.svg</file>
<file>backspace.svg</file>
<file>bar.svg</file>
<file>battery.svg</file>
<file>bug.svg</file>
<file>chart.svg</file>
<file>close.svg</file>
<file>code.svg</file>
<file>compass.svg</file>
<file>connect.svg</file>
<file>copy.svg</file>
<file>dashboard.svg</file>
<file>dataset.svg</file>
<file>delete-item.svg</file>
<file>delete.svg</file>
@ -22,32 +24,34 @@
<file>down.svg</file>
<file>drag-drop.svg</file>
<file>end-sequence.svg</file>
<file>equalizer.svg</file>
<file>error.svg</file>
<file>ethernet.svg</file>
<file>expand.svg</file>
<file>fullscreen-exit.svg</file>
<file>fullscreen.svg</file>
<file>gauge.svg</file>
<file>graphs.svg</file>
<file>group.svg</file>
<file>gyro.svg</file>
<file>help.svg</file>
<file>info.svg</file>
<file>json.svg</file>
<file>link.svg</file>
<file>location-off.svg</file>
<file>location-on.svg</file>
<file>map.svg</file>
<file>media-next.svg</file>
<file>media-pause.svg</file>
<file>media-play.svg</file>
<file>media-prev.svg</file>
<file>new.svg</file>
<file>open.svg</file>
<file>plot.svg</file>
<file>power.svg</file>
<file>ram.svg</file>
<file>refresh.svg</file>
<file>registration.svg</file>
<file>right.svg</file>
<file>save.svg</file>
<file>scatter-plot.svg</file>
<file>schedule.svg</file>
<file>scroll-bottom.svg</file>
<file>scroll-down.svg</file>
@ -58,14 +62,12 @@
<file>separator.svg</file>
<file>settings.svg</file>
<file>start-sequence.svg</file>
<file>tab.svg</file>
<file>terminal.svg</file>
<file>up.svg</file>
<file>update.svg</file>
<file>usb.svg</file>
<file>visibility.svg</file>
<file>warning.svg</file>
<file>widget.svg</file>
<file>expand.svg</file>
<file>thermometer.svg</file>
</qresource>
</RCC>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M11.59 7.41L15.17 11H1v2h14.17l-3.59 3.59L13 18l6-6-6-6-1.41 1.41zM20 6v12h2V6h-2z"/></svg>

Before

Width:  |  Height:  |  Size: 220 B

View File

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 31.586 31.586" style="enable-background:new 0 0 31.586 31.586;" xml:space="preserve">
<g>
<path d="M29.328,2.255H2.256C1.01,2.255,0,3.264,0,4.51v22.564c0,1.245,1.01,2.256,2.256,2.256h27.072
c1.244,0,2.258-1.012,2.258-2.256V4.51C31.586,3.264,30.572,2.255,29.328,2.255z M7.333,3.949c0.622,0,1.128,0.502,1.128,1.128
c0,0.623-0.506,1.125-1.128,1.125c-0.626,0-1.131-0.502-1.131-1.125C6.202,4.451,6.707,3.949,7.333,3.949z M3.947,3.949
c0.623,0,1.127,0.502,1.127,1.128c0,0.623-0.504,1.125-1.127,1.125c-0.624,0-1.129-0.502-1.129-1.125
C2.818,4.451,3.323,3.949,3.947,3.949z M29.328,27.075H2.256V7.92h27.072C29.328,7.92,29.328,27.075,29.328,27.075z"/>
<polygon points="12.645,12.556 5.4,9.243 5.4,10.84 11.003,13.235 11.003,13.266 5.4,15.66 5.4,17.256 12.645,13.943 "/>
<rect x="16.056" y="12.488" width="3.946" height="1.522"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15 13V5c0-1.66-1.34-3-3-3S9 3.34 9 5v8c-1.21.91-2 2.37-2 4 0 2.76 2.24 5 5 5s5-2.24 5-5c0-1.63-.79-3.09-2-4zm-4-8c0-.55.45-1 1-1s1 .45 1 1h-1v1h1v2h-1v1h1v2h-2V5z"/></svg>

After

Width:  |  Height:  |  Size: 322 B

View File

@ -413,6 +413,7 @@ ApplicationWindow {
SwipeView {
id: swipe
clip: true
interactive: false
Layout.fillWidth: true
Layout.fillHeight: true

View File

@ -22,7 +22,7 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12 as QtWindow
import QtQuick.Controls 2.12
import "../Widgets" as Widgets
@ -33,4 +33,57 @@ Item {
// Animations
//
Behavior on opacity {NumberAnimation{}}
//
// Main layout
//
ColumnLayout {
x: 2 * app.spacing
anchors.fill: parent
spacing: app.spacing * 2
anchors.margins: app.spacing * 1.5
//
// Widget selector + widgets
//
RowLayout {
spacing: app.spacing
Layout.fillWidth: true
Layout.fillHeight: true
//
// View options window + shadow
//
Item {
Layout.fillHeight: true
Layout.minimumWidth: 240
ViewOptions {
id: viewOptions
anchors.fill: parent
}
Widgets.Shadow {
source: viewOptions
}
}
//
// Widget grid
//
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumWidth: 240
}
}
//
// Dashboard title window
//
DashboardTitle {
height: 32
Layout.fillWidth: true
}
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.0
import "../Widgets" as Widgets
Item {
id: root
Rectangle {
id: window
radius: 5
anchors.fill: parent
gradient: Gradient {
GradientStop {
position: 0
color: Cpp_ThemeManager.windowGradient1
}
GradientStop {
position: 1
color: Cpp_ThemeManager.windowGradient2
}
}
RowLayout {
spacing: app.spacing
anchors {
left: parent.left
leftMargin: app.spacing
verticalCenter: parent.verticalCenter
}
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(24, 24)
source: "qrc:/icons/arrow-right.svg"
Layout.alignment: Qt.AlignVCenter
ColorOverlay {
source: parent
anchors.fill: parent
color: palette.brightText
}
}
Label {
font.bold: true
font.pixelSize: 16
color: palette.brightText
font.family: app.monoFont
text: Cpp_UI_Dashboard.title
}
}
Label {
font.family: app.monoFont
color: palette.brightText
visible: !Cpp_CSV_Player.isOpen
text: Cpp_IO_Manager.receivedDataLength //*! Optimize this function
anchors {
right: parent.right
rightMargin: app.spacing
verticalCenter: parent.verticalCenter
}
}
}
Widgets.Shadow {
source: window
}
}

View File

@ -163,7 +163,7 @@ Control {
onClicked: root.dashboardClicked()
enabled: Cpp_UI_Dashboard.available
text: qsTr("Dashboard") + _btSpacer
icon.source: "qrc:/icons/equalizer.svg"
icon.source: "qrc:/icons/dashboard.svg"
icon.color: Cpp_ThemeManager.brightText
palette.buttonText: Cpp_ThemeManager.brightText
palette.button: Cpp_ThemeManager.toolbarGradient1

View File

@ -0,0 +1,445 @@
/*
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.0
import "../Widgets" as Widgets
Widgets.Window {
id: root
//
// Window properties
//
gradient: true
title: qsTr("View")
headerDoubleClickEnabled: false
icon.source: "qrc:/icons/visibility.svg"
backgroundColor: Cpp_ThemeManager.embeddedWindowBackground
//
// Put all items inside a scrollview
//
ScrollView {
clip: true
contentWidth: -1
anchors.fill: parent
anchors.margins: app.spacing
anchors.topMargin: root.borderWidth
anchors.bottomMargin: root.borderWidth
//
// Main layout
//
ColumnLayout {
x: app.spacing
width: parent.width - 10 - 2 * app.spacing
Item {
height: app.spacing
}
//
// Groups
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.groupCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/group.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Groups") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.groupCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.groupTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setGroupVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Plots
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.plotCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/plot.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Plots") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.plotCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.plotTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setPlotVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Bars
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.barCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/bar.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Bars") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.barCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.barTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setBarVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Gauges
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.gaugeCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/gauge.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Gauges") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.gaugeCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.gaugeTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setGaugeVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Thermometers
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.thermometerCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/thermometer.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Thermometers") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.thermometerCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.thermometerTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setThermometerVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Compasses
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.compassCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/compass.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Compasses") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.compassCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.compassTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setCompassVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Gyroscopes
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.gyroscopeCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/gyro.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Gyroscopes") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.compassCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.gyroscopeTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setGyroscopeVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Accelerometers
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.accelerometerCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/accelerometer.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Accelerometers") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.accelerometerCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.accelerometerTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setAccelerometerVisible(index, checked)
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Maps
//
RowLayout {
spacing: app.spacing
visible: Cpp_UI_Dashboard.mapCount > 0
Image {
width: sourceSize.width
height: sourceSize.height
sourceSize: Qt.size(18, 18)
source: "qrc:/icons/map.svg"
ColorOverlay {
source: parent
color: palette.text
anchors.fill: parent
}
} Label {
font.bold: true
text: qsTr("Maps") + ":"
} Item {
Layout.fillWidth: true
}
} Item {
height: app.spacing / 2
} Repeater {
model: Cpp_UI_Dashboard.mapCount
delegate: Switch {
checked: true
Layout.fillWidth: true
text: Cpp_UI_Dashboard.mapTitles()[index]
palette.highlight: Cpp_ThemeManager.alternativeHighlight
onCheckedChanged: Cpp_UI_Dashboard.setMapVisible(index, checked)
}
}
}
}
}

View File

@ -26,5 +26,7 @@
<file>JsonEditor/JsonGroupDelegate.qml</file>
<file>Widgets/Shadow.qml</file>
<file>JSONDropArea.qml</file>
<file>Windows/ViewOptions.qml</file>
<file>Windows/DashboardTitle.qml</file>
</qresource>
</RCC>

View File

@ -175,8 +175,12 @@ void Bridge::acceptConnection()
// Close connection if system is not enabled
if (!enabled())
{
socket->close();
socket->deleteLater();
if (socket)
{
socket->close();
socket->deleteLater();
}
return;
}

View File

@ -35,6 +35,10 @@ using namespace UI;
*/
static Dashboard *INSTANCE = nullptr;
//--------------------------------------------------------------------------------------------------
// Constructor/deconstructor & singleton
//--------------------------------------------------------------------------------------------------
/**
* Constructor of the class
*/
@ -63,9 +67,10 @@ Dashboard *Dashboard::getInstance()
return INSTANCE;
}
/**
* @return The title of the current frame
*/
//--------------------------------------------------------------------------------------------------
// Misc member access functions
//--------------------------------------------------------------------------------------------------
QString Dashboard::title()
{
return m_latestFrame.title();
@ -76,6 +81,15 @@ bool Dashboard::available()
return groupCount() > 0;
}
bool Dashboard::frameValid() const
{
return m_latestFrame.isValid();
}
//--------------------------------------------------------------------------------------------------
// Widget count functions
//--------------------------------------------------------------------------------------------------
int Dashboard::mapCount()
{
return m_mapWidgets.count();
@ -96,9 +110,6 @@ int Dashboard::gaugeCount()
return m_gaugeWidgets.count();
}
/**
* @return The number of groups contained in the current frame.
*/
int Dashboard::groupCount()
{
return m_latestFrame.groupCount();
@ -124,6 +135,10 @@ int Dashboard::accelerometerCount()
return m_accelerometerWidgets.count();
}
//--------------------------------------------------------------------------------------------------
// Widget title functions
//--------------------------------------------------------------------------------------------------
QStringList Dashboard::barTitles()
{
QStringList list;
@ -205,6 +220,10 @@ QStringList Dashboard::accelerometerTitles()
return list;
}
//--------------------------------------------------------------------------------------------------
// Widget visibility access functions
//--------------------------------------------------------------------------------------------------
bool Dashboard::barVisible(const int index)
{
if (index < m_barVisibility.count())
@ -231,8 +250,8 @@ bool Dashboard::plotVisible(const int index)
bool Dashboard::groupVisible(const int index)
{
if (index < m_groupVisiblity.count())
return m_groupVisiblity.at(index);
if (index < m_groupVisibility.count())
return m_groupVisibility.at(index);
return false;
}
@ -277,13 +296,9 @@ bool Dashboard::accelerometerVisible(const int index)
return false;
}
/**
* Returns @c true if the latest frame contains data
*/
bool Dashboard::frameValid() const
{
return m_latestFrame.isValid();
}
//--------------------------------------------------------------------------------------------------
// Visibility-related slots
//--------------------------------------------------------------------------------------------------
void Dashboard::setBarVisible(const int index, const bool visible)
{
@ -323,11 +338,11 @@ void Dashboard::setPlotVisible(const int index, const bool visible)
void Dashboard::setGroupVisible(const int index, const bool visible)
{
if (index < m_groupVisiblity.count())
if (index < m_groupVisibility.count())
{
if (groupVisible(index) != visible)
{
m_groupVisiblity.replace(index, visible);
m_groupVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
@ -393,6 +408,10 @@ void Dashboard::setAccelerometerVisible(const int index, const bool visible)
}
}
//--------------------------------------------------------------------------------------------------
// Frame data handling slots
//--------------------------------------------------------------------------------------------------
/**
* Removes all available data from the UI when the device is disconnected or the CSV
* file is closed.
@ -403,9 +422,33 @@ void Dashboard::resetData()
m_latestJsonFrame = JFI_Empty();
m_latestFrame.read(m_latestJsonFrame.jsonDocument.object());
// Clear widget data
m_barWidgets.clear();
m_mapWidgets.clear();
m_plotWidgets.clear();
m_gaugeWidgets.clear();
m_compassWidgets.clear();
m_gyroscopeWidgets.clear();
m_thermometerWidgets.clear();
m_accelerometerWidgets.clear();
// Clear widget visibility data
m_barVisibility.clear();
m_mapVisibility.clear();
m_plotVisibility.clear();
m_gaugeVisibility.clear();
m_groupVisibility.clear();
m_compassVisibility.clear();
m_gyroscopeVisibility.clear();
m_thermometerVisibility.clear();
m_accelerometerVisibility.clear();
// Update UI
emit updated();
emit dataReset();
emit titleChanged();
emit widgetCountChanged();
emit widgetVisibilityChanged();
}
/**
@ -413,8 +456,99 @@ void Dashboard::resetData()
*/
void Dashboard::updateData()
{
if (m_latestFrame.read(m_latestJsonFrame.jsonDocument.object()))
emit updated();
// Save widget count
int barC = barCount();
int mapC = mapCount();
int plotC = plotCount();
int groupC = groupCount();
int gaugeC = gaugeCount();
int compassC = compassCount();
int gyroscopeC = gyroscopeCount();
int thermometerC = thermometerCount();
int accelerometerC = accelerometerCount();
// Save previous title
auto pTitle = title();
// Clear widget data
m_barWidgets.clear();
m_mapWidgets.clear();
m_plotWidgets.clear();
m_gaugeWidgets.clear();
m_compassWidgets.clear();
m_gyroscopeWidgets.clear();
m_thermometerWidgets.clear();
m_accelerometerWidgets.clear();
// Check if frame is valid
if (!m_latestFrame.read(m_latestJsonFrame.jsonDocument.object()))
return;
// Update widget vectors
m_plotWidgets = getPlotWidgets();
m_mapWidgets = getWidgetGroups("map");
m_barWidgets = getWidgetDatasets("bar");
m_gaugeWidgets = getWidgetDatasets("gauge");
m_gyroscopeWidgets = getWidgetGroups("gyro");
m_compassWidgets = getWidgetDatasets("compass");
m_thermometerWidgets = getWidgetDatasets("thermometer");
m_accelerometerWidgets = getWidgetGroups("accelerometer");
// Check if we need to update title
if (pTitle != title())
emit titleChanged();
// Check if we need to regenerate widgets
bool regenerateWidgets = false;
regenerateWidgets |= (barC != barCount());
regenerateWidgets |= (mapC != mapCount());
regenerateWidgets |= (plotC != plotCount());
regenerateWidgets |= (gaugeC != gaugeCount());
regenerateWidgets |= (groupC != groupCount());
regenerateWidgets |= (compassC != compassCount());
regenerateWidgets |= (gyroscopeC != gyroscopeCount());
regenerateWidgets |= (thermometerC != thermometerCount());
regenerateWidgets |= (accelerometerC != accelerometerCount());
// Regenerate widget visiblity models
if (regenerateWidgets)
{
m_barVisibility.clear();
m_mapVisibility.clear();
m_plotVisibility.clear();
m_gaugeVisibility.clear();
m_groupVisibility.clear();
m_compassVisibility.clear();
m_gyroscopeVisibility.clear();
m_thermometerVisibility.clear();
m_accelerometerVisibility.clear();
int i;
for (i = 0; i < barCount(); ++i)
m_barVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_mapVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_plotVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_gaugeVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_groupVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_compassVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_gyroscopeVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_thermometerVisibility.append(true);
for (i = 0; i < barCount(); ++i)
m_accelerometerVisibility.append(true);
emit widgetCountChanged();
emit widgetVisibilityChanged();
}
// Update UI
emit updated();
}
/**
@ -430,20 +564,48 @@ void Dashboard::selectLatestJSON(const JFI_Object &frameInfo)
m_latestJsonFrame = frameInfo;
}
//--------------------------------------------------------------------------------------------------
// Widget discovery functions
//--------------------------------------------------------------------------------------------------
QVector<JSON::Dataset *> Dashboard::getPlotWidgets()
{
QVector<JSON::Dataset *> widgets;
foreach (auto group, m_latestFrame.groups())
{
foreach (auto dataset, group->datasets())
{
if (dataset->graph())
widgets.append(dataset);
}
}
return widgets;
}
QVector<JSON::Group *> Dashboard::getWidgetGroup(const QString &handle)
QVector<JSON::Group *> Dashboard::getWidgetGroups(const QString &handle)
{
QVector<JSON::Group *> widgets;
foreach (auto group, m_latestFrame.groups())
{
if (group->widget().toLower() == handle)
widgets.append(group);
}
return widgets;
}
QVector<JSON::Dataset *> Dashboard::getWidgetDatasets(const QString &handle)
{
QVector<JSON::Dataset *> widgets;
foreach (auto group, m_latestFrame.groups())
{
foreach (auto dataset, group->datasets())
{
if (dataset->widget() == handle)
widgets.append(dataset);
}
}
return widgets;
}

View File

@ -38,41 +38,41 @@ class Dashboard : public QObject
NOTIFY titleChanged)
Q_PROPERTY(bool available
READ available
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int mapCount
READ mapCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int barCount
READ barCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int plotCount
READ plotCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int groupCount
READ groupCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int gaugeCount
READ gaugeCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int compassCount
READ compassCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int gyroscopeCount
READ gyroscopeCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int thermometerCount
READ thermometerCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
Q_PROPERTY(int accelerometerCount
READ accelerometerCount
NOTIFY dataCountChanged)
NOTIFY widgetCountChanged)
// clang-format on
signals:
void updated();
void dataReset();
void titleChanged();
void dataCountChanged();
void widgetCountChanged();
void widgetVisibilityChanged();
public:
@ -132,14 +132,14 @@ private slots:
private:
Dashboard();
QVector<JSON::Dataset *> getPlotWidgets();
QVector<JSON::Group *> getWidgetGroup(const QString &handle);
QVector<JSON::Group *> getWidgetGroups(const QString &handle);
QVector<JSON::Dataset *> getWidgetDatasets(const QString &handle);
private:
QVector<bool> m_barVisibility;
QVector<bool> m_mapVisibility;
QVector<bool> m_plotVisibility;
QVector<bool> m_groupVisiblity;
QVector<bool> m_groupVisibility;
QVector<bool> m_gaugeVisibility;
QVector<bool> m_compassVisibility;
QVector<bool> m_gyroscopeVisibility;