Begin working on Dashboard module

This commit is contained in:
Alex Spataru 2021-09-25 00:03:27 -05:00
parent a25c8f4cd6
commit a5bee32c74
11 changed files with 628 additions and 234 deletions

View File

@ -147,7 +147,7 @@ HEADERS += \
src/Misc/Translator.h \
src/Misc/Utilities.h \
src/Plugins/Bridge.h \
src/UI/QmlDataProvider.h \
src/UI/Dashboard.h \
src/Widgets/Accelerometer.h \
src/Widgets/Bar.h \
src/Widgets/Compass.h \
@ -159,6 +159,7 @@ HEADERS += \
src/Widgets/Thermometer.h
SOURCES += \
src/UI/Dashboard.cpp \
src/main.cpp \
src/CSV/Export.cpp \
src/CSV/Player.cpp \
@ -181,7 +182,6 @@ SOURCES += \
src/Misc/Translator.cpp \
src/Misc/Utilities.cpp \
src/Plugins/Bridge.cpp \
src/UI/QmlDataProvider.cpp \
src/Widgets/Accelerometer.cpp \
src/Widgets/Bar.cpp \
src/Widgets/Compass.cpp \

View File

@ -92,7 +92,6 @@ ApplicationWindow {
property alias vt100emulation: terminal.vt100emulation
readonly property bool consoleVisible: terminal.visible
readonly property bool dashboardVisible: dashboard.visible
readonly property bool dashboardAvailable: Cpp_UI_QmlDataProvider.groupCount > 0
//
// Menubar status
@ -317,12 +316,12 @@ ApplicationWindow {
// Hide console & device manager when we receive first valid frame
//
Connections {
target: Cpp_UI_QmlDataProvider
target: Cpp_UI_Dashboard
enabled: !app.firstValidFrame
function onUpdated() {
if ((Cpp_IO_Manager.connected || Cpp_CSV_Player.isOpen) &&
Cpp_UI_QmlDataProvider.frameValid()) {
Cpp_UI_Dashboard.frameValid()) {
setup.hide()
app.showDashboard()
app.firstValidFrame = true
@ -340,10 +339,10 @@ ApplicationWindow {
// Show console tab on serial disconnect
//
Connections {
target: Cpp_UI_QmlDataProvider
target: Cpp_UI_Dashboard
function onDataReset() {
toolbar.consoleClicked()
setup.show()
app.showConsole()
app.firstValidFrame = false
}
}
@ -386,7 +385,7 @@ ApplicationWindow {
onSetupClicked: setup.visible ? setup.hide() : setup.show()
onDashboardClicked: {
if (app.dashboardAvailable) {
if (Cpp_UI_Dashboard.available) {
consoleChecked = 0
dashboardChecked = 1
swipe.currentIndex = 1

View File

@ -181,7 +181,7 @@ MenuBar {
sequence: "ctrl+d"
text: qsTr("Dashboard")
checked: app.dashboardVisible
enabled: app.dashboardAvailable
enabled: Cpp_UI_Dashboard.available
onTriggered: app.showDashboard()
onCheckedChanged: {
if (app.dashboardVisible !== checked)

View File

@ -156,7 +156,7 @@ MenuBar {
shortcut: "ctrl+d"
text: qsTr("Dashboard")
checked: app.dashboardVisible
enabled: app.dashboardAvailable
enabled: Cpp_UI_Dashboard.available
onTriggered: app.showDashboard()
onCheckedChanged: {
if (app.dashboardVisible !== checked)
@ -179,8 +179,7 @@ MenuBar {
DecentMenuItem {
sequence: StandardKey.FullScreen
onTriggered: app.toggleFullscreen()
text: app.fullScreen ? qsTr("Exit full screen") :
qsTr("Enter full screen")
text: app.fullScreen ? qsTr("Exit full screen") : qsTr("Enter full screen")
}
}

View File

@ -175,8 +175,8 @@ Item {
MenuItem {
enabled: visible
visible: app.menuBar != null
onTriggered: app.toggleMenubar()
height: visible ? implicitHeight : 0
onTriggered: app.menubarEnabled = !app.menubarEnabled
text: visible && app.menuBar.visible ? qsTr("Hide menubar") :
qsTr("Show menubar")
}

View File

@ -161,7 +161,7 @@ Control {
icon.height: 24
Layout.fillHeight: true
onClicked: root.dashboardClicked()
enabled: app.dashboardAvailable
enabled: Cpp_UI_Dashboard.available
text: qsTr("Dashboard") + _btSpacer
icon.source: "qrc:/icons/equalizer.svg"
icon.color: Cpp_ThemeManager.brightText

View File

@ -48,7 +48,7 @@
#include <MQTT/Client.h>
#include <Plugins/Bridge.h>
#include <UI/QmlDataProvider.h>
#include <UI/Dashboard.h>
#include <Widgets/Bar.h>
#include <Widgets/Plot.h>
@ -159,6 +159,7 @@ void ModuleManager::initializeQmlInterface()
auto updater = QSimpleUpdater::getInstance();
auto jsonEditor = JSON::Editor::getInstance();
auto mqttClient = MQTT::Client::getInstance();
auto uiDashboard = UI::Dashboard::getInstance();
auto jsonGenerator = JSON::Generator::getInstance();
auto pluginsBridge = Plugins::Bridge::getInstance();
auto miscUtilities = Misc::Utilities::getInstance();
@ -168,7 +169,6 @@ void ModuleManager::initializeQmlInterface()
auto miscTimerEvents = Misc::TimerEvents::getInstance();
auto ioNetwork = IO::DataSources::Network::getInstance();
auto miscThemeManager = Misc::ThemeManager::getInstance();
auto uiQmlDataProvider = UI::QmlDataProvider::getInstance();
// Retranslate the QML interface automagically
connect(miscTranslator, SIGNAL(languageChanged()), engine(), SLOT(retranslate()));
@ -184,6 +184,7 @@ void ModuleManager::initializeQmlInterface()
c->setContextProperty("Cpp_IO_Network", ioNetwork);
c->setContextProperty("Cpp_JSON_Editor", jsonEditor);
c->setContextProperty("Cpp_MQTT_Client", mqttClient);
c->setContextProperty("Cpp_UI_Dashboard", uiDashboard);
c->setContextProperty("Cpp_JSON_Generator", jsonGenerator);
c->setContextProperty("Cpp_Plugins_Bridge", pluginsBridge);
c->setContextProperty("Cpp_Misc_MacExtras", miscMacExtras);
@ -192,7 +193,6 @@ void ModuleManager::initializeQmlInterface()
c->setContextProperty("Cpp_Misc_Translator", miscTranslator);
c->setContextProperty("Cpp_Misc_TimerEvents", miscTimerEvents);
c->setContextProperty("Cpp_UpdaterEnabled", autoUpdaterEnabled());
c->setContextProperty("Cpp_UI_QmlDataProvider", uiQmlDataProvider);
c->setContextProperty("Cpp_ModuleManager", this);
// Register app info with QML

449
src/UI/Dashboard.cpp Normal file
View File

@ -0,0 +1,449 @@
/*
* 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 <IO/Manager.h>
#include <IO/Console.h>
#include <CSV/Player.h>
#include <JSON/Generator.h>
#include <Misc/TimerEvents.h>
#include "Dashboard.h"
using namespace UI;
/*
* Only instance of the class
*/
static Dashboard *INSTANCE = nullptr;
/**
* Constructor of the class
*/
Dashboard::Dashboard()
: m_latestJsonFrame(JFI_Empty())
{
auto cp = CSV::Player::getInstance();
auto io = IO::Manager::getInstance();
auto ge = JSON::Generator::getInstance();
auto te = Misc::TimerEvents::getInstance();
connect(cp, SIGNAL(openChanged()), this, SLOT(resetData()));
connect(te, SIGNAL(highFreqTimeout()), this, SLOT(updateData()));
connect(io, SIGNAL(connectedChanged()), this, SLOT(resetData()));
connect(ge, SIGNAL(jsonFileMapChanged()), this, SLOT(resetData()));
connect(ge, &JSON::Generator::jsonChanged, this, &Dashboard::selectLatestJSON);
}
/**
* Returns the only instance of the class
*/
Dashboard *Dashboard::getInstance()
{
if (!INSTANCE)
INSTANCE = new Dashboard();
return INSTANCE;
}
/**
* @return The title of the current frame
*/
QString Dashboard::title()
{
return m_latestFrame.title();
}
bool Dashboard::available()
{
return groupCount() > 0;
}
int Dashboard::mapCount()
{
return m_mapWidgets.count();
}
int Dashboard::barCount()
{
return m_barWidgets.count();
}
int Dashboard::plotCount()
{
return m_plotWidgets.count();
}
int Dashboard::gaugeCount()
{
return m_gaugeWidgets.count();
}
/**
* @return The number of groups contained in the current frame.
*/
int Dashboard::groupCount()
{
return m_latestFrame.groupCount();
}
int Dashboard::compassCount()
{
return m_compassWidgets.count();
}
int Dashboard::gyroscopeCount()
{
return m_gyroscopeWidgets.count();
}
int Dashboard::thermometerCount()
{
return m_thermometerWidgets.count();
}
int Dashboard::accelerometerCount()
{
return m_accelerometerWidgets.count();
}
QStringList Dashboard::barTitles()
{
QStringList list;
foreach (auto set, m_barWidgets)
list.append(set->title());
return list;
}
QStringList Dashboard::mapTitles()
{
QStringList list;
foreach (auto group, m_mapWidgets)
list.append(group->title());
return list;
}
QStringList Dashboard::plotTitles()
{
QStringList list;
foreach (auto set, m_plotWidgets)
list.append(set->title());
return list;
}
QStringList Dashboard::groupTitles()
{
QStringList list;
foreach (auto group, m_latestFrame.groups())
list.append(group->title());
return list;
}
QStringList Dashboard::gaugeTitles()
{
QStringList list;
foreach (auto set, m_gaugeWidgets)
list.append(set->title());
return list;
}
QStringList Dashboard::compassTitles()
{
QStringList list;
foreach (auto set, m_compassWidgets)
list.append(set->title());
return list;
}
QStringList Dashboard::gyroscopeTitles()
{
QStringList list;
foreach (auto group, m_gyroscopeWidgets)
list.append(group->title());
return list;
}
QStringList Dashboard::thermometerTitles()
{
QStringList list;
foreach (auto set, m_thermometerWidgets)
list.append(set->title());
return list;
}
QStringList Dashboard::accelerometerTitles()
{
QStringList list;
foreach (auto group, m_accelerometerWidgets)
list.append(group->title());
return list;
}
bool Dashboard::barVisible(const int index)
{
if (index < m_barVisibility.count())
return m_barVisibility.at(index);
return false;
}
bool Dashboard::mapVisible(const int index)
{
if (index < m_mapVisibility.count())
return m_mapVisibility.at(index);
return false;
}
bool Dashboard::plotVisible(const int index)
{
if (index < m_plotVisibility.count())
return m_plotVisibility.at(index);
return false;
}
bool Dashboard::groupVisible(const int index)
{
if (index < m_groupVisiblity.count())
return m_groupVisiblity.at(index);
return false;
}
bool Dashboard::gaugeVisible(const int index)
{
if (index < m_gaugeVisibility.count())
return m_gaugeVisibility.at(index);
return false;
}
bool Dashboard::compassVisible(const int index)
{
if (index < m_compassVisibility.count())
return m_compassVisibility.at(index);
return false;
}
bool Dashboard::gyroscopeVisible(const int index)
{
if (index < m_gyroscopeVisibility.count())
return m_gyroscopeVisibility.at(index);
return false;
}
bool Dashboard::thermometerVisible(const int index)
{
if (index < m_thermometerVisibility.count())
return m_thermometerVisibility.at(index);
return false;
}
bool Dashboard::accelerometerVisible(const int index)
{
if (index < m_accelerometerVisibility.count())
return m_accelerometerVisibility.at(index);
return false;
}
/**
* Returns @c true if the latest frame contains data
*/
bool Dashboard::frameValid() const
{
return m_latestFrame.isValid();
}
void Dashboard::setBarVisible(const int index, const bool visible)
{
if (index < m_barVisibility.count())
{
if (barVisible(index) != visible)
{
m_barVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setMapVisible(const int index, const bool visible)
{
if (index < m_mapVisibility.count())
{
if (mapVisible(index) != visible)
{
m_mapVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setPlotVisible(const int index, const bool visible)
{
if (index < m_plotVisibility.count())
{
if (plotVisible(index) != visible)
{
m_plotVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setGroupVisible(const int index, const bool visible)
{
if (index < m_groupVisiblity.count())
{
if (groupVisible(index) != visible)
{
m_groupVisiblity.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setGaugeVisible(const int index, const bool visible)
{
if (index < m_gaugeVisibility.count())
{
if (gaugeVisible(index) != visible)
{
m_gaugeVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setCompassVisible(const int index, const bool visible)
{
if (index < m_compassVisibility.count())
{
if (compassVisible(index) != visible)
{
m_compassVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setGyroscopeVisible(const int index, const bool visible)
{
if (index < m_gyroscopeVisibility.count())
{
if (gyroscopeVisible(index) != visible)
{
m_gyroscopeVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setThermometerVisible(const int index, const bool visible)
{
if (index < m_thermometerVisibility.count())
{
if (thermometerVisible(index) != visible)
{
m_thermometerVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
void Dashboard::setAccelerometerVisible(const int index, const bool visible)
{
if (index < m_accelerometerVisibility.count())
{
if (accelerometerVisible(index) != visible)
{
m_accelerometerVisibility.replace(index, visible);
emit widgetVisibilityChanged();
}
}
}
/**
* Removes all available data from the UI when the device is disconnected or the CSV
* file is closed.
*/
void Dashboard::resetData()
{
// Make latest frame invalid
m_latestJsonFrame = JFI_Empty();
m_latestFrame.read(m_latestJsonFrame.jsonDocument.object());
// Update UI
emit updated();
emit dataReset();
}
/**
* Interprets the most recent JSON frame & signals the UI to regenerate itself.
*/
void Dashboard::updateData()
{
if (m_latestFrame.read(m_latestJsonFrame.jsonDocument.object()))
emit updated();
}
/**
* Ensures that only the most recent JSON document will be displayed on the user
* interface.
*/
void Dashboard::selectLatestJSON(const JFI_Object &frameInfo)
{
auto frameCount = frameInfo.frameNumber;
auto currFrameCount = m_latestJsonFrame.frameNumber;
if (currFrameCount < frameCount)
m_latestJsonFrame = frameInfo;
}
QVector<JSON::Dataset *> Dashboard::getPlotWidgets()
{
QVector<JSON::Dataset *> widgets;
return widgets;
}
QVector<JSON::Group *> Dashboard::getWidgetGroup(const QString &handle)
{
QVector<JSON::Group *> widgets;
return widgets;
}
QVector<JSON::Dataset *> Dashboard::getWidgetDatasets(const QString &handle)
{
QVector<JSON::Dataset *> widgets;
return widgets;
}

164
src/UI/Dashboard.h Normal file
View File

@ -0,0 +1,164 @@
/*
* 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 UI_DASHBOARD_H
#define UI_DASHBOARD_H
#include <QObject>
#include <JSON/Frame.h>
#include <JSON/FrameInfo.h>
namespace UI
{
class Dashboard : public QObject
{
// clang-format off
Q_OBJECT
Q_PROPERTY(QString title
READ title
NOTIFY titleChanged)
Q_PROPERTY(bool available
READ available
NOTIFY dataCountChanged)
Q_PROPERTY(int mapCount
READ mapCount
NOTIFY dataCountChanged)
Q_PROPERTY(int barCount
READ barCount
NOTIFY dataCountChanged)
Q_PROPERTY(int plotCount
READ plotCount
NOTIFY dataCountChanged)
Q_PROPERTY(int groupCount
READ groupCount
NOTIFY dataCountChanged)
Q_PROPERTY(int gaugeCount
READ gaugeCount
NOTIFY dataCountChanged)
Q_PROPERTY(int compassCount
READ compassCount
NOTIFY dataCountChanged)
Q_PROPERTY(int gyroscopeCount
READ gyroscopeCount
NOTIFY dataCountChanged)
Q_PROPERTY(int thermometerCount
READ thermometerCount
NOTIFY dataCountChanged)
Q_PROPERTY(int accelerometerCount
READ accelerometerCount
NOTIFY dataCountChanged)
// clang-format on
signals:
void updated();
void dataReset();
void titleChanged();
void dataCountChanged();
void widgetVisibilityChanged();
public:
static Dashboard *getInstance();
QString title();
bool available();
int mapCount();
int barCount();
int plotCount();
int groupCount();
int gaugeCount();
int compassCount();
int gyroscopeCount();
int thermometerCount();
int accelerometerCount();
Q_INVOKABLE QStringList barTitles();
Q_INVOKABLE QStringList mapTitles();
Q_INVOKABLE QStringList plotTitles();
Q_INVOKABLE QStringList groupTitles();
Q_INVOKABLE QStringList gaugeTitles();
Q_INVOKABLE QStringList compassTitles();
Q_INVOKABLE QStringList gyroscopeTitles();
Q_INVOKABLE QStringList thermometerTitles();
Q_INVOKABLE QStringList accelerometerTitles();
Q_INVOKABLE bool barVisible(const int index);
Q_INVOKABLE bool mapVisible(const int index);
Q_INVOKABLE bool plotVisible(const int index);
Q_INVOKABLE bool groupVisible(const int index);
Q_INVOKABLE bool gaugeVisible(const int index);
Q_INVOKABLE bool compassVisible(const int index);
Q_INVOKABLE bool gyroscopeVisible(const int index);
Q_INVOKABLE bool thermometerVisible(const int index);
Q_INVOKABLE bool accelerometerVisible(const int index);
Q_INVOKABLE bool frameValid() const;
public slots:
void setBarVisible(const int index, const bool visible);
void setMapVisible(const int index, const bool visible);
void setPlotVisible(const int index, const bool visible);
void setGroupVisible(const int index, const bool visible);
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 setThermometerVisible(const int index, const bool visible);
void setAccelerometerVisible(const int index, const bool visible);
private slots:
void resetData();
void updateData();
void selectLatestJSON(const JFI_Object &frameInfo);
private:
Dashboard();
QVector<JSON::Dataset *> getPlotWidgets();
QVector<JSON::Group *> getWidgetGroup(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_gaugeVisibility;
QVector<bool> m_compassVisibility;
QVector<bool> m_gyroscopeVisibility;
QVector<bool> m_thermometerVisibility;
QVector<bool> m_accelerometerVisibility;
QVector<JSON::Dataset *> m_barWidgets;
QVector<JSON::Dataset *> m_plotWidgets;
QVector<JSON::Dataset *> m_gaugeWidgets;
QVector<JSON::Dataset *> m_compassWidgets;
QVector<JSON::Dataset *> m_thermometerWidgets;
QVector<JSON::Group *> m_mapWidgets;
QVector<JSON::Group *> m_gyroscopeWidgets;
QVector<JSON::Group *> m_accelerometerWidgets;
JSON::Frame m_latestFrame;
JFI_Object m_latestJsonFrame;
};
}
#endif

View File

@ -1,144 +0,0 @@
/*
* 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 <IO/Manager.h>
#include <IO/Console.h>
#include <CSV/Player.h>
#include <JSON/Generator.h>
#include <Misc/TimerEvents.h>
#include "QmlDataProvider.h"
using namespace UI;
/*
* Only instance of the class
*/
static QmlDataProvider *INSTANCE = nullptr;
/**
* Constructor of the class
*/
QmlDataProvider::QmlDataProvider()
: m_latestJsonFrame(JFI_Empty())
{
auto cp = CSV::Player::getInstance();
auto io = IO::Manager::getInstance();
auto ge = JSON::Generator::getInstance();
auto te = Misc::TimerEvents::getInstance();
connect(cp, SIGNAL(openChanged()), this, SLOT(resetData()));
connect(te, SIGNAL(highFreqTimeout()), this, SLOT(updateData()));
connect(io, SIGNAL(connectedChanged()), this, SLOT(resetData()));
connect(ge, SIGNAL(jsonFileMapChanged()), this, SLOT(resetData()));
connect(ge, &JSON::Generator::jsonChanged, this, &QmlDataProvider::selectLatestJSON);
}
/**
* Returns the only instance of the class
*/
QmlDataProvider *QmlDataProvider::getInstance()
{
if (!INSTANCE)
INSTANCE = new QmlDataProvider();
return INSTANCE;
}
/**
* @return The title of the current frame
*/
QString QmlDataProvider::title()
{
return m_latestFrame.title();
}
/**
* @return The number of groups contained in the current frame.
*/
int QmlDataProvider::groupCount()
{
return m_latestFrame.groupCount();
}
/**
* Returns a pointer to the latest frame
*/
JSON::Frame *QmlDataProvider::latestFrame()
{
return &m_latestFrame;
}
/**
* Returns @c true if the latest frame contains data
*/
bool QmlDataProvider::frameValid() const
{
return m_latestFrame.isValid();
}
/**
* Returns a reference to the group object registered with the given @a index.
*/
JSON::Group *QmlDataProvider::getGroup(const int index)
{
if (index < groupCount())
return m_latestFrame.groups().at(index);
return Q_NULLPTR;
}
/**
* Removes all available data from the UI when the device is disconnected or the CSV
* file is closed.
*/
void QmlDataProvider::resetData()
{
// Make latest frame invalid
m_latestJsonFrame = JFI_Empty();
m_latestFrame.read(m_latestJsonFrame.jsonDocument.object());
// Update UI
emit updated();
emit dataReset();
}
/**
* Interprets the most recent JSON frame & signals the UI to regenerate itself.
*/
void QmlDataProvider::updateData()
{
if (m_latestFrame.read(m_latestJsonFrame.jsonDocument.object()))
emit updated();
}
/**
* Ensures that only the most recent JSON document will be displayed on the user
* interface.
*/
void QmlDataProvider::selectLatestJSON(const JFI_Object &frameInfo)
{
auto frameCount = frameInfo.frameNumber;
auto currFrameCount = m_latestJsonFrame.frameNumber;
if (currFrameCount < frameCount)
m_latestJsonFrame = frameInfo;
}

View File

@ -1,73 +0,0 @@
/*
* 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 UI_QML_DATA_PROVIDER_H
#define UI_QML_DATA_PROVIDER_H
#include <QObject>
#include <JSON/Frame.h>
#include <JSON/FrameInfo.h>
namespace UI
{
class QmlDataProvider : public QObject
{
// clang-format off
Q_OBJECT
Q_PROPERTY(QString title
READ title
NOTIFY updated)
Q_PROPERTY(int groupCount
READ groupCount
NOTIFY updated)
// clang-format on
signals:
void updated();
void dataReset();
public:
static QmlDataProvider *getInstance();
QString title();
int groupCount();
JSON::Frame *latestFrame();
Q_INVOKABLE bool frameValid() const;
Q_INVOKABLE JSON::Group *getGroup(const int index);
private:
QmlDataProvider();
private slots:
void resetData();
void updateData();
void selectLatestJSON(const JFI_Object &frameInfo);
private:
JSON::Frame m_latestFrame;
JFI_Object m_latestJsonFrame;
};
}
#endif