mirror of
https://github.com/Sani7/remote-ui.git
synced 2026-10-27 06:01:14 +01:00
Client
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets Svg WebSockets)
|
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets Svg Protobuf Grpc)
|
||||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Svg WebSockets)
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Svg Protobuf Grpc)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
@@ -19,8 +19,6 @@ set(PROJECT_SOURCES
|
|||||||
helpers.hpp
|
helpers.hpp
|
||||||
ui_base.cpp
|
ui_base.cpp
|
||||||
ui_base.hpp
|
ui_base.hpp
|
||||||
web_socket_wrapper.cpp
|
|
||||||
web_socket_wrapper.hpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_executable(unisim_client
|
qt_add_executable(unisim_client
|
||||||
@@ -31,7 +29,6 @@ set_target_properties(
|
|||||||
unisim_client
|
unisim_client
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
AUTOMOC ON
|
AUTOMOC ON
|
||||||
AUTORCC ON
|
|
||||||
AUTOUIC ON
|
AUTOUIC ON
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,7 +40,7 @@ target_include_directories(unisim_client
|
|||||||
${PROJECT_BINARY_DIR}/
|
${PROJECT_BINARY_DIR}/
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(unisim_client PUBLIC Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::WebSockets spdlog magic_enum::magic_enum nlohmann_json::nlohmann_json git_tag qwt UI_enum)
|
target_link_libraries(unisim_client PUBLIC Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Protobuf Qt${QT_VERSION_MAJOR}::Grpc spdlog magic_enum::magic_enum qwt git_tag proto-ui-client)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
install(TARGETS unisim_client
|
install(TARGETS unisim_client
|
||||||
|
|||||||
+4
-4
@@ -9,7 +9,7 @@
|
|||||||
class UIFactory
|
class UIFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Creator = std::function<UI_base *(Web_socket_wrapper *web_socket, QWidget *)>;
|
using Creator = std::function<UI_base *(RemoteUiService::Client *s, QWidget *)>;
|
||||||
|
|
||||||
static UIFactory &instance()
|
static UIFactory &instance()
|
||||||
{
|
{
|
||||||
@@ -25,12 +25,12 @@ class UIFactory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_base *create(const QString &key, Web_socket_wrapper *w, QWidget *parent = nullptr) const
|
UI_base *create(const QString &key, RemoteUiService::Client *s, QWidget *parent = nullptr) const
|
||||||
{
|
{
|
||||||
auto it = m_creators.constFind(key);
|
auto it = m_creators.constFind(key);
|
||||||
if (it == m_creators.cend())
|
if (it == m_creators.cend())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return it.value()(w, parent);
|
return it.value()(s, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList keys() const
|
QStringList keys() const
|
||||||
@@ -50,7 +50,7 @@ class UIFactory
|
|||||||
Register##TYPE() \
|
Register##TYPE() \
|
||||||
{ \
|
{ \
|
||||||
UIFactory::instance().registerType(TYPE::name(), \
|
UIFactory::instance().registerType(TYPE::name(), \
|
||||||
[](Web_socket_wrapper *w, QWidget *p) { return new TYPE(w, p); }); \
|
[](RemoteUiService::Client *s, QWidget *p) { return new TYPE(s, p); }); \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
static Register##TYPE register_##TYPE; \
|
static Register##TYPE register_##TYPE; \
|
||||||
|
|||||||
+71
-56
@@ -3,33 +3,35 @@
|
|||||||
#include "git_version.h"
|
#include "git_version.h"
|
||||||
#include "ui_base.hpp"
|
#include "ui_base.hpp"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "web_socket_wrapper.hpp"
|
#include "messages_client.grpc.qpb.h"
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
#include <magic_enum/magic_enum.hpp>
|
#include <magic_enum/magic_enum.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <QGrpcHttp2Channel>
|
||||||
|
#include <QGrpcChannelOptions>
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
#include <QSslSocket>
|
||||||
|
|
||||||
MainWindow::MainWindow(QUrl ws_url, QString sim, QWidget *parent)
|
typedef UI_base *(*Get_UI)(RemoteUiService::Client *, QWidget *);
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QUrl server_url, QString sim, QWidget *parent)
|
||||||
: QMainWindow(parent), ui(new Ui::MainWindow), m_error(new QMessageBox()),
|
: QMainWindow(parent), ui(new Ui::MainWindow), m_error(new QMessageBox()),
|
||||||
m_web_socket(new Web_socket_wrapper(ws_url))
|
m_remote_ui_client(new RemoteUiService::Client()), m_ping(new QTimer())
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->statusbar->showMessage(QString("Version: %1-%2%3")
|
ui->statusbar->showMessage(QString("Version: %1-%2%3")
|
||||||
.arg(Git_version::branch)
|
.arg(Git_version::branch)
|
||||||
.arg(Git_version::shortSha1)
|
.arg(Git_version::shortSha1)
|
||||||
.arg(Git_version::dirty ? "-dirty" : ""));
|
.arg(Git_version::dirty ? "-dirty" : ""));
|
||||||
connect(m_web_socket.get(), &Web_socket_wrapper::log_signal, this,
|
m_ping->setInterval(std::chrono::milliseconds(1000));
|
||||||
[](const char *filename_in, int line_in, const char *funcname_in, int level, QString msg) {
|
|
||||||
if (spdlog::default_logger_raw()->should_log((spdlog::level::level_enum)level))
|
|
||||||
spdlog::default_logger_raw()->log(spdlog::source_loc{filename_in, line_in, funcname_in},
|
|
||||||
(spdlog::level::level_enum)level, msg.toStdString());
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const QString &name : UIFactory::instance().keys())
|
for (const QString &name : UIFactory::instance().keys())
|
||||||
{
|
{
|
||||||
if (auto *w = UIFactory::instance().create(name, m_web_socket.get(), this))
|
if (auto *w = UIFactory::instance().create(name, m_remote_ui_client.get(), this))
|
||||||
{
|
{
|
||||||
w->set_name(name);
|
w->set_name(name);
|
||||||
m_sims.insert(std::make_pair(name, w));
|
m_sims.insert(std::make_pair(name, w));
|
||||||
@@ -42,9 +44,6 @@ MainWindow::MainWindow(QUrl ws_url, QString sim, QWidget *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert debug sims here
|
|
||||||
// INSERT_SIMULATOR(SIM_NAME);
|
|
||||||
|
|
||||||
setWindowTitle("Unisim cpp client");
|
setWindowTitle("Unisim cpp client");
|
||||||
m_error->setIcon(QMessageBox::Critical);
|
m_error->setIcon(QMessageBox::Critical);
|
||||||
m_error->setWindowTitle("Critical");
|
m_error->setWindowTitle("Critical");
|
||||||
@@ -52,12 +51,42 @@ MainWindow::MainWindow(QUrl ws_url, QString sim, QWidget *parent)
|
|||||||
QPushButton *exit_app = m_error->addButton("Exit Application", QMessageBox::AcceptRole);
|
QPushButton *exit_app = m_error->addButton("Exit Application", QMessageBox::AcceptRole);
|
||||||
m_error->addButton("Close", QMessageBox::RejectRole);
|
m_error->addButton("Close", QMessageBox::RejectRole);
|
||||||
connect(exit_app, &QPushButton::clicked, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
connect(exit_app, &QPushButton::clicked, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
||||||
ui->connection->setText("Connected to " + ws_url.toString());
|
ui->connection->setText("Connected to " + server_url.toString());
|
||||||
// Default sim
|
// Default sim
|
||||||
if (!sim.isEmpty())
|
if (!sim.isEmpty())
|
||||||
default_sim(sim);
|
default_sim(sim);
|
||||||
|
|
||||||
|
QSslConfiguration ssl_config = QSslConfiguration::defaultConfiguration();
|
||||||
|
|
||||||
|
// Required for HTTP/2
|
||||||
|
ssl_config.setAllowedNextProtocols({ "h2" });
|
||||||
|
|
||||||
|
// Disable certificate verification
|
||||||
|
ssl_config.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||||
|
|
||||||
|
QGrpcChannelOptions options;
|
||||||
|
options.setSslConfiguration(ssl_config);
|
||||||
|
|
||||||
|
server_url.setScheme("https");
|
||||||
|
auto channel = std::make_shared<QGrpcHttp2Channel>(server_url, options);
|
||||||
|
m_remote_ui_client->attachChannel(channel);
|
||||||
|
|
||||||
connect(ui->pushButton, &QPushButton::clicked, this, [=, this] { open_sim(ui->comboBox->currentText()); });
|
connect(ui->pushButton, &QPushButton::clicked, this, [=, this] { open_sim(ui->comboBox->currentText()); });
|
||||||
|
connect(m_ping, &QTimer::timeout, this, [this]{
|
||||||
|
// TODO: find a way to check if the channel is open
|
||||||
|
});
|
||||||
|
connect(this, &MainWindow::on_show_event, this, [this]{
|
||||||
|
auto reply = m_remote_ui_client->Command_get_simulators(Empty());
|
||||||
|
connect(reply.get(), &QGrpcCallReply::finished, this, [this, reply = reply.get()](const QGrpcStatus &status) {
|
||||||
|
auto response = reply->read<Simulators_m>();
|
||||||
|
if (!response.has_value() || !status.isOk())
|
||||||
|
{
|
||||||
|
SPDLOG_CRITICAL("Command get simulators has got no response");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pase_sim_names(response.value());
|
||||||
|
}, Qt::SingleShotConnection);
|
||||||
|
}, Qt::SingleShotConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
@@ -68,19 +97,14 @@ MainWindow::~MainWindow()
|
|||||||
void MainWindow::showEvent(QShowEvent *event)
|
void MainWindow::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
connect(m_web_socket.get(), &Web_socket_wrapper::on_command_cb, this, [=, this](json &j) { on_cmd_cb(j); });
|
emit on_show_event();
|
||||||
connect(m_web_socket.get(), &Web_socket_wrapper::on_connected, this,
|
m_ping->start();
|
||||||
[=, this] { m_web_socket->send_command(Web_socket_wrapper::Command::get_simulators); });
|
|
||||||
connect(m_web_socket.get(), &Web_socket_wrapper::on_closed, this, [=, this] {
|
|
||||||
m_error->open();
|
|
||||||
ui->connection->setText("Could not connect to the server");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::hideEvent(QHideEvent *event)
|
void MainWindow::hideEvent(QHideEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::hideEvent(event);
|
QWidget::hideEvent(event);
|
||||||
disconnect(m_web_socket.get(), nullptr, nullptr, nullptr);
|
disconnect(m_remote_ui_client.get(), nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::default_sim(QString name)
|
void MainWindow::default_sim(QString name)
|
||||||
@@ -89,12 +113,11 @@ void MainWindow::default_sim(QString name)
|
|||||||
this->m_default_sim = true;
|
this->m_default_sim = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::pase_sim_names(json &sims)
|
void MainWindow::pase_sim_names(Simulators_m &sims)
|
||||||
{
|
{
|
||||||
for (json &item : sims)
|
for (auto &item : sims.simulator())
|
||||||
{
|
{
|
||||||
if (m_sims.contains(QString::fromStdString(item)))
|
ui->comboBox->addItem(item);
|
||||||
ui->comboBox->addItem(QString::fromStdString(item));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QThread::msleep(30);
|
QThread::msleep(30);
|
||||||
@@ -119,7 +142,18 @@ void MainWindow::open_sim(QString sim_name)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_web_socket->send_command(Web_socket_wrapper::Command::get_active_simulator_name);
|
auto cmd = Simulator_m();
|
||||||
|
cmd.setSimuator(sim_name);
|
||||||
|
auto reply = m_remote_ui_client->Command_switch_simulator(cmd);
|
||||||
|
connect(reply.get(), &QGrpcCallReply::finished, this, [this, reply = reply.get()] {
|
||||||
|
auto response = reply->read<Empty>();
|
||||||
|
if (!response.has_value())
|
||||||
|
{
|
||||||
|
qDebug("Switch simulator deserialization failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
open_sim_window();
|
||||||
|
}, Qt::SingleShotConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::open_sim_window(void)
|
void MainWindow::open_sim_window(void)
|
||||||
@@ -130,15 +164,6 @@ void MainWindow::open_sim_window(void)
|
|||||||
|
|
||||||
void MainWindow::check_active_sim(QString name)
|
void MainWindow::check_active_sim(QString name)
|
||||||
{
|
{
|
||||||
if (name == "")
|
|
||||||
{
|
|
||||||
SPDLOG_DEBUG("Name not set");
|
|
||||||
m_web_socket->send_command(Web_socket_wrapper::Command::switch_simulator, m_selected_sim_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPDLOG_DEBUG("Current sim:", name);
|
|
||||||
|
|
||||||
if (name == m_selected_sim_name)
|
if (name == m_selected_sim_name)
|
||||||
{
|
{
|
||||||
SPDLOG_DEBUG("Name set and the same");
|
SPDLOG_DEBUG("Name set and the same");
|
||||||
@@ -146,26 +171,16 @@ void MainWindow::check_active_sim(QString name)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_DEBUG("Name set and wrong");
|
auto cmd = Simulator_m();
|
||||||
m_web_socket->send_command(Web_socket_wrapper::Command::switch_simulator, m_selected_sim_name);
|
cmd.setSimuator(m_selected_sim_name);
|
||||||
|
auto reply = m_remote_ui_client->Command_switch_simulator(cmd);
|
||||||
|
connect(reply.get(), &QGrpcCallReply::finished, this, [this, reply = reply.get()] {
|
||||||
|
auto response = reply->read<Empty>();
|
||||||
|
if (!response.has_value())
|
||||||
|
{
|
||||||
|
qDebug("Switch simulator deserialization failed");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_cmd_cb(json &j)
|
|
||||||
{
|
|
||||||
auto response = magic_enum::enum_cast<Web_socket_wrapper::Command>(std::string(j.at("type")))
|
|
||||||
.value_or(Web_socket_wrapper::Command::end);
|
|
||||||
switch (response)
|
|
||||||
{
|
|
||||||
case Web_socket_wrapper::Command::get_simulators:
|
|
||||||
pase_sim_names(j.at("simulators"));
|
|
||||||
break;
|
|
||||||
case Web_socket_wrapper::Command::get_active_simulator_name:
|
|
||||||
check_active_sim(QString::fromStdString(j.at("name")));
|
|
||||||
break;
|
|
||||||
case Web_socket_wrapper::Command::switch_simulator:
|
|
||||||
open_sim_window();
|
open_sim_window();
|
||||||
break;
|
}, Qt::SingleShotConnection);
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-13
@@ -1,16 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "nlohmann/json.hpp"
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "messages.qpb.h"
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
#define INSERT_SIMULATOR(type) \
|
#define INSERT_SIMULATOR(type) \
|
||||||
m_sims.insert(std::make_pair(type().sim_name(), std::make_unique<type>(m_web_socket.get(), this)))
|
m_sims.insert(std::make_pair(type().sim_name(), std::make_unique<type>(m_web_socket.get(), this)))
|
||||||
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QMessageBox);
|
Q_FORWARD_DECLARE_OBJC_CLASS(QMessageBox);
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(Web_socket_wrapper);
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(UI_base);
|
Q_FORWARD_DECLARE_OBJC_CLASS(UI_base);
|
||||||
|
Q_FORWARD_DECLARE_OBJC_CLASS(QTimer);
|
||||||
|
namespace RemoteUiService
|
||||||
|
{
|
||||||
|
class Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Health
|
||||||
|
{
|
||||||
|
class Client;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@@ -32,6 +39,8 @@ class MainWindow : public QMainWindow
|
|||||||
explicit MainWindow(QUrl ws_url, QString sim, QWidget *parent = nullptr);
|
explicit MainWindow(QUrl ws_url, QString sim, QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void on_show_event();
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Handle the show event
|
* @brief Handle the show event
|
||||||
@@ -59,7 +68,7 @@ class MainWindow : public QMainWindow
|
|||||||
*
|
*
|
||||||
* @param sims The JSON array of simulator names
|
* @param sims The JSON array of simulator names
|
||||||
*/
|
*/
|
||||||
void pase_sim_names(json &sims);
|
void pase_sim_names(Simulators_m &sims);
|
||||||
/**
|
/**
|
||||||
* @brief Open the simulator window using the selected simulator
|
* @brief Open the simulator window using the selected simulator
|
||||||
*/
|
*/
|
||||||
@@ -78,18 +87,12 @@ class MainWindow : public QMainWindow
|
|||||||
*/
|
*/
|
||||||
void open_sim(QString sim_name);
|
void open_sim(QString sim_name);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Handle command callbacks from the server
|
|
||||||
*
|
|
||||||
* @param j The JSON command
|
|
||||||
*/
|
|
||||||
void on_cmd_cb(json &j);
|
|
||||||
|
|
||||||
bool m_default_sim = false;
|
bool m_default_sim = false;
|
||||||
QString m_selected_sim_name;
|
QString m_selected_sim_name;
|
||||||
QMainWindow *m_selected_sim;
|
QMainWindow *m_selected_sim;
|
||||||
QMessageBox *m_error;
|
QMessageBox *m_error;
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
std::unique_ptr<Web_socket_wrapper> m_web_socket;
|
std::unique_ptr<RemoteUiService::Client> m_remote_ui_client;
|
||||||
std::map<QString, std::unique_ptr<UI_base>> m_sims;
|
std::map<QString, std::unique_ptr<UI_base>> m_sims;
|
||||||
|
QTimer *m_ping;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
REGISTER_UI(Can_Debugger);
|
REGISTER_UI(Can_Debugger);
|
||||||
|
|
||||||
Can_Debugger::Can_Debugger(Web_socket_wrapper *web_socket, QWidget *parent)
|
Can_Debugger::Can_Debugger(RemoteUiService::Client *web_socket, QWidget *parent)
|
||||||
: UI_base(web_socket, parent), ui(new Ui::Can_Debugger)
|
: UI_base(web_socket, parent), ui(new Ui::Can_Debugger)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Can_Debugger : public UI_base
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Can_Debugger(Web_socket_wrapper *web_socket = nullptr, QWidget *parent = nullptr);
|
explicit Can_Debugger(RemoteUiService::Client *web_socket = nullptr, QWidget *parent = nullptr);
|
||||||
~Can_Debugger();
|
~Can_Debugger();
|
||||||
static QString name()
|
static QString name()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
REGISTER_UI(Test_Sim);
|
REGISTER_UI(Test_Sim);
|
||||||
|
|
||||||
Test_Sim::Test_Sim(Web_socket_wrapper *web_socket, QWidget *parent) : UI_base(web_socket, parent), ui(new Ui::Test_Sim)
|
Test_Sim::Test_Sim(RemoteUiService::Client *web_socket, QWidget *parent) : UI_base(web_socket, parent), ui(new Ui::Test_Sim)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Test_Sim : public UI_base
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Test_Sim(Web_socket_wrapper *web_socket = nullptr, QWidget *parent = nullptr);
|
explicit Test_Sim(RemoteUiService::Client *web_socket = nullptr, QWidget *parent = nullptr);
|
||||||
~Test_Sim();
|
~Test_Sim();
|
||||||
|
|
||||||
static QString name()
|
static QString name()
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ Can_Transceive::Can_Transceive(QWidget *parent) : QWidget(parent), ui(new Ui::Ca
|
|||||||
connect(ui->b_can_send_send, &QPushButton::clicked, this, [=, this] {
|
connect(ui->b_can_send_send, &QPushButton::clicked, this, [=, this] {
|
||||||
emit send_can_message(
|
emit send_can_message(
|
||||||
ui->s_can_send_sid->value(), ui->c_can_send_dlc->currentIndex(),
|
ui->s_can_send_sid->value(), ui->c_can_send_dlc->currentIndex(),
|
||||||
std::array<uint8_t, 8>(
|
QByteArray().append((uint8_t)(can_send_hexspinboxes[0]->value())).append((uint8_t)(can_send_hexspinboxes[0]->value()))
|
||||||
{(uint8_t)(can_send_hexspinboxes[0]->value()), (uint8_t)(can_send_hexspinboxes[1]->value()),
|
.append((uint8_t)(can_send_hexspinboxes[1]->value())).append((uint8_t)(can_send_hexspinboxes[2]->value()))
|
||||||
(uint8_t)(can_send_hexspinboxes[2]->value()), (uint8_t)(can_send_hexspinboxes[3]->value()),
|
.append((uint8_t)(can_send_hexspinboxes[3]->value())).append((uint8_t)(can_send_hexspinboxes[4]->value()))
|
||||||
(uint8_t)(can_send_hexspinboxes[4]->value()), (uint8_t)(can_send_hexspinboxes[5]->value()),
|
.append((uint8_t)(can_send_hexspinboxes[5]->value())).append((uint8_t)(can_send_hexspinboxes[6]->value()))
|
||||||
(uint8_t)(can_send_hexspinboxes[6]->value()), (uint8_t)(can_send_hexspinboxes[7]->value())}));
|
.append((uint8_t)(can_send_hexspinboxes[7]->value())));
|
||||||
});
|
});
|
||||||
connect(ui->b_clear, &QPushButton::clicked, this, [=, this] { emit can_clear(); });
|
connect(ui->b_clear, &QPushButton::clicked, this, [=, this] { emit can_clear(); });
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ void Can_Transceive::clear()
|
|||||||
ui->send_list->setRowCount(0);
|
ui->send_list->setRowCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Can_Transceive::add_send_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
|
void Can_Transceive::add_send_item(uint32_t id, uint8_t dlc, QByteArray payload)
|
||||||
{
|
{
|
||||||
size_t rc = ui->send_list->rowCount();
|
size_t rc = ui->send_list->rowCount();
|
||||||
ui->send_list->setRowCount(rc + 1);
|
ui->send_list->setRowCount(rc + 1);
|
||||||
@@ -62,7 +62,7 @@ void Can_Transceive::add_send_item(uint32_t id, uint8_t dlc, std::array<uint8_t,
|
|||||||
ui->send_list->resizeColumnsToContents();
|
ui->send_list->resizeColumnsToContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Can_Transceive::add_receive_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
|
void Can_Transceive::add_receive_item(uint32_t id, uint8_t dlc, QByteArray payload)
|
||||||
{
|
{
|
||||||
size_t rc = ui->recvd_list->rowCount();
|
size_t rc = ui->recvd_list->rowCount();
|
||||||
ui->recvd_list->setRowCount(rc + 1);
|
ui->recvd_list->setRowCount(rc + 1);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Can_Transceive : public QWidget
|
|||||||
* @param dlc The Data Length Code
|
* @param dlc The Data Length Code
|
||||||
* @param payload The CAN message payload
|
* @param payload The CAN message payload
|
||||||
*/
|
*/
|
||||||
void add_send_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
|
void add_send_item(uint32_t id, uint8_t dlc, QByteArray payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add a received CAN message to the receive list
|
* @brief Add a received CAN message to the receive list
|
||||||
@@ -56,7 +56,7 @@ class Can_Transceive : public QWidget
|
|||||||
* @param dlc The Data Length Code
|
* @param dlc The Data Length Code
|
||||||
* @param payload The CAN message payload
|
* @param payload The CAN message payload
|
||||||
*/
|
*/
|
||||||
void add_receive_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
|
void add_receive_item(uint32_t id, uint8_t dlc, QByteArray payload);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +66,7 @@ class Can_Transceive : public QWidget
|
|||||||
* @param dlc The Data Length Code
|
* @param dlc The Data Length Code
|
||||||
* @param payload The CAN message payload
|
* @param payload The CAN message payload
|
||||||
*/
|
*/
|
||||||
void send_can_message(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
|
void send_can_message(uint32_t id, uint8_t dlc, QByteArray payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Emitted when the CAN message lists are to be cleared
|
* @brief Emitted when the CAN message lists are to be cleared
|
||||||
|
|||||||
+227
-181
@@ -3,12 +3,12 @@
|
|||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "led.hpp"
|
#include "led.hpp"
|
||||||
#include "plot_wrapper.hpp"
|
#include "plot_wrapper.hpp"
|
||||||
#include "web_socket_wrapper.hpp"
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <magic_enum/magic_enum.hpp>
|
#include <magic_enum/magic_enum.hpp>
|
||||||
|
#include "messages_client.grpc.qpb.h"
|
||||||
|
|
||||||
UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
UI_base::UI_base(RemoteUiService::Client *remote_ui_client, QWidget *parent)
|
||||||
: QMainWindow{parent}, m_timer_update(new QTimer()), m_error(new QMessageBox(this)), m_web_socket(web_socket)
|
: QMainWindow{parent}, m_timer_update(new QTimer()), m_error(new QMessageBox(this)), m_remote_ui_client(remote_ui_client)
|
||||||
{
|
{
|
||||||
this->setWindowState(Qt::WindowMaximized);
|
this->setWindowState(Qt::WindowMaximized);
|
||||||
m_ui_lookup.reserve(40);
|
m_ui_lookup.reserve(40);
|
||||||
@@ -19,7 +19,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
QPushButton *exit_app = m_error->addButton("Exit Application", QMessageBox::AcceptRole);
|
QPushButton *exit_app = m_error->addButton("Exit Application", QMessageBox::AcceptRole);
|
||||||
m_error->addButton("Close", QMessageBox::RejectRole);
|
m_error->addButton("Close", QMessageBox::RejectRole);
|
||||||
connect(exit_app, &QPushButton::clicked, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
connect(exit_app, &QPushButton::clicked, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
||||||
m_process_lookup.insert(UI_enum::ui_label, [=, this](json &ui_item, QWidget *widget) {
|
|
||||||
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_label, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto label = qobject_cast<QLabel *>(widget);
|
auto label = qobject_cast<QLabel *>(widget);
|
||||||
if (label == nullptr)
|
if (label == nullptr)
|
||||||
{
|
{
|
||||||
@@ -27,9 +28,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString value = QString::fromStdString(ui_item.at("text"));
|
QString value = ui_item.label().text();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (label->isEnabled() != enabled)
|
if (label->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -47,8 +48,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_process_lookup.insert(UI_enum::ui_slider, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_slider, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
QLabel *label = id_to_label(id_to_ui(ui_item.id_proto()));
|
||||||
auto slider = qobject_cast<QwtSlider *>(widget);
|
auto slider = qobject_cast<QwtSlider *>(widget);
|
||||||
if (slider == nullptr)
|
if (slider == nullptr)
|
||||||
{
|
{
|
||||||
@@ -56,10 +57,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
bool enable = ui_item.at("enabled");
|
bool enable = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
QString unit = ui_item.range().unit();
|
||||||
|
|
||||||
if (label != nullptr)
|
if (label != nullptr)
|
||||||
{
|
{
|
||||||
@@ -82,8 +83,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
}
|
}
|
||||||
// TODO: Add color for scale
|
// TODO: Add color for scale
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_dial, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_dial, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
QLabel *label = id_to_label(id_to_ui(ui_item.id_proto()));
|
||||||
auto dial = qobject_cast<QwtDial *>(widget);
|
auto dial = qobject_cast<QwtDial *>(widget);
|
||||||
if (dial == nullptr)
|
if (dial == nullptr)
|
||||||
{
|
{
|
||||||
@@ -91,9 +92,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
QString unit = ui_item.range().unit();
|
||||||
|
|
||||||
if (label != nullptr)
|
if (label != nullptr)
|
||||||
{
|
{
|
||||||
@@ -110,8 +111,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
dial->setVisible(visible);
|
dial->setVisible(visible);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_thermo, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_thermo, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
QLabel *label = id_to_label(id_to_ui(ui_item.id_proto()));
|
||||||
auto thermo = qobject_cast<QwtThermo *>(widget);
|
auto thermo = qobject_cast<QwtThermo *>(widget);
|
||||||
if (thermo == nullptr)
|
if (thermo == nullptr)
|
||||||
{
|
{
|
||||||
@@ -119,9 +120,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
QString unit = ui_item.range().unit();
|
||||||
|
|
||||||
if (label != nullptr)
|
if (label != nullptr)
|
||||||
{
|
{
|
||||||
@@ -138,7 +139,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
thermo->setVisible(visible);
|
thermo->setVisible(visible);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_textbox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_textbox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto line_edit = qobject_cast<QLineEdit *>(widget);
|
auto line_edit = qobject_cast<QLineEdit *>(widget);
|
||||||
if (line_edit == nullptr)
|
if (line_edit == nullptr)
|
||||||
{
|
{
|
||||||
@@ -146,10 +147,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
QString hint = QString::fromStdString(ui_item.at("hint"));
|
QString hint = ui_item.textbox().hint();
|
||||||
QString text = QString::fromStdString(ui_item.at("text"));
|
QString text = ui_item.textbox().text();
|
||||||
|
|
||||||
if (line_edit->isVisible() != visible)
|
if (line_edit->isVisible() != visible)
|
||||||
{
|
{
|
||||||
@@ -169,7 +170,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
line_edit->setText(text);
|
line_edit->setText(text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_combobox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_combobox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto combobox = qobject_cast<QComboBox *>(widget);
|
auto combobox = qobject_cast<QComboBox *>(widget);
|
||||||
if (combobox == nullptr)
|
if (combobox == nullptr)
|
||||||
{
|
{
|
||||||
@@ -177,9 +178,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t selected = ui_item.at("selected");
|
size_t selected = ui_item.combobox().selected();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (combobox->isEnabled() != enabled)
|
if (combobox->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -191,10 +192,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
combobox->setVisible(visible);
|
combobox->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (json &item : ui_item.at("options"))
|
for (const QString &item : ui_item.combobox().options())
|
||||||
{
|
{
|
||||||
if (combobox->findText(QString::fromStdString(item)) == -1)
|
if (combobox->findText(item) == -1)
|
||||||
combobox->addItem(QString::fromStdString(item));
|
combobox->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (combobox->currentIndex() != selected)
|
if (combobox->currentIndex() != selected)
|
||||||
@@ -202,9 +203,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
combobox->setCurrentIndex(selected);
|
combobox->setCurrentIndex(selected);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// m_process_lookup.insert(UI_enum::ui_radiobutton,
|
// m_process_lookup.insert(UI_typeGadget::UI_type::ui_radiobutton,
|
||||||
// [=, this](json &ui_item, QWidget *widget) { LOG_CRITICAL("Not implemented"); });
|
// [=, this](const UI_item_m &ui_item, QWidget *widget) { LOG_CRITICAL("Not implemented"); });
|
||||||
m_process_lookup.insert(UI_enum::ui_checkbox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_checkbox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto checkbox = qobject_cast<QCheckBox *>(widget);
|
auto checkbox = qobject_cast<QCheckBox *>(widget);
|
||||||
if (checkbox == nullptr)
|
if (checkbox == nullptr)
|
||||||
{
|
{
|
||||||
@@ -212,12 +213,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
QColor bg_color = QColor(ui_item.checkbox().color().bgColor());
|
||||||
QColor fg_color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
QColor fg_color = QColor(ui_item.checkbox().color().fgColor());
|
||||||
QString text = QString::fromStdString(ui_item.at("text"));
|
QString text = ui_item.checkbox().text();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
bool checked = ui_item.at("checked");
|
bool checked = ui_item.checkbox().checked();
|
||||||
|
|
||||||
if (checkbox->isChecked() != checked)
|
if (checkbox->isChecked() != checked)
|
||||||
{
|
{
|
||||||
@@ -268,7 +269,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
set_widget_color(checkbox, fg_color, bg_color);
|
set_widget_color(checkbox, fg_color, bg_color);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_button, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_button, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto button = qobject_cast<QPushButton *>(widget);
|
auto button = qobject_cast<QPushButton *>(widget);
|
||||||
if (button == nullptr)
|
if (button == nullptr)
|
||||||
{
|
{
|
||||||
@@ -276,11 +277,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
QColor bg_color = QColor(ui_item.label().color().bgColor());
|
||||||
QColor fg_color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
QColor fg_color = QColor(ui_item.label().color().fgColor());
|
||||||
QString text = QString::fromStdString(ui_item.at("text"));
|
QString text = ui_item.label().text();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (button->isEnabled() != enabled)
|
if (button->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -326,7 +327,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
set_widget_color(button, fg_color, bg_color);
|
set_widget_color(button, fg_color, bg_color);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_led, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_led, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto led = qobject_cast<Led *>(widget);
|
auto led = qobject_cast<Led *>(widget);
|
||||||
if (led == nullptr)
|
if (led == nullptr)
|
||||||
{
|
{
|
||||||
@@ -334,10 +335,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
QColor bg_color = QColor(ui_item.label().color().bgColor());
|
||||||
QColor color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
QColor color = QColor(ui_item.label().color().fgColor());
|
||||||
QString text = QString::fromStdString(ui_item.at("text"));
|
QString text = ui_item.label().text();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (led->isVisible() != visible)
|
if (led->isVisible() != visible)
|
||||||
{
|
{
|
||||||
@@ -378,7 +379,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
set_widget_color(led, color, bg_color);
|
set_widget_color(led, color, bg_color);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_spinbox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_spinbox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto spinbox = qobject_cast<QSpinBox *>(widget);
|
auto spinbox = qobject_cast<QSpinBox *>(widget);
|
||||||
if (spinbox == nullptr)
|
if (spinbox == nullptr)
|
||||||
{
|
{
|
||||||
@@ -386,11 +387,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
double min = ui_item.at("min");
|
double min = ui_item.range().min();
|
||||||
double max = ui_item.at("max");
|
double max = ui_item.range().max();
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
|
|
||||||
if (enabled != spinbox->isEnabled())
|
if (enabled != spinbox->isEnabled())
|
||||||
{
|
{
|
||||||
@@ -415,7 +416,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
spinbox->setValue((int)value);
|
spinbox->setValue((int)value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_double_spinbox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_double_spinbox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto spinbox = qobject_cast<QDoubleSpinBox *>(widget);
|
auto spinbox = qobject_cast<QDoubleSpinBox *>(widget);
|
||||||
if (spinbox == nullptr)
|
if (spinbox == nullptr)
|
||||||
{
|
{
|
||||||
@@ -423,11 +424,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
double min = ui_item.at("min");
|
double min = ui_item.range().min();
|
||||||
double max = ui_item.at("max");
|
double max = ui_item.range().max();
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
|
|
||||||
if (enabled != spinbox->isEnabled())
|
if (enabled != spinbox->isEnabled())
|
||||||
{
|
{
|
||||||
@@ -452,7 +453,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
spinbox->setValue(value);
|
spinbox->setValue(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_hex_spinbox, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_hex_spinbox, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto spinbox = qobject_cast<HexSpinBox *>(widget);
|
auto spinbox = qobject_cast<HexSpinBox *>(widget);
|
||||||
if (spinbox == nullptr)
|
if (spinbox == nullptr)
|
||||||
{
|
{
|
||||||
@@ -460,11 +461,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
double min = ui_item.at("min");
|
double min = ui_item.range().min();
|
||||||
double max = ui_item.at("max");
|
double max = ui_item.range().max();
|
||||||
double value = ui_item.at("value");
|
double value = ui_item.range().value();
|
||||||
|
|
||||||
if (enabled != spinbox->isEnabled())
|
if (enabled != spinbox->isEnabled())
|
||||||
{
|
{
|
||||||
@@ -489,7 +490,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
spinbox->setValue((int)value);
|
spinbox->setValue((int)value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_tab_widget, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_tab_widget, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto tab_widget = qobject_cast<QTabWidget *>(widget);
|
auto tab_widget = qobject_cast<QTabWidget *>(widget);
|
||||||
if (tab_widget == nullptr)
|
if (tab_widget == nullptr)
|
||||||
{
|
{
|
||||||
@@ -497,15 +498,15 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab_widget->count() != ui_item.at("tab_names").size())
|
if (tab_widget->count() != ui_item.tabWidget().tabNames().size())
|
||||||
{
|
{
|
||||||
LOG_ERROR("QTabWidget has not the same amount of tabs as the server");
|
LOG_ERROR("QTabWidget has not the same amount of tabs as the server");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tab_names = ui_item.at("tab_names");
|
auto tab_names = ui_item.tabWidget().tabNames();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (tab_widget->isEnabled() != enabled)
|
if (tab_widget->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -519,22 +520,22 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
|
|
||||||
for (size_t i = 0; i < tab_names.size(); i++)
|
for (size_t i = 0; i < tab_names.size(); i++)
|
||||||
{
|
{
|
||||||
if (tab_widget->tabText(i) != QString::fromStdString(tab_names[i]))
|
if (tab_widget->tabText(i) != tab_names[i])
|
||||||
{
|
{
|
||||||
tab_widget->setTabText(i, QString::fromStdString(tab_names[i]));
|
tab_widget->setTabText(i, tab_names[i]);
|
||||||
}
|
}
|
||||||
if (tab_widget->isVisible() != ui_item.at("tab_visible")[i])
|
if (tab_widget->isVisible() != ui_item.tabWidget().tabVisible()[i])
|
||||||
{
|
{
|
||||||
tab_widget->setTabVisible(i, ui_item.at("tab_visible")[i]);
|
tab_widget->setTabVisible(i, ui_item.tabWidget().tabVisible()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab_widget->currentIndex() != ui_item.at("selected"))
|
if (tab_widget->currentIndex() != ui_item.tabWidget().selecteTab())
|
||||||
{
|
{
|
||||||
tab_widget->setCurrentIndex(ui_item.at("selected"));
|
tab_widget->setCurrentIndex(ui_item.tabWidget().selecteTab());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_stacked_widget, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_stacked_widget, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto stacked_widget = qobject_cast<QStackedWidget *>(widget);
|
auto stacked_widget = qobject_cast<QStackedWidget *>(widget);
|
||||||
if (stacked_widget == nullptr)
|
if (stacked_widget == nullptr)
|
||||||
{
|
{
|
||||||
@@ -542,14 +543,14 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stacked_widget->count() != ui_item.at("tab_count"))
|
if (stacked_widget->count() != ui_item.stackedWidget().tabCount())
|
||||||
{
|
{
|
||||||
LOG_ERROR("QStackedWidget has not the same amount of tabs as the server");
|
LOG_ERROR("QStackedWidget has not the same amount of tabs as the server");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (stacked_widget->isEnabled() != enabled)
|
if (stacked_widget->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -561,12 +562,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
stacked_widget->setVisible(visible);
|
stacked_widget->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stacked_widget->currentIndex() != ui_item.at("current_tab"))
|
if (stacked_widget->currentIndex() != ui_item.stackedWidget().currentTab())
|
||||||
{
|
{
|
||||||
stacked_widget->setCurrentIndex(ui_item.at("current_tab"));
|
stacked_widget->setCurrentIndex(ui_item.stackedWidget().currentTab());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_status_bar, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_status_bar, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto status_bar = qobject_cast<QStatusBar *>(widget);
|
auto status_bar = qobject_cast<QStatusBar *>(widget);
|
||||||
if (status_bar == nullptr)
|
if (status_bar == nullptr)
|
||||||
{
|
{
|
||||||
@@ -574,12 +575,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status_bar->currentMessage() != QString::fromStdString(ui_item.at("text")))
|
if (status_bar->currentMessage() != ui_item.statusBar().message())
|
||||||
{
|
{
|
||||||
status_bar->showMessage(QString::fromStdString(ui_item.at("text")), ui_item.at("timeout"));
|
status_bar->showMessage(ui_item.statusBar().message(), ui_item.statusBar().timeout());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_plot, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_plot, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto plot = qobject_cast<Plot_wrapper *>(widget);
|
auto plot = qobject_cast<Plot_wrapper *>(widget);
|
||||||
if (plot == nullptr)
|
if (plot == nullptr)
|
||||||
{
|
{
|
||||||
@@ -587,17 +588,17 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString text = QString::fromStdString(ui_item.at("text"));
|
QString text = ui_item.plot().text();
|
||||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
QColor bg_color = QColor(ui_item.plot().color().bgColor());
|
||||||
QColor color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
QColor color = QColor(ui_item.plot().color().fgColor());
|
||||||
QString x_label = QString::fromStdString(ui_item.at("x_label"));
|
QString x_label = ui_item.plot().xLabel();
|
||||||
QString y_label = QString::fromStdString(ui_item.at("y_label"));
|
QString y_label = ui_item.plot().yLabel();
|
||||||
|
|
||||||
std::vector<double> x_vals = (std::vector<double>)ui_item.at("x_vals");
|
QList<double> x_vals = ui_item.plot().xVals();
|
||||||
std::vector<double> y_vals = (std::vector<double>)ui_item.at("y_vals");
|
QList<double> y_vals = ui_item.plot().yVals();
|
||||||
|
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (plot->isEnabled() != enabled)
|
if (plot->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -639,7 +640,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
plot->setAxisScale(QwtAxis::XBottom, x_vals[0], x_vals[x_vals.size() - 1]);
|
plot->setAxisScale(QwtAxis::XBottom, x_vals[0], x_vals[x_vals.size() - 1]);
|
||||||
plot->replot();
|
plot->replot();
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_table, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_table, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto table = qobject_cast<QTableWidget *>(widget);
|
auto table = qobject_cast<QTableWidget *>(widget);
|
||||||
if (table == nullptr)
|
if (table == nullptr)
|
||||||
{
|
{
|
||||||
@@ -647,13 +648,13 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t row_count = ui_item.at("row_count");
|
size_t row_count = ui_item.table().rowCount();
|
||||||
std::vector<std::string> row_labels = (std::vector<std::string>)ui_item.at("row_labels");
|
QList<QString> row_labels = ui_item.table().rowLabels();
|
||||||
size_t column_count = ui_item.at("column_count");
|
size_t column_count = ui_item.table().columnCount();
|
||||||
std::vector<std::string> column_labels = (std::vector<std::string>)ui_item.at("column_labels");
|
QList<QString> column_labels = ui_item.table().columnLabels();
|
||||||
std::vector<std::string> table_data = (std::vector<std::string>)ui_item.at("table");
|
QList<QString> table_data = ui_item.table().table();
|
||||||
bool enabled = ui_item.at("enabled");
|
bool enabled = ui_item.enabled();
|
||||||
bool visible = ui_item.at("visible");
|
bool visible = ui_item.visible();
|
||||||
|
|
||||||
if (table->isEnabled() != enabled)
|
if (table->isEnabled() != enabled)
|
||||||
{
|
{
|
||||||
@@ -683,7 +684,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
if (table->verticalHeaderItem(i) == nullptr)
|
if (table->verticalHeaderItem(i) == nullptr)
|
||||||
table->setVerticalHeaderItem(i, new QTableWidgetItem());
|
table->setVerticalHeaderItem(i, new QTableWidgetItem());
|
||||||
if (row_labels[i] != table->verticalHeaderItem(i)->text())
|
if (row_labels[i] != table->verticalHeaderItem(i)->text())
|
||||||
table->verticalHeaderItem(i)->setText(QString::fromStdString(row_labels[i]));
|
table->verticalHeaderItem(i)->setText(row_labels[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (column_count != 0)
|
if (column_count != 0)
|
||||||
@@ -693,7 +694,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
if (table->horizontalHeaderItem(i) == nullptr)
|
if (table->horizontalHeaderItem(i) == nullptr)
|
||||||
table->setHorizontalHeaderItem(i, new QTableWidgetItem());
|
table->setHorizontalHeaderItem(i, new QTableWidgetItem());
|
||||||
if (column_labels[i] != table->horizontalHeaderItem(i)->text())
|
if (column_labels[i] != table->horizontalHeaderItem(i)->text())
|
||||||
table->horizontalHeaderItem(i)->setText(QString::fromStdString(column_labels[i]));
|
table->horizontalHeaderItem(i)->setText(column_labels[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < table_data.size(); i++)
|
for (size_t i = 0; i < table_data.size(); i++)
|
||||||
@@ -704,11 +705,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
{
|
{
|
||||||
table->setItem(row, column, new QTableWidgetItem());
|
table->setItem(row, column, new QTableWidgetItem());
|
||||||
}
|
}
|
||||||
table->item(row, column)->setText(QString::fromStdString(table_data[i]));
|
table->item(row, column)->setText(table_data[i]);
|
||||||
}
|
}
|
||||||
table->resizeColumnsToContents();
|
table->resizeColumnsToContents();
|
||||||
});
|
});
|
||||||
m_process_lookup.insert(UI_enum::ui_can, [=, this](json &ui_item, QWidget *widget) {
|
m_process_lookup.insert(UI_typeGadget::UI_type::ui_can, [=, this](const UI_item_m &ui_item, QWidget *widget) {
|
||||||
auto can_ui = qobject_cast<Can_Transceive *>(widget);
|
auto can_ui = qobject_cast<Can_Transceive *>(widget);
|
||||||
if (can_ui == nullptr)
|
if (can_ui == nullptr)
|
||||||
{
|
{
|
||||||
@@ -717,14 +718,14 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
can_ui->clear();
|
can_ui->clear();
|
||||||
for (auto &send_item : ui_item.at("send_msgs"))
|
for (auto &send_item : ui_item.can().sendFrames())
|
||||||
{
|
{
|
||||||
can_ui->add_send_item(send_item.at("id"), send_item.at("dlc"), send_item.at("payload"));
|
can_ui->add_send_item(send_item.sid(), send_item.dlc(), send_item.payload());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &recvd_item : ui_item.at("rcvd_msgs"))
|
for (auto &recvd_item : ui_item.can().recvFrames())
|
||||||
{
|
{
|
||||||
can_ui->add_receive_item(recvd_item.at("id"), recvd_item.at("dlc"), recvd_item.at("payload"));
|
can_ui->add_receive_item(recvd_item.sid(), recvd_item.dlc(), recvd_item.payload());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -746,12 +747,42 @@ void UI_base::showEvent(QShowEvent *event)
|
|||||||
LOG_DEBUG("Connecting callbacks");
|
LOG_DEBUG("Connecting callbacks");
|
||||||
m_first_load = true;
|
m_first_load = true;
|
||||||
|
|
||||||
connect(m_web_socket, &Web_socket_wrapper::on_command_cb, this, [=, this](json &j) { on_cmd_cb(j); });
|
auto reply = m_remote_ui_client->Command_get_ui_elements(Empty());
|
||||||
connect(m_web_socket, &Web_socket_wrapper::on_event_cb, this, [=, this](json &j) { on_event_cb(j); });
|
connect(reply.get(), &QGrpcCallReply::finished, reply.get(), [this, reply = std::move(reply)](const QGrpcStatus &status) {
|
||||||
connect(m_web_socket, &Web_socket_wrapper::on_closed, this, [=, this] { m_error->open(); });
|
if (!status.isOk())
|
||||||
|
{
|
||||||
|
LOG_ERROR(QString("Command get ui elements failed: %0").arg(status.message()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto response = reply->read<UI_items_m>();
|
||||||
|
if (!response.has_value())
|
||||||
|
{
|
||||||
|
qDebug("Command get ui elements deserialization failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UI_item_parser(response.value());
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
|
||||||
m_web_socket->inhibit_events(true);
|
m_stream = m_remote_ui_client->SubscribeUIChanges(Empty());
|
||||||
m_web_socket->send_command(Web_socket_wrapper::Command::get_UI_elements);
|
|
||||||
|
connect(
|
||||||
|
m_stream.get(), &QGrpcServerStream::finished, this,
|
||||||
|
[this](const QGrpcStatus &status) {
|
||||||
|
if (!status.isOk())
|
||||||
|
m_error->show();
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
|
||||||
|
connect(m_stream.get(), &QGrpcServerStream::messageReceived, this, [this, stream = m_stream.get()] {
|
||||||
|
auto response = stream->read<UI_items_m>();
|
||||||
|
if (!response.has_value())
|
||||||
|
{
|
||||||
|
qDebug("Client (UnaryCall) deserialization failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UI_item_parser(response.value());
|
||||||
|
});
|
||||||
this->m_timer_update->start(m_refresh_rate);
|
this->m_timer_update->start(m_refresh_rate);
|
||||||
m_open = true;
|
m_open = true;
|
||||||
}
|
}
|
||||||
@@ -763,64 +794,30 @@ void UI_base::closeEvent(QCloseEvent *event)
|
|||||||
{
|
{
|
||||||
LOG_DEBUG("Disconnecting callbacks");
|
LOG_DEBUG("Disconnecting callbacks");
|
||||||
m_timer_update->stop();
|
m_timer_update->stop();
|
||||||
disconnect(m_web_socket, nullptr, nullptr, nullptr);
|
disconnect(m_stream.get(), nullptr, nullptr, nullptr);
|
||||||
m_open = false;
|
m_open = false;
|
||||||
this->parentWidget()->show();
|
this->parentWidget()->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::on_cmd_cb(json &j)
|
|
||||||
{
|
|
||||||
auto response = magic_enum::enum_cast<Web_socket_wrapper::Command>(std::string(j.at("type")))
|
|
||||||
.value_or(Web_socket_wrapper::Command::end);
|
|
||||||
switch (response)
|
|
||||||
{
|
|
||||||
case Web_socket_wrapper::Command::get_UI_elements:
|
|
||||||
case Web_socket_wrapper::Command::get_UI_element:
|
|
||||||
UI_item_parser(j);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (m_first_load)
|
|
||||||
{
|
|
||||||
m_web_socket->inhibit_events(false);
|
|
||||||
m_first_load = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UI_base::on_event_cb(json &j)
|
|
||||||
{
|
|
||||||
auto response = magic_enum::enum_cast<Web_socket_wrapper::Event>(std::string(j.at("type")))
|
|
||||||
.value_or(Web_socket_wrapper::Event::end);
|
|
||||||
switch (response)
|
|
||||||
{
|
|
||||||
case Web_socket_wrapper::Event::ui_changed:
|
|
||||||
UI_item_parser(j);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UI_base::push_ui_item(QWidget *item)
|
void UI_base::push_ui_item(QWidget *item)
|
||||||
{
|
{
|
||||||
m_ui_lookup.emplace_back(item);
|
m_ui_lookup.emplace_back(item);
|
||||||
setup_ui_item(item, m_ui_lookup.size() - 1);
|
setup_ui_item(item, m_ui_lookup.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::UI_item_parser(json &input)
|
void UI_base::UI_item_parser(UI_items_m &input)
|
||||||
{
|
{
|
||||||
for (auto &ui_item : input.at("UI_items"))
|
for (auto &ui_item : input.item())
|
||||||
{
|
{
|
||||||
auto widget = id_to_ui(ui_item.at("id"));
|
auto widget = id_to_ui(ui_item.id_proto());
|
||||||
if (widget == nullptr)
|
if (widget == nullptr)
|
||||||
{
|
{
|
||||||
LOG_WARN(QString("id_to_ui returned null on %0").arg((size_t)ui_item.at("id")));
|
LOG_WARN(QString("id_to_ui returned null on %0").arg((size_t)ui_item.id_proto()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_process_lookup[magic_enum::enum_cast<UI_enum>((std::string)ui_item.at("type")).value_or(UI_enum::end)](
|
m_process_lookup[ui_item.type()](
|
||||||
ui_item, widget);
|
ui_item, widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,8 +842,12 @@ void UI_base::setup_button(QWidget *item, size_t index)
|
|||||||
QPushButton *button = qobject_cast<QPushButton *>(item);
|
QPushButton *button = qobject_cast<QPushButton *>(item);
|
||||||
if (button == nullptr)
|
if (button == nullptr)
|
||||||
return;
|
return;
|
||||||
connect(button, &QPushButton::clicked, this,
|
connect(button, &QPushButton::clicked, this, [=, this] {
|
||||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::clicked, index); });
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setClicked(Clicked_m());
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::setup_combobox(QWidget *item, size_t index)
|
void UI_base::setup_combobox(QWidget *item, size_t index)
|
||||||
@@ -855,8 +856,12 @@ void UI_base::setup_combobox(QWidget *item, size_t index)
|
|||||||
if (combobox == nullptr)
|
if (combobox == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(combobox, &QComboBox::activated, this, [=, this] {
|
connect(combobox, &QComboBox::activated, this, [=, this](int combo_index) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::selected, index, (size_t)combobox->currentIndex());
|
auto event = Event_m();
|
||||||
|
event.setSelected(Selected_m());
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.selected().setSelected(combo_index);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,8 +871,12 @@ void UI_base::setup_checkbox(QWidget *item, size_t index)
|
|||||||
if (checkbox == nullptr)
|
if (checkbox == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(checkbox, &QCheckBox::clicked, this,
|
connect(checkbox, &QCheckBox::clicked, this, [=, this] {
|
||||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::clicked, index); });
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setClicked(Clicked_m());
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::setup_dial(QWidget *item, size_t index)
|
void UI_base::setup_dial(QWidget *item, size_t index)
|
||||||
@@ -891,8 +900,13 @@ void UI_base::setup_slider(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(slider, &QwtSlider::sliderMoved, this,
|
connect(slider, &QwtSlider::sliderMoved, this, [=, this] (double value) {
|
||||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, slider->value()); });
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setValueChanged(Value_changed_m());
|
||||||
|
event.valueChanged().setValue(value);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::setup_textbox(QWidget *item, size_t index)
|
void UI_base::setup_textbox(QWidget *item, size_t index)
|
||||||
@@ -901,8 +915,13 @@ void UI_base::setup_textbox(QWidget *item, size_t index)
|
|||||||
if (line_edit == nullptr)
|
if (line_edit == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(line_edit, &QLineEdit::textEdited, this,
|
connect(line_edit, &QLineEdit::textEdited, this, [=, this] {
|
||||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::text_changed, index, line_edit->text()); });
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setTextChanged(Text_changed_m());
|
||||||
|
event.textChanged().setText(line_edit->text());
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_base::setup_spinbox(QWidget *item, size_t index)
|
void UI_base::setup_spinbox(QWidget *item, size_t index)
|
||||||
@@ -912,7 +931,11 @@ void UI_base::setup_spinbox(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
connect(spinbox, &QSpinBox::valueChanged, this, [=, this](int value) {
|
connect(spinbox, &QSpinBox::valueChanged, this, [=, this](int value) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, (double)value);
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setValueChanged(Value_changed_m());
|
||||||
|
event.valueChanged().setValue(value);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,7 +946,11 @@ void UI_base::setup_double_spinbox(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
connect(spinbox, &QDoubleSpinBox::valueChanged, this, [=, this](double value) {
|
connect(spinbox, &QDoubleSpinBox::valueChanged, this, [=, this](double value) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, value);
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setValueChanged(Value_changed_m());
|
||||||
|
event.valueChanged().setValue(value);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,7 +961,11 @@ void UI_base::setup_hex_spinbox(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
connect(spinbox, &HexSpinBox::valueChanged, this, [=, this](int value) {
|
connect(spinbox, &HexSpinBox::valueChanged, this, [=, this](int value) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, (double)value);
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setValueChanged(Value_changed_m());
|
||||||
|
event.valueChanged().setValue(value);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,7 +976,11 @@ void UI_base::setup_tab_widget(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
connect(tab_widget, &QTabWidget::currentChanged, this, [=, this](int tab_index) {
|
connect(tab_widget, &QTabWidget::currentChanged, this, [=, this](int tab_index) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::selected, index, (size_t)tab_index);
|
auto event = Event_m();
|
||||||
|
event.setSelected(Selected_m());
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.selected().setSelected(tab_index);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -956,9 +991,20 @@ void UI_base::setup_can_ui(QWidget *item, size_t index)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
connect(can, &Can_Transceive::send_can_message, this,
|
connect(can, &Can_Transceive::send_can_message, this,
|
||||||
[=, this](uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload) {
|
[=, this](uint32_t id, uint8_t dlc, QByteArray payload) {
|
||||||
m_web_socket->send_event(Web_socket_wrapper::Event::can_send, index, id, dlc, payload);
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setCanSend(CAN_send_m());
|
||||||
|
event.canSend().mutFrame().setSid(id);
|
||||||
|
event.canSend().mutFrame().setDlc(dlc);
|
||||||
|
event.canSend().mutFrame().setPayload(payload);
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
});
|
});
|
||||||
connect(can, &Can_Transceive::can_clear, this,
|
connect(can, &Can_Transceive::can_clear, this,
|
||||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::clear, index); });
|
[=, this] {
|
||||||
|
auto event = Event_m();
|
||||||
|
event.setId_proto(index);
|
||||||
|
event.setClear(Clear_m());
|
||||||
|
(void)m_remote_ui_client->SendEvent(event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-22
@@ -1,16 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ui_enum.hpp"
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <nlohmann/json.hpp>
|
#include "messages.qpb.h"
|
||||||
|
#include "m_ui_items.qpb.h"
|
||||||
|
#include "messages_client.grpc.qpb.h"
|
||||||
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(Web_socket_wrapper);
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QTimer);
|
Q_FORWARD_DECLARE_OBJC_CLASS(QTimer);
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QLabel);
|
Q_FORWARD_DECLARE_OBJC_CLASS(QLabel);
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QMessageBox);
|
Q_FORWARD_DECLARE_OBJC_CLASS(QMessageBox);
|
||||||
|
|
||||||
using json = nlohmann::json;
|
namespace RemoteUiService
|
||||||
|
{
|
||||||
|
class Client;
|
||||||
|
}
|
||||||
|
|
||||||
#define PUSH_UI_ITEM(item) push_ui_item(ui->item)
|
#define PUSH_UI_ITEM(item) push_ui_item(ui->item)
|
||||||
|
|
||||||
@@ -44,11 +47,10 @@ class UI_base : public QMainWindow
|
|||||||
* @brief Construct a new ui base object
|
* @brief Construct a new ui base object
|
||||||
*
|
*
|
||||||
* @param name The name of the simulator
|
* @param name The name of the simulator
|
||||||
* @param api The weboscket connection to the server API
|
* @param api The grpc connection to the server API
|
||||||
* @param parent The parent widget
|
* @param parent The parent widget
|
||||||
*/
|
*/
|
||||||
explicit UI_base(Web_socket_wrapper *api, QWidget *parent = nullptr);
|
explicit UI_base(RemoteUiService::Client *api, QWidget *parent = nullptr);
|
||||||
void set_name(QString name);
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the UI element by its ID
|
* @brief Get the UI element by its ID
|
||||||
*
|
*
|
||||||
@@ -56,6 +58,7 @@ class UI_base : public QMainWindow
|
|||||||
* @return QWidget* The UI element
|
* @return QWidget* The UI element
|
||||||
*/
|
*/
|
||||||
QWidget *id_to_ui(size_t id);
|
QWidget *id_to_ui(size_t id);
|
||||||
|
void set_name(QString name);
|
||||||
/**
|
/**
|
||||||
* @brief Get the label associated with a widget
|
* @brief Get the label associated with a widget
|
||||||
* This function has to be overridden in derived classes if labels are used
|
* This function has to be overridden in derived classes if labels are used
|
||||||
@@ -70,18 +73,6 @@ class UI_base : public QMainWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
|
||||||
* @brief Handle an event callback from the server
|
|
||||||
*
|
|
||||||
* @param j The JSON event
|
|
||||||
*/
|
|
||||||
void on_event_cb(json &j);
|
|
||||||
/**
|
|
||||||
* @brief Handle a command callback from the server
|
|
||||||
*
|
|
||||||
* @param j The JSON command
|
|
||||||
*/
|
|
||||||
void on_cmd_cb(json &j);
|
|
||||||
/**
|
/**
|
||||||
* @brief Push a UI item to the internal list and setup its connections
|
* @brief Push a UI item to the internal list and setup its connections
|
||||||
* The item have to be in the same order as from the server
|
* The item have to be in the same order as from the server
|
||||||
@@ -94,7 +85,7 @@ class UI_base : public QMainWindow
|
|||||||
*
|
*
|
||||||
* @param input The JSON input containing UI items
|
* @param input The JSON input containing UI items
|
||||||
*/
|
*/
|
||||||
void UI_item_parser(json &input);
|
void UI_item_parser(UI_items_m &input);
|
||||||
/**
|
/**
|
||||||
* @brief Setup a generic UI item
|
* @brief Setup a generic UI item
|
||||||
*
|
*
|
||||||
@@ -198,7 +189,8 @@ class UI_base : public QMainWindow
|
|||||||
void log_signal(const char *filename_in, int line_in, const char *funcname_in, int level, QString msg);
|
void log_signal(const char *filename_in, int line_in, const char *funcname_in, int level, QString msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Web_socket_wrapper *m_web_socket;
|
RemoteUiService::Client *m_remote_ui_client;
|
||||||
|
std::unique_ptr<QGrpcServerStream> m_stream;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QTimer *m_timer_update;
|
QTimer *m_timer_update;
|
||||||
uint32_t m_refresh_rate;
|
uint32_t m_refresh_rate;
|
||||||
@@ -206,5 +198,5 @@ class UI_base : public QMainWindow
|
|||||||
bool m_open = false;
|
bool m_open = false;
|
||||||
bool m_first_load = true;
|
bool m_first_load = true;
|
||||||
std::vector<QWidget *> m_ui_lookup;
|
std::vector<QWidget *> m_ui_lookup;
|
||||||
QMap<UI_enum, std::function<void(json &, QWidget *)>> m_process_lookup;
|
QMap<UI_typeGadget::UI_type, std::function<void(const UI_item_m &, QWidget *)>> m_process_lookup;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,240 +0,0 @@
|
|||||||
#include "web_socket_wrapper.hpp"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QtWebSockets/QWebSocket>
|
|
||||||
#include <magic_enum/magic_enum.hpp>
|
|
||||||
|
|
||||||
#define LOG_SRC_LOC(level, msg) emit log_signal(__FILE__, __LINE__, __FUNCTION__, (int)(level), (msg))
|
|
||||||
#define LOG_TRACE(msg) LOG_SRC_LOC(Log_level_enum::trace, msg)
|
|
||||||
#define LOG_DEBUG(msg) LOG_SRC_LOC(Log_level_enum::debug, msg)
|
|
||||||
#define LOG_INFO(msg) LOG_SRC_LOC(Log_level_enum::info, msg)
|
|
||||||
#define LOG_WARN(msg) LOG_SRC_LOC(Log_level_enum::warn, msg)
|
|
||||||
#define LOG_ERROR(msg) LOG_SRC_LOC(Log_level_enum::err, msg)
|
|
||||||
#define LOG_CRITICAL(msg) LOG_SRC_LOC(Log_level_enum::critical, msg)
|
|
||||||
|
|
||||||
Web_socket_wrapper::Web_socket_wrapper(const QUrl &url, QObject *parent)
|
|
||||||
: QObject(parent), m_web_socket(new QWebSocket("", QWebSocketProtocol::VersionLatest, this)),
|
|
||||||
m_ping_timer(new QTimer(this)), m_pong_timer(new QTimer(this))
|
|
||||||
{
|
|
||||||
connect(m_web_socket, &QWebSocket::connected, this, [=, this] {
|
|
||||||
m_connected = true;
|
|
||||||
connect(m_web_socket, &QWebSocket::textMessageReceived, this, &Web_socket_wrapper::m_on_received);
|
|
||||||
m_ping_timer->start(5000);
|
|
||||||
emit on_connected();
|
|
||||||
});
|
|
||||||
connect(m_web_socket, &QWebSocket::disconnected, this, [=, this] { emit on_closed(); });
|
|
||||||
connect(m_web_socket, &QWebSocket::errorOccurred, this, [this](QAbstractSocket::SocketError error) {
|
|
||||||
LOG_ERROR(QString::fromStdString(std::string(magic_enum::enum_name(error))));
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_ping_timer, &QTimer::timeout, this, [=, this] {
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
if (m_web_socket->state() != QAbstractSocket::ConnectedState)
|
|
||||||
{
|
|
||||||
m_web_socket->close();
|
|
||||||
emit on_closed();
|
|
||||||
}
|
|
||||||
m_ping_timer->start(1000);
|
|
||||||
});
|
|
||||||
#else
|
|
||||||
m_web_socket->ping();
|
|
||||||
m_pong_timer->start(1000);
|
|
||||||
});
|
|
||||||
connect(m_web_socket, &QWebSocket::pong, this, [=, this](quint64 elapsedTime) {
|
|
||||||
if (elapsedTime > 1000)
|
|
||||||
{
|
|
||||||
m_web_socket->close();
|
|
||||||
emit on_closed();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pong_timer->stop();
|
|
||||||
m_ping_timer->start(1000);
|
|
||||||
});
|
|
||||||
connect(m_pong_timer, &QTimer::timeout, this, [=, this] {
|
|
||||||
LOG_CRITICAL("Pong timeout");
|
|
||||||
m_web_socket->close();
|
|
||||||
emit on_closed();
|
|
||||||
});
|
|
||||||
connect(m_web_socket, &QWebSocket::sslErrors,
|
|
||||||
this, [&](const QList<QSslError> &errors) {
|
|
||||||
QList<QSslError> exeptions;
|
|
||||||
for (const QSslError &err : errors) {
|
|
||||||
switch (err.error()) {
|
|
||||||
case QSslError::UnableToGetLocalIssuerCertificate:
|
|
||||||
// case QSslError::UnableToVerifyFirstCertificate:
|
|
||||||
// case QSslError::SelfSignedCertificate:
|
|
||||||
// case QSslError::SelfSignedCertificateInChain:
|
|
||||||
// case QSslError::CertificateUntrusted:
|
|
||||||
exeptions.append(err);
|
|
||||||
LOG_WARN(QString("Allowing SSL error: %1 (%2)")
|
|
||||||
.arg(err.errorString(), err.certificate().isNull()
|
|
||||||
? "no cert"
|
|
||||||
: err.certificate().subjectDisplayName()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR(QString("Unexpected SSL error (not ignored): %1")
|
|
||||||
.arg(err.errorString()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exeptions.isEmpty()) {
|
|
||||||
m_web_socket->ignoreSslErrors(exeptions);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
m_ping_timer->setSingleShot(true);
|
|
||||||
m_pong_timer->setSingleShot(true);
|
|
||||||
m_web_socket->setProxy(QNetworkProxy::NoProxy);
|
|
||||||
m_web_socket->open(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_command(Command c, size_t id)
|
|
||||||
{
|
|
||||||
json j;
|
|
||||||
j["command"]["type"] = magic_enum::enum_name(c).data();
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case Command::get_UI_element:
|
|
||||||
j["command"]["id"] = id;
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
case Command::get_UI_elements:
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
case Command::get_active_simulator_name:
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
case Command::get_simulators:
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_command(Command command, QString val)
|
|
||||||
{
|
|
||||||
json j;
|
|
||||||
j["command"]["type"] = magic_enum::enum_name(command).data();
|
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
case Command::switch_simulator:
|
|
||||||
j["command"]["name"] = val.toStdString();
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_event(Event e, size_t id)
|
|
||||||
{
|
|
||||||
if (m_inhibit_events)
|
|
||||||
return;
|
|
||||||
json j;
|
|
||||||
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case Event::clicked:
|
|
||||||
case Event::clear:
|
|
||||||
j["event"]["id"] = id;
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_event(Event e, size_t id, size_t val)
|
|
||||||
{
|
|
||||||
if (m_inhibit_events)
|
|
||||||
return;
|
|
||||||
json j;
|
|
||||||
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case Event::selected:
|
|
||||||
j["event"]["id"] = id;
|
|
||||||
j["event"]["selected"] = val;
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_event(Event e, size_t id, double val)
|
|
||||||
{
|
|
||||||
if (m_inhibit_events)
|
|
||||||
return;
|
|
||||||
json j;
|
|
||||||
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case Event::value_changed:
|
|
||||||
j["event"]["id"] = id;
|
|
||||||
j["event"]["value"] = val;
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_event(Event e, size_t id, QString val)
|
|
||||||
{
|
|
||||||
if (m_inhibit_events)
|
|
||||||
return;
|
|
||||||
json j;
|
|
||||||
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case Event::text_changed:
|
|
||||||
j["event"]["id"] = id;
|
|
||||||
j["event"]["text"] = val.toStdString();
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::send_event(Event e, size_t id, uint32_t sid, uint8_t dlc, std::array<uint8_t, 8> payload)
|
|
||||||
{
|
|
||||||
if (m_inhibit_events)
|
|
||||||
return;
|
|
||||||
json j;
|
|
||||||
j["event"]["type"] = magic_enum::enum_name(e).data();
|
|
||||||
switch (e)
|
|
||||||
{
|
|
||||||
case Event::can_send:
|
|
||||||
j["event"]["id"] = id;
|
|
||||||
j["event"]["sid"] = sid;
|
|
||||||
j["event"]["dlc"] = dlc;
|
|
||||||
j["event"]["payload"] = payload;
|
|
||||||
m_web_socket->sendTextMessage(QString(j.dump().data()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::m_on_received(QString message)
|
|
||||||
{
|
|
||||||
json j = json::parse(message.toStdString());
|
|
||||||
if (j.contains("response"))
|
|
||||||
{
|
|
||||||
emit on_command_cb(j.at("response"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (j.contains("event"))
|
|
||||||
{
|
|
||||||
emit on_event_cb(j.at("event"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Web_socket_wrapper::inhibit_events(bool inhibit)
|
|
||||||
{
|
|
||||||
m_inhibit_events = inhibit;
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QObject>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QWebSocket);
|
|
||||||
Q_FORWARD_DECLARE_OBJC_CLASS(QTimer);
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Class wrapping a WebSocket connection
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class Web_socket_wrapper : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Enumeration of commands
|
|
||||||
*/
|
|
||||||
enum class Command
|
|
||||||
{
|
|
||||||
get_UI_element,
|
|
||||||
get_UI_elements,
|
|
||||||
switch_simulator,
|
|
||||||
get_active_simulator_name,
|
|
||||||
get_simulators,
|
|
||||||
end,
|
|
||||||
begin = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Log_level_enum : int
|
|
||||||
{
|
|
||||||
trace,
|
|
||||||
debug,
|
|
||||||
info,
|
|
||||||
warn,
|
|
||||||
err,
|
|
||||||
critical,
|
|
||||||
off,
|
|
||||||
n_levels
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumeration of events
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum class Event
|
|
||||||
{
|
|
||||||
clicked,
|
|
||||||
value_changed,
|
|
||||||
text_changed,
|
|
||||||
selected,
|
|
||||||
can_send,
|
|
||||||
clear,
|
|
||||||
ui_changed,
|
|
||||||
end,
|
|
||||||
begin = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Construct a new Web_socket_wrapper object
|
|
||||||
*
|
|
||||||
* @param url The WebSocket URL to connect to
|
|
||||||
* @param parent The parent QObject
|
|
||||||
*/
|
|
||||||
explicit Web_socket_wrapper(const QUrl &url, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Send a command to the server
|
|
||||||
*
|
|
||||||
* @param c The command to send
|
|
||||||
* @param id The ID associated with the command (if applicable)
|
|
||||||
*/
|
|
||||||
void send_command(Command c, size_t id = 0);
|
|
||||||
/**
|
|
||||||
* @brief Send a command to the server with a string value
|
|
||||||
*
|
|
||||||
* @param c The command to send
|
|
||||||
* @param val The string value associated with the command
|
|
||||||
*/
|
|
||||||
void send_command(Command c, QString val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Send an event to the server
|
|
||||||
*
|
|
||||||
* @param e The event to send
|
|
||||||
* @param id The ID associated with the event
|
|
||||||
*/
|
|
||||||
void send_event(Event e, size_t id);
|
|
||||||
/**
|
|
||||||
* @brief Send an event to the server with a size_t value
|
|
||||||
*
|
|
||||||
* @param e The event to send
|
|
||||||
* @param id The ID associated with the event
|
|
||||||
* @param val The size_t value associated with the event
|
|
||||||
*/
|
|
||||||
void send_event(Event e, size_t id, size_t val);
|
|
||||||
/**
|
|
||||||
* @brief Send an event to the server with a double value
|
|
||||||
*
|
|
||||||
* @param e The event to send
|
|
||||||
* @param id The ID associated with the event
|
|
||||||
* @param val The double value associated with the event
|
|
||||||
*/
|
|
||||||
void send_event(Event e, size_t id, double val);
|
|
||||||
/**
|
|
||||||
* @brief Send an event to the server with a string value
|
|
||||||
*
|
|
||||||
* @param e The event to send
|
|
||||||
* @param id The ID associated with the event
|
|
||||||
* @param val The string value associated with the event
|
|
||||||
*/
|
|
||||||
void send_event(Event e, size_t id, QString val);
|
|
||||||
/**
|
|
||||||
* @brief Send a CAN event to the server
|
|
||||||
*
|
|
||||||
* @param e The event to send
|
|
||||||
* @param id The ID associated with the event
|
|
||||||
* @param sid The CAN standard identifier
|
|
||||||
* @param dlc The CAN data length code
|
|
||||||
* @param payload The CAN data payload
|
|
||||||
*/
|
|
||||||
void send_event(Event e, size_t id, uint32_t sid, uint8_t dlc, std::array<uint8_t, 8> payload);
|
|
||||||
/**
|
|
||||||
* @brief Inhibit or allow sending events to the server
|
|
||||||
*
|
|
||||||
* @param inhibit True to inhibit events, false to allow
|
|
||||||
*/
|
|
||||||
void inhibit_events(bool inhibit);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when the WebSocket is connected
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void on_connected();
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when the WebSocket is closed
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void on_closed();
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when a command is received from the server
|
|
||||||
*
|
|
||||||
* @param data The JSON command data
|
|
||||||
*/
|
|
||||||
void on_command_cb(json &data);
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when an event is received from the server
|
|
||||||
*
|
|
||||||
* @param data The JSON event data
|
|
||||||
*/
|
|
||||||
void on_event_cb(json &data);
|
|
||||||
|
|
||||||
void log_signal(const char *filename_in, int line_in, const char *funcname_in, int level, QString msg);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
/**
|
|
||||||
* @brief Internal slot for handling WebSocket disconnection
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void m_on_received(QString message);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_connected = false;
|
|
||||||
bool m_inhibit_events = false;
|
|
||||||
QWebSocket *m_web_socket;
|
|
||||||
QTimer *m_ping_timer;
|
|
||||||
QTimer *m_pong_timer;
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user