Add base code organization for multi-plot widget

This commit is contained in:
Alex Spataru 2021-09-27 03:35:38 -05:00
parent 2f32ecd14a
commit a8a858b5b8
10 changed files with 132 additions and 14 deletions

View File

@ -176,6 +176,7 @@ HEADERS += \
src/Widgets/DataGroup.h \
src/Widgets/Gauge.h \
src/Widgets/Gyroscope.h \
src/Widgets/MultiPlot.h \
src/Widgets/Plot.h \
src/Widgets/Terminal.h \
src/Widgets/Thermometer.h \
@ -184,6 +185,7 @@ HEADERS += \
SOURCES += \
src/UI/Dashboard.cpp \
src/Widgets/AnalogGauge.cpp \
src/Widgets/MultiPlot.cpp \
src/Widgets/WidgetLoader.cpp \
src/main.cpp \
src/CSV/Export.cpp \

View File

@ -76,6 +76,17 @@ Widgets.Window {
onCheckedChanged: Cpp_UI_Dashboard.setGroupVisible(index, checked)
}
//
// Multiplots
//
ViewOptionsDelegate {
title: qsTr("Multiple data plots")
icon: "qrc:/icons/plot.svg"
count: Cpp_UI_Dashboard.multiPlotCount
titles: Cpp_UI_Dashboard.multiPlotCount
onCheckedChanged: Cpp_UI_Dashboard.setMultiplotVisible(index, checked)
}
//
// Plots
//

View File

@ -155,7 +155,7 @@ Widgets.Window {
Layout.fillWidth: true
Layout.minimumWidth: 320
Layout.minimumHeight: 320
showGroupWidget: widget.currentIndex > 0
showGroupWidget: widget.currentIndex > 0 && widget.currentIndex !== 4
}
}
}

View File

@ -39,7 +39,8 @@ ApplicationWindow {
// Quit application on close
//
onClosing: {
if (Cpp_JSON_Editor.askSave())
close.accepted = Cpp_JSON_Editor.askSave()
if (close.accepted)
Cpp_ModuleManager.quit()
}

View File

@ -93,7 +93,7 @@ Editor *Editor::getInstance()
QStringList Editor::availableGroupLevelWidgets()
{
return QStringList { tr("Dataset widgets"), tr("Accelerometer"), tr("Gyroscope"),
tr("Map") };
tr("Map"), tr("Multiple data plot") };
}
/**
@ -326,7 +326,7 @@ bool Editor::saveJsonFile()
json.insert("g", groups);
// Write JSON data to file
file.write(QJsonDocument(json).toJson(QJsonDocument::Compact));
file.write(QJsonDocument(json).toJson(QJsonDocument::Indented));
file.close();
// Load JSON file to Serial Studio
@ -414,6 +414,9 @@ int Editor::groupWidgetIndex(const int group)
if (widget == "map")
return 3;
if (widget == "multiplot")
return 4;
}
return 0;
@ -823,7 +826,13 @@ bool Editor::setGroupWidget(const int group, const int widgetId)
if (grp)
{
// Warn user if group contains existing datasets
if (!(grp->m_datasets.isEmpty()))
if (!(grp->m_datasets.isEmpty()) && widgetId != 4)
{
if (widgetId == 0 && grp->widget() == "multiplot")
;
// Do nothing
else
{
auto ret = Misc::Utilities::showMessageBox(
tr("Are you sure you want to change the group-level widget?"),
@ -834,6 +843,7 @@ bool Editor::setGroupWidget(const int group, const int widgetId)
else
grp->m_datasets.clear();
}
}
// Accelerometer widget
if (widgetId == 1)
@ -937,6 +947,10 @@ bool Editor::setGroupWidget(const int group, const int widgetId)
grp->m_datasets.append(lon);
}
// Multi plot widget
else if (widgetId == 4)
grp->m_widget = "multiplot";
// Update UI
emit groupChanged(group);
return true;

View File

@ -84,6 +84,7 @@ JSON::Dataset *Dashboard::getPlot(const int index) { return getDatasetWid
JSON::Dataset *Dashboard::getGauge(const int index) { return getDatasetWidget(m_gaugeWidgets, index); }
JSON::Group *Dashboard::getGyroscope(const int index) { return getGroupWidget(m_gyroscopeWidgets, index); }
JSON::Dataset *Dashboard::getCompass(const int index) { return getDatasetWidget(m_compassWidgets, index); }
JSON::Group *Dashboard::getMultiplot(const int index) { return getGroupWidget(m_accelerometerWidgets, index); }
JSON::Group *Dashboard::getAccelerometer(const int index) { return getGroupWidget(m_accelerometerWidgets, index); }
JSON::Dataset *Dashboard::getThermometer(const int index) { return getDatasetWidget(m_thermometerWidgets, index); }
// clang-format on
@ -140,6 +141,7 @@ int Dashboard::totalWidgetCount() const
gaugeCount() +
groupCount() +
compassCount() +
multiPlotCount() +
gyroscopeCount() +
thermometerCount() +
accelerometerCount();
@ -156,6 +158,7 @@ int Dashboard::gaugeCount() const { return m_gaugeWidgets.count();
int Dashboard::groupCount() const { return m_latestFrame.groupCount(); }
int Dashboard::compassCount() const { return m_compassWidgets.count(); }
int Dashboard::gyroscopeCount() const { return m_gyroscopeWidgets.count(); }
int Dashboard::multiPlotCount() const { return m_gyroscopeWidgets.count(); }
int Dashboard::thermometerCount() const { return m_thermometerWidgets.count(); }
int Dashboard::accelerometerCount() const { return m_accelerometerWidgets.count(); }
// clang-format on
@ -177,6 +180,7 @@ QStringList Dashboard::widgetTitles() const
// clang-format off
return groupTitles() +
multiPlotTitles() +
plotTitles() +
barTitles() +
gaugeTitles() +
@ -218,8 +222,13 @@ int Dashboard::relativeIndex(const int globalIndex) const
if (index < groupCount())
return index;
// Check if we should return plot widget
// Check if we should return multi-plot widget
index -= groupCount();
if (index < multiPlotCount())
return index;
// Check if we should return plot widget
index -= multiPlotCount();
if (index < plotCount())
return index;
@ -289,6 +298,9 @@ bool Dashboard::widgetVisible(const int globalIndex) const
case WidgetType::Group:
visible = groupVisible(index);
break;
case WidgetType::MultiPlot:
visible = multiPlotVisible(index);
break;
case WidgetType::Plot:
visible = plotVisible(index);
break;
@ -344,6 +356,9 @@ QString Dashboard::widgetIcon(const int globalIndex) const
case WidgetType::Group:
return "qrc:/icons/group.svg";
break;
case WidgetType::MultiPlot:
return "qrc:/icons/plot.svg";
break;
case WidgetType::Plot:
return "qrc:/icons/plot.svg";
break;
@ -380,6 +395,7 @@ QString Dashboard::widgetIcon(const int globalIndex) const
* Possible return values are:
* - @c WidgetType::Unknown
* - @c WidgetType::Group
* - @c WidgetType::MultiPlot
* - @c WidgetType::Plot
* - @c WidgetType::Bar
* - @c WidgetType::Gauge
@ -418,8 +434,13 @@ Dashboard::WidgetType Dashboard::widgetType(const int globalIndex) const
if (index < groupCount())
return WidgetType::Group;
// Check if we should return plot widget
// Check if we should return multi-plot widget
index -= groupCount();
if (index < multiPlotCount())
return WidgetType::MultiPlot;
// Check if we should return plot widget
index -= multiPlotCount();
if (index < plotCount())
return WidgetType::Plot;
@ -474,6 +495,7 @@ bool Dashboard::groupVisible(const int index) const { return getVisibili
bool Dashboard::gaugeVisible(const int index) const { return getVisibility(m_gaugeVisibility, index); }
bool Dashboard::compassVisible(const int index) const { return getVisibility(m_compassVisibility, index); }
bool Dashboard::gyroscopeVisible(const int index) const { return getVisibility(m_gyroscopeVisibility, index); }
bool Dashboard::multiPlotVisible(const int index) const { return getVisibility(m_multiPlotVisibility, index); }
bool Dashboard::thermometerVisible(const int index) const { return getVisibility(m_thermometerVisibility, index); }
bool Dashboard::accelerometerVisible(const int index) const { return getVisibility(m_accelerometerVisibility, index); }
// clang-format on
@ -490,6 +512,7 @@ QStringList Dashboard::groupTitles() const { return groupTitles(m_latest
QStringList Dashboard::gaugeTitles() const { return datasetTitles(m_gaugeWidgets); }
QStringList Dashboard::compassTitles() const { return datasetTitles(m_compassWidgets); }
QStringList Dashboard::gyroscopeTitles() const { return groupTitles(m_gyroscopeWidgets); }
QStringList Dashboard::multiPlotTitles() const { return groupTitles(m_multiPlotWidgets); }
QStringList Dashboard::thermometerTitles() const { return datasetTitles(m_thermometerWidgets); }
QStringList Dashboard::accelerometerTitles() const { return groupTitles(m_accelerometerWidgets); }
// clang-format on
@ -506,6 +529,7 @@ void Dashboard::setGroupVisible(const int i, const bool v) { setVisibili
void Dashboard::setGaugeVisible(const int i, const bool v) { setVisibility(m_gaugeVisibility, i, v); }
void Dashboard::setCompassVisible(const int i, const bool v) { setVisibility(m_compassVisibility, i, v); }
void Dashboard::setGyroscopeVisible(const int i, const bool v) { setVisibility(m_gyroscopeVisibility, i, v); }
void Dashboard::setMultiplotVisible(const int i, const bool v) { setVisibility(m_multiPlotVisibility, i, v); }
void Dashboard::setThermometerVisible(const int i, const bool v) { setVisibility(m_thermometerVisibility, i, v); }
void Dashboard::setAccelerometerVisible(const int i, const bool v) { setVisibility(m_accelerometerVisibility, i, v); }
// clang-format on

View File

@ -64,6 +64,9 @@ class Dashboard : public QObject
Q_PROPERTY(int gyroscopeCount
READ gyroscopeCount
NOTIFY widgetCountChanged)
Q_PROPERTY(int multiPlotCount
READ multiPlotCount
NOTIFY widgetCountChanged)
Q_PROPERTY(int thermometerCount
READ thermometerCount
NOTIFY widgetCountChanged)
@ -91,6 +94,9 @@ class Dashboard : public QObject
Q_PROPERTY(QStringList gyroscopeTitles
READ gyroscopeTitles
NOTIFY widgetCountChanged)
Q_PROPERTY(QStringList multiPlotTitles
READ multiPlotTitles
NOTIFY widgetCountChanged)
Q_PROPERTY(QStringList thermometerTitles
READ thermometerTitles
NOTIFY widgetCountChanged)
@ -110,6 +116,7 @@ public:
enum class WidgetType
{
Group,
MultiPlot,
Plot,
Bar,
Gauge,
@ -132,6 +139,7 @@ public:
JSON::Dataset *getGauge(const int index);
JSON::Group *getGyroscope(const int index);
JSON::Dataset *getCompass(const int index);
JSON::Group *getMultiplot(const int index);
JSON::Group *getAccelerometer(const int index);
JSON::Dataset *getThermometer(const int index);
@ -146,6 +154,7 @@ public:
int gaugeCount() const;
int compassCount() const;
int gyroscopeCount() const;
int multiPlotCount() const;
int thermometerCount() const;
int accelerometerCount() const;
@ -163,6 +172,7 @@ public:
Q_INVOKABLE bool gaugeVisible(const int index) const;
Q_INVOKABLE bool compassVisible(const int index) const;
Q_INVOKABLE bool gyroscopeVisible(const int index) const;
Q_INVOKABLE bool multiPlotVisible(const int index) const;
Q_INVOKABLE bool thermometerVisible(const int index) const;
Q_INVOKABLE bool accelerometerVisible(const int index) const;
@ -173,6 +183,7 @@ public:
Q_INVOKABLE QStringList gaugeTitles() const;
Q_INVOKABLE QStringList compassTitles() const;
Q_INVOKABLE QStringList gyroscopeTitles() const;
Q_INVOKABLE QStringList multiPlotTitles() const;
Q_INVOKABLE QStringList thermometerTitles() const;
Q_INVOKABLE QStringList accelerometerTitles() const;
@ -184,6 +195,7 @@ public slots:
void setGaugeVisible(const int index, const bool visible);
void setCompassVisible(const int index, const bool visible);
void setGyroscopeVisible(const int index, const bool visible);
void setMultiplotVisible(const int index, const bool visible);
void setThermometerVisible(const int index, const bool visible);
void setAccelerometerVisible(const int index, const bool visible);
@ -217,6 +229,7 @@ private:
QVector<bool> m_gaugeVisibility;
QVector<bool> m_compassVisibility;
QVector<bool> m_gyroscopeVisibility;
QVector<bool> m_multiPlotVisibility;
QVector<bool> m_thermometerVisibility;
QVector<bool> m_accelerometerVisibility;
@ -227,6 +240,7 @@ private:
QVector<JSON::Dataset *> m_thermometerWidgets;
QVector<JSON::Group *> m_mapWidgets;
QVector<JSON::Group *> m_multiPlotWidgets;
QVector<JSON::Group *> m_gyroscopeWidgets;
QVector<JSON::Group *> m_accelerometerWidgets;

23
src/Widgets/MultiPlot.cpp Normal file
View File

@ -0,0 +1,23 @@
/*
* 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.
*/
#include "MultiPlot.h"

26
src/Widgets/MultiPlot.h Normal file
View File

@ -0,0 +1,26 @@
/*
* 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.
*/
#ifndef WIDGETS_MULTIPLOT_H
#define WIDGETS_MULTIPLOT_H
#endif

View File

@ -242,6 +242,9 @@ void WidgetLoader::setWidgetIndex(const int index)
m_widget = new DataGroup(relativeIndex());
m_window.setCentralWidget(new DataGroup(relativeIndex()));
break;
case UI::Dashboard::WidgetType::MultiPlot:
m_widget = new QPushButton("Multi-Plot");
break;
case UI::Dashboard::WidgetType::Plot:
m_widget = new QPushButton("Plot");
break;