diff --git a/.vscode/settings.json b/.vscode/settings.json index 2b0522bb4f21daeda5d494bc8d6901d06fe98155..1d109b3056c36df9b04dccc0160d07304777ba1a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -98,7 +98,10 @@ "qpushbutton": "cpp", "qdialog": "cpp", "valarray": "cpp", - "*.ipp": "cpp" + "*.ipp": "cpp", + "qmap": "cpp", + "hash_map": "cpp", + "unordered_set": "cpp" }, "editor.defaultFormatter": "chiehyu.vscode-astyle", "[xml]": { diff --git a/Modules/CommandPad/CommandPad.cpp b/Modules/CommandPad/CommandPad.cpp index 176f70fffb979a23cd719e1f1fecbadb09ccdfe0..62dbeac5e1b58e3378ab6653ef9ad6f46b02f453 100644 --- a/Modules/CommandPad/CommandPad.cpp +++ b/Modules/CommandPad/CommandPad.cpp @@ -91,8 +91,6 @@ void CommandPad::setupUi() if (formElements.contains(key)) { auto message = formElements[key]->prepareMessage(key); - qDebug() << message.getTopic().toString(); - qDebug() << message.toString(); getCore()->getModuleMessagesBroker()->publish(message); } }); diff --git a/Modules/CompactCommandPad/CommandSelector.cpp b/Modules/CompactCommandPad/CommandSelector.cpp index a08764533f7b2147b573595d3add0374e7d61ed1..06efd3c8fd677fbf08dfb869b08fe60532486153 100644 --- a/Modules/CompactCommandPad/CommandSelector.cpp +++ b/Modules/CompactCommandPad/CommandSelector.cpp @@ -40,10 +40,6 @@ void CommandSelector::fromXmlObject(const XmlObject& obj) selectedLabel = obj.getAttribute("label"); lineEdit->setText(selectedLabel); selected = !selectedLabel.isEmpty(); - - qDebug() << "Command selector setup"; - qDebug() << selectedMessage.getTopic().toString(); - qDebug() << selectedMessage.toString(); } } } diff --git a/Modules/CompactCommandPad/CompactCommandPad.cpp b/Modules/CompactCommandPad/CompactCommandPad.cpp index 92f68daa57e5c16cd346336fb63a58dde2ddba53..1b50605b276719151ccbbc620e8512644748a66e 100644 --- a/Modules/CompactCommandPad/CompactCommandPad.cpp +++ b/Modules/CompactCommandPad/CompactCommandPad.cpp @@ -54,11 +54,7 @@ void CompactCommandPad::setupUi() [=]() { if (selected) - { - qDebug() << selectedMessage.getTopic().toString(); - qDebug() << selectedMessage.toString(); getCore()->getModuleMessagesBroker()->publish(selectedMessage); - } }); setLayout(outerLayout); diff --git a/Modules/CompactCommandPad/CompactCommandPad.h b/Modules/CompactCommandPad/CompactCommandPad.h index 7f7518fc1510b08da76bb54521fdfdbf2dc527b7..69993d2f7e456889102ff6490144f65d0a6bc46c 100644 --- a/Modules/CompactCommandPad/CompactCommandPad.h +++ b/Modules/CompactCommandPad/CompactCommandPad.h @@ -21,7 +21,7 @@ private slots: private: void setupUi(); - void addCustomActionsToMenu(); + void addCustomActionsToMenu() override; CommandSelector* selector; QPushButton* button; diff --git a/Modules/StateViewer/StateViewer.cpp b/Modules/StateViewer/StateViewer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2490b51938b4daab2d306745f3a4dab1cb6a4618 --- /dev/null +++ b/Modules/StateViewer/StateViewer.cpp @@ -0,0 +1,137 @@ +#include "StateViewer.h" + +#include <Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h> +#include <Core/modulemessagesbroker.h> + +StateViewerModule::StateViewerModule(QWidget* parent) : DefaultModule(parent) +{ + setupUi(); + defaultContextMenuSetup(); +} + +StateViewerModule::~StateViewerModule() +{ + getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(), + this); +} + +QWidget* StateViewerModule::toWidget() { return this; } + +XmlObject StateViewerModule::toXmlObject() +{ + XmlObject obj(getName(ModuleId::STATEVIEWER)); + + obj.addAttribute("filter", filter.toString()); + + return obj; +} + +void StateViewerModule::fromXmlObject(const XmlObject& xmlObject) +{ + if (xmlObject.getObjectName() == getName(ModuleId::STATEVIEWER)) + { + auto filter = TopicAndFieldFilter::fromStringUnsafe( + xmlObject.getAttribute("filter")); + setFilter(filter); + } +} + +void StateViewerModule::setupUi() +{ + outerLayout = new QHBoxLayout; + outerLayout->setContentsMargins(0, 0, 0, 0); + outerLayout->setSpacing(0); + + for (auto labelText : StatesList::statesLabels) + { + QLabel* label = new QLabel; + label->setText(labelText); + label->setAlignment(Qt::AlignCenter); + label->setContentsMargins(4, 4, 4, 4); + outerLayout->addWidget(label); + } + + setLayout(outerLayout); +} + +void StateViewerModule::addCustomActionsToMenu() +{ + QAction* action = new QAction("Choose topic and field"); + connect(action, &QAction::triggered, this, + &StateViewerModule::onConfigureClicked); + + addActionToMenu(action); +} + +void StateViewerModule::onConfigureClicked() +{ + TopicAndFieldFilterSelector::selectFilter( + filter, + [this](const TopicAndFieldFilter& newFilter) { setFilter(newFilter); }); +} + +void StateViewerModule::setFilter(const TopicAndFieldFilter& newFilter) +{ + getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(), + this); + getCore()->getModuleMessagesBroker()->subscribe( + newFilter.getTopicFilter(), this, + [this](const ModuleMessage& msg) { onMsgReceived(msg); }); + filter = newFilter; +} + +void StateViewerModule::onMsgReceived(const ModuleMessage& msg) +{ + MessageField field; + + // Check if the message matches the filter + if (!filter.matchMessage(msg, field)) + return; + + StatesList::State state = + static_cast<StatesList::State>(field.getUInteger(-1)); + + if (state == StatesList::State::INVALID) + { + qDebug() << "Invalid state"; + return; + } + + if (state != currentState) + { + currentState = static_cast<StatesList::State>(state); + + QString baseStyle = + "border-bottom-width:1px;border-left-width:1px;border-top-width:" + "1px;border-radius:0;"; + QString currentStateStyle = + "background-color:yellow; color:black;" + baseStyle; + QString completedStyle = "background-color:green;" + baseStyle; + QString errorStyle = "background-color:red;" + baseStyle; + + int index = StatesList::statesIndexes[currentState]; + auto label = outerLayout->itemAt(index)->widget(); + + if (currentState == StatesList::State::INIT) + label->setStyleSheet(currentStateStyle); + else if (currentState == StatesList::State::INIT_ERROR) + label->setStyleSheet(errorStyle); + else if (currentState > StatesList::State::INIT_ERROR) + label->setStyleSheet(currentStateStyle); + + // Set as completed every state before the current + for (int i = index - 1; i >= 0; i--) + outerLayout->itemAt(i)->widget()->setStyleSheet(completedStyle); + + // Reset every state after the current + for (int i = index + 1; i < StatesList::statesLabels.count(); i++) + outerLayout->itemAt(i)->widget()->setStyleSheet(baseStyle); + + auto tmp = outerLayout->itemAt(StatesList::statesLabels.count() - 1) + ->widget() + ->styleSheet(); + outerLayout->itemAt(StatesList::statesLabels.count() - 1) + ->widget() + ->setStyleSheet(tmp + "border-right-width:1px;"); + } +} diff --git a/Modules/StateViewer/stateviewermodule.h b/Modules/StateViewer/StateViewer.h similarity index 63% rename from Modules/StateViewer/stateviewermodule.h rename to Modules/StateViewer/StateViewer.h index 2e6e5da0d7cd8c9980f9df486a449ab2cee14573..0ae00252d097e74a79d0480cc673d772fd0cd1f5 100644 --- a/Modules/StateViewer/stateviewermodule.h +++ b/Modules/StateViewer/StateViewer.h @@ -1,17 +1,14 @@ #ifndef STATEVIEWERMODULE_H #define STATEVIEWERMODULE_H +#include <Core/Message/modulemessage.h> +#include <Core/Message/topicandfieldfilter.h> +#include <Modules/DefaultModule/defaultmodule.h> + #include <QLabel> #include <QWidget> -#include "Core/Message/modulemessage.h" -#include "Core/Message/topicandfieldfilter.h" -#include "Modules/DefaultModule/defaultmodule.h" - -namespace Ui -{ -class StateViewerModule; -} +#include "StatesList.h" class StateViewerModule : public DefaultModule { @@ -26,22 +23,17 @@ public: XmlObject toXmlObject() override; void fromXmlObject(const XmlObject& xmlObject) override; -protected: +private: + void setupUi(); void addCustomActionsToMenu() override; void onConfigureClicked(); void setFilter(const TopicAndFieldFilter& filter); void onMsgReceived(const ModuleMessage& msg); - void setState(int state); - void updateView(int state); -private: - Ui::StateViewerModule* ui; - TopicAndFieldFilter filter; + QHBoxLayout* outerLayout; - QList<QLabel*> labels; - - int currentState = -1; - QMap<int, int> labelsIndexes; + TopicAndFieldFilter filter; + StatesList::State currentState; }; #endif // STATEVIEWERMODULE_H diff --git a/Modules/StateViewer/StatesList.h b/Modules/StateViewer/StatesList.h new file mode 100644 index 0000000000000000000000000000000000000000..150a87ee4503715e6224a059e08c026e01f586c9 --- /dev/null +++ b/Modules/StateViewer/StatesList.h @@ -0,0 +1,45 @@ +#pragma once + +#include <QList> +#include <QMap> +#include <QString> + +namespace StatesList +{ + +enum class State : int +{ + INVALID = 0, + INIT, + INIT_ERROR, + TEST_MODE, + SENSORS_CALIBRATION, + ALGOS_CALIBRATION, + DISARMED, + ARMED, + ASCENDING, + DROGUE_DESCENT, + TERMINAL_DESCENT, + LANDED, +}; + +static const QList<QString> statesLabels{ + "INIT", "TEST\nMODE", "SENSORS\nCALIBRATION", "DISARMED", "ARMED", + "ASCENDING", "DROGUE\nDESCENT", "TERMINAL\nDESCENT", "LANDED", +}; + +static const QMap<State, int> statesIndexes{ + {State::INIT, 0}, + {State::INIT_ERROR, 0}, + {State::TEST_MODE, 1}, + {State::SENSORS_CALIBRATION, 2}, + {State::ALGOS_CALIBRATION, 2}, + {State::DISARMED, 3}, + {State::ARMED, 4}, + {State::ASCENDING, 5}, + {State::DROGUE_DESCENT, 6}, + {State::TERMINAL_DESCENT, 7}, + {State::LANDED, 8}, +}; + +} // namespace StatesList \ No newline at end of file diff --git a/Modules/StateViewer/stateviewermodule.cpp b/Modules/StateViewer/stateviewermodule.cpp deleted file mode 100644 index d88b34682f3a16c2d08bd48bd2a186b7ebe4712d..0000000000000000000000000000000000000000 --- a/Modules/StateViewer/stateviewermodule.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "stateviewermodule.h" - -#include <QInputDialog> -#include <QLineEdit> - -#include "Components/TopicAndFieldFilterSelector/topicandfieldfilterselector.h" -#include "Core/modulemessagesbroker.h" -#include "ui_stateviewermodule.h" - -enum states -{ - INVALID = 0, - INIT, - INIT_ERROR, - SENSORS_CALIBRATION, - ALGOS_CALIBRATION, - DISARMED, - TEST_MODE, - ARMED, - ASCENDING, - DROGUE_DESCENT, - TERMINAL_DESCENT, - LANDED -}; - -StateViewerModule::StateViewerModule(QWidget* parent) - : DefaultModule(parent), ui(new Ui::StateViewerModule) -{ - ui->setupUi(this); - defaultContextMenuSetup(); - - labels.append(ui->label_1_INIT); - labels.append(ui->label_2_TEST); - labels.append(ui->label_3_CALIBRATION); - labels.append(ui->label_4_DISARMED); - labels.append(ui->label_5_ARMED); - labels.append(ui->label_6_ASCENDING); - labels.append(ui->label_7_DROGUE); - labels.append(ui->label_8_TERMINAL); - labels.append(ui->label_9_END); - - labelsIndexes = { - {INIT, 0}, - {INIT_ERROR, 0}, - {TEST_MODE, 1}, - {SENSORS_CALIBRATION, 2}, - {ALGOS_CALIBRATION, 2}, - {DISARMED, 3}, - {ARMED, 4}, - {ASCENDING, 5}, - {DROGUE_DESCENT, 6}, - {TERMINAL_DESCENT, 7}, - {LANDED, 8}, - }; -} - -StateViewerModule::~StateViewerModule() -{ - getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(), - this); - delete ui; -} - -QWidget* StateViewerModule::toWidget() { return this; } - -XmlObject StateViewerModule::toXmlObject() -{ - XmlObject obj(getName(ModuleId::STATEVIEWER)); - - obj.addAttribute("filter", filter.toString()); - - return obj; -} - -void StateViewerModule::fromXmlObject(const XmlObject& xmlObject) -{ - if (xmlObject.getObjectName() == getName(ModuleId::STATEVIEWER)) - { - auto filter = TopicAndFieldFilter::fromStringUnsafe( - xmlObject.getAttribute("filter")); - setFilter(filter); - } -} - -void StateViewerModule::addCustomActionsToMenu() -{ - QAction* config = new QAction("Choose input topic and field"); - connect(config, &QAction::triggered, this, - &StateViewerModule::onConfigureClicked); - - addActionToMenu(config); -} - -void StateViewerModule::onConfigureClicked() -{ - TopicAndFieldFilterSelector::selectFilter( - filter, - [this](const TopicAndFieldFilter& filter) { setFilter(filter); }); -} - -void StateViewerModule::setFilter(const TopicAndFieldFilter& newFilter) -{ - getCore()->getModuleMessagesBroker()->unsubscribe(filter.getTopicFilter(), - this); - getCore()->getModuleMessagesBroker()->subscribe( - newFilter.getTopicFilter(), this, - [this](const ModuleMessage& msg) { onMsgReceived(msg); }); - filter = newFilter; -} - -void StateViewerModule::onMsgReceived(const ModuleMessage& msg) -{ - MessageField field; - - if (!filter.matchMessage(msg, field)) - return; - - int value = (int)field.getUInteger(-1); - if (value != -1) - setState(value); -} - -void StateViewerModule::setState(int state) -{ - if (state != currentState) - { - currentState = state; - updateView(state); - } -} - -void StateViewerModule::updateView(int state) -{ - QString currentStateStyle = "background-color:yellow; color:black;"; - QString completedStyle = "background-color:green;"; - QString errorStyle = "background-color:red;"; - - if (state == INIT) - { - ui->label_1_INIT->setStyleSheet(currentStateStyle); - } - else if (state == INIT_ERROR) - { - ui->label_1_INIT->setStyleSheet(errorStyle); - } - else if (state > INIT_ERROR && labelsIndexes.contains(state)) - { - int index = labelsIndexes[state]; - - if (index < labels.count()) - labels[index]->setStyleSheet(currentStateStyle); - } - - if (labelsIndexes.contains(state)) - { - int index = labelsIndexes[state]; - - // Set as completed every state before the current - for (int i = index - 1; i >= 0; i--) - labels[i]->setStyleSheet(completedStyle); - - // Reset every state after the current - for (int i = index + 1; i < labels.count(); i++) - labels[i]->setStyleSheet(""); - } -} diff --git a/Modules/StateViewer/stateviewermodule.ui b/Modules/StateViewer/stateviewermodule.ui deleted file mode 100644 index d489155124219990a9c97f3deae393b750035cdd..0000000000000000000000000000000000000000 --- a/Modules/StateViewer/stateviewermodule.ui +++ /dev/null @@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>StateViewerModule</class> - <widget class="QWidget" name="StateViewerModule"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>975</width> - <height>225</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QScrollArea" name="scrollArea"> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>953</width> - <height>203</height> - </rect> - </property> - <property name="styleSheet"> - <string notr="true">border: 1px solid grey; color: white;</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="4"> - <widget class="QLabel" name="label_5_ARMED"> - <property name="text"> - <string>ARMED</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_2_TEST"> - <property name="text"> - <string>TEST -MODE</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QLabel" name="label_3_CALIBRATION"> - <property name="text"> - <string>CALIBRATION</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="7"> - <widget class="QLabel" name="label_8_TERMINAL"> - <property name="text"> - <string>TERMINAL -DESCENT</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="5"> - <widget class="QLabel" name="label_6_ASCENDING"> - <property name="text"> - <string>ASCENDING</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="3"> - <widget class="QLabel" name="label_4_DISARMED"> - <property name="styleSheet"> - <string notr="true">border: 1px solid grey; color: white;</string> - </property> - <property name="text"> - <string>DISARMED</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="6"> - <widget class="QLabel" name="label_7_DROGUE"> - <property name="text"> - <string>DROGUE -DESCENT</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label_1_INIT"> - <property name="text"> - <string>INIT</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="0" column="8"> - <widget class="QLabel" name="label_9_END"> - <property name="text"> - <string>END -MISSION</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <resources /> - <connections /> -</ui> \ No newline at end of file diff --git a/Modules/moduleslist.cpp b/Modules/moduleslist.cpp index 2f95bff03cc1882c8b35e9041a5d53a9d7ac84e4..d50ed9862862ba32ca33e817385dd14cc655130e 100644 --- a/Modules/moduleslist.cpp +++ b/Modules/moduleslist.cpp @@ -12,7 +12,7 @@ #include <Modules/OutgoingMessagesViewer/outgoingmessagesviewermodule.h> #include <Modules/SkywardHub/skywardhubmodule.h> #include <Modules/Splitter/splittermodule.h> -#include <Modules/StateViewer/stateviewermodule.h> +#include <Modules/StateViewer/StateViewer.h> #include <Modules/Tabs/tabsmodule.h> #include <Modules/Test/testmodule.h> #include <Modules/TimerController/timercontrollermodule.h> diff --git a/SkywardHub.pro b/SkywardHub.pro index da3983b183ec9dc8b0cbbe97e763dc0026f6578f..f6e6fcb5b83ca289b0fe35e895bfc7f8900ed07f 100644 --- a/SkywardHub.pro +++ b/SkywardHub.pro @@ -54,7 +54,7 @@ SOURCES += \ Modules/SkywardHub/prefabviewelement.cpp \ Modules/SkywardHub/skywardhubmodule.cpp \ Modules/Splitter/splittermodule.cpp \ - Modules/StateViewer/stateviewermodule.cpp \ + Modules/StateViewer/StateViewer.cpp \ Modules/Tabs/tabsmodule.cpp \ Modules/Test/testmodule.cpp \ Modules/TimerController/timercontrollermodule.cpp \ @@ -113,7 +113,7 @@ HEADERS += \ Modules/SkywardHub/prefabviewelement.h \ Modules/SkywardHub/skywardhubmodule.h \ Modules/Splitter/splittermodule.h \ - Modules/StateViewer/stateviewermodule.h \ + Modules/StateViewer/StateViewer.h \ Modules/Tabs/tabsmodule.h \ Modules/Test/testmodule.h \ Modules/TimerController/timercontrollermodule.h \ @@ -139,7 +139,6 @@ FORMS += \ Modules/SkywardHub/prefabdialog.ui \ Modules/SkywardHub/prefabviewelement.ui \ Modules/SkywardHub/skywardhubmodule.ui \ - Modules/StateViewer/stateviewermodule.ui \ Modules/Test/testmodule.ui \ Modules/TimerController/timercontrollermodule.ui \ Modules/ValuesConverterViewer/valuesconverterviewermodule.ui \