diff --git a/.vscode/settings.json b/.vscode/settings.json index 1d109b3056c36df9b04dccc0160d07304777ba1a..9f25ba9ffc4ef50e7318f7376545c5a0bf91e6be 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -101,13 +101,18 @@ "*.ipp": "cpp", "qmap": "cpp", "hash_map": "cpp", - "unordered_set": "cpp" + "unordered_set": "cpp", + "qtimer": "cpp", + "*.inc": "cpp", + "qlist": "cpp" }, "editor.defaultFormatter": "chiehyu.vscode-astyle", "[xml]": { "editor.defaultFormatter": "redhat.vscode-xml" }, "cSpell.words": [ - "Mavlink" + "Mavlink", + "Plottables", + "replot" ] } \ No newline at end of file diff --git a/Components/SubscriptionsPanel/subscriptionspanel.cpp b/Components/SubscriptionsPanel/subscriptionspanel.cpp index 17870ac0051c17bae2ac544a1c78114387d0cb0f..05d3e0051e91c07d3866ae9366e9f88273f4e9c4 100644 --- a/Components/SubscriptionsPanel/subscriptionspanel.cpp +++ b/Components/SubscriptionsPanel/subscriptionspanel.cpp @@ -7,16 +7,14 @@ #include "ui_subscriptionspanel.h" SubscriptionsPanel::SubscriptionsPanel( - const QList<TopicAndFieldFilter>* subscriptionsList) + const QList<TopicAndFieldFilter>& filters) : QWidget(nullptr), ui(new Ui::SubscriptionsPanel) { ui->setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose, true); - for (auto s : *subscriptionsList) - { - addSubscription(s); - } + for (auto filter : filters) + addSubscription(filter); connect(ui->button_addTopic, &QPushButton::clicked, this, &SubscriptionsPanel::onAddTopicClicked); diff --git a/Components/SubscriptionsPanel/subscriptionspanel.h b/Components/SubscriptionsPanel/subscriptionspanel.h index a38bf4d4d688db0d685db5d9b02e8d8fc0de8cda..e84eac2abefeb0821ee9ec395162905fde0393b5 100644 --- a/Components/SubscriptionsPanel/subscriptionspanel.h +++ b/Components/SubscriptionsPanel/subscriptionspanel.h @@ -17,8 +17,7 @@ class SubscriptionsPanel : public QWidget Q_OBJECT public: - explicit SubscriptionsPanel( - const QList<TopicAndFieldFilter>* subscriptionsList); + explicit SubscriptionsPanel(const QList<TopicAndFieldFilter>& filters); ~SubscriptionsPanel(); void addSubscription(const TopicAndFieldFilter& filter); diff --git a/Modules/Graph/Graph.cpp b/Modules/Graph/Graph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..37da61de630bbf0a58b49d6fa598ef40036821c2 --- /dev/null +++ b/Modules/Graph/Graph.cpp @@ -0,0 +1,271 @@ +#include "Graph.h" + +#include <Components/ContextMenuSeparator/contextmenuseparator.h> +#include <Components/SubscriptionsPanel/subscriptionspanel.h> +#include <Core/modulemessagesbroker.h> + +#include <QDebug> +#include <QTimer> +#include <algorithm> + +Graph::Graph(QWidget* parent) : DefaultModule(parent) +{ + setupUi(); + customContextMenuSetup(); + + connect(&updaterTimer, &QTimer::timeout, this, &Graph::onUpdateTimerTick); + updaterTimer.setSingleShot(false); + updaterTimer.start(updatePeriod); + + getCore()->getModuleMessagesBroker()->subscribe( + {"*"}, this, [this](const ModuleMessage& msg) { onMsgReceived(msg); }); +} + +Graph::~Graph() {} + +QWidget* Graph::toWidget() { return this; } + +XmlObject Graph::toXmlObject() +{ + XmlObject obj(getName(ModuleId::GRAPH)); + + obj.addAttribute("stopped", stopped ? 1 : 0); + obj.addAttribute("following", following ? 1 : 0); + obj.addAttribute("y_lower_range", (float)plot->yAxis->range().lower); + obj.addAttribute("y_upper_range", (float)plot->yAxis->range().upper); + obj.addAttribute("x_lower_range", (float)plot->xAxis->range().lower); + obj.addAttribute("x_upper_range", (float)plot->xAxis->range().upper); + + for (int i = 0; i < filters.count(); i++) + { + XmlObject element("subscription"); + element.addAttribute("filter", filters[i].toString()); + obj.addChild(element); + } + + return obj; +} + +void Graph::fromXmlObject(const XmlObject& obj) +{ + if (obj.getObjectName() == getName(ModuleId::GRAPH)) + { + int tmp; + obj.getAttribute("stopped", tmp); + stopped = (tmp == 1); + obj.getAttribute("following", tmp); + following = (tmp == 1); + + float lowerRange, upperRange; + obj.getAttribute("y_lower_range", lowerRange); + obj.getAttribute("y_upper_range", upperRange); + plot->yAxis->setRange(lowerRange, upperRange); + obj.getAttribute("x_lower_range", lowerRange); + obj.getAttribute("x_upper_range", upperRange); + plot->xAxis->setRange(lowerRange, upperRange); + + for (int i = 0; i < obj.childCount(); i++) + { + XmlObject child = obj.childAt(i); + + if (child.getObjectName() == "subscription") + { + auto filter = TopicAndFieldFilter::fromStringUnsafe( + child.getAttribute("filter")); + onSubscriptionAdded(filter); + } + } + } +} + +void Graph::onSubscribeClicked() +{ + SubscriptionsPanel* panel = new SubscriptionsPanel(filters); + panel->setWindowTitle("Graph subscriptions"); + connect(panel, &SubscriptionsPanel::SubscriptionAdded, this, + &Graph::onSubscriptionAdded); + connect(panel, &SubscriptionsPanel::SubscriptionRemoved, this, + &Graph::onSubscriptionRemoved); + panel->show(); +} + +void Graph::onClearClicked() +{ + for (auto graph : graphs) + graph->data()->clear(); + + // plot->replot(); +} + +void Graph::onStopClicked(bool checked) +{ + stopped = checked; + + if (stopped) + updaterTimer.stop(); + else + updaterTimer.start(updatePeriod); +} + +void Graph::onFollowClicked(bool checked) { following = checked; } + +void Graph::onSubscriptionAdded(const TopicAndFieldFilter& filter) +{ + if (!filters.contains(filter)) + { + QCPGraph* graph = plot->addGraph(); + graph->setPen( + QPen(QColor(rand() % 255, rand() % 255, rand() % 255), 2)); + graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone, 2)); + graph->setSelectable(QCP::stNone); + graph->setName(filter.toString()); + + // Add the filter and the graph along with new buffers + filters.append(filter); + graphs.append(graph); + buffersX.append(QVector<double>()); + buffersY.append(QVector<double>()); + } +} + +void Graph::onSubscriptionRemoved(const TopicAndFieldFilter& filter) +{ + if (filters.contains(filter)) + { + int index = filters.indexOf(filter); + + filters.removeAt(index); + graphs.removeAt(index); + buffersX.removeAt(index); + buffersY.removeAt(index); + } +} + +void Graph::onUpdateTimerTick() +{ + bool newData = false; + double maxX = 0; + + // Check if new data items are available and redraw + for (int i = 0; i < filters.size(); i++) + { + QCPGraph* graph = graphs[i]; + QVector<double>& bufferX = buffersX[i]; + QVector<double>& bufferY = buffersY[i]; + + if (bufferX.size() > 0) + { + newData = true; + + graph->addData(bufferX, bufferY); + + for (auto tmp : bufferX) + if (tmp > maxX) + maxX = tmp; + + bufferX.clear(); + bufferY.clear(); + + // Check if there are too many data points + graph->data()->removeBefore(maxX - MAX_DATA_AGE); + } + } + + if (newData) + { + plot->replot(); + + if (following) + { + double size = plot->xAxis->range().size(); + plot->xAxis->setRange(maxX, size, Qt::AlignmentFlag::AlignRight); + } + } +} + +void Graph::onMsgReceived(const ModuleMessage& msg) +{ + if (stopped) + return; + + MessageField value; + + for (auto filter : filters) + { + if (filter.matchMessage(msg, value)) + { + int index = filters.indexOf(filter); + + QVector<double>& bufferX = buffersX[index]; + QVector<double>& bufferY = buffersY[index]; + + double x = msg.getField("timestamp").getUInteger(0) / 1e6; + double y = value.getDouble(0); + + bufferX.append(x); + bufferY.append(y); + } + } +} + +void Graph::setupUi() +{ + QHBoxLayout* outerLayout = new QHBoxLayout; + outerLayout->setContentsMargins(0, 0, 0, 0); + + plot = new QCustomPlot; + outerLayout->addWidget(plot); + + setLayout(outerLayout); + + plot->legend->setVisible(true); + + // Allow user to drag axis ranges with mouse, zoom with mouse wheel and + // select graphs by clicking: + plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | + QCP::iSelectPlottables); +} + +void Graph::customContextMenuSetup() +{ + setContextMenuPolicy(Qt::CustomContextMenu); + + // Redirect event from the plot to the widget + plot->setContextMenuPolicy(Qt::CustomContextMenu); + connect(plot, &QCustomPlot::customContextMenuRequested, this, + &Graph::onCustomContextMenuRequested); +} + +void Graph::onCustomContextMenuRequested(const QPoint& pos) +{ + QMenu menu; + + // Subscribe -> Edit graph series + QAction* subscribe = new QAction("Subscribe"); + connect(subscribe, &QAction::triggered, this, &Graph::onSubscribeClicked); + menu.addAction(subscribe); + + // Clear -> Removes all data currently on the plot + QAction* clear = new QAction("Clear"); + connect(clear, &QAction::triggered, this, &Graph::onClearClicked); + menu.addAction(clear); + + // Stop -> Pauses the graph + QAction* stop = new QAction("Stop"); + stop->setCheckable(true); + stop->setChecked(stopped); + connect(stop, &QAction::triggered, this, &Graph::onStopClicked); + menu.addAction(stop); + + // Follow -> Automatically move the graph to follow new data + QAction* follow = new QAction("Follow"); + follow->setCheckable(true); + follow->setChecked(following); + connect(follow, &QAction::triggered, this, &Graph::onFollowClicked); + menu.addAction(follow); + + // Add a separator + menu.addSeparator(); + + emit getModuleEventsHandler()->contextMenuRequest(menu, mapToGlobal(pos)); +} \ No newline at end of file diff --git a/Modules/Graph/Graph.h b/Modules/Graph/Graph.h new file mode 100644 index 0000000000000000000000000000000000000000..e595a701c2d5688c1dca609e221790ac37dc8938 --- /dev/null +++ b/Modules/Graph/Graph.h @@ -0,0 +1,54 @@ +#pragma once + +#include <Core/Message/modulemessage.h> +#include <Core/Message/topicandfieldfilter.h> +#include <Core/QCustomPlot/QCustomPlot.h> +#include <Core/module.h> +#include <Modules/DefaultModule/defaultmodule.h> + +#include <QList> +#include <QTimer> +#include <QWidget> + +class Graph : public DefaultModule +{ + Q_OBJECT + + static constexpr int MAX_DATA_AGE = 30 * 60; // [s] + +public: + explicit Graph(QWidget* parent = nullptr); + ~Graph(); + + QWidget* toWidget() override; + XmlObject toXmlObject() override; + void fromXmlObject(const XmlObject& xmlObject) override; + +private slots: + void onSubscribeClicked(); + void onClearClicked(); + void onStopClicked(bool checked); + void onFollowClicked(bool checked); + void onSubscriptionAdded(const TopicAndFieldFilter& filter); + void onSubscriptionRemoved(const TopicAndFieldFilter& filter); + void onUpdateTimerTick(); + void onMsgReceived(const ModuleMessage& msg); + +private: + void setupUi(); + void customContextMenuSetup(); + void onCustomContextMenuRequested(const QPoint& pos) override; + + QCustomPlot* plot; + + QList<TopicAndFieldFilter> filters; + QList<QCPGraph*> graphs; + QList<QVector<double>> buffersX; + QList<QVector<double>> buffersY; + + QTimer updaterTimer; + int updatePeriod = 1000 / 10; + + bool stopped = false; + bool following = true; +}; diff --git a/Modules/Graph/graphmodule.cpp b/Modules/Graph/graphmodule.cpp deleted file mode 100644 index e92d80cbfb4235d67d923688901f8f2c36ed6cf4..0000000000000000000000000000000000000000 --- a/Modules/Graph/graphmodule.cpp +++ /dev/null @@ -1,331 +0,0 @@ -#include "graphmodule.h" - -#include <QDebug> -#include <QTimer> - -#include "Components/ContextMenuSeparator/contextmenuseparator.h" -#include "Components/SubscriptionsPanel/subscriptionspanel.h" -#include "Core/modulemessagesbroker.h" -#include "ui_graphmodule.h" - -GraphModule::GraphModule(QWidget* parent) - : DefaultModule(parent), ui(new Ui::GraphModule) -{ - ui->setupUi(this); - defaultContextMenuSetup(); - buildCentralGraphView(); - ui->centralLayout->addWidget(&graphCentralView); - connect(&updaterTimer, &QTimer::timeout, this, - &GraphModule::onUpdateTimerTick); - updaterTimer.setSingleShot(false); - updaterTimer.start(updatePeriod); - - getCore()->getModuleMessagesBroker()->subscribe( - {"*"}, this, [this](const ModuleMessage& msg) { onMsgReceived(msg); }); -} - -GraphModule::~GraphModule() -{ - // QCPGraph are destroyed automatically - delete ui; -} - -void GraphModule::buildCentralGraphView() -{ - setTheme(); - - graphCentralView.yAxis2->setVisible(true); - graphCentralView.yAxis2->setTicks(false); - graphCentralView.yAxis2->setTickLabels(false); - - // graphCentralView.xAxis2->setVisible(true); - // textTicker = QSharedPointer<QCPAxisTickerText>(new QCPAxisTickerText()); - // cPlot.xAxis2->setTicker(textTicker); - // graphCentralView.xAxis2->setTickLabels(true); - - // QSharedPointer<QCPAxisTickerTime> dateTimeTicker(new - // QCPAxisTickerTime); graphCentralView.xAxis->setTicker(dateTimeTicker); - // QDateTime rangeLowerBound = QDateTime::currentDateTime().addDays(-2); - // double now = QDateTime::currentDateTime().toTime_t(); - // QDateTime rangeUpperBound = QDateTime::currentDateTime().addDays(+2); - // graphCentralView.xAxis->setRange(now, - // QCPAxisTickerDateTime::(rangeUpperBound)); - // dateTimeTicker->setTimeFormat(dateFormat); - - graphCentralView.legend->setVisible(true); - - // make left and bottom axes always transfer their ranges to right and top - // axes: - connect(graphCentralView.xAxis, SIGNAL(rangeChanged(QCPRange)), - graphCentralView.xAxis2, SLOT(setRange(QCPRange))); - connect(graphCentralView.yAxis, SIGNAL(rangeChanged(QCPRange)), - graphCentralView.yAxis2, SLOT(setRange(QCPRange))); - - // Allow user to drag axis ranges with mouse, zoom with mouse wheel and - // select graphs by clicking: - graphCentralView.setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | - QCP::iSelectPlottables); - - // Enable context menu - graphCentralView.setContextMenuPolicy(Qt::CustomContextMenu); - // connect(&graphCentralView,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(onCustomContextMenuRequested(QPoint))); - connect(&graphCentralView, &QCustomPlot::customContextMenuRequested, this, - &GraphModule::onCustomContextMenuRequested); - // connect(customPlot,SIGNAL(selectionChangedByUser()),this,SLOT(selectedGraphChange())); -} - -void GraphModule::setTheme() -{ - // QColor accentColor; - // QColor themeColor; - // QColor themeBackgroundColor; - // QColor traceColor; - - // accentColor = QColor(78, 156, 207); - // traceColor = accentColor; - // themeColor = QColor(Qt::gray); - // themeBackgroundColor = QColor(50, 50, 50); - - // foreach(QCPAxisRect* rect, graphCentralView.axisRects()){ - // foreach(QCPAxis* axis, rect->axes()){ - // axis->setLabelColor(themeColor); - // axis->setBasePen(QPen(themeColor, 1)); - // axis->setTickPen(QPen(themeColor, 1)); - // axis->setSubTickPen(QPen(themeColor, 1)); - // axis->setTickLabelColor(themeColor); - // axis->grid()->setPen(QPen(themeColor, 0.5, Qt::DotLine)); - // axis->grid()->setSubGridVisible(false); - - // axis->setSelectedTickLabelColor(accentColor); - // axis->setSelectedLabelColor(accentColor); - // axis->setSelectedBasePen(QPen(accentColor, 1)); - // axis->setSelectedSubTickPen(QPen(accentColor, 1)); - // axis->setSelectedTickPen(QPen(accentColor, 1)); - // } - // } - // graphCentralView.setBackground(QBrush(themeBackgroundColor)); - // replotAll(); -} - -void GraphModule::onUpdateTimerTick() { replotAll(); } - -QCPGraph* GraphModule::instantiateNewGraph() -{ - QCPGraph* graph = graphCentralView.addGraph(); - int r = rand() % 255; - int g = rand() % 255; - int b = rand() % 255; - graph->setPen(QPen(QColor(r, g, b), 2)); - graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 3)); - graph->setSelectable(QCP::stSingleData); - return graph; -} - -QWidget* GraphModule::toWidget() { return this; } - -XmlObject GraphModule::toXmlObject() -{ - XmlObject obj(getName(ModuleId::GRAPH)); - for (int i = 0; i < subsFilters.count(); i++) - { - XmlObject subscription("Subscription"); - subscription.addAttribute("Value", subsFilters[i].toString()); - obj.addChild(subscription); - } - return obj; -} - -void GraphModule::fromXmlObject(const XmlObject& xmlObject) -{ - if (xmlObject.getObjectName() == getName(ModuleId::GRAPH)) - { - for (int i = 0; i < xmlObject.childCount(); i++) - { - XmlObject child = xmlObject.childAt(i); - if (child.getObjectName() == "Subscription") - { - auto subscription = TopicAndFieldFilter::fromStringUnsafe( - child.getAttribute("Value")); - onSubscriptionAdded(subscription); - } - } - } -} - -void GraphModule::onSubscribeClicked() -{ - SubscriptionsPanel* sPanel = new SubscriptionsPanel(&subsFilters); - sPanel->setWindowTitle("Graph Subscriptions"); - connect(sPanel, &SubscriptionsPanel::SubscriptionAdded, this, - &GraphModule::onSubscriptionAdded); - connect(sPanel, &SubscriptionsPanel::SubscriptionRemoved, this, - &GraphModule::onSubscriptionRemoved); - sPanel->show(); -} - -void GraphModule::onSubscriptionAdded(const TopicAndFieldFilter& filter) -{ - - QCPGraph* graph = instantiateNewGraph(); - graph->setName(filter.toString()); - subsFilters.append(filter); - subsGraphs.append(graph); - - // Da rimuovere per performance - graphCentralView.replot(); -} - -void GraphModule::onSubscriptionRemoved(const TopicAndFieldFilter& filter) -{ - int i = subsFilters.indexOf(filter); - - if (i != -1) - { - subsFilters.removeAt(i); - graphCentralView.removeGraph(subsGraphs[i]); - subsGraphs.removeAt(i); - } - - // Da rimuovere per performance - graphCentralView.replot(); -} - -void GraphModule::onMsgReceived(const ModuleMessage& msg) -{ - if (stopPlot) - return; - - MessageField value; - for (int i = 0; i < subsFilters.size(); i++) - { - if (subsFilters[i].matchMessage(msg, value)) - { - QCPGraph* graph = subsGraphs[i]; - - double x = 0, y = 0; - x = msg.getField("timestamp").getUInteger(0) / 1e6; - y = value.getDouble(0.0); - if (graph != nullptr) - { - graph->addData(x, y); - // Da rimuovere per performance - // replotAll(); - } - } - } -} - -void GraphModule::setFollowedGraphIndex(bool checked) -{ - if (checked) - { - QCPGraph* selectedGraph = getSelectedGraph(); - - if (selectedGraph) - { - - for (int i = 0; i < graphCentralView.graphCount(); i++) - { - if (selectedGraph == graphCentralView.graph(i)) - followedGraphIndex = i; - } - } - else if (graphCentralView.graphCount() > 0) - { - // If no graph is selected, select the first graph - followedGraphIndex = 0; - } - } - else - { - followedGraphIndex = -1; - } -} - -void GraphModule::onClearClicked() -{ - for (QCPGraph* g : subsGraphs) - { - g->data()->clear(); - } - - replotAll(); -} - -void GraphModule::onStopClicked(bool checked) -{ - stopPlot = checked; - - if (stopPlot) - updaterTimer.stop(); - else - { - updaterTimer.start(updatePeriod); - } -} - -QCPGraph* GraphModule::getSelectedGraph() -{ - QList<QCPGraph*> selection; - // if(graph) - selection = graphCentralView.selectedGraphs(); - if (selection.size() > 0) - { - return selection.first(); - } - return nullptr; -} - -void GraphModule::centerView(const QCPGraph* graph) -{ - if (!graph->data()->isEmpty()) - { - double lastKey = (graph->data()->constEnd() - 1)->key; - double lastValue = (graph->data()->constEnd() - 1)->value; - double size_x = graphCentralView.xAxis->range().size(); - double size_y = graphCentralView.yAxis->range().size(); - graphCentralView.xAxis->setRange(lastKey, size_x, - Qt::AlignmentFlag::AlignRight); - graphCentralView.yAxis->setRange(lastValue, size_y, - Qt::AlignmentFlag::AlignCenter); - } -} - -void GraphModule::replotAll() -{ - if (followedGraphIndex < graphCentralView.graphCount() && - followedGraphIndex >= 0) - { - centerView(graphCentralView.graph(followedGraphIndex)); - } - graphCentralView.replot(); -} - -void GraphModule::addCustomActionsToMenu() -{ - QAction* subscribe = new QAction("Subscribe"); - connect(subscribe, &QAction::triggered, this, - &GraphModule::onSubscribeClicked); - - QAction* clear = new QAction("Clear"); - connect(clear, &QAction::triggered, this, &GraphModule::onClearClicked); - - QAction* stop = new QAction("Stop"); - stop->setCheckable(true); - stop->setChecked(stopPlot); - connect(stop, &QAction::triggered, this, &GraphModule::onStopClicked); - - QAction* follow = new QAction("Follow"); - follow->setCheckable(true); - if (followedGraphIndex >= 0) - { - follow->setChecked(true); - } - connect(follow, &QAction::triggered, this, - &GraphModule::setFollowedGraphIndex); - - addActionToMenu(follow); - addActionToMenu(subscribe); - addActionToMenu(clear); - addActionToMenu(stop); -} diff --git a/Modules/Graph/graphmodule.h b/Modules/Graph/graphmodule.h deleted file mode 100644 index 773e781252d418f4befaf23d8425af6c1bfe57a5..0000000000000000000000000000000000000000 --- a/Modules/Graph/graphmodule.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef GRAPHMODULE_H -#define GRAPHMODULE_H - -#include <Core/QCustomPlot/QCustomPlot.h> - -#include <QList> -#include <QTimer> -#include <QWidget> - -#include "Core/Message/modulemessage.h" -#include "Core/Message/topicandfieldfilter.h" -#include "Core/module.h" -#include "Modules/DefaultModule/defaultmodule.h" - -namespace Ui -{ -class GraphModule; -} - -class GraphModule : public DefaultModule -{ - Q_OBJECT - -public: - explicit GraphModule(QWidget* parent = nullptr); - ~GraphModule(); - - QWidget* toWidget() override; - XmlObject toXmlObject() override; - void fromXmlObject(const XmlObject& xmlObject) override; - - void centerView(const QCPGraph* graph); - void replotAll(); - -public slots: - void onSubscribeClicked(); - void onSubscriptionAdded(const TopicAndFieldFilter& filter); - void onSubscriptionRemoved(const TopicAndFieldFilter& filter); - void onMsgReceived(const ModuleMessage& msg); - void setFollowedGraphIndex(bool checked); - void onClearClicked(); - void onStopClicked(bool checked); - -protected: - void buildCentralGraphView(); - QCPGraph* instantiateNewGraph(); - void addCustomActionsToMenu() override; - QCPGraph* getSelectedGraph(); - void setTheme(); - void onUpdateTimerTick(); - -private: - Ui::GraphModule* ui; - QCustomPlot graphCentralView; - - QList<TopicAndFieldFilter> subsFilters; - QList<QCPGraph*> subsGraphs; - - int followedGraphIndex = -1; - QString dateFormat = "%h:%m:%s (%z)"; //"HH:mm:ss\n(zzz)"; - // QSharedPointer<QCPAxisTickerDateTime> dateTicker; - QTimer updaterTimer; - int updatePeriod = 1000; // [ms] - bool stopPlot = false; -}; - -#endif // GRAPHMODULE_H diff --git a/Modules/Graph/graphmodule.ui b/Modules/Graph/graphmodule.ui deleted file mode 100644 index a3246f844523b0e2185072726e35d39a0cae2f72..0000000000000000000000000000000000000000 --- a/Modules/Graph/graphmodule.ui +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>GraphModule</class> - <widget class="QWidget" name="GraphModule"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <layout class="QVBoxLayout" name="centralLayout"/> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp b/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp index afeb21faf01ab4fd6d8b26f0e1a5a85902dcf456..47300263e322d61e5a7c51cdebd0a91d65b467b2 100644 --- a/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp +++ b/Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp @@ -127,7 +127,7 @@ void IncomingMessagesViewerModule::addCustomActionsToMenu() connect(manage, &QAction::triggered, this, [this]() { - auto* panel = new SubscriptionsPanel(&filters); + auto* panel = new SubscriptionsPanel(filters); panel->setWindowTitle("IncomingMessagesViewer subscriptions"); connect(panel, &SubscriptionsPanel::SubscriptionAdded, this, &IncomingMessagesViewerModule::addSubscription); diff --git a/Modules/moduleslist.cpp b/Modules/moduleslist.cpp index d50ed9862862ba32ca33e817385dd14cc655130e..0fb40f009506af33133b947edb6d85ac0a57fd2a 100644 --- a/Modules/moduleslist.cpp +++ b/Modules/moduleslist.cpp @@ -1,11 +1,11 @@ #include "moduleslist.h" #include <Components/ModulesPicker/modulespicker.h> -#include <Modules/CommandPad/commandpad.h> +#include <Modules/CommandPad/CommandPad.h> #include <Modules/CompactCommandPad/CompactCommandPad.h> #include <Modules/Empty/emptymodule.h> #include <Modules/FileStream/filestreammodule.h> -#include <Modules/Graph/graphmodule.h> +#include <Modules/Graph/Graph.h> #include <Modules/IncomingMessagesViewer/incomingmessagesviewermodule.h> #include <Modules/Mavlink/mavlinkmodule.h> #include <Modules/Mavlink/mavlinkrocketmsgtestingmodule.h> @@ -77,13 +77,11 @@ void ModulesList::createModuleList() addModuleInfo(testModule); #endif -#ifdef GRAPHMODULE_H ModuleInfo graphModule(ModuleId::GRAPH, "Graph", ModuleCategory::DATAVISUAL); - graphModule.setFactory([]() { return new GraphModule(); }); + graphModule.setFactory([]() { return new Graph(); }); graphModule.addModuleSourceFiles("Modules/Graph/"); addModuleInfo(graphModule); -#endif #ifdef OUTCOMINGMESSAGESVIEWERMODULE_H ModuleInfo outMsgViewer(ModuleId::OUTCOMINGMESSAGEVIEWER, diff --git a/SkywardHub.pro b/SkywardHub.pro index fb60c7a1b4b7e824b21ed2a69262ce3529846737..53d3865d59dd7fffa7b2cb2904c026e04711a8f0 100644 --- a/SkywardHub.pro +++ b/SkywardHub.pro @@ -38,7 +38,7 @@ SOURCES += \ Modules/DefaultModule/defaultmodule.cpp \ Modules/Empty/emptymodule.cpp \ Modules/FileStream/filestreammodule.cpp \ - Modules/Graph/graphmodule.cpp \ + Modules/Graph/Graph.cpp \ Modules/IncomingMessagesViewer/incomingmessagesviewermodule.cpp \ Modules/MainWindow/skywardhubmainwindow.cpp \ Modules/MainWindow/window.cpp \ @@ -95,7 +95,7 @@ HEADERS += \ Modules/DefaultModule/defaultmodule.h \ Modules/Empty/emptymodule.h \ Modules/FileStream/filestreammodule.h \ - Modules/Graph/graphmodule.h \ + Modules/Graph/Graph.h \ Modules/IncomingMessagesViewer/incomingmessagesviewermodule.h \ Modules/MainWindow/skywardhubmainwindow.h \ Modules/MainWindow/window.h \ @@ -130,7 +130,6 @@ FORMS += \ Components/SubscriptionsPanel/subscriptionspanel.ui \ Modules/Empty/emptymodule.ui \ Modules/FileStream/filestreammodule.ui \ - Modules/Graph/graphmodule.ui \ Modules/MainWindow/skywardhubmainwindow.ui \ Modules/MainWindow/window.ui \ Modules/Mavlink/mavlinkrocketmsgtestingmodule.ui \