mirror of
https://github.com/Sani7/remote-ui.git
synced 2026-10-26 21:51:13 +01:00
Compare commits
4
Commits
67d7e959b1
...
b1b2c70500
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1b2c70500 | ||
|
|
338bd461af | ||
|
|
cb41ac2aa2 | ||
|
|
ecbd8bf8a9 |
@@ -28,6 +28,8 @@ add_subdirectory(client)
|
||||
# contains an "external" library we will link to
|
||||
add_subdirectory(external)
|
||||
|
||||
add_subdirectory(protobuf)
|
||||
|
||||
# defines the executable
|
||||
if(NOT EMSCRIPTEN)
|
||||
add_subdirectory(server)
|
||||
|
||||
+2
-11
@@ -1,5 +1,5 @@
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
if(NOT EMSCRIPTEN)
|
||||
|
||||
add_library(UI STATIC)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core SerialBus)
|
||||
@@ -33,17 +33,8 @@ target_include_directories(UI
|
||||
target_link_libraries(UI
|
||||
PUBLIC
|
||||
Color
|
||||
nlohmann_json::nlohmann_json
|
||||
magic_enum::magic_enum
|
||||
Qt::Core
|
||||
Qt::SerialBus
|
||||
UI_enum
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(UI_enum INTERFACE)
|
||||
|
||||
target_include_directories(UI_enum
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/enum
|
||||
proto-ui
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum class UI_enum
|
||||
{
|
||||
ui_button,
|
||||
ui_can,
|
||||
ui_checkbox,
|
||||
ui_combobox,
|
||||
ui_dial,
|
||||
ui_double_spinbox,
|
||||
ui_hex_spinbox,
|
||||
ui_label,
|
||||
ui_led,
|
||||
ui_plot,
|
||||
ui_slider,
|
||||
ui_spinbox,
|
||||
ui_stacked_widget,
|
||||
ui_status_bar,
|
||||
ui_tab_widget,
|
||||
ui_table,
|
||||
ui_textbox,
|
||||
ui_thermo,
|
||||
end,
|
||||
begin = 0
|
||||
};
|
||||
+32
-9
@@ -1,24 +1,47 @@
|
||||
#include "ui_button.hpp"
|
||||
#include "ui_enum.hpp"
|
||||
|
||||
UI_button::UI_button(std::string text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_button, text, fg_color, bg_color, parent)
|
||||
UI_button::UI_button(QString text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_button, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
m_ui_item.label().setText(text);
|
||||
m_ui_item.label().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.label().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
UI_button::UI_button(QObject *parent) : UI_item(UI_enum::ui_button, parent)
|
||||
UI_button::UI_button(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_button, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
}
|
||||
|
||||
void UI_button::from_json(const json &j)
|
||||
void UI_button::set_text(QString text)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_ui_item.label().setText(text);
|
||||
}
|
||||
|
||||
json UI_button::to_json(size_t id) const
|
||||
QString UI_button::text() const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
return j;
|
||||
return m_ui_item.label().text();
|
||||
}
|
||||
|
||||
void UI_button::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setFgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_button::fg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_button::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setBgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_button::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().bgColor());
|
||||
}
|
||||
|
||||
void UI_button::click()
|
||||
|
||||
+13
-10
@@ -17,7 +17,7 @@ class UI_button : public UI_item
|
||||
* @param bg_color The background color of the button
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_button(std::string text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
UI_button(QString text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI button object
|
||||
*
|
||||
@@ -26,18 +26,21 @@ class UI_button : public UI_item
|
||||
UI_button(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Deserialize the button from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
* @brief set_text
|
||||
* @param text The text field of the button
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
void set_text(QString text) override;
|
||||
|
||||
/**
|
||||
* @brief Serialize the button to JSON
|
||||
*
|
||||
* @param id The id of the button
|
||||
* @return json The JSON representation of the button
|
||||
* @brief text
|
||||
* @return The text field of the button
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
QString text() const;
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Handle a click event on the button
|
||||
|
||||
+23
-71
@@ -1,53 +1,49 @@
|
||||
#include "ui_can.hpp"
|
||||
|
||||
template <class T> T ByteArrayToStdArray(const QByteArray &byteArray)
|
||||
{
|
||||
T stdArray;
|
||||
|
||||
for (unsigned int i = 0; i < stdArray.size() && i < (unsigned int)byteArray.size(); i++)
|
||||
{
|
||||
stdArray[i] = (unsigned char)byteArray.at(i);
|
||||
}
|
||||
|
||||
return stdArray;
|
||||
}
|
||||
|
||||
UI_can::UI_can(Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_can, "", fg_color, bg_color, parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_can, parent)
|
||||
{
|
||||
setup_item(false, true, true);
|
||||
m_ui_item.can().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.can().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
UI_can::UI_can(QObject *parent) : UI_item(UI_enum::ui_can, parent)
|
||||
UI_can::UI_can(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_can, parent)
|
||||
{
|
||||
setup_item(false, true, true);
|
||||
}
|
||||
|
||||
void UI_can::add_send_message(QCanBusFrame msg)
|
||||
{
|
||||
CanFrame frame(msg.frameId(), (uint8_t)msg.payload().size(),
|
||||
ByteArrayToStdArray<std::array<uint8_t, 8>>(msg.payload()));
|
||||
m_can_send_messages.push_back(frame);
|
||||
CAN_Frame_m frame;(msg.frameId(), msg.payload().size(), msg.payload());
|
||||
frame.setSid(msg.frameId());
|
||||
frame.setDlc(msg.payload().size());
|
||||
frame.setPayload(msg.payload());
|
||||
auto send_frames = m_ui_item.can().sendFrames();
|
||||
send_frames.append(frame);
|
||||
m_ui_item.can().setSendFrames(send_frames);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_can::add_received_message(QCanBusFrame msg)
|
||||
{
|
||||
CanFrame frame(msg.frameId(), (uint8_t)msg.payload().size(),
|
||||
ByteArrayToStdArray<std::array<uint8_t, 8>>(msg.payload()));
|
||||
m_can_received_messages.push_back(frame);
|
||||
CAN_Frame_m frame;(msg.frameId(), msg.payload().size(), msg.payload());
|
||||
frame.setSid(msg.frameId());
|
||||
frame.setDlc(msg.payload().size());
|
||||
frame.setPayload(msg.payload());
|
||||
auto recv_frames = m_ui_item.can().recvFrames();
|
||||
recv_frames.append(frame);
|
||||
m_ui_item.can().setRecvFrames(recv_frames);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_can::clear_send_buffer()
|
||||
{
|
||||
m_can_send_messages.clear();
|
||||
m_ui_item.can().setSendFrames(QList<CAN_Frame_m>());
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_can::clear_receive_buffer()
|
||||
{
|
||||
m_can_received_messages.clear();
|
||||
m_ui_item.can().setSendFrames(QList<CAN_Frame_m>());
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
@@ -57,56 +53,12 @@ void UI_can::clear()
|
||||
clear_receive_buffer();
|
||||
}
|
||||
|
||||
void UI_can::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_can_send_messages.clear();
|
||||
m_can_received_messages.clear();
|
||||
for (const auto &msg : j.at("send_msgs"))
|
||||
{
|
||||
CanFrame can_msg(msg.at("id"), msg.at("dlc"), msg.at("payload"));
|
||||
m_can_send_messages.push_back(can_msg);
|
||||
}
|
||||
for (const auto &msg : j.at("rcvd_msgs"))
|
||||
{
|
||||
CanFrame can_msg(msg.at("id"), msg.at("dlc"), msg.at("payload"));
|
||||
m_can_received_messages.push_back(can_msg);
|
||||
}
|
||||
}
|
||||
|
||||
json UI_can::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
json can_send_messages = json::array();
|
||||
json can_received_messages = json::array();
|
||||
for (const auto &msg : m_can_send_messages)
|
||||
{
|
||||
json can_msg;
|
||||
can_msg["id"] = (uint32_t)msg.m_SID;
|
||||
can_msg["dlc"] = msg.m_DLC;
|
||||
can_msg["payload"] = msg.m_payload;
|
||||
|
||||
can_send_messages.push_back(can_msg);
|
||||
}
|
||||
j["send_msgs"] = can_send_messages;
|
||||
for (const auto &msg : m_can_received_messages)
|
||||
{
|
||||
json can_msg;
|
||||
can_msg["id"] = (uint32_t)msg.m_SID;
|
||||
can_msg["dlc"] = msg.m_DLC;
|
||||
can_msg["payload"] = msg.m_payload;
|
||||
|
||||
can_received_messages.push_back(can_msg);
|
||||
}
|
||||
j["rcvd_msgs"] = can_received_messages;
|
||||
return j;
|
||||
}
|
||||
|
||||
void UI_can::can_send(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
|
||||
void UI_can::can_send(uint32_t id, uint64_t dlc, QByteArray payload)
|
||||
{
|
||||
QCanBusFrame frame;
|
||||
Q_UNUSED(dlc);
|
||||
frame.setFrameId(id);
|
||||
frame.setPayload(QByteArray::fromRawData((const char *)(payload.data()), dlc));
|
||||
frame.setPayload(payload);
|
||||
|
||||
emit send(frame);
|
||||
}
|
||||
|
||||
+1
-19
@@ -83,20 +83,6 @@ class UI_can : public UI_item
|
||||
*/
|
||||
void clear_receive_buffer();
|
||||
|
||||
/**
|
||||
* @brief Deserialize the CAN item from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the CAN item to JSON
|
||||
*
|
||||
* @param id The id of the CAN item
|
||||
* @return json The JSON representation of the CAN item
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
/**
|
||||
* @brief Handle a CAN send event
|
||||
*
|
||||
@@ -104,7 +90,7 @@ class UI_can : public UI_item
|
||||
* @param dlc The data length code
|
||||
* @param payload The data payload
|
||||
*/
|
||||
void can_send(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload) override;
|
||||
void can_send(uint32_t id, uint64_t dlc, QByteArray payload) override;
|
||||
/**
|
||||
* @brief Clear the CAN item
|
||||
*
|
||||
@@ -116,8 +102,4 @@ class UI_can : public UI_item
|
||||
* @param msg The CAN message sent
|
||||
*/
|
||||
void send(QCanBusFrame msg);
|
||||
|
||||
private:
|
||||
std::vector<CanFrame> m_can_send_messages;
|
||||
std::vector<CanFrame> m_can_received_messages;
|
||||
};
|
||||
|
||||
+44
-25
@@ -1,46 +1,65 @@
|
||||
#include "ui_checkbox.hpp"
|
||||
|
||||
UI_checkbox::UI_checkbox(QObject *parent) : UI_item(UI_enum::ui_checkbox, parent), m_checked()
|
||||
UI_checkbox::UI_checkbox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_checkbox, parent)
|
||||
{
|
||||
m_ui_item.setCheckbox(UI_checkbox_m());
|
||||
}
|
||||
|
||||
UI_checkbox::UI_checkbox(std::string text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_checkbox, text, fg_color, bg_color, parent), m_checked(false)
|
||||
UI_checkbox::UI_checkbox(QString text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_checkbox, parent)
|
||||
{
|
||||
m_ui_item.setCheckbox(UI_checkbox_m());
|
||||
m_ui_item.checkbox().setText(text);
|
||||
m_ui_item.checkbox().setChecked(false);
|
||||
m_ui_item.label().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.label().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
void UI_checkbox::set_text(QString text)
|
||||
{
|
||||
m_ui_item.label().setText(text);
|
||||
}
|
||||
|
||||
QString UI_checkbox::text() const
|
||||
{
|
||||
return m_ui_item.label().text();
|
||||
}
|
||||
|
||||
void UI_checkbox::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setFgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_checkbox::fg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_checkbox::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setBgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_checkbox::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().bgColor());
|
||||
}
|
||||
|
||||
void UI_checkbox::click()
|
||||
{
|
||||
m_checked = !m_checked;
|
||||
m_ui_item.checkbox().setChecked(!m_ui_item.checkbox().checked());
|
||||
emit ui_changed();
|
||||
emit changed(m_checked);
|
||||
emit changed(m_ui_item.checkbox().checked());
|
||||
}
|
||||
|
||||
void UI_checkbox::set_state(bool state)
|
||||
{
|
||||
m_checked = state;
|
||||
m_ui_item.checkbox().setChecked(state);
|
||||
emit ui_changed();
|
||||
emit changed(m_checked);
|
||||
emit changed(m_ui_item.checkbox().checked());
|
||||
}
|
||||
|
||||
bool UI_checkbox::state() const
|
||||
{
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
void UI_checkbox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
if (j.contains("checked"))
|
||||
{
|
||||
m_checked = j["checked"];
|
||||
}
|
||||
}
|
||||
|
||||
json UI_checkbox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["checked"] = m_checked;
|
||||
return j;
|
||||
return m_ui_item.checkbox().checked();
|
||||
}
|
||||
|
||||
+18
-18
@@ -23,7 +23,24 @@ class UI_checkbox : public UI_item
|
||||
* @param bg_color The background color
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_checkbox(std::string text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
UI_checkbox(QString text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief set_text
|
||||
* @param text The text field of the button
|
||||
*/
|
||||
void set_text(QString text) override;
|
||||
|
||||
/**
|
||||
* @brief text
|
||||
* @return The text field of the button
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Handle a click event on the checkbox
|
||||
@@ -44,20 +61,6 @@ class UI_checkbox : public UI_item
|
||||
*/
|
||||
bool state() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the checkbox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the checkbox to JSON
|
||||
*
|
||||
* @param id The id of the checkbox
|
||||
* @return json The JSON representation of the checkbox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the checkbox state changes
|
||||
@@ -65,7 +68,4 @@ class UI_checkbox : public UI_item
|
||||
* @param checked The new state of the checkbox
|
||||
*/
|
||||
void changed(bool checked);
|
||||
|
||||
private:
|
||||
bool m_checked;
|
||||
};
|
||||
|
||||
+17
-37
@@ -1,31 +1,33 @@
|
||||
#include "ui_combobox.hpp"
|
||||
|
||||
UI_combobox::UI_combobox(QObject *parent) : UI_item(UI_enum::ui_combobox, parent), m_options()
|
||||
UI_combobox::UI_combobox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_combobox, parent)
|
||||
{
|
||||
setup_item(false, true, true);
|
||||
m_ui_item.setCombobox(UI_combobox_m());
|
||||
}
|
||||
|
||||
UI_combobox::UI_combobox(Color fg_color, Color bg_color, std::vector<std::string> options, size_t selected,
|
||||
UI_combobox::UI_combobox(QList<QString> options, qsizetype selected,
|
||||
QObject *parent)
|
||||
: UI_item(UI_enum::ui_combobox, "", fg_color, bg_color, parent), m_options(options), m_selected(selected)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_combobox, parent)
|
||||
{
|
||||
setup_item(false, true, true);
|
||||
m_ui_item.setCombobox(UI_combobox_m());
|
||||
m_ui_item.combobox().setOptions(options);
|
||||
m_ui_item.combobox().setSelected(selected);
|
||||
}
|
||||
|
||||
void UI_combobox::set_selected(size_t selected)
|
||||
void UI_combobox::set_selected(qsizetype selected)
|
||||
{
|
||||
if (selected == m_selected)
|
||||
if (selected == m_ui_item.combobox().selected())
|
||||
return;
|
||||
m_selected = std::move(selected);
|
||||
m_ui_item.combobox().setSelected(selected);
|
||||
emit ui_changed();
|
||||
emit changed(selected_text());
|
||||
}
|
||||
|
||||
void UI_combobox::set_selected(std::string selected)
|
||||
void UI_combobox::set_selected(QString selected)
|
||||
{
|
||||
for (size_t i = 0; i < m_options.size(); i++)
|
||||
for (qsizetype i = 0; i < m_ui_item.combobox().options().size(); i++)
|
||||
{
|
||||
if (m_options[i] == selected)
|
||||
if (m_ui_item.combobox().options().at(i) == selected)
|
||||
{
|
||||
set_selected(i);
|
||||
return;
|
||||
@@ -33,34 +35,12 @@ void UI_combobox::set_selected(std::string selected)
|
||||
}
|
||||
}
|
||||
|
||||
size_t UI_combobox::selected() const
|
||||
qsizetype UI_combobox::selected() const
|
||||
{
|
||||
return m_selected;
|
||||
return m_ui_item.combobox().selected();
|
||||
}
|
||||
|
||||
std::string UI_combobox::selected_text() const &
|
||||
QString UI_combobox::selected_text() const &
|
||||
{
|
||||
return m_options[m_selected];
|
||||
}
|
||||
|
||||
void UI_combobox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
if (j.contains("options"))
|
||||
{
|
||||
this->m_options.clear();
|
||||
for (auto &option : j["options"])
|
||||
{
|
||||
this->m_options.push_back(option);
|
||||
}
|
||||
}
|
||||
m_selected = j.at("selected");
|
||||
}
|
||||
|
||||
json UI_combobox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["options"] = this->m_options;
|
||||
j["selected"] = m_selected;
|
||||
return j;
|
||||
return m_ui_item.combobox().options().at(m_ui_item.combobox().selected());
|
||||
}
|
||||
|
||||
+11
-24
@@ -24,56 +24,43 @@ class UI_combobox : public UI_item
|
||||
* @param selected The initially selected option
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_combobox(Color fg_color, Color bg_color, std::vector<std::string> options, size_t selected = 0,
|
||||
UI_combobox(QList<QString> options, qsizetype selected = 0,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Set the selected option by index
|
||||
*
|
||||
* @param selected The index of the option to select
|
||||
*/
|
||||
void set_selected(size_t selected) override;
|
||||
void set_selected(qsizetype selected) override;
|
||||
/**
|
||||
* @brief Set the selected option by text
|
||||
*
|
||||
* @param selected The text of the option to select
|
||||
*/
|
||||
void set_selected(std::string selected);
|
||||
void set_selected(QString selected);
|
||||
/**
|
||||
* @brief Get the index of the selected option
|
||||
*
|
||||
* @return size_t The index of the selected option
|
||||
*/
|
||||
size_t selected() const;
|
||||
qsizetype selected() const;
|
||||
/**
|
||||
* @brief Get the text of the selected option
|
||||
*
|
||||
* @return std::string The text of the selected option
|
||||
*/
|
||||
std::string selected_text() const &;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the combobox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the combobox to JSON
|
||||
*
|
||||
* @param id The id of the combobox
|
||||
* @return json The JSON representation of the combobox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
QString selected_text() const &;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the selected option changes
|
||||
*
|
||||
* @param selected The text of the newly selected option
|
||||
*/
|
||||
void changed(std::string selected);
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_options;
|
||||
size_t m_selected;
|
||||
void changed(QString selected);
|
||||
};
|
||||
|
||||
+19
-43
@@ -1,78 +1,54 @@
|
||||
#include "ui_dial.hpp"
|
||||
|
||||
UI_dial::UI_dial(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max,
|
||||
UI_dial::UI_dial(QString text, QString unit, double min, double max,
|
||||
double value, QObject *parent)
|
||||
: UI_item(UI_enum::ui_dial, text, fg_color, bg_color, parent), m_min(min), m_max(max), m_value(value), m_unit(unit)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_dial, parent)
|
||||
{
|
||||
m_ui_item.setRange(UI_range_m());
|
||||
m_ui_item.range().setText(text);
|
||||
m_ui_item.range().setUnit(unit);
|
||||
m_ui_item.range().setMin(min);
|
||||
m_ui_item.range().setMax(max);
|
||||
m_ui_item.range().setValue(value);
|
||||
}
|
||||
|
||||
UI_dial::UI_dial(std::string text, std::string unit, double min, double max, double value, QObject *parent)
|
||||
: UI_dial(text, unit, Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_dial::UI_dial(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_dial::UI_dial(QString text, double min, double max, double value,
|
||||
QObject *parent)
|
||||
: UI_dial(text, "", fg_color, bg_color, min, max, value, parent)
|
||||
: UI_dial(text, "", min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_dial::UI_dial(std::string text, double min, double max, double value, QObject *parent)
|
||||
: UI_dial(text, "", Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_dial::UI_dial(QObject *parent) : UI_item(UI_enum::ui_dial, parent)
|
||||
UI_dial::UI_dial(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_dial, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void UI_dial::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.range().min() || value > m_ui_item.range().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.range().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.range().setValue(value);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
double UI_dial::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.range().value();
|
||||
}
|
||||
|
||||
double UI_dial::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.range().min();
|
||||
}
|
||||
|
||||
double UI_dial::max() const
|
||||
{
|
||||
return m_max;
|
||||
return m_ui_item.range().max();
|
||||
}
|
||||
|
||||
std::string UI_dial::unit() const &
|
||||
QString UI_dial::unit() const &
|
||||
{
|
||||
return m_unit;
|
||||
}
|
||||
|
||||
void UI_dial::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
this->m_unit = j.at("unit");
|
||||
}
|
||||
|
||||
json UI_dial::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
j["unit"] = this->m_unit;
|
||||
return j;
|
||||
return m_ui_item.range().unit();
|
||||
}
|
||||
|
||||
+4
-51
@@ -14,39 +14,12 @@ class UI_dial : public UI_item
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the dial
|
||||
* @param fg_color The foreground color
|
||||
* @param bg_color The background color
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_dial(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI dial object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the dial
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_dial(std::string text, std::string unit, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI dial object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param fg_color The foreground color
|
||||
* @param bg_color The background color
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_dial(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
UI_dial(QString text, QString unit, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI dial object
|
||||
*
|
||||
@@ -56,7 +29,7 @@ class UI_dial : public UI_item
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_dial(std::string text, double min, double max, double value, QObject *parent = nullptr);
|
||||
UI_dial(QString text, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI dial object
|
||||
*
|
||||
@@ -92,27 +65,7 @@ class UI_dial : public UI_item
|
||||
/**
|
||||
* @brief Get the unit of the dial
|
||||
*
|
||||
* @return std::string The unit of the dial
|
||||
* @return QString The unit of the dial
|
||||
*/
|
||||
std::string unit() const &;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the dial from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the dial to JSON
|
||||
*
|
||||
* @param id The id of the dial
|
||||
* @return json The JSON representation of the dial
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
std::string m_unit;
|
||||
QString unit() const &;
|
||||
};
|
||||
|
||||
+14
-32
@@ -1,58 +1,40 @@
|
||||
#include "ui_double_spinbox.hpp"
|
||||
|
||||
UI_double_spinbox::UI_double_spinbox(QObject *parent) : UI_item(UI_enum::ui_double_spinbox, parent)
|
||||
UI_double_spinbox::UI_double_spinbox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_double_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
}
|
||||
|
||||
UI_double_spinbox::UI_double_spinbox(double min, double max, double value, QObject *parent)
|
||||
: UI_item(UI_enum::ui_double_spinbox, parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_double_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
m_value = value;
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
m_ui_item.spinbox().setMin(min);
|
||||
m_ui_item.spinbox().setMax(max);
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
}
|
||||
|
||||
void UI_double_spinbox::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.spinbox().min() || value > m_ui_item.spinbox().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.spinbox().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
emit ui_changed();
|
||||
emit changed(m_value);
|
||||
emit changed(m_ui_item.spinbox().value());
|
||||
}
|
||||
double UI_double_spinbox::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.spinbox().value();
|
||||
}
|
||||
|
||||
double UI_double_spinbox::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.spinbox().min();
|
||||
}
|
||||
double UI_double_spinbox::max() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void UI_double_spinbox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
}
|
||||
|
||||
json UI_double_spinbox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
return j;
|
||||
return m_ui_item.spinbox().max();
|
||||
}
|
||||
|
||||
@@ -50,20 +50,6 @@ class UI_double_spinbox : public UI_item
|
||||
* @return double The maximum value
|
||||
*/
|
||||
double max() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the double spinbox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the double spinbox to JSON
|
||||
*
|
||||
* @param id The id of the double spinbox
|
||||
* @return json The JSON representation of the double spinbox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the double spinbox value changes
|
||||
@@ -71,9 +57,4 @@ class UI_double_spinbox : public UI_item
|
||||
* @param value The new value
|
||||
*/
|
||||
void changed(double value);
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
};
|
||||
|
||||
+14
-32
@@ -1,58 +1,40 @@
|
||||
#include "ui_hex_spinbox.hpp"
|
||||
|
||||
UI_hex_spinbox::UI_hex_spinbox(QObject *parent) : UI_item(UI_enum::ui_hex_spinbox, parent)
|
||||
UI_hex_spinbox::UI_hex_spinbox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_hex_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
}
|
||||
|
||||
UI_hex_spinbox::UI_hex_spinbox(double min, double max, double value, QObject *parent)
|
||||
: UI_item(UI_enum::ui_hex_spinbox, parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_hex_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
m_value = value;
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
m_ui_item.spinbox().setMin(min);
|
||||
m_ui_item.spinbox().setMax(max);
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
}
|
||||
|
||||
void UI_hex_spinbox::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.spinbox().min() || value > m_ui_item.spinbox().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.spinbox().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
emit ui_changed();
|
||||
emit changed(m_value);
|
||||
emit changed(m_ui_item.spinbox().value());
|
||||
}
|
||||
double UI_hex_spinbox::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.spinbox().value();
|
||||
}
|
||||
|
||||
double UI_hex_spinbox::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.spinbox().min();
|
||||
}
|
||||
double UI_hex_spinbox::max() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void UI_hex_spinbox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
}
|
||||
|
||||
json UI_hex_spinbox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
return j;
|
||||
return m_ui_item.spinbox().max();
|
||||
}
|
||||
|
||||
@@ -50,20 +50,6 @@ class UI_hex_spinbox : public UI_item
|
||||
* @return double The maximum value
|
||||
*/
|
||||
double max() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the hex spinbox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the hex spinbox to JSON
|
||||
*
|
||||
* @param id The id of the hex spinbox
|
||||
* @return json The JSON representation of the hex spinbox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the hex spinbox value changes
|
||||
@@ -71,9 +57,4 @@ class UI_hex_spinbox : public UI_item
|
||||
* @param value The new value
|
||||
*/
|
||||
void changed(double value);
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
};
|
||||
|
||||
+34
-125
@@ -1,172 +1,81 @@
|
||||
#include "ui_item.hpp"
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
UI_item::UI_item(UI_enum type, std::string text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: QObject(parent), m_id((size_t)-1), m_type(type), m_text(text), m_fg_color(fg_color), m_bg_color(bg_color),
|
||||
m_enabled(true), m_visible(true)
|
||||
UI_item::UI_item(UI_typeGadget::UI_type type, QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_ui_item.setId_proto((size_t)-1);
|
||||
m_ui_item.setType(type);
|
||||
m_ui_item.setEnabled(true);
|
||||
m_ui_item.setVisible(true);
|
||||
}
|
||||
|
||||
UI_item::UI_item(UI_enum type, QObject *parent)
|
||||
: QObject(parent), m_id((size_t)-1), m_type(type), m_text(""), m_fg_color(Color::Default),
|
||||
m_bg_color(Color::Default), m_enabled(true), m_visible(true)
|
||||
void UI_item::set_id(size_t id)
|
||||
{
|
||||
}
|
||||
|
||||
std::string_view UI_item::type() const &
|
||||
{
|
||||
return magic_enum::enum_name(m_type);
|
||||
}
|
||||
|
||||
bool UI_item::is_type(json j)
|
||||
{
|
||||
if (!j.contains("type"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return magic_enum::enum_cast<UI_enum>((std::string)j.at("type")).value_or(UI_enum::end) == m_type;
|
||||
}
|
||||
|
||||
void UI_item::set_text(std::string text)
|
||||
{
|
||||
if (this->m_text != text)
|
||||
{
|
||||
this->m_text = std::move(text);
|
||||
emit ui_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void UI_item::append_text(std::string text)
|
||||
{
|
||||
m_text.append(text);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_item::text() const &
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
void UI_item::set_fg_color(Color fg_color)
|
||||
{
|
||||
if (this->m_fg_color != fg_color)
|
||||
{
|
||||
this->m_fg_color = std::move(fg_color);
|
||||
emit ui_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Color UI_item::fg_color() const &
|
||||
{
|
||||
return m_fg_color;
|
||||
}
|
||||
|
||||
void UI_item::set_bg_color(Color bg_color)
|
||||
{
|
||||
if (this->m_bg_color != bg_color)
|
||||
{
|
||||
this->m_bg_color = std::move(bg_color);
|
||||
emit ui_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Color UI_item::bg_color() const &
|
||||
{
|
||||
return m_bg_color;
|
||||
m_ui_item.setId_proto(id);
|
||||
}
|
||||
|
||||
void UI_item::set_enabled(bool enabled)
|
||||
{
|
||||
if (this->m_enabled != enabled)
|
||||
if (m_ui_item.enabled() != enabled)
|
||||
{
|
||||
this->m_enabled = std::move(enabled);
|
||||
m_ui_item.setEnabled(enabled);
|
||||
emit ui_changed();
|
||||
}
|
||||
}
|
||||
|
||||
bool UI_item::is_enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
return m_ui_item.enabled();
|
||||
}
|
||||
|
||||
void UI_item::set_visible(bool visible)
|
||||
{
|
||||
if (this->m_visible != visible)
|
||||
if (m_ui_item.visible() != visible)
|
||||
{
|
||||
this->m_visible = std::move(visible);
|
||||
m_ui_item.setVisible(visible);
|
||||
emit ui_changed();
|
||||
}
|
||||
}
|
||||
|
||||
bool UI_item::is_visible() const
|
||||
{
|
||||
return m_visible;
|
||||
return m_ui_item.visible();
|
||||
}
|
||||
|
||||
void UI_item::from_json(const json &j)
|
||||
UI_item_m UI_item::to_proto() const
|
||||
{
|
||||
if (!is_type(j))
|
||||
return;
|
||||
j.at("id").get_to(m_id);
|
||||
if (j.contains("text"))
|
||||
j.at("text").get_to(m_text);
|
||||
std::string color;
|
||||
if (j.contains("fg_color"))
|
||||
{
|
||||
j.at("fg_color").get_to(color);
|
||||
m_fg_color = Color(color);
|
||||
color.clear();
|
||||
}
|
||||
if (j.contains("bg_color"))
|
||||
{
|
||||
j.at("bg_color").get_to(color);
|
||||
m_bg_color = Color(color);
|
||||
}
|
||||
j.at("enabled").get_to(m_enabled);
|
||||
j.at("visible").get_to(m_visible);
|
||||
return m_ui_item;
|
||||
}
|
||||
|
||||
json UI_item::to_json(size_t id) const
|
||||
void UI_item::from_proto(UI_item_m item)
|
||||
{
|
||||
json j;
|
||||
j["id"] = id;
|
||||
j["type"] = type();
|
||||
if (m_text_enabled)
|
||||
j["text"] = m_text;
|
||||
if (m_fg_color_enabled)
|
||||
j["fg_color"] = m_fg_color.to_hex();
|
||||
if (m_bg_color_enabled)
|
||||
j["bg_color"] = m_bg_color.to_hex();
|
||||
j["enabled"] = m_enabled;
|
||||
j["visible"] = m_visible;
|
||||
return j;
|
||||
m_ui_item = item;
|
||||
}
|
||||
|
||||
void UI_item::click() {};
|
||||
|
||||
void UI_item::set_selected(size_t selected)
|
||||
void UI_item::set_selected(qsizetype selected)
|
||||
{
|
||||
UNUSED(selected);
|
||||
};
|
||||
Q_UNUSED(selected);
|
||||
}
|
||||
|
||||
void UI_item::set_text(QString text)
|
||||
{
|
||||
Q_UNUSED(text);
|
||||
}
|
||||
|
||||
void UI_item::set_value(double value)
|
||||
{
|
||||
UNUSED(value);
|
||||
};
|
||||
Q_UNUSED(value);
|
||||
}
|
||||
|
||||
void UI_item::can_send(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
|
||||
void UI_item::can_send(uint32_t id, uint64_t dlc, QByteArray payload)
|
||||
{
|
||||
UNUSED(id);
|
||||
UNUSED(dlc);
|
||||
UNUSED(payload);
|
||||
};
|
||||
Q_UNUSED(id);
|
||||
Q_UNUSED(dlc);
|
||||
Q_UNUSED(payload);
|
||||
}
|
||||
|
||||
void UI_item::clear()
|
||||
{
|
||||
}
|
||||
|
||||
void UI_item::setup_item(bool text, bool fg_color, bool bg_color)
|
||||
{
|
||||
m_text_enabled = text;
|
||||
m_fg_color_enabled = fg_color;
|
||||
m_bg_color_enabled = bg_color;
|
||||
}
|
||||
|
||||
+15
-147
@@ -1,15 +1,13 @@
|
||||
#pragma once
|
||||
#include "color.hpp"
|
||||
#include "ui_enum.hpp"
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#include "m_ui_items.qpb.h"
|
||||
#include <QProtobufSerializer>
|
||||
#include <cstdint>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <QCanBusFrame>
|
||||
#include <QObject>
|
||||
using json = nlohmann::json;
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
/**
|
||||
* @brief Base class representing a UI item
|
||||
@@ -25,77 +23,14 @@ class UI_item : public QObject
|
||||
* @param type The type of the UI item
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
explicit UI_item(UI_enum type, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a new UI item object
|
||||
*
|
||||
* @param type The type of the UI item
|
||||
* @param text The text of the UI item
|
||||
* @param fg_color The foreground color of the UI item
|
||||
* @param bg_color The background color of the UI item
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
explicit UI_item(UI_enum type, std::string text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
explicit UI_item(UI_typeGadget::UI_type type, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get the type of the UI item
|
||||
* @brief set_id Function for setting ID, DO NOT USE THIS IN A SIM YOURSELF
|
||||
*
|
||||
* @return std::string The type of the UI item
|
||||
* @param id
|
||||
*/
|
||||
std::string_view type() const &;
|
||||
/**
|
||||
* @brief Check if the JSON object is of the correct type
|
||||
*
|
||||
* @param j The JSON object
|
||||
* @return true If the JSON object is of the correct type
|
||||
* @return false If the JSON object is not of the correct type
|
||||
*/
|
||||
bool is_type(json j);
|
||||
|
||||
/**
|
||||
* @brief Set the text of the UI item
|
||||
*
|
||||
* @param text The text to set
|
||||
*/
|
||||
virtual void set_text(std::string text);
|
||||
/**
|
||||
* @brief Append text to the UI item
|
||||
*
|
||||
* @param text The text to append
|
||||
*/
|
||||
void append_text(std::string text);
|
||||
/**
|
||||
* @brief Get the text of the UI item
|
||||
*
|
||||
* @return std::string The text of the UI item
|
||||
*/
|
||||
std::string text() const &;
|
||||
|
||||
/**
|
||||
* @brief Set the foreground color of the UI item
|
||||
*
|
||||
* @param fg_color The foreground color to set
|
||||
*/
|
||||
void set_fg_color(Color fg_color);
|
||||
/**
|
||||
* @brief Get the foreground color of the UI item
|
||||
*
|
||||
* @return Color The foreground color of the UI item
|
||||
*/
|
||||
Color fg_color() const &;
|
||||
|
||||
/**
|
||||
* @brief Set the background color of the UI item
|
||||
*
|
||||
* @param bg_color The background color to set
|
||||
*/
|
||||
void set_bg_color(Color bg_color);
|
||||
/**
|
||||
* @brief Get the background color of the UI item
|
||||
*
|
||||
* @return Color The background color of the UI item
|
||||
*/
|
||||
Color bg_color() const &;
|
||||
void set_id(size_t id);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the UI item
|
||||
@@ -125,20 +60,8 @@ class UI_item : public QObject
|
||||
*/
|
||||
bool is_visible() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the UI item from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
virtual void from_json(const json &j);
|
||||
|
||||
/**
|
||||
* @brief Serialize the UI item to JSON
|
||||
*
|
||||
* @param id The id of the UI item
|
||||
* @return json The JSON representation of the UI item
|
||||
*/
|
||||
virtual json to_json(size_t id) const;
|
||||
UI_item_m to_proto() const;
|
||||
void from_proto(UI_item_m item);
|
||||
|
||||
/**
|
||||
* @brief Virtual method to handle click events
|
||||
@@ -150,7 +73,10 @@ class UI_item : public QObject
|
||||
*
|
||||
* @param selected The index of the option to select
|
||||
*/
|
||||
virtual void set_selected(size_t selected);
|
||||
virtual void set_selected(qsizetype selected);
|
||||
|
||||
virtual void set_text(QString text);
|
||||
|
||||
/**
|
||||
* @brief Virtual method to set the value (for spinboxes)
|
||||
*
|
||||
@@ -164,7 +90,7 @@ class UI_item : public QObject
|
||||
* @param dlc The data length code
|
||||
* @param payload The payload data
|
||||
*/
|
||||
virtual void can_send(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
|
||||
virtual void can_send(uint32_t id, uint64_t dlc, QByteArray payload);
|
||||
/**
|
||||
* @brief Virtual method to clear the UI item
|
||||
*
|
||||
@@ -179,63 +105,5 @@ class UI_item : public QObject
|
||||
void ui_changed();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Setup the UI item properties
|
||||
*
|
||||
* @param text Enable text property
|
||||
* @param fg_color Enable foreground color property
|
||||
* @param bg_color Enable background color property
|
||||
*/
|
||||
void setup_item(bool text, bool fg_color, bool bg_color);
|
||||
|
||||
/**
|
||||
* @brief The id of the UI item
|
||||
*
|
||||
*/
|
||||
size_t m_id;
|
||||
/**
|
||||
* @brief The type of the UI item
|
||||
*
|
||||
*/
|
||||
UI_enum m_type;
|
||||
/**
|
||||
* @brief The text of the UI item
|
||||
*
|
||||
*/
|
||||
std::string m_text;
|
||||
/**
|
||||
* @brief Whether the text property is enabled
|
||||
*
|
||||
*/
|
||||
bool m_text_enabled = true;
|
||||
/**
|
||||
* @brief The foreground color of the UI item
|
||||
*
|
||||
*/
|
||||
Color m_fg_color;
|
||||
/**
|
||||
* @brief Whether the foreground color property is enabled
|
||||
*
|
||||
*/
|
||||
bool m_fg_color_enabled = true;
|
||||
/**
|
||||
* @brief The background color of the UI item
|
||||
*
|
||||
*/
|
||||
Color m_bg_color;
|
||||
/**
|
||||
* @brief Whether the background color property is enabled
|
||||
*
|
||||
*/
|
||||
bool m_bg_color_enabled = true;
|
||||
/**
|
||||
* @brief Whether the UI item is enabled
|
||||
*
|
||||
*/
|
||||
bool m_enabled;
|
||||
/**
|
||||
* @brief Whether the UI item is visible
|
||||
*
|
||||
*/
|
||||
bool m_visible;
|
||||
UI_item_m m_ui_item;
|
||||
};
|
||||
|
||||
+39
-7
@@ -1,20 +1,52 @@
|
||||
#include "ui_label.hpp"
|
||||
|
||||
UI_label::UI_label(std::string text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_label, text, fg_color, bg_color, parent)
|
||||
UI_label::UI_label(QString text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_label, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
m_ui_item.label().setText(text);
|
||||
m_ui_item.label().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.label().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
UI_label::UI_label(QObject *parent) : UI_item(UI_enum::ui_label, parent)
|
||||
UI_label::UI_label(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_label, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
}
|
||||
|
||||
void UI_label::from_json(const json &j)
|
||||
void UI_label::set_text(QString text)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_ui_item.label().setText(text);
|
||||
}
|
||||
|
||||
json UI_label::to_json(size_t id) const
|
||||
void UI_label::append_text(QString text)
|
||||
{
|
||||
return UI_item::to_json(id);
|
||||
QString prev = m_ui_item.label().text();
|
||||
prev.append(text);
|
||||
m_ui_item.label().setText(prev);
|
||||
}
|
||||
|
||||
QString UI_label::text() const
|
||||
{
|
||||
return m_ui_item.label().text();
|
||||
}
|
||||
|
||||
void UI_label::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setFgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_label::fg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_label::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setBgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_label::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().bgColor());
|
||||
}
|
||||
+19
-10
@@ -18,7 +18,7 @@ class UI_label : public UI_item
|
||||
* @param bg_color The background color
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_label(std::string text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
UI_label(QString text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI label object
|
||||
*
|
||||
@@ -27,16 +27,25 @@ class UI_label : public UI_item
|
||||
UI_label(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Deserialize the label from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
* @brief set_text
|
||||
* @param text The text field of the button
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
void set_text(QString text);
|
||||
|
||||
/**
|
||||
* @brief Serialize the label to JSON
|
||||
*
|
||||
* @param id The id of the label
|
||||
* @return json The JSON representation of the label
|
||||
* @brief append_text Append
|
||||
* @param text
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
void append_text(QString text);
|
||||
|
||||
/**
|
||||
* @brief text
|
||||
* @return The text field of the button
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
};
|
||||
|
||||
+38
-14
@@ -1,12 +1,47 @@
|
||||
#include "ui_led.hpp"
|
||||
|
||||
UI_led::UI_led(QObject *parent) : UI_item(UI_enum::ui_led, "", Color::Default, Color::Default, parent)
|
||||
UI_led::UI_led(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_led, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
}
|
||||
|
||||
UI_led::UI_led(std::string text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_led, text, fg_color, bg_color, parent)
|
||||
UI_led::UI_led(QString text, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_led, parent)
|
||||
{
|
||||
m_ui_item.setLabel(UI_label_m());
|
||||
m_ui_item.label().setText(text);
|
||||
m_ui_item.label().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.label().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
void UI_led::set_text(QString text)
|
||||
{
|
||||
m_ui_item.label().setText(text);
|
||||
}
|
||||
|
||||
QString UI_led::text() const
|
||||
{
|
||||
return m_ui_item.label().text();
|
||||
}
|
||||
|
||||
void UI_led::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setFgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_led::fg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_led::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setBgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_led::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().bgColor());
|
||||
}
|
||||
|
||||
bool UI_led::set_led(bool state, Color on, Color off)
|
||||
@@ -14,14 +49,3 @@ bool UI_led::set_led(bool state, Color on, Color off)
|
||||
set_bg_color(state ? on : off);
|
||||
return state;
|
||||
}
|
||||
|
||||
void UI_led::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
}
|
||||
|
||||
json UI_led::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
return j;
|
||||
}
|
||||
|
||||
+18
-15
@@ -24,7 +24,24 @@ class UI_led : public UI_item
|
||||
* @param bg_color The background color
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_led(std::string text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
UI_led(QString text, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief set_text
|
||||
* @param text The text field of the button
|
||||
*/
|
||||
void set_text(QString text) override;
|
||||
|
||||
/**
|
||||
* @brief text
|
||||
* @return The text field of the button
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Set the state of the LED
|
||||
@@ -35,18 +52,4 @@ class UI_led : public UI_item
|
||||
* @return state
|
||||
*/
|
||||
bool set_led(bool state, Color on, Color off);
|
||||
|
||||
/**
|
||||
* @brief Deserialize the LED from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the LED to JSON
|
||||
*
|
||||
* @param id The id of the LED
|
||||
* @return json The JSON representation of the LED
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
};
|
||||
|
||||
+58
-41
@@ -1,88 +1,105 @@
|
||||
#include "ui_plot.hpp"
|
||||
|
||||
UI_plot::UI_plot(QObject *parent) : UI_item{UI_enum::ui_plot, parent}
|
||||
UI_plot::UI_plot(QObject *parent) : UI_item{UI_typeGadget::UI_type::ui_plot, parent}
|
||||
{
|
||||
m_ui_item.setPlot(UI_plot_m());
|
||||
}
|
||||
|
||||
UI_plot::UI_plot(std::string text, std::string x_label, std::string y_label, QObject *parent)
|
||||
: UI_item(UI_enum::ui_plot, parent), m_x_label(x_label), m_y_label(y_label)
|
||||
UI_plot::UI_plot(QString text, QString x_label, QString y_label, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_plot, parent)
|
||||
{
|
||||
set_text(text);
|
||||
m_ui_item.setPlot(UI_plot_m());
|
||||
m_ui_item.plot().setText(text);
|
||||
m_ui_item.plot().setXLabel(x_label);
|
||||
m_ui_item.plot().setYLabel(y_label);
|
||||
}
|
||||
|
||||
void UI_plot::set_x_label(std::string name)
|
||||
void UI_plot::set_x_label(QString name)
|
||||
{
|
||||
m_x_label = std::move(name);
|
||||
m_ui_item.plot().setXLabel(name);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_plot::x_label() const &
|
||||
QString UI_plot::x_label() const &
|
||||
{
|
||||
return m_x_label;
|
||||
return m_ui_item.plot().xLabel();
|
||||
}
|
||||
|
||||
void UI_plot::set_y_label(std::string name)
|
||||
void UI_plot::set_y_label(QString name)
|
||||
{
|
||||
m_y_label = std::move(name);
|
||||
m_ui_item.plot().setYLabel(name);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_plot::y_label() const &
|
||||
QString UI_plot::y_label() const &
|
||||
{
|
||||
return m_y_label;
|
||||
return m_ui_item.plot().yLabel();
|
||||
}
|
||||
|
||||
void UI_plot::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.plot().mutColor().setFgColor(color.color());
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
Color UI_plot::fg_color() const&
|
||||
{
|
||||
return Color(m_ui_item.plot().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_plot::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.plot().mutColor().setBgColor(color.color());
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
Color UI_plot::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.plot().color().bgColor());
|
||||
}
|
||||
|
||||
void UI_plot::add_value(double y)
|
||||
{
|
||||
m_x_vals.push_back((double)m_x_vals.size());
|
||||
m_y_vals.push_back(y);
|
||||
auto x_vals = m_ui_item.plot().xVals();
|
||||
auto y_vals = m_ui_item.plot().yVals();
|
||||
x_vals.push_back((double)x_vals.size());
|
||||
y_vals.push_back(y);
|
||||
m_ui_item.plot().setXVals(x_vals);
|
||||
m_ui_item.plot().setYVals(y_vals);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_plot::add_value(double x, double y)
|
||||
{
|
||||
m_x_vals.push_back(x);
|
||||
m_y_vals.push_back(y);
|
||||
auto x_vals = m_ui_item.plot().xVals();
|
||||
auto y_vals = m_ui_item.plot().yVals();
|
||||
x_vals.push_back(x);
|
||||
y_vals.push_back(y);
|
||||
m_ui_item.plot().setXVals(x_vals);
|
||||
m_ui_item.plot().setYVals(y_vals);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
const std::vector<double> &UI_plot::x_vals() const &
|
||||
const QList<double> &UI_plot::x_vals() const &
|
||||
{
|
||||
return m_x_vals;
|
||||
return m_ui_item.plot().xVals();
|
||||
}
|
||||
|
||||
const std::vector<double> &UI_plot::y_vals() const &
|
||||
const QList<double> &UI_plot::y_vals() const &
|
||||
{
|
||||
return m_y_vals;
|
||||
return m_ui_item.plot().yVals();
|
||||
}
|
||||
|
||||
void UI_plot::clean_vals()
|
||||
{
|
||||
m_x_vals.clear();
|
||||
m_y_vals.clear();
|
||||
m_ui_item.plot().setXVals(QList<double>());
|
||||
m_ui_item.plot().setYVals(QList<double>());
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_plot::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
this->m_x_label = j.at("x_label");
|
||||
this->m_y_label = j.at("y_label");
|
||||
this->m_x_vals = (std::vector<double>)j.at("x_vals");
|
||||
this->m_y_vals = (std::vector<double>)j.at("y_vals");
|
||||
}
|
||||
|
||||
json UI_plot::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["x_label"] = m_x_label;
|
||||
j["y_label"] = m_y_label;
|
||||
j["x_vals"] = m_x_vals;
|
||||
j["y_vals"] = m_y_vals;
|
||||
return j;
|
||||
}
|
||||
|
||||
+29
-29
@@ -23,33 +23,53 @@ class UI_plot : public UI_item
|
||||
* @param y_label The label for the y-axis
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_plot(std::string text, std::string x_label, std::string y_label, QObject *parent = nullptr);
|
||||
UI_plot(QString text, QString x_label, QString y_label, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Set the label for the x-axis
|
||||
*
|
||||
* @param name The name to set
|
||||
*/
|
||||
void set_x_label(std::string name);
|
||||
void set_x_label(QString name);
|
||||
/**
|
||||
* @brief Get the label for the x-axis
|
||||
*
|
||||
* @return std::string The x-axis label
|
||||
* @return QString The x-axis label
|
||||
*/
|
||||
std::string x_label() const &;
|
||||
QString x_label() const &;
|
||||
|
||||
/**
|
||||
* @brief Set the label for the y-axis
|
||||
*
|
||||
* @param name The name to set
|
||||
*/
|
||||
void set_y_label(std::string name);
|
||||
void set_y_label(QString name);
|
||||
/**
|
||||
* @brief Get the label for the y-axis
|
||||
*
|
||||
* @return std::string The y-axis label
|
||||
* @return QString The y-axis label
|
||||
*/
|
||||
std::string y_label() const &;
|
||||
QString y_label() const &;
|
||||
/**
|
||||
* @brief set_fg_color Set the pen color
|
||||
* @param color The color
|
||||
*/
|
||||
void set_fg_color(Color color);
|
||||
/**
|
||||
* @brief fg_color Get the pen color
|
||||
* @return The color
|
||||
*/
|
||||
Color fg_color() const&;
|
||||
/**
|
||||
* @brief set_bg_color Set the background color
|
||||
* @param color The color
|
||||
*/
|
||||
void set_bg_color(Color color);
|
||||
/**
|
||||
* @brief bg_color Get the background color
|
||||
* @return The color
|
||||
*/
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Add a value to the plot
|
||||
@@ -70,37 +90,17 @@ class UI_plot : public UI_item
|
||||
*
|
||||
* @return a list of x values and a list of y values
|
||||
*/
|
||||
const std::vector<double> &x_vals() const &;
|
||||
const QList<double> &x_vals() const &;
|
||||
/**
|
||||
* @brief Get the y values of the plot
|
||||
* This is only for testing purposes
|
||||
*
|
||||
* @return a list of y values
|
||||
*/
|
||||
const std::vector<double> &y_vals() const &;
|
||||
const QList<double> &y_vals() const &;
|
||||
/**
|
||||
* @brief Clear all values from the plot
|
||||
*
|
||||
*/
|
||||
void clean_vals();
|
||||
|
||||
/**
|
||||
* @brief Deserialize the plot from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the plot to JSON
|
||||
*
|
||||
* @param id The id of the plot
|
||||
* @return json The JSON representation of the plot
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
std::vector<double> m_x_vals;
|
||||
std::vector<double> m_y_vals;
|
||||
std::string m_x_label;
|
||||
std::string m_y_label;
|
||||
};
|
||||
|
||||
+19
-43
@@ -1,75 +1,51 @@
|
||||
#include "ui_slider.hpp"
|
||||
|
||||
UI_slider::UI_slider(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max,
|
||||
UI_slider::UI_slider(QString text, QString unit, double min, double max,
|
||||
double value, QObject *parent)
|
||||
: UI_item(UI_enum::ui_slider, text, fg_color, bg_color, parent), m_min(min), m_max(max), m_value(value),
|
||||
m_unit(unit)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_slider, parent)
|
||||
{
|
||||
m_ui_item.setRange(UI_range_m());
|
||||
m_ui_item.range().setText(text);
|
||||
m_ui_item.range().setUnit(unit);
|
||||
m_ui_item.range().setMax(max);
|
||||
m_ui_item.range().setMin(min);
|
||||
m_ui_item.range().setValue(value);
|
||||
}
|
||||
|
||||
UI_slider::UI_slider(std::string text, std::string unit, double min, double max, double value, QObject *parent)
|
||||
: UI_slider(text, unit, Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_slider::UI_slider(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_slider::UI_slider(QString text, double min, double max, double value,
|
||||
QObject *parent)
|
||||
: UI_slider(text, "", fg_color, bg_color, min, max, value, parent)
|
||||
: UI_slider(text, "", min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_slider::UI_slider(std::string text, double min, double max, double value, QObject *parent)
|
||||
: UI_slider(text, "", Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_slider::UI_slider(QObject *parent) : UI_item(UI_enum::ui_slider, parent)
|
||||
UI_slider::UI_slider(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_slider, parent)
|
||||
{
|
||||
m_ui_item.setRange(UI_range_m());
|
||||
}
|
||||
|
||||
void UI_slider::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.range().min() || value > m_ui_item.range().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.range().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.range().setValue(value);
|
||||
emit ui_changed();
|
||||
emit changed(m_value);
|
||||
emit changed(m_ui_item.range().value());
|
||||
}
|
||||
|
||||
double UI_slider::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.range().value();
|
||||
}
|
||||
|
||||
double UI_slider::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.range().min();
|
||||
}
|
||||
|
||||
double UI_slider::max() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void UI_slider::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
this->m_unit = j.at("unit");
|
||||
}
|
||||
|
||||
json UI_slider::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
j["unit"] = this->m_unit;
|
||||
return j;
|
||||
return m_ui_item.range().max();
|
||||
}
|
||||
|
||||
+3
-45
@@ -14,26 +14,13 @@ class UI_slider : public UI_item
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the slider
|
||||
* @param fg_color The foreground color
|
||||
* @param bg_color The background color
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_slider(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_slider(QString text, QString unit, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI slider object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the slider
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_slider(std::string text, std::string unit, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI slider object
|
||||
*
|
||||
@@ -45,18 +32,9 @@ class UI_slider : public UI_item
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_slider(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_slider(QString text, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI slider object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_slider(std::string text, double min, double max, double value, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Construct a UI slider object
|
||||
*
|
||||
@@ -89,20 +67,6 @@ class UI_slider : public UI_item
|
||||
* @return double The maximum value
|
||||
*/
|
||||
double max() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the slider from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the slider to JSON
|
||||
*
|
||||
* @param id The id of the slider
|
||||
* @return json The JSON representation of the slider
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the slider value changes
|
||||
@@ -110,10 +74,4 @@ class UI_slider : public UI_item
|
||||
* @param value The new value of the slider
|
||||
*/
|
||||
void changed(double value);
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
std::string m_unit;
|
||||
};
|
||||
|
||||
+14
-32
@@ -1,57 +1,39 @@
|
||||
#include "ui_spinbox.hpp"
|
||||
|
||||
UI_spinbox::UI_spinbox(QObject *parent) : UI_item(UI_enum::ui_spinbox, parent)
|
||||
UI_spinbox::UI_spinbox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
}
|
||||
|
||||
UI_spinbox::UI_spinbox(double min, double max, double value, QObject *parent) : UI_item(UI_enum::ui_spinbox, parent)
|
||||
UI_spinbox::UI_spinbox(double min, double max, double value, QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_spinbox, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
m_value = value;
|
||||
m_ui_item.setSpinbox(UI_spinbox_m());
|
||||
m_ui_item.spinbox().setMin(min);
|
||||
m_ui_item.spinbox().setMax(max);
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
}
|
||||
|
||||
void UI_spinbox::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.spinbox().min() || value > m_ui_item.spinbox().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.spinbox().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.spinbox().setValue(value);
|
||||
emit ui_changed();
|
||||
emit changed(m_value);
|
||||
emit changed(m_ui_item.spinbox().value());
|
||||
}
|
||||
double UI_spinbox::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.spinbox().value();
|
||||
}
|
||||
|
||||
double UI_spinbox::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.spinbox().min();
|
||||
}
|
||||
double UI_spinbox::max() const
|
||||
{
|
||||
return m_max;
|
||||
}
|
||||
|
||||
void UI_spinbox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
}
|
||||
|
||||
json UI_spinbox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
return j;
|
||||
return m_ui_item.spinbox().max();
|
||||
}
|
||||
|
||||
@@ -50,20 +50,6 @@ class UI_spinbox : public UI_item
|
||||
* @return double The maximum value
|
||||
*/
|
||||
double max() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the spinbox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the spinbox to JSON
|
||||
*
|
||||
* @param id The id of the spinbox
|
||||
* @return json The JSON representation of the spinbox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the spinbox value changes
|
||||
@@ -71,9 +57,4 @@ class UI_spinbox : public UI_item
|
||||
* @param value The new value of the spinbox
|
||||
*/
|
||||
void changed(double value);
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
};
|
||||
|
||||
+14
-24
@@ -1,44 +1,34 @@
|
||||
#include "ui_stacked_widget.hpp"
|
||||
|
||||
UI_stacked_widget::UI_stacked_widget(QObject *parent) : UI_item(UI_enum::ui_stacked_widget, parent)
|
||||
UI_stacked_widget::UI_stacked_widget(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_stacked_widget, parent)
|
||||
{
|
||||
m_ui_item.setStackedWidget(UI_stacked_widget_m());
|
||||
}
|
||||
|
||||
UI_stacked_widget::UI_stacked_widget(size_t tab_count, size_t current_tab, QObject *parent)
|
||||
: UI_item(UI_enum::ui_stacked_widget, parent), m_tab_count(tab_count), m_current_tab(current_tab)
|
||||
UI_stacked_widget::UI_stacked_widget(qsizetype tab_count, qsizetype current_tab, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_stacked_widget, parent)
|
||||
{
|
||||
m_ui_item.setStackedWidget(UI_stacked_widget_m());
|
||||
m_ui_item.stackedWidget().setTabCount(tab_count);
|
||||
m_ui_item.stackedWidget().setCurrentTab(current_tab);
|
||||
}
|
||||
|
||||
void UI_stacked_widget::set_selected(size_t selected)
|
||||
void UI_stacked_widget::set_selected(qsizetype selected)
|
||||
{
|
||||
if (selected >= m_tab_count)
|
||||
if (selected >= m_ui_item.stackedWidget().tabCount())
|
||||
return;
|
||||
m_current_tab = selected;
|
||||
m_ui_item.stackedWidget().setCurrentTab(selected);
|
||||
emit ui_changed();
|
||||
}
|
||||
size_t UI_stacked_widget::selected() const
|
||||
qsizetype UI_stacked_widget::selected() const
|
||||
{
|
||||
return m_current_tab;
|
||||
return m_ui_item.stackedWidget().currentTab();
|
||||
}
|
||||
|
||||
void UI_stacked_widget::advance_tab()
|
||||
{
|
||||
if (m_tab_count == 0)
|
||||
if (m_ui_item.stackedWidget().tabCount() == 0)
|
||||
return;
|
||||
m_current_tab = (m_current_tab + 1) % m_tab_count;
|
||||
m_ui_item.stackedWidget().setCurrentTab((m_ui_item.stackedWidget().currentTab() + 1) % m_ui_item.stackedWidget().tabCount());
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_stacked_widget::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_tab_count = j.at("tab_count");
|
||||
m_current_tab = j.at("current_tab");
|
||||
}
|
||||
json UI_stacked_widget::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["tab_count"] = m_tab_count;
|
||||
j["current_tab"] = m_current_tab;
|
||||
return j;
|
||||
}
|
||||
|
||||
@@ -22,41 +22,23 @@ class UI_stacked_widget : public UI_item
|
||||
* @param current_tab The currently selected tab
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_stacked_widget(size_t tab_count, size_t current_tab, QObject *parent = nullptr);
|
||||
UI_stacked_widget(qsizetype tab_count, qsizetype current_tab, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Set the selected tab by index
|
||||
*
|
||||
* @param selected The index of the tab to select
|
||||
*/
|
||||
void set_selected(size_t selected) override;
|
||||
void set_selected(qsizetype selected) override;
|
||||
/**
|
||||
* @brief Get the index of the selected tab
|
||||
*
|
||||
* @return size_t The index of the selected tab
|
||||
*/
|
||||
size_t selected() const;
|
||||
qsizetype selected() const;
|
||||
/**
|
||||
* @brief Advance to the next tab
|
||||
*
|
||||
*/
|
||||
void advance_tab();
|
||||
|
||||
/**
|
||||
* @brief Deserialize the stacked widget from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the stacked widget to JSON
|
||||
*
|
||||
* @param id The id of the stacked widget
|
||||
* @return json The JSON representation of the stacked widget
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
size_t m_tab_count;
|
||||
size_t m_current_tab;
|
||||
};
|
||||
|
||||
+14
-25
@@ -1,44 +1,33 @@
|
||||
#include "ui_status_bar.hpp"
|
||||
|
||||
UI_status_bar::UI_status_bar(QObject *parent) : UI_item(UI_enum::ui_status_bar, parent), m_timeout(0)
|
||||
UI_status_bar::UI_status_bar(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_status_bar, parent)
|
||||
{
|
||||
setup_item(true, false, false);
|
||||
m_ui_item.setStatusBar(UI_status_bar_m());
|
||||
m_ui_item.statusBar().setTimeout(0);
|
||||
}
|
||||
|
||||
UI_status_bar::UI_status_bar(std::string message, QObject *parent)
|
||||
: UI_item(UI_enum::ui_status_bar, parent), m_timeout(0)
|
||||
UI_status_bar::UI_status_bar(QString message, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_status_bar, parent)
|
||||
{
|
||||
m_text = std::move(message);
|
||||
setup_item(true, false, false);
|
||||
m_ui_item.setStatusBar(UI_status_bar_m());
|
||||
m_ui_item.statusBar().setMessage(message);
|
||||
m_ui_item.statusBar().setTimeout(0);
|
||||
}
|
||||
|
||||
void UI_status_bar::show_message(std::string message, size_t timeout)
|
||||
void UI_status_bar::show_message(QString message, size_t timeout)
|
||||
{
|
||||
// This should work because the message gets only send once when it changes
|
||||
m_text = std::move(message);
|
||||
m_timeout = timeout;
|
||||
m_ui_item.statusBar().setMessage(message);
|
||||
m_ui_item.statusBar().setTimeout(timeout);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_status_bar::message() const &
|
||||
QString UI_status_bar::message() const &
|
||||
{
|
||||
return m_text;
|
||||
return m_ui_item.statusBar().message();
|
||||
}
|
||||
|
||||
size_t UI_status_bar::timeout() const
|
||||
{
|
||||
return m_timeout;
|
||||
}
|
||||
|
||||
void UI_status_bar::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_timeout = j.at("timeout");
|
||||
}
|
||||
|
||||
json UI_status_bar::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["timeout"] = m_timeout;
|
||||
return j;
|
||||
return m_ui_item.statusBar().timeout();
|
||||
}
|
||||
|
||||
+4
-21
@@ -21,7 +21,7 @@ class UI_status_bar : public UI_item
|
||||
* @param message The initial message
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_status_bar(std::string message, QObject *parent = nullptr);
|
||||
UI_status_bar(QString message, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Show a message on the status bar
|
||||
@@ -29,34 +29,17 @@ class UI_status_bar : public UI_item
|
||||
* @param message The message to show
|
||||
* @param timeout The timeout in milliseconds (0 for no timeout)
|
||||
*/
|
||||
void show_message(std::string message, size_t timeout = 0);
|
||||
void show_message(QString message, size_t timeout = 0);
|
||||
/**
|
||||
* @brief Get the current message
|
||||
*
|
||||
* @return std::string The current message
|
||||
* @return QString The current message
|
||||
*/
|
||||
std::string message() const &;
|
||||
QString message() const &;
|
||||
/**
|
||||
* @brief Get the timeout for the current message
|
||||
*
|
||||
* @return size_t The timeout in milliseconds
|
||||
*/
|
||||
size_t timeout() const;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the status bar from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the status bar to JSON
|
||||
*
|
||||
* @param id The id of the status bar
|
||||
* @return json The JSON representation of the status bar
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
size_t m_timeout;
|
||||
};
|
||||
|
||||
+32
-58
@@ -1,104 +1,78 @@
|
||||
#include "ui_tab_widget.hpp"
|
||||
|
||||
UI_tab_widget::UI_tab_widget(QObject *parent) : UI_item(UI_enum::ui_tab_widget, parent)
|
||||
UI_tab_widget::UI_tab_widget(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_tab_widget, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_ui_item.setStackedWidget(UI_stacked_widget_m());
|
||||
}
|
||||
|
||||
UI_tab_widget::UI_tab_widget(std::vector<std::string> tab_names, size_t selected, QObject *parent)
|
||||
: UI_item(UI_enum::ui_tab_widget, parent), m_selected_tab(selected), m_tab_names(tab_names)
|
||||
UI_tab_widget::UI_tab_widget(QList<QString> tab_names, qsizetype selected, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_tab_widget, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_tab_visible.resize(m_tab_names.size(), true);
|
||||
m_ui_item.setTabWidget(UI_tab_widget_m());
|
||||
m_ui_item.tabWidget().setTabNames(tab_names);
|
||||
m_ui_item.tabWidget().setSelecteTab(selected);
|
||||
}
|
||||
|
||||
void UI_tab_widget::set_selected(size_t selected)
|
||||
void UI_tab_widget::set_selected(qsizetype selected)
|
||||
{
|
||||
if (selected >= m_tab_names.size())
|
||||
if (selected >= m_ui_item.tabWidget().tabNames().size())
|
||||
return;
|
||||
m_selected_tab = selected;
|
||||
m_ui_item.tabWidget().setSelecteTab(selected);
|
||||
emit ui_changed();
|
||||
emit changed(m_selected_tab);
|
||||
emit changed(selected);
|
||||
}
|
||||
size_t UI_tab_widget::selected() const
|
||||
qsizetype UI_tab_widget::selected() const
|
||||
{
|
||||
return m_selected_tab;
|
||||
return m_ui_item.tabWidget().selecteTab();
|
||||
}
|
||||
|
||||
void UI_tab_widget::set_visible(size_t index, bool visible)
|
||||
void UI_tab_widget::set_visible(qsizetype index, bool visible)
|
||||
{
|
||||
if (index >= m_tab_visible.size())
|
||||
if (index >= m_ui_item.tabWidget().tabNames().size())
|
||||
{
|
||||
// Only allow known tab amount from constructor
|
||||
return;
|
||||
}
|
||||
m_tab_visible.at(index) = visible;
|
||||
auto list = m_ui_item.tabWidget().tabVisible();
|
||||
list.replace(index, visible);
|
||||
m_ui_item.tabWidget().setTabVisible(list);
|
||||
emit ui_changed();
|
||||
}
|
||||
bool UI_tab_widget::visible(size_t index) const
|
||||
bool UI_tab_widget::visible(qsizetype index) const
|
||||
{
|
||||
if (index >= m_tab_visible.size())
|
||||
if (index >= m_ui_item.tabWidget().tabNames().size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_tab_visible.at(index);
|
||||
return m_ui_item.tabWidget().tabVisible().at(index);
|
||||
}
|
||||
|
||||
void UI_tab_widget::set_tab_name(size_t index, std::string name)
|
||||
void UI_tab_widget::set_tab_name(qsizetype index, QString name)
|
||||
{
|
||||
if (index >= m_tab_names.size() || index >= m_tab_visible.size())
|
||||
if (index >= m_ui_item.tabWidget().tabNames().size() || index >= m_ui_item.tabWidget().tabVisible().size())
|
||||
{
|
||||
// Only allow known tab amount from constructor
|
||||
return;
|
||||
}
|
||||
m_tab_names.at(index) = name;
|
||||
auto list = m_ui_item.tabWidget().tabNames();
|
||||
list.replace(index, name);
|
||||
m_ui_item.tabWidget().setTabNames(list);
|
||||
emit ui_changed();
|
||||
}
|
||||
std::string UI_tab_widget::tab_name(size_t index) const
|
||||
QString UI_tab_widget::tab_name(qsizetype index) const
|
||||
{
|
||||
if (index >= m_tab_names.size())
|
||||
if (index >= m_ui_item.tabWidget().tabNames().size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return m_tab_names.at(index);
|
||||
return m_ui_item.tabWidget().tabNames().at(index);
|
||||
}
|
||||
|
||||
void UI_tab_widget::advance_tab()
|
||||
{
|
||||
if (m_tab_names.size() == 0)
|
||||
if (m_ui_item.tabWidget().tabNames().empty())
|
||||
return;
|
||||
m_selected_tab = (m_selected_tab + 1) % m_tab_names.size();
|
||||
m_ui_item.tabWidget().setSelecteTab((m_ui_item.tabWidget().selecteTab() + 1) % m_ui_item.tabWidget().tabNames().size());
|
||||
emit ui_changed();
|
||||
emit changed(m_selected_tab);
|
||||
}
|
||||
|
||||
void UI_tab_widget::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
if (j.contains("tab_names"))
|
||||
{
|
||||
this->m_tab_names.clear();
|
||||
for (auto &option : j["tab_names"])
|
||||
{
|
||||
this->m_tab_names.push_back(option);
|
||||
}
|
||||
}
|
||||
if (j.contains("tab_visible"))
|
||||
{
|
||||
this->m_tab_visible.clear();
|
||||
for (auto &option : j["tab_visible"])
|
||||
{
|
||||
this->m_tab_visible.push_back(option);
|
||||
}
|
||||
}
|
||||
m_selected_tab = j.at("selected");
|
||||
}
|
||||
|
||||
json UI_tab_widget::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["tab_names"] = m_tab_names;
|
||||
j["tab_visible"] = m_tab_visible;
|
||||
j["selected"] = m_selected_tab;
|
||||
return j;
|
||||
emit changed(m_ui_item.tabWidget().selecteTab());
|
||||
}
|
||||
|
||||
+8
-27
@@ -21,20 +21,20 @@ class UI_tab_widget : public UI_item
|
||||
* @param selected The initially selected tab
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_tab_widget(std::vector<std::string> tab_names, size_t selected = 0, QObject *parent = nullptr);
|
||||
UI_tab_widget(QList<QString> tab_names, qsizetype selected = 0, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Set the selected tab by index
|
||||
*
|
||||
* @param selected The index of the tab to select
|
||||
*/
|
||||
void set_selected(size_t selected) override;
|
||||
void set_selected(qsizetype selected) override;
|
||||
/**
|
||||
* @brief Get the index of the selected tab
|
||||
*
|
||||
* @return size_t The index of the selected tab
|
||||
*/
|
||||
size_t selected() const;
|
||||
qsizetype selected() const;
|
||||
|
||||
/**
|
||||
* @brief Set the visibility of a tab by index
|
||||
@@ -42,7 +42,7 @@ class UI_tab_widget : public UI_item
|
||||
* @param index The index of the tab
|
||||
* @param visible True to show, false to hide
|
||||
*/
|
||||
void set_visible(size_t index, bool visible);
|
||||
void set_visible(qsizetype index, bool visible);
|
||||
/**
|
||||
* @brief Get the visibility of a tab by index
|
||||
*
|
||||
@@ -50,7 +50,7 @@ class UI_tab_widget : public UI_item
|
||||
* @return true If the tab is visible
|
||||
* @return false If the tab is hidden
|
||||
*/
|
||||
bool visible(size_t index) const;
|
||||
bool visible(qsizetype index) const;
|
||||
|
||||
/**
|
||||
* @brief Set the name of a tab by index
|
||||
@@ -58,44 +58,25 @@ class UI_tab_widget : public UI_item
|
||||
* @param index The index of the tab
|
||||
* @param name The name to set
|
||||
*/
|
||||
void set_tab_name(size_t index, std::string name);
|
||||
void set_tab_name(qsizetype index, QString name);
|
||||
/**
|
||||
* @brief Get the name of a tab by index
|
||||
*
|
||||
* @param index The index of the tab
|
||||
* @return std::string The name of the tab
|
||||
*/
|
||||
std::string tab_name(size_t index) const;
|
||||
QString tab_name(qsizetype index) const;
|
||||
|
||||
/**
|
||||
* @brief Advance to the next tab
|
||||
*
|
||||
*/
|
||||
void advance_tab();
|
||||
|
||||
/**
|
||||
* @brief Deserialize the tab widget from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the tab widget to JSON
|
||||
*
|
||||
* @param id The id of the tab widget
|
||||
* @return json The JSON representation of the tab widget
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the selected tab changes
|
||||
*
|
||||
* @param index The index of the newly selected tab
|
||||
*/
|
||||
void changed(size_t index);
|
||||
|
||||
private:
|
||||
size_t m_selected_tab;
|
||||
std::vector<std::string> m_tab_names;
|
||||
std::vector<bool> m_tab_visible;
|
||||
void changed(qsizetype index);
|
||||
};
|
||||
|
||||
+80
-74
@@ -1,162 +1,168 @@
|
||||
#include "ui_table.hpp"
|
||||
|
||||
UI_table::UI_table(QObject *parent) : UI_item(UI_enum::ui_table, parent), m_row_count(0), m_column_count(0)
|
||||
UI_table::UI_table(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_table, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_ui_item.setTable(UI_table_m());
|
||||
}
|
||||
|
||||
UI_table::UI_table(size_t row_count, size_t column_count, std::vector<std::string> row_labels,
|
||||
std::vector<std::string> column_labels, QObject *parent)
|
||||
: UI_item(UI_enum::ui_table, parent), m_row_count(row_count), m_column_count(column_count),
|
||||
m_row_labels(row_labels), m_column_labels(column_labels), m_table()
|
||||
UI_table::UI_table(qsizetype row_count, qsizetype column_count, QList<QString> row_labels,
|
||||
QList<QString> column_labels, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_table, parent)
|
||||
{
|
||||
setup_item(false, false, false);
|
||||
m_row_labels.reserve(100);
|
||||
m_column_labels.reserve(100);
|
||||
m_table.reserve(500);
|
||||
m_ui_item.setTable(UI_table_m());
|
||||
m_ui_item.table().setRowCount(row_count);
|
||||
m_ui_item.table().setColumnCount(column_count);
|
||||
m_ui_item.table().setColumnLabels(column_labels);
|
||||
m_ui_item.table().setRowLabels(row_labels);
|
||||
}
|
||||
|
||||
void UI_table::set_row_count(size_t count)
|
||||
void UI_table::set_row_count(qsizetype count)
|
||||
{
|
||||
m_row_count = count;
|
||||
if (m_row_count != 0 || m_column_count != 0)
|
||||
m_ui_item.table().setRowCount(count);
|
||||
auto column_count = m_ui_item.table().columnCount();
|
||||
auto row_count = m_ui_item.table().rowCount();
|
||||
auto row_labels = m_ui_item.table().rowLabels();
|
||||
|
||||
if (row_count != 0 || column_count != 0)
|
||||
{
|
||||
m_table.resize(m_column_count * m_row_count);
|
||||
auto table = m_ui_item.table().table();
|
||||
table.resize(column_count * count);
|
||||
m_ui_item.table().setTable(table);
|
||||
}
|
||||
|
||||
m_row_labels.resize(m_row_count);
|
||||
row_labels.resize(count);
|
||||
m_ui_item.table().setRowLabels(row_labels);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
size_t UI_table::row_count() const
|
||||
qsizetype UI_table::row_count() const
|
||||
{
|
||||
return m_row_count;
|
||||
return m_ui_item.table().rowCount();
|
||||
}
|
||||
|
||||
void UI_table::set_column_count(size_t count)
|
||||
void UI_table::set_column_count(qsizetype count)
|
||||
{
|
||||
m_column_count = count;
|
||||
if (m_row_count != 0 || m_column_count != 0)
|
||||
m_ui_item.table().setColumnCount(count);
|
||||
auto column_count = m_ui_item.table().columnCount();
|
||||
auto row_count = m_ui_item.table().rowCount();
|
||||
auto column_labels = m_ui_item.table().columnLabels();
|
||||
|
||||
if (row_count != 0 || column_count != 0)
|
||||
{
|
||||
m_table.resize(m_column_count * m_row_count);
|
||||
auto table = m_ui_item.table().table();
|
||||
table.resize(column_count * count);
|
||||
m_ui_item.table().setTable(table);
|
||||
}
|
||||
m_column_labels.resize(m_column_count);
|
||||
|
||||
column_labels.resize(count);
|
||||
m_ui_item.table().setColumnLabels(column_labels);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
size_t UI_table::column_count() const
|
||||
qsizetype UI_table::column_count() const
|
||||
{
|
||||
return m_column_count;
|
||||
return m_ui_item.table().columnCount();
|
||||
}
|
||||
|
||||
size_t UI_table::capacity() const
|
||||
qsizetype UI_table::capacity() const
|
||||
{
|
||||
return m_row_count * m_column_count;
|
||||
return m_ui_item.table().rowCount() * m_ui_item.table().columnCount();
|
||||
}
|
||||
|
||||
void UI_table::set_row_label(size_t index, std::string label)
|
||||
void UI_table::set_row_label(qsizetype index, QString label)
|
||||
{
|
||||
if (m_row_count <= index)
|
||||
if (m_ui_item.table().rowCount() <= index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_row_labels[index] = std::move(label);
|
||||
auto labels = m_ui_item.table().rowLabels();
|
||||
labels.replace(index, label);
|
||||
m_ui_item.table().setRowLabels(labels);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_table::row_label(size_t index) const
|
||||
QString UI_table::row_label(qsizetype index) const
|
||||
{
|
||||
if (m_row_count <= index)
|
||||
if (m_ui_item.table().rowCount() <= index)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_row_labels[index];
|
||||
return m_ui_item.table().rowLabels().at(index);
|
||||
}
|
||||
|
||||
void UI_table::set_column_label(size_t index, std::string label)
|
||||
void UI_table::set_column_label(qsizetype index, QString label)
|
||||
{
|
||||
if (m_column_count <= index)
|
||||
if (m_ui_item.table().columnCount() <= index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_column_labels[index] = std::move(label);
|
||||
auto labels = m_ui_item.table().columnLabels();
|
||||
labels.replace(index, label);
|
||||
m_ui_item.table().setColumnLabels(labels);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_table::column_label(size_t index) const &
|
||||
QString UI_table::column_label(qsizetype index) const &
|
||||
{
|
||||
if (m_column_count <= index)
|
||||
if (m_ui_item.table().columnCount() <= index)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_column_labels[index];
|
||||
return m_ui_item.table().columnLabels().at(index);
|
||||
}
|
||||
|
||||
void UI_table::insert_item(size_t row, size_t column, std::string text)
|
||||
void UI_table::insert_item(qsizetype row, qsizetype column, QString text)
|
||||
{
|
||||
if (m_column_count <= column || m_row_count <= row)
|
||||
if (m_ui_item.table().columnCount() <= column || m_ui_item.table().rowCount() <= row)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (capacity() > m_table.size())
|
||||
if (capacity() > m_ui_item.table().table().size())
|
||||
{
|
||||
m_table.resize(capacity());
|
||||
auto table = m_ui_item.table().table();
|
||||
table.resize(capacity());
|
||||
m_ui_item.table().setTable(table);
|
||||
}
|
||||
|
||||
size_t index = row * m_column_count + column;
|
||||
qsizetype index = row * m_ui_item.table().columnCount() + column;
|
||||
|
||||
m_table.at(index) = std::move(text);
|
||||
auto table = m_ui_item.table().table();
|
||||
table.replace(index, text);
|
||||
m_ui_item.table().setTable(table);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_table::item(size_t row, size_t column) const &
|
||||
QString UI_table::item(qsizetype row, qsizetype column) const &
|
||||
{
|
||||
if (m_column_count <= column || m_row_count <= row)
|
||||
if (m_ui_item.table().columnCount() <= column || m_ui_item.table().rowCount() <= row)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
size_t index = row * m_column_count + column;
|
||||
qsizetype index = row * m_ui_item.table().columnCount() + column;
|
||||
|
||||
return m_table.at(index);
|
||||
return m_ui_item.table().table().at(index);
|
||||
}
|
||||
|
||||
void UI_table::empty_item(size_t row, size_t column)
|
||||
void UI_table::empty_item(qsizetype row, qsizetype column)
|
||||
{
|
||||
size_t index = row * m_column_count + column;
|
||||
if (m_ui_item.table().columnCount() <= column || m_ui_item.table().rowCount() <= row)
|
||||
{
|
||||
return;
|
||||
}
|
||||
qsizetype index = row * m_ui_item.table().columnCount() + column;
|
||||
|
||||
m_table[index] = "";
|
||||
auto table = m_ui_item.table().table();
|
||||
table.replace(index, "");
|
||||
m_ui_item.table().setTable(table);
|
||||
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_table::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_row_count = j.at("row_count");
|
||||
this->m_row_labels = j.at("row_labels");
|
||||
this->m_column_count = j.at("column_count");
|
||||
this->m_column_labels = j.at("column_labels");
|
||||
this->m_table = j.at("table");
|
||||
}
|
||||
|
||||
json UI_table::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["row_count"] = m_row_count;
|
||||
j["row_labels"] = m_row_labels;
|
||||
j["column_count"] = m_column_count;
|
||||
j["column_labels"] = m_column_labels;
|
||||
j["table"] = m_table;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
+17
-39
@@ -24,41 +24,41 @@ class UI_table : public UI_item
|
||||
* @param column_labels The labels for the columns
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
explicit UI_table(size_t row_count, size_t column_count, std::vector<std::string> row_labels,
|
||||
std::vector<std::string> column_labels, QObject *parent = nullptr);
|
||||
explicit UI_table(qsizetype row_count, qsizetype column_count, QList<QString> row_labels,
|
||||
QList<QString> column_labels, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Set the number of rows in the table
|
||||
*
|
||||
* @param count The number of rows
|
||||
*/
|
||||
void set_row_count(size_t count);
|
||||
void set_row_count(qsizetype count);
|
||||
/**
|
||||
* @brief Get the number of rows in the table
|
||||
*
|
||||
* @return size_t The number of rows
|
||||
*/
|
||||
size_t row_count() const;
|
||||
qsizetype row_count() const;
|
||||
|
||||
/**
|
||||
* @brief Set the number of columns in the table
|
||||
*
|
||||
* @param count The number of columns
|
||||
*/
|
||||
void set_column_count(size_t count);
|
||||
void set_column_count(qsizetype count);
|
||||
/**
|
||||
* @brief Get the number of columns in the table
|
||||
*
|
||||
* @return size_t The number of columns
|
||||
*/
|
||||
size_t column_count() const;
|
||||
qsizetype column_count() const;
|
||||
|
||||
/**
|
||||
* @brief Get the capacity of the table (rows * columns)
|
||||
*
|
||||
* @return size_t The capacity of the table
|
||||
*/
|
||||
size_t capacity() const;
|
||||
qsizetype capacity() const;
|
||||
|
||||
/**
|
||||
* @brief Set the label for a specific row
|
||||
@@ -66,14 +66,14 @@ class UI_table : public UI_item
|
||||
* @param index The index of the row
|
||||
* @param label The label to set
|
||||
*/
|
||||
void set_row_label(size_t index, std::string label);
|
||||
void set_row_label(qsizetype index, QString label);
|
||||
/**
|
||||
* @brief Get the label of a specific row
|
||||
*
|
||||
* @param index The index of the row
|
||||
* @return std::string The label of the row
|
||||
* @return QString The label of the row
|
||||
*/
|
||||
std::string row_label(size_t index) const;
|
||||
QString row_label(qsizetype index) const;
|
||||
|
||||
/**
|
||||
* @brief Set the label for a specific column
|
||||
@@ -81,14 +81,14 @@ class UI_table : public UI_item
|
||||
* @param index The index of the column
|
||||
* @param label The label to set
|
||||
*/
|
||||
void set_column_label(size_t index, std::string label);
|
||||
void set_column_label(qsizetype index, QString label);
|
||||
/**
|
||||
* @brief Get the label of a specific column
|
||||
*
|
||||
* @param index The index of the column
|
||||
* @return std::string The label of the column
|
||||
* @return QString The label of the column
|
||||
*/
|
||||
std::string column_label(size_t index) const &;
|
||||
QString column_label(qsizetype index) const &;
|
||||
|
||||
/**
|
||||
* @brief Insert an item into the table at the specified row and column
|
||||
@@ -97,42 +97,20 @@ class UI_table : public UI_item
|
||||
* @param column The column of the item
|
||||
* @param text The text of the item
|
||||
*/
|
||||
void insert_item(size_t row, size_t column, std::string text);
|
||||
void insert_item(qsizetype row, qsizetype column, QString text);
|
||||
/**
|
||||
* @brief Get the item at the specified row and column
|
||||
*
|
||||
* @param row The row of the item
|
||||
* @param column The column of the item
|
||||
* @return std::string The text of the item
|
||||
* @return QString The text of the item
|
||||
*/
|
||||
std::string item(size_t row, size_t column) const &;
|
||||
QString item(qsizetype row, qsizetype column) const &;
|
||||
|
||||
/**
|
||||
* @brief empty_item This function clears the item
|
||||
* @param row The row of the item
|
||||
* @param column The column of the item
|
||||
*/
|
||||
void empty_item(size_t row, size_t column);
|
||||
|
||||
/**
|
||||
* @brief Deserialize the table from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the table to JSON
|
||||
*
|
||||
* @param id The id of the table
|
||||
* @return json The JSON representation of the table
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
size_t m_row_count;
|
||||
size_t m_column_count;
|
||||
std::vector<std::string> m_row_labels;
|
||||
std::vector<std::string> m_column_labels;
|
||||
|
||||
std::vector<std::string> m_table;
|
||||
void empty_item(qsizetype row, qsizetype column);
|
||||
};
|
||||
|
||||
+41
-23
@@ -1,43 +1,61 @@
|
||||
#include "ui_textbox.hpp"
|
||||
|
||||
UI_textbox::UI_textbox(std::string hint, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_enum::ui_textbox, "", fg_color, bg_color, parent), m_hint(hint)
|
||||
UI_textbox::UI_textbox(QString hint, Color fg_color, Color bg_color, QObject *parent)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_textbox, parent)
|
||||
{
|
||||
m_ui_item.setTextbox(UI_textbox_m());
|
||||
m_ui_item.textbox().setHint(hint);
|
||||
m_ui_item.textbox().mutColor().setFgColor(fg_color.color());
|
||||
m_ui_item.textbox().mutColor().setBgColor(bg_color.color());
|
||||
}
|
||||
|
||||
UI_textbox::UI_textbox(QObject *parent) : UI_item(UI_enum::ui_textbox, parent)
|
||||
UI_textbox::UI_textbox(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_textbox, parent)
|
||||
{
|
||||
m_ui_item.setTextbox(UI_textbox_m());
|
||||
}
|
||||
|
||||
void UI_textbox::set_text(std::string text)
|
||||
void UI_textbox::set_text(QString text)
|
||||
{
|
||||
if (text == m_text)
|
||||
if (text == m_ui_item.textbox().text())
|
||||
return;
|
||||
m_text = std::move(text);
|
||||
m_ui_item.textbox().setText(text);
|
||||
emit ui_changed();
|
||||
emit changed(m_text);
|
||||
emit changed(m_ui_item.textbox().text());
|
||||
}
|
||||
|
||||
void UI_textbox::set_hint(std::string hint)
|
||||
QString UI_textbox::text() const
|
||||
{
|
||||
m_hint = std::move(hint);
|
||||
return m_ui_item.label().text();
|
||||
}
|
||||
|
||||
void UI_textbox::set_fg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setFgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_textbox::fg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().fgColor());
|
||||
}
|
||||
|
||||
void UI_textbox::set_bg_color(Color color)
|
||||
{
|
||||
m_ui_item.label().mutColor().setBgColor(color.color());
|
||||
}
|
||||
|
||||
Color UI_textbox::bg_color() const
|
||||
{
|
||||
return Color(m_ui_item.label().color().bgColor());
|
||||
}
|
||||
|
||||
void UI_textbox::set_hint(QString hint)
|
||||
{
|
||||
m_ui_item.textbox().setHint(hint);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
std::string UI_textbox::hint() const &
|
||||
QString UI_textbox::hint() const &
|
||||
{
|
||||
return m_hint;
|
||||
return m_ui_item.textbox().hint();
|
||||
}
|
||||
|
||||
void UI_textbox::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
m_hint = j.at("hint");
|
||||
}
|
||||
|
||||
json UI_textbox::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["hint"] = m_hint;
|
||||
return j;
|
||||
}
|
||||
|
||||
+13
-23
@@ -18,7 +18,7 @@ class UI_textbox : public UI_item
|
||||
* @param bg_color The background color
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_textbox(std::string hint, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
UI_textbox(QString hint, Color fg_color, Color bg_color, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI textbox object
|
||||
*
|
||||
@@ -31,42 +31,32 @@ class UI_textbox : public UI_item
|
||||
*
|
||||
* @param text The text to set
|
||||
*/
|
||||
void set_text(std::string text) override;
|
||||
void set_text(QString text) override;
|
||||
|
||||
QString text() const;
|
||||
|
||||
void set_fg_color(Color fg_color);
|
||||
Color fg_color() const;
|
||||
void set_bg_color(Color bg_color);
|
||||
Color bg_color() const;
|
||||
|
||||
/**
|
||||
* @brief Get the hint text of the textbox
|
||||
*
|
||||
* @param hint The hint text to set
|
||||
*/
|
||||
void set_hint(std::string hint);
|
||||
void set_hint(QString hint);
|
||||
/**
|
||||
* @brief Get the hint text of the textbox
|
||||
*
|
||||
* @return std::string The hint text
|
||||
* @return QString The hint text
|
||||
*/
|
||||
std::string hint() const &;
|
||||
|
||||
/**
|
||||
* @brief Deserialize the textbox from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the textbox to JSON
|
||||
*
|
||||
* @param id The id of the textbox
|
||||
* @return json The JSON representation of the textbox
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
QString hint() const &;
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the text changes
|
||||
*
|
||||
* @param text The new text
|
||||
*/
|
||||
void changed(std::string text);
|
||||
|
||||
private:
|
||||
std::string m_hint;
|
||||
void changed(QString text);
|
||||
};
|
||||
|
||||
+47
-83
@@ -1,143 +1,107 @@
|
||||
#include "ui_thermo.hpp"
|
||||
|
||||
UI_thermo::UI_thermo(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max,
|
||||
UI_thermo::UI_thermo(QString text, QString unit, double min, double max,
|
||||
double value, QObject *parent)
|
||||
: UI_item(UI_enum::ui_thermo, text, fg_color, bg_color, parent), m_min(min), m_max(max), m_value(value),
|
||||
m_unit(unit)
|
||||
: UI_item(UI_typeGadget::UI_type::ui_thermo, parent)
|
||||
{
|
||||
m_ui_item.setRange(UI_range_m());
|
||||
m_ui_item.range().setText(text);
|
||||
m_ui_item.range().setUnit(unit);
|
||||
m_ui_item.range().setMin(min);
|
||||
m_ui_item.range().setMax(max);
|
||||
m_ui_item.range().setValue(value);
|
||||
}
|
||||
|
||||
UI_thermo::UI_thermo(std::string text, std::string unit, double min, double max, double value, QObject *parent)
|
||||
: UI_thermo(text, unit, Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_thermo::UI_thermo(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_thermo::UI_thermo(QString text, double min, double max, double value,
|
||||
QObject *parent)
|
||||
: UI_thermo(text, "", fg_color, bg_color, min, max, value, parent)
|
||||
: UI_thermo(text, "", min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_thermo::UI_thermo(std::string text, double min, double max, double value, QObject *parent)
|
||||
: UI_thermo(text, "", Color::Default, Color::Default, min, max, value, parent)
|
||||
{
|
||||
}
|
||||
|
||||
UI_thermo::UI_thermo(QObject *parent) : UI_item(UI_enum::ui_thermo, parent)
|
||||
UI_thermo::UI_thermo(QObject *parent) : UI_item(UI_typeGadget::UI_type::ui_thermo, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void UI_thermo::set_value(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
if (value < m_ui_item.range().min() || value > m_ui_item.range().max())
|
||||
return;
|
||||
if (value == m_value)
|
||||
if (value == m_ui_item.range().value())
|
||||
return;
|
||||
|
||||
this->m_value = value;
|
||||
m_ui_item.range().setValue(value);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
double UI_thermo::value() const
|
||||
{
|
||||
return m_value;
|
||||
return m_ui_item.range().value();
|
||||
}
|
||||
|
||||
double UI_thermo::min() const
|
||||
{
|
||||
return m_min;
|
||||
return m_ui_item.range().min();
|
||||
}
|
||||
|
||||
double UI_thermo::max() const
|
||||
{
|
||||
return m_max;
|
||||
return m_ui_item.range().max();
|
||||
}
|
||||
|
||||
void UI_thermo::set_start_color(Color color)
|
||||
{
|
||||
this->m_color_map[0] = color;
|
||||
emit ui_changed();
|
||||
Q_UNUSED(color);
|
||||
// this->m_color_map[0] = color;
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::set_end_color(Color color)
|
||||
{
|
||||
this->m_color_map[1] = color;
|
||||
emit ui_changed();
|
||||
Q_UNUSED(color);
|
||||
// this->m_color_map[1] = color;
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::add_color_stop(double value, Color color)
|
||||
{
|
||||
if (value <= 0 || value >= 1)
|
||||
return;
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(color);
|
||||
// if (value <= 0 || value >= 1)
|
||||
// return;
|
||||
|
||||
this->m_color_map[value] = color;
|
||||
emit ui_changed();
|
||||
// this->m_color_map[value] = color;
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::add_color_stop_normalized(double value, Color color)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
return;
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(color);
|
||||
// if (value < m_min || value > m_max)
|
||||
// return;
|
||||
|
||||
double normalized = (value - m_min) / (m_max - m_min);
|
||||
this->m_color_map[normalized] = color;
|
||||
emit ui_changed();
|
||||
// double normalized = (value - m_min) / (m_max - m_min);
|
||||
// this->m_color_map[normalized] = color;
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::remove_color_stop(double value)
|
||||
{
|
||||
if (value <= 0 || value >= 1)
|
||||
return;
|
||||
Q_UNUSED(value);
|
||||
// if (value <= 0 || value >= 1)
|
||||
// return;
|
||||
|
||||
this->m_color_map.erase(value);
|
||||
emit ui_changed();
|
||||
// this->m_color_map.erase(value);
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::remove_color_stop_normalized(double value)
|
||||
{
|
||||
if (value < m_min || value > m_max)
|
||||
return;
|
||||
Q_UNUSED(value);
|
||||
// if (value < m_min || value > m_max)
|
||||
// return;
|
||||
|
||||
double normalized = (value - m_min) / (m_max - m_min);
|
||||
this->m_color_map.erase(normalized);
|
||||
emit ui_changed();
|
||||
}
|
||||
|
||||
void UI_thermo::from_json(const json &j)
|
||||
{
|
||||
UI_item::from_json(j);
|
||||
|
||||
this->m_min = j.at("min");
|
||||
this->m_max = j.at("max");
|
||||
this->m_value = j.at("value");
|
||||
this->m_unit = j.at("unit");
|
||||
this->m_color_map.clear();
|
||||
if (!j.contains("color_map"))
|
||||
return;
|
||||
for (auto &i : j["color_map"])
|
||||
{
|
||||
double k = i.at("key");
|
||||
std::string c = i.at("value");
|
||||
this->m_color_map[k] = Color(c);
|
||||
}
|
||||
}
|
||||
|
||||
json UI_thermo::to_json(size_t id) const
|
||||
{
|
||||
json j = UI_item::to_json(id);
|
||||
j["min"] = this->m_min;
|
||||
j["max"] = this->m_max;
|
||||
j["value"] = this->m_value;
|
||||
j["unit"] = this->m_unit;
|
||||
if (this->m_color_map.empty())
|
||||
return j;
|
||||
j["color_map"] = json::array();
|
||||
for (auto &[key, value] : this->m_color_map)
|
||||
{
|
||||
json item = json::object();
|
||||
item["key"] = key;
|
||||
item["value"] = value.to_hex();
|
||||
j["color_map"].push_back(item);
|
||||
}
|
||||
return j;
|
||||
// double normalized = (value - m_min) / (m_max - m_min);
|
||||
// this->m_color_map.erase(normalized);
|
||||
// emit ui_changed();
|
||||
}
|
||||
|
||||
+2
-46
@@ -15,26 +15,13 @@ class UI_thermo : public UI_item
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the thermometer
|
||||
* @param fg_color The foreground color
|
||||
* @param bg_color The background color
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_thermo(std::string text, std::string unit, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_thermo(QString text, QString unit, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI thermometer object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param unit The unit of the thermometer
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_thermo(std::string text, std::string unit, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI thermometer object
|
||||
*
|
||||
@@ -46,18 +33,8 @@ class UI_thermo : public UI_item
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_thermo(std::string text, Color fg_color, Color bg_color, double min, double max, double value,
|
||||
UI_thermo(QString text, double min, double max, double value,
|
||||
QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI thermometer object
|
||||
*
|
||||
* @param text The text to display
|
||||
* @param min The minimum value
|
||||
* @param max The maximum value
|
||||
* @param value The initial value
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
UI_thermo(std::string text, double min, double max, double value, QObject *parent = nullptr);
|
||||
/**
|
||||
* @brief Construct a UI thermometer object
|
||||
*
|
||||
@@ -129,25 +106,4 @@ class UI_thermo : public UI_item
|
||||
* @param value The normalized value (0.0 to 1.0) of the color stop to remove
|
||||
*/
|
||||
void remove_color_stop_normalized(double value);
|
||||
|
||||
/**
|
||||
* @brief Deserialize the thermometer from JSON
|
||||
*
|
||||
* @param j The JSON object
|
||||
*/
|
||||
void from_json(const json &j) override;
|
||||
/**
|
||||
* @brief Serialize the thermometer to JSON
|
||||
*
|
||||
* @param id The id of the thermometer
|
||||
* @return json The JSON representation of the thermometer
|
||||
*/
|
||||
json to_json(size_t id) const override;
|
||||
|
||||
private:
|
||||
double m_min;
|
||||
double m_max;
|
||||
double m_value;
|
||||
std::string m_unit;
|
||||
std::unordered_map<double, Color> m_color_map;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets Svg WebSockets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 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 Protobuf Grpc)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -19,19 +19,16 @@ set(PROJECT_SOURCES
|
||||
helpers.hpp
|
||||
ui_base.cpp
|
||||
ui_base.hpp
|
||||
web_socket_wrapper.cpp
|
||||
web_socket_wrapper.hpp
|
||||
)
|
||||
|
||||
qt_add_executable(unisim_client
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
unisim_client
|
||||
PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
AUTOUIC ON
|
||||
)
|
||||
|
||||
@@ -43,11 +40,11 @@ target_include_directories(unisim_client
|
||||
${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)
|
||||
install(TARGETS unisim_client
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
)
|
||||
+4
-4
@@ -9,7 +9,7 @@
|
||||
class UIFactory
|
||||
{
|
||||
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()
|
||||
{
|
||||
@@ -25,12 +25,12 @@ class UIFactory
|
||||
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);
|
||||
if (it == m_creators.cend())
|
||||
return nullptr;
|
||||
return it.value()(w, parent);
|
||||
return it.value()(s, parent);
|
||||
}
|
||||
|
||||
QStringList keys() const
|
||||
@@ -50,7 +50,7 @@ class UIFactory
|
||||
Register##TYPE() \
|
||||
{ \
|
||||
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; \
|
||||
|
||||
+73
-58
@@ -3,33 +3,35 @@
|
||||
#include "git_version.h"
|
||||
#include "ui_base.hpp"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "web_socket_wrapper.hpp"
|
||||
#include "messages_client.grpc.qpb.h"
|
||||
#include <QDirIterator>
|
||||
#include <QLibrary>
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#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()),
|
||||
m_web_socket(new Web_socket_wrapper(ws_url))
|
||||
m_remote_ui_client(new RemoteUiService::Client()), m_ping(new QTimer())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->statusbar->showMessage(QString("Version: %1-%2%3")
|
||||
.arg(Git_version::branch)
|
||||
.arg(Git_version::shortSha1)
|
||||
.arg(Git_version::dirty ? "-dirty" : ""));
|
||||
connect(m_web_socket.get(), &Web_socket_wrapper::log_signal, this,
|
||||
[](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());
|
||||
});
|
||||
m_ping->setInterval(std::chrono::milliseconds(1000));
|
||||
|
||||
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);
|
||||
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");
|
||||
m_error->setIcon(QMessageBox::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);
|
||||
m_error->addButton("Close", QMessageBox::RejectRole);
|
||||
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
|
||||
if (!sim.isEmpty())
|
||||
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(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()
|
||||
@@ -68,19 +97,14 @@ MainWindow::~MainWindow()
|
||||
void MainWindow::showEvent(QShowEvent *event)
|
||||
{
|
||||
QWidget::showEvent(event);
|
||||
connect(m_web_socket.get(), &Web_socket_wrapper::on_command_cb, this, [=, this](json &j) { on_cmd_cb(j); });
|
||||
connect(m_web_socket.get(), &Web_socket_wrapper::on_connected, this,
|
||||
[=, 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");
|
||||
});
|
||||
emit on_show_event();
|
||||
m_ping->start();
|
||||
}
|
||||
|
||||
void MainWindow::hideEvent(QHideEvent *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)
|
||||
@@ -89,12 +113,11 @@ void MainWindow::default_sim(QString name)
|
||||
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(QString::fromStdString(item));
|
||||
ui->comboBox->addItem(item);
|
||||
}
|
||||
|
||||
QThread::msleep(30);
|
||||
@@ -119,7 +142,18 @@ void MainWindow::open_sim(QString sim_name)
|
||||
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)
|
||||
@@ -130,42 +164,23 @@ void MainWindow::open_sim_window(void)
|
||||
|
||||
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)
|
||||
{
|
||||
SPDLOG_DEBUG("Name set and the same");
|
||||
open_sim_window();
|
||||
return;
|
||||
}
|
||||
|
||||
SPDLOG_DEBUG("Name set and wrong");
|
||||
m_web_socket->send_command(Web_socket_wrapper::Command::switch_simulator, m_selected_sim_name);
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
auto cmd = Simulator_m();
|
||||
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;
|
||||
}
|
||||
open_sim_window();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}, Qt::SingleShotConnection);
|
||||
}
|
||||
|
||||
+16
-13
@@ -1,16 +1,23 @@
|
||||
#pragma once
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <QMainWindow>
|
||||
#include <map>
|
||||
|
||||
using json = nlohmann::json;
|
||||
#include "messages.qpb.h"
|
||||
|
||||
#define INSERT_SIMULATOR(type) \
|
||||
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(Web_socket_wrapper);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(UI_base);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QTimer);
|
||||
namespace RemoteUiService
|
||||
{
|
||||
class Client;
|
||||
}
|
||||
|
||||
namespace Health
|
||||
{
|
||||
class Client;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@@ -32,6 +39,8 @@ class MainWindow : public QMainWindow
|
||||
explicit MainWindow(QUrl ws_url, QString sim, QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
signals:
|
||||
void on_show_event();
|
||||
private:
|
||||
/**
|
||||
* @brief Handle the show event
|
||||
@@ -59,7 +68,7 @@ class MainWindow : public QMainWindow
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@@ -78,18 +87,12 @@ class MainWindow : public QMainWindow
|
||||
*/
|
||||
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;
|
||||
QString m_selected_sim_name;
|
||||
QMainWindow *m_selected_sim;
|
||||
QMessageBox *m_error;
|
||||
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;
|
||||
QTimer *m_ping;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
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->setupUi(this);
|
||||
|
||||
@@ -11,7 +11,7 @@ class Can_Debugger : public UI_base
|
||||
Q_OBJECT
|
||||
|
||||
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();
|
||||
static QString name()
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Test_Sim : public UI_base
|
||||
Q_OBJECT
|
||||
|
||||
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();
|
||||
|
||||
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] {
|
||||
emit send_can_message(
|
||||
ui->s_can_send_sid->value(), ui->c_can_send_dlc->currentIndex(),
|
||||
std::array<uint8_t, 8>(
|
||||
{(uint8_t)(can_send_hexspinboxes[0]->value()), (uint8_t)(can_send_hexspinboxes[1]->value()),
|
||||
(uint8_t)(can_send_hexspinboxes[2]->value()), (uint8_t)(can_send_hexspinboxes[3]->value()),
|
||||
(uint8_t)(can_send_hexspinboxes[4]->value()), (uint8_t)(can_send_hexspinboxes[5]->value()),
|
||||
(uint8_t)(can_send_hexspinboxes[6]->value()), (uint8_t)(can_send_hexspinboxes[7]->value())}));
|
||||
QByteArray().append((uint8_t)(can_send_hexspinboxes[0]->value())).append((uint8_t)(can_send_hexspinboxes[0]->value()))
|
||||
.append((uint8_t)(can_send_hexspinboxes[1]->value())).append((uint8_t)(can_send_hexspinboxes[2]->value()))
|
||||
.append((uint8_t)(can_send_hexspinboxes[3]->value())).append((uint8_t)(can_send_hexspinboxes[4]->value()))
|
||||
.append((uint8_t)(can_send_hexspinboxes[5]->value())).append((uint8_t)(can_send_hexspinboxes[6]->value()))
|
||||
.append((uint8_t)(can_send_hexspinboxes[7]->value())));
|
||||
});
|
||||
connect(ui->b_clear, &QPushButton::clicked, this, [=, this] { emit can_clear(); });
|
||||
}
|
||||
@@ -48,7 +48,7 @@ void Can_Transceive::clear()
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
ui->recvd_list->setRowCount(rc + 1);
|
||||
|
||||
@@ -47,7 +47,7 @@ class Can_Transceive : public QWidget
|
||||
* @param dlc The Data Length Code
|
||||
* @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
|
||||
@@ -56,7 +56,7 @@ class Can_Transceive : public QWidget
|
||||
* @param dlc The Data Length Code
|
||||
* @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:
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class Can_Transceive : public QWidget
|
||||
* @param dlc The Data Length Code
|
||||
* @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
|
||||
|
||||
+227
-181
@@ -3,12 +3,12 @@
|
||||
#include "helpers.hpp"
|
||||
#include "led.hpp"
|
||||
#include "plot_wrapper.hpp"
|
||||
#include "web_socket_wrapper.hpp"
|
||||
#include <QMessageBox>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#include "messages_client.grpc.qpb.h"
|
||||
|
||||
UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
: QMainWindow{parent}, m_timer_update(new QTimer()), m_error(new QMessageBox(this)), m_web_socket(web_socket)
|
||||
UI_base::UI_base(RemoteUiService::Client *remote_ui_client, QWidget *parent)
|
||||
: QMainWindow{parent}, m_timer_update(new QTimer()), m_error(new QMessageBox(this)), m_remote_ui_client(remote_ui_client)
|
||||
{
|
||||
this->setWindowState(Qt::WindowMaximized);
|
||||
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);
|
||||
m_error->addButton("Close", QMessageBox::RejectRole);
|
||||
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);
|
||||
if (label == nullptr)
|
||||
{
|
||||
@@ -27,9 +28,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
QString value = QString::fromStdString(ui_item.at("text"));
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
QString value = ui_item.label().text();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
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) {
|
||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
||||
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.id_proto()));
|
||||
auto slider = qobject_cast<QwtSlider *>(widget);
|
||||
if (slider == nullptr)
|
||||
{
|
||||
@@ -56,10 +57,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
double value = ui_item.at("value");
|
||||
bool enable = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
||||
double value = ui_item.range().value();
|
||||
bool enable = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
QString unit = ui_item.range().unit();
|
||||
|
||||
if (label != nullptr)
|
||||
{
|
||||
@@ -82,8 +83,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
}
|
||||
// TODO: Add color for scale
|
||||
});
|
||||
m_process_lookup.insert(UI_enum::ui_dial, [=, this](json &ui_item, QWidget *widget) {
|
||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
||||
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.id_proto()));
|
||||
auto dial = qobject_cast<QwtDial *>(widget);
|
||||
if (dial == nullptr)
|
||||
{
|
||||
@@ -91,9 +92,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
double value = ui_item.at("value");
|
||||
bool visible = ui_item.at("visible");
|
||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
||||
double value = ui_item.range().value();
|
||||
bool visible = ui_item.visible();
|
||||
QString unit = ui_item.range().unit();
|
||||
|
||||
if (label != nullptr)
|
||||
{
|
||||
@@ -110,8 +111,8 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
dial->setVisible(visible);
|
||||
}
|
||||
});
|
||||
m_process_lookup.insert(UI_enum::ui_thermo, [=, this](json &ui_item, QWidget *widget) {
|
||||
QLabel *label = id_to_label(id_to_ui(ui_item.at("id")));
|
||||
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.id_proto()));
|
||||
auto thermo = qobject_cast<QwtThermo *>(widget);
|
||||
if (thermo == nullptr)
|
||||
{
|
||||
@@ -119,9 +120,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
double value = ui_item.at("value");
|
||||
bool visible = ui_item.at("visible");
|
||||
QString unit = QString::fromStdString(ui_item.at("unit"));
|
||||
double value = ui_item.range().value();
|
||||
bool visible = ui_item.visible();
|
||||
QString unit = ui_item.range().unit();
|
||||
|
||||
if (label != nullptr)
|
||||
{
|
||||
@@ -138,7 +139,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (line_edit == nullptr)
|
||||
{
|
||||
@@ -146,10 +147,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
bool visible = ui_item.at("visible");
|
||||
bool enabled = ui_item.at("enabled");
|
||||
QString hint = QString::fromStdString(ui_item.at("hint"));
|
||||
QString text = QString::fromStdString(ui_item.at("text"));
|
||||
bool visible = ui_item.visible();
|
||||
bool enabled = ui_item.enabled();
|
||||
QString hint = ui_item.textbox().hint();
|
||||
QString text = ui_item.textbox().text();
|
||||
|
||||
if (line_edit->isVisible() != visible)
|
||||
{
|
||||
@@ -169,7 +170,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (combobox == nullptr)
|
||||
{
|
||||
@@ -177,9 +178,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
size_t selected = ui_item.at("selected");
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
size_t selected = ui_item.combobox().selected();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
if (combobox->isEnabled() != enabled)
|
||||
{
|
||||
@@ -191,10 +192,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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)
|
||||
combobox->addItem(QString::fromStdString(item));
|
||||
if (combobox->findText(item) == -1)
|
||||
combobox->addItem(item);
|
||||
}
|
||||
|
||||
if (combobox->currentIndex() != selected)
|
||||
@@ -202,9 +203,9 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
combobox->setCurrentIndex(selected);
|
||||
}
|
||||
});
|
||||
// m_process_lookup.insert(UI_enum::ui_radiobutton,
|
||||
// [=, this](json &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_radiobutton,
|
||||
// [=, this](const UI_item_m &ui_item, QWidget *widget) { LOG_CRITICAL("Not implemented"); });
|
||||
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);
|
||||
if (checkbox == nullptr)
|
||||
{
|
||||
@@ -212,12 +213,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
||||
QColor fg_color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
||||
QString text = QString::fromStdString(ui_item.at("text"));
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
bool checked = ui_item.at("checked");
|
||||
QColor bg_color = QColor(ui_item.checkbox().color().bgColor());
|
||||
QColor fg_color = QColor(ui_item.checkbox().color().fgColor());
|
||||
QString text = ui_item.checkbox().text();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
bool checked = ui_item.checkbox().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);
|
||||
}
|
||||
});
|
||||
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);
|
||||
if (button == nullptr)
|
||||
{
|
||||
@@ -276,11 +277,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
||||
QColor fg_color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
||||
QString text = QString::fromStdString(ui_item.at("text"));
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
QColor bg_color = QColor(ui_item.label().color().bgColor());
|
||||
QColor fg_color = QColor(ui_item.label().color().fgColor());
|
||||
QString text = ui_item.label().text();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
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);
|
||||
if (led == nullptr)
|
||||
{
|
||||
@@ -334,10 +335,10 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
||||
QColor color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
||||
QString text = QString::fromStdString(ui_item.at("text"));
|
||||
bool visible = ui_item.at("visible");
|
||||
QColor bg_color = QColor(ui_item.label().color().bgColor());
|
||||
QColor color = QColor(ui_item.label().color().fgColor());
|
||||
QString text = ui_item.label().text();
|
||||
bool visible = ui_item.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);
|
||||
}
|
||||
});
|
||||
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);
|
||||
if (spinbox == nullptr)
|
||||
{
|
||||
@@ -386,11 +387,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
double min = ui_item.at("min");
|
||||
double max = ui_item.at("max");
|
||||
double value = ui_item.at("value");
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
double min = ui_item.range().min();
|
||||
double max = ui_item.range().max();
|
||||
double value = ui_item.range().value();
|
||||
|
||||
if (enabled != spinbox->isEnabled())
|
||||
{
|
||||
@@ -415,7 +416,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (spinbox == nullptr)
|
||||
{
|
||||
@@ -423,11 +424,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
double min = ui_item.at("min");
|
||||
double max = ui_item.at("max");
|
||||
double value = ui_item.at("value");
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
double min = ui_item.range().min();
|
||||
double max = ui_item.range().max();
|
||||
double value = ui_item.range().value();
|
||||
|
||||
if (enabled != spinbox->isEnabled())
|
||||
{
|
||||
@@ -452,7 +453,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (spinbox == nullptr)
|
||||
{
|
||||
@@ -460,11 +461,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
double min = ui_item.at("min");
|
||||
double max = ui_item.at("max");
|
||||
double value = ui_item.at("value");
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
double min = ui_item.range().min();
|
||||
double max = ui_item.range().max();
|
||||
double value = ui_item.range().value();
|
||||
|
||||
if (enabled != spinbox->isEnabled())
|
||||
{
|
||||
@@ -489,7 +490,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (tab_widget == nullptr)
|
||||
{
|
||||
@@ -497,15 +498,15 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
auto tab_names = ui_item.at("tab_names");
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
auto tab_names = ui_item.tabWidget().tabNames();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
if (stacked_widget == nullptr)
|
||||
{
|
||||
@@ -542,14 +543,14 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
if (stacked_widget->isEnabled() != enabled)
|
||||
{
|
||||
@@ -561,12 +562,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (status_bar == nullptr)
|
||||
{
|
||||
@@ -574,12 +575,12 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
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);
|
||||
if (plot == nullptr)
|
||||
{
|
||||
@@ -587,17 +588,17 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = QString::fromStdString(ui_item.at("text"));
|
||||
QColor bg_color = QColor(QString::fromStdString(ui_item.at("bg_color")));
|
||||
QColor color = QColor(QString::fromStdString(ui_item.at("fg_color")));
|
||||
QString x_label = QString::fromStdString(ui_item.at("x_label"));
|
||||
QString y_label = QString::fromStdString(ui_item.at("y_label"));
|
||||
QString text = ui_item.plot().text();
|
||||
QColor bg_color = QColor(ui_item.plot().color().bgColor());
|
||||
QColor color = QColor(ui_item.plot().color().fgColor());
|
||||
QString x_label = ui_item.plot().xLabel();
|
||||
QString y_label = ui_item.plot().yLabel();
|
||||
|
||||
std::vector<double> x_vals = (std::vector<double>)ui_item.at("x_vals");
|
||||
std::vector<double> y_vals = (std::vector<double>)ui_item.at("y_vals");
|
||||
QList<double> x_vals = ui_item.plot().xVals();
|
||||
QList<double> y_vals = ui_item.plot().yVals();
|
||||
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
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->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);
|
||||
if (table == nullptr)
|
||||
{
|
||||
@@ -647,13 +648,13 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
return;
|
||||
}
|
||||
|
||||
size_t row_count = ui_item.at("row_count");
|
||||
std::vector<std::string> row_labels = (std::vector<std::string>)ui_item.at("row_labels");
|
||||
size_t column_count = ui_item.at("column_count");
|
||||
std::vector<std::string> column_labels = (std::vector<std::string>)ui_item.at("column_labels");
|
||||
std::vector<std::string> table_data = (std::vector<std::string>)ui_item.at("table");
|
||||
bool enabled = ui_item.at("enabled");
|
||||
bool visible = ui_item.at("visible");
|
||||
size_t row_count = ui_item.table().rowCount();
|
||||
QList<QString> row_labels = ui_item.table().rowLabels();
|
||||
size_t column_count = ui_item.table().columnCount();
|
||||
QList<QString> column_labels = ui_item.table().columnLabels();
|
||||
QList<QString> table_data = ui_item.table().table();
|
||||
bool enabled = ui_item.enabled();
|
||||
bool visible = ui_item.visible();
|
||||
|
||||
if (table->isEnabled() != enabled)
|
||||
{
|
||||
@@ -683,7 +684,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
if (table->verticalHeaderItem(i) == nullptr)
|
||||
table->setVerticalHeaderItem(i, new QTableWidgetItem());
|
||||
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)
|
||||
@@ -693,7 +694,7 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
if (table->horizontalHeaderItem(i) == nullptr)
|
||||
table->setHorizontalHeaderItem(i, new QTableWidgetItem());
|
||||
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++)
|
||||
@@ -704,11 +705,11 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
{
|
||||
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();
|
||||
});
|
||||
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);
|
||||
if (can_ui == nullptr)
|
||||
{
|
||||
@@ -717,14 +718,14 @@ UI_base::UI_base(Web_socket_wrapper *web_socket, QWidget *parent)
|
||||
}
|
||||
|
||||
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");
|
||||
m_first_load = true;
|
||||
|
||||
connect(m_web_socket, &Web_socket_wrapper::on_command_cb, this, [=, this](json &j) { on_cmd_cb(j); });
|
||||
connect(m_web_socket, &Web_socket_wrapper::on_event_cb, this, [=, this](json &j) { on_event_cb(j); });
|
||||
connect(m_web_socket, &Web_socket_wrapper::on_closed, this, [=, this] { m_error->open(); });
|
||||
auto reply = m_remote_ui_client->Command_get_ui_elements(Empty());
|
||||
connect(reply.get(), &QGrpcCallReply::finished, reply.get(), [this, reply = std::move(reply)](const QGrpcStatus &status) {
|
||||
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_web_socket->send_command(Web_socket_wrapper::Command::get_UI_elements);
|
||||
m_stream = m_remote_ui_client->SubscribeUIChanges(Empty());
|
||||
|
||||
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);
|
||||
m_open = true;
|
||||
}
|
||||
@@ -763,64 +794,30 @@ void UI_base::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
LOG_DEBUG("Disconnecting callbacks");
|
||||
m_timer_update->stop();
|
||||
disconnect(m_web_socket, nullptr, nullptr, nullptr);
|
||||
disconnect(m_stream.get(), nullptr, nullptr, nullptr);
|
||||
m_open = false;
|
||||
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)
|
||||
{
|
||||
m_ui_lookup.emplace_back(item);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -845,8 +842,12 @@ void UI_base::setup_button(QWidget *item, size_t index)
|
||||
QPushButton *button = qobject_cast<QPushButton *>(item);
|
||||
if (button == nullptr)
|
||||
return;
|
||||
connect(button, &QPushButton::clicked, this,
|
||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::clicked, index); });
|
||||
connect(button, &QPushButton::clicked, this, [=, this] {
|
||||
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)
|
||||
@@ -855,8 +856,12 @@ void UI_base::setup_combobox(QWidget *item, size_t index)
|
||||
if (combobox == nullptr)
|
||||
return;
|
||||
|
||||
connect(combobox, &QComboBox::activated, this, [=, this] {
|
||||
m_web_socket->send_event(Web_socket_wrapper::Event::selected, index, (size_t)combobox->currentIndex());
|
||||
connect(combobox, &QComboBox::activated, this, [=, this](int combo_index) {
|
||||
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)
|
||||
return;
|
||||
|
||||
connect(checkbox, &QCheckBox::clicked, this,
|
||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::clicked, index); });
|
||||
connect(checkbox, &QCheckBox::clicked, this, [=, this] {
|
||||
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)
|
||||
@@ -891,8 +900,13 @@ void UI_base::setup_slider(QWidget *item, size_t index)
|
||||
return;
|
||||
}
|
||||
|
||||
connect(slider, &QwtSlider::sliderMoved, this,
|
||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::value_changed, index, slider->value()); });
|
||||
connect(slider, &QwtSlider::sliderMoved, this, [=, this] (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);
|
||||
});
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
connect(line_edit, &QLineEdit::textEdited, this,
|
||||
[=, this] { m_web_socket->send_event(Web_socket_wrapper::Event::text_changed, index, line_edit->text()); });
|
||||
connect(line_edit, &QLineEdit::textEdited, this, [=, this] {
|
||||
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)
|
||||
@@ -912,7 +931,11 @@ void UI_base::setup_spinbox(QWidget *item, size_t index)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
connect(can, &Can_Transceive::send_can_message, this,
|
||||
[=, this](uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload) {
|
||||
m_web_socket->send_event(Web_socket_wrapper::Event::can_send, index, id, dlc, payload);
|
||||
[=, this](uint32_t id, uint8_t dlc, QByteArray 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,
|
||||
[=, 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
|
||||
#include "ui_enum.hpp"
|
||||
#include <QMainWindow>
|
||||
#include <QWidget>
|
||||
#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(QLabel);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QMessageBox);
|
||||
|
||||
using json = nlohmann::json;
|
||||
namespace RemoteUiService
|
||||
{
|
||||
class Client;
|
||||
}
|
||||
|
||||
#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
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
explicit UI_base(Web_socket_wrapper *api, QWidget *parent = nullptr);
|
||||
void set_name(QString name);
|
||||
explicit UI_base(RemoteUiService::Client *api, QWidget *parent = nullptr);
|
||||
/**
|
||||
* @brief Get the UI element by its ID
|
||||
*
|
||||
@@ -56,6 +58,7 @@ class UI_base : public QMainWindow
|
||||
* @return QWidget* The UI element
|
||||
*/
|
||||
QWidget *id_to_ui(size_t id);
|
||||
void set_name(QString name);
|
||||
/**
|
||||
* @brief Get the label associated with a widget
|
||||
* This function has to be overridden in derived classes if labels are used
|
||||
@@ -70,18 +73,6 @@ class UI_base : public QMainWindow
|
||||
}
|
||||
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
void UI_item_parser(json &input);
|
||||
void UI_item_parser(UI_items_m &input);
|
||||
/**
|
||||
* @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);
|
||||
|
||||
private:
|
||||
Web_socket_wrapper *m_web_socket;
|
||||
RemoteUiService::Client *m_remote_ui_client;
|
||||
std::unique_ptr<QGrpcServerStream> m_stream;
|
||||
QString m_name;
|
||||
QTimer *m_timer_update;
|
||||
uint32_t m_refresh_rate;
|
||||
@@ -206,5 +198,5 @@ class UI_base : public QMainWindow
|
||||
bool m_open = false;
|
||||
bool m_first_load = true;
|
||||
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;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
find_package(Qt6 REQUIRED COMPONENTS Protobuf Grpc)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_library(proto-ui STATIC)
|
||||
set_target_properties(
|
||||
proto-ui
|
||||
PROPERTIES
|
||||
AUTOMOC ON
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
qt_add_protobuf(proto-ui
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/m_ui_items.proto
|
||||
${CMAKE_CURRENT_LIST_DIR}/messages.proto
|
||||
)
|
||||
target_link_libraries(proto-ui PUBLIC Qt6::Protobuf)
|
||||
|
||||
add_library(proto-ui-client STATIC)
|
||||
set_target_properties(
|
||||
proto-ui-client
|
||||
PROPERTIES
|
||||
AUTOMOC ON
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
qt_add_grpc(proto-ui-client CLIENT
|
||||
PROTO_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/messages.proto
|
||||
)
|
||||
target_link_libraries(proto-ui-client PUBLIC Qt6::Protobuf Qt6::Grpc proto-ui)
|
||||
|
||||
# add_library(proto-ui-server STATIC)
|
||||
# set_target_properties(
|
||||
# proto-ui-server
|
||||
# PROPERTIES
|
||||
# AUTOMOC ON
|
||||
# POSITION_INDEPENDENT_CODE ON
|
||||
# )
|
||||
# qt_add_grpc(proto-ui-server SERVER
|
||||
# PROTO_FILES
|
||||
# ${CMAKE_CURRENT_LIST_DIR}/messages.proto
|
||||
# )
|
||||
# target_link_libraries(proto-ui-server PUBLIC Qt6::Protobuf Qt6::Grpc proto-ui)
|
||||
@@ -0,0 +1,131 @@
|
||||
syntax = "proto3";
|
||||
|
||||
enum UI_type {
|
||||
undef = 0;
|
||||
ui_button = 1;
|
||||
ui_can = 2;
|
||||
ui_checkbox = 3;
|
||||
ui_combobox = 4;
|
||||
ui_dial = 5;
|
||||
ui_double_spinbox = 6;
|
||||
ui_hex_spinbox = 7;
|
||||
ui_label = 8;
|
||||
ui_led = 9;
|
||||
ui_plot = 10;
|
||||
ui_slider = 11;
|
||||
ui_spinbox = 12;
|
||||
ui_stacked_widget = 13;
|
||||
ui_status_bar = 14;
|
||||
ui_tab_widget = 15;
|
||||
ui_table = 16;
|
||||
ui_textbox = 17;
|
||||
ui_thermo = 18;
|
||||
}
|
||||
|
||||
message CAN_Frame_m {
|
||||
uint32 sid = 1;
|
||||
int64 dlc = 2;
|
||||
bytes payload = 3;
|
||||
}
|
||||
|
||||
message UI_color {
|
||||
uint32 fg_color = 1;
|
||||
uint32 bg_color = 2;
|
||||
}
|
||||
|
||||
message UI_label_m {
|
||||
UI_color color = 1;
|
||||
string text = 2;
|
||||
}
|
||||
|
||||
message UI_can_m {
|
||||
UI_color color = 1;
|
||||
repeated CAN_Frame_m send_frames = 2;
|
||||
repeated CAN_Frame_m recv_frames = 3;
|
||||
}
|
||||
|
||||
message UI_checkbox_m {
|
||||
UI_color color = 1;
|
||||
string text = 2;
|
||||
bool checked = 3;
|
||||
}
|
||||
|
||||
message UI_combobox_m {
|
||||
int64 selected = 1;
|
||||
repeated string options = 2;
|
||||
}
|
||||
|
||||
message UI_range_m {
|
||||
double min = 1;
|
||||
double max = 2;
|
||||
double value = 3;
|
||||
string unit = 4;
|
||||
string text = 5;
|
||||
}
|
||||
|
||||
message UI_spinbox_m {
|
||||
double min = 1;
|
||||
double max = 2;
|
||||
double value = 3;
|
||||
}
|
||||
|
||||
message UI_plot_m {
|
||||
UI_color color = 1;
|
||||
string text = 2;
|
||||
string x_label = 3;
|
||||
string y_label = 4;
|
||||
repeated double x_vals = 5;
|
||||
repeated double y_vals = 6;
|
||||
}
|
||||
|
||||
message UI_stacked_widget_m {
|
||||
int64 tab_count = 1;
|
||||
int64 current_tab = 2;
|
||||
}
|
||||
|
||||
message UI_tab_widget_m {
|
||||
int64 selecte_tab = 1;
|
||||
repeated string tab_names = 2;
|
||||
repeated bool tab_visible = 3;
|
||||
}
|
||||
|
||||
message UI_status_bar_m {
|
||||
uint64 timeout = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
message UI_table_m {
|
||||
int64 row_count = 1;
|
||||
int64 column_count = 2;
|
||||
repeated string row_labels = 3;
|
||||
repeated string column_labels = 4;
|
||||
repeated string table = 5;
|
||||
}
|
||||
|
||||
message UI_textbox_m {
|
||||
UI_color color = 1;
|
||||
string text = 2;
|
||||
string hint = 3;
|
||||
}
|
||||
|
||||
message UI_item_m {
|
||||
uint64 id = 1;
|
||||
UI_type type = 2;
|
||||
bool enabled = 3;
|
||||
bool visible = 4;
|
||||
|
||||
oneof kind {
|
||||
UI_label_m label = 5;
|
||||
UI_can_m can = 6;
|
||||
UI_checkbox_m checkbox = 7;
|
||||
UI_combobox_m combobox = 8;
|
||||
UI_range_m range = 9;
|
||||
UI_spinbox_m spinbox = 10;
|
||||
UI_plot_m plot = 11;
|
||||
UI_stacked_widget_m stacked_widget = 12;
|
||||
UI_tab_widget_m tab_widget = 13;
|
||||
UI_status_bar_m status_bar = 14;
|
||||
UI_table_m table = 15;
|
||||
UI_textbox_m textbox = 16;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
syntax = "proto3";
|
||||
import "m_ui_items.proto";
|
||||
|
||||
message Empty {}
|
||||
|
||||
message UI_id_m { uint32 id = 1; }
|
||||
message UI_items_m { repeated UI_item_m item = 1; }
|
||||
|
||||
message Simulator_m { string simuator = 1;}
|
||||
|
||||
message Simulators_m { repeated string simulator = 1; }
|
||||
|
||||
message Clicked_m {}
|
||||
|
||||
message Value_changed_m { double value = 1; }
|
||||
|
||||
message Text_changed_m { string text = 1; }
|
||||
|
||||
message Selected_m { uint32 selected = 1; }
|
||||
|
||||
message CAN_send_m { CAN_Frame_m frame = 1; }
|
||||
|
||||
message Clear_m {}
|
||||
|
||||
message Event_m {
|
||||
uint32 id = 1;
|
||||
oneof kind {
|
||||
Clicked_m clicked = 2;
|
||||
Value_changed_m value_changed = 3;
|
||||
Text_changed_m text_changed = 4;
|
||||
Selected_m selected = 5;
|
||||
CAN_send_m can_send = 6;
|
||||
Clear_m clear = 7;
|
||||
}
|
||||
}
|
||||
|
||||
service RemoteUiService {
|
||||
// Commands
|
||||
rpc Command_get_ui_element (UI_id_m) returns (UI_items_m);
|
||||
rpc Command_get_ui_elements (Empty) returns (UI_items_m);
|
||||
rpc Command_switch_simulator (Simulator_m) returns (Empty);
|
||||
rpc Command_get_active_simulator (Empty) returns (Simulator_m);
|
||||
rpc Command_get_simulators (Empty) returns (Simulators_m);
|
||||
|
||||
// Events
|
||||
rpc SendEvent (Event_m) returns (Empty);
|
||||
|
||||
// Broadcasting
|
||||
rpc SubscribeUIChanges (Empty) returns (stream UI_items_m);
|
||||
}
|
||||
@@ -57,6 +57,7 @@ target_sources(server_common
|
||||
target_link_libraries(server_common
|
||||
PUBLIC
|
||||
UI
|
||||
proto-ui
|
||||
spdlog
|
||||
cpp_templates
|
||||
${GPIOD_LIB}
|
||||
|
||||
+109
-114
@@ -3,131 +3,126 @@
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
QString Simulators::message_parser(QString message)
|
||||
// TODO: Fix parsing messages
|
||||
QByteArray Simulators::message_parser(QByteArray message)
|
||||
{
|
||||
json j = json::parse(message.toStdString());
|
||||
if (j.contains("command"))
|
||||
Event_m event_m;
|
||||
bool event = m_serializer.deserialize(&event_m, message);
|
||||
// if (j.contains("command"))
|
||||
// {
|
||||
// return QString::fromStdString(command_parser(j["command"]).dump());
|
||||
// }
|
||||
/*else*/ if (event)
|
||||
{
|
||||
return QString::fromStdString(command_parser(j["command"]).dump());
|
||||
event_handler(event_m);
|
||||
}
|
||||
else if (j.contains("event"))
|
||||
{
|
||||
event_handler(j["event"]);
|
||||
}
|
||||
return "{}";
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
json Simulators::command_parser(json command)
|
||||
// QByteArray Simulators::command_parser(json command)
|
||||
// {
|
||||
// json j = "{}"_json;
|
||||
// try
|
||||
// {
|
||||
// std::string type = command.at("type");
|
||||
// Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end);
|
||||
// switch (cmd)
|
||||
// {
|
||||
// case Command::get_UI_element:
|
||||
// SPDLOG_INFO("Command {}: {}", type, (size_t)command.at("id"));
|
||||
// if (is_not_active())
|
||||
// {
|
||||
// SPDLOG_ERROR("Command got called but there is no active simulator");
|
||||
// return j;
|
||||
// }
|
||||
// j["response"]["type"] = type;
|
||||
// j["response"]["UI_item"] =
|
||||
// invoke_active_simulator()->get_UI_item(command.at("id"))->to_json(command.at("id"));
|
||||
// break;
|
||||
// case Command::get_UI_elements:
|
||||
// SPDLOG_INFO("Command {}", type);
|
||||
// if (is_not_active())
|
||||
// {
|
||||
// SPDLOG_ERROR("Command got called but there is no active simulator");
|
||||
// return j;
|
||||
// }
|
||||
// j["response"]["type"] = type;
|
||||
// j["response"]["UI_items"] = invoke_active_simulator()->get_UI_items()["UI_items"];
|
||||
// break;
|
||||
// case Command::switch_simulator:
|
||||
// SPDLOG_INFO("Command {} to {}", type, std::string(command.at("name")));
|
||||
// switch_simulator(command.at("name"));
|
||||
// j["response"]["type"] = type;
|
||||
// break;
|
||||
// case Command::get_active_simulator_name:
|
||||
// SPDLOG_INFO("Command {}", type);
|
||||
// j["response"]["type"] = type;
|
||||
// j["response"]["name"] = active_simulator_name();
|
||||
// break;
|
||||
// case Command::get_simulators:
|
||||
// SPDLOG_INFO("Command {}", type);
|
||||
// j["response"]["type"] = type;
|
||||
// j["response"]["simulators"] = list_simulators();
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// catch (const json::exception &e)
|
||||
// {
|
||||
// SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
|
||||
// }
|
||||
|
||||
// return j;
|
||||
// }
|
||||
|
||||
void Simulators::event_handler(Event_m event)
|
||||
{
|
||||
json j = "{}"_json;
|
||||
try
|
||||
if (invoke_active_simulator() == nullptr)
|
||||
{
|
||||
std::string type = command.at("type");
|
||||
Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end);
|
||||
switch (cmd)
|
||||
{
|
||||
case Command::get_UI_element:
|
||||
SPDLOG_INFO("Command {}: {}", type, (size_t)command.at("id"));
|
||||
if (is_not_active())
|
||||
{
|
||||
SPDLOG_ERROR("Command got called but there is no active simulator");
|
||||
return j;
|
||||
}
|
||||
j["response"]["type"] = type;
|
||||
j["response"]["UI_item"] =
|
||||
invoke_active_simulator()->get_UI_item(command.at("id"))->to_json(command.at("id"));
|
||||
break;
|
||||
case Command::get_UI_elements:
|
||||
SPDLOG_INFO("Command {}", type);
|
||||
if (is_not_active())
|
||||
{
|
||||
SPDLOG_ERROR("Command got called but there is no active simulator");
|
||||
return j;
|
||||
}
|
||||
j["response"]["type"] = type;
|
||||
j["response"]["UI_items"] = invoke_active_simulator()->get_UI_items()["UI_items"];
|
||||
break;
|
||||
case Command::switch_simulator:
|
||||
SPDLOG_INFO("Command {} to {}", type, std::string(command.at("name")));
|
||||
switch_simulator(command.at("name"));
|
||||
j["response"]["type"] = type;
|
||||
break;
|
||||
case Command::get_active_simulator_name:
|
||||
SPDLOG_INFO("Command {}", type);
|
||||
j["response"]["type"] = type;
|
||||
j["response"]["name"] = active_simulator_name();
|
||||
break;
|
||||
case Command::get_simulators:
|
||||
SPDLOG_INFO("Command {}", type);
|
||||
j["response"]["type"] = type;
|
||||
j["response"]["simulators"] = list_simulators();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const json::exception &e)
|
||||
{
|
||||
SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
|
||||
SPDLOG_ERROR("Event got called but there is no active simulator");
|
||||
return;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
QString type; // = QString::fromStdString(magic_enum::enum_cast<Event_m::KindFields>(event.kindField()).value_or(Event_m::KindFields::UninitializedField));
|
||||
|
||||
void Simulators::event_handler(json event)
|
||||
{
|
||||
try
|
||||
switch (event.kindField())
|
||||
{
|
||||
std::string type = event.at("type");
|
||||
Event e = magic_enum::enum_cast<Event>(type).value_or(Event::end);
|
||||
if (invoke_active_simulator() == nullptr)
|
||||
{
|
||||
SPDLOG_ERROR("Event got called but there is no active simulator");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case Event::clicked: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
|
||||
invoke_active_simulator()->get_UI_item(event.at("id"))->click();
|
||||
break;
|
||||
}
|
||||
case Event::value_changed: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), (double)(event["value"]));
|
||||
invoke_active_simulator()->get_UI_item(event.at("id"))->set_value((double)event.at("value"));
|
||||
break;
|
||||
}
|
||||
case Event::text_changed: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), std::string(event.at("text")));
|
||||
invoke_active_simulator()->get_UI_item(event.at("id"))->set_text(std::string(event.at("text")));
|
||||
break;
|
||||
}
|
||||
case Event::selected: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, (size_t)event.at("id"), std::to_string((size_t)event.at("selected")));
|
||||
invoke_active_simulator()->get_UI_item(event.at("id"))->set_selected(event.at("selected"));
|
||||
break;
|
||||
}
|
||||
case Event::can_send: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
|
||||
invoke_active_simulator()
|
||||
->get_UI_item(event.at("id"))
|
||||
->can_send((uint32_t)event.at("sid"), (uint8_t)event.at("dlc"),
|
||||
(std::array<uint8_t, 8>)event.at("payload"));
|
||||
break;
|
||||
}
|
||||
case Event::clear: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.at("id"));
|
||||
invoke_active_simulator()->get_UI_item(event.at("id"))->clear();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case Event_m::KindFields::Clicked: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, (size_t)event.id_proto());
|
||||
invoke_active_simulator()->get_UI_item(event.id_proto())->click();
|
||||
break;
|
||||
}
|
||||
case Event_m::KindFields::ValueChanged: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), event.valueChanged().value());
|
||||
invoke_active_simulator()->get_UI_item(event.id_proto())->set_value(event.valueChanged().value());
|
||||
break;
|
||||
}
|
||||
case Event_m::KindFields::TextChanged: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), event.textChanged().text());
|
||||
invoke_active_simulator()->get_UI_item(event.id_proto())->set_text(event.textChanged().text());
|
||||
break;
|
||||
}
|
||||
case Event_m::KindFields::Selected: {
|
||||
SPDLOG_DEBUG("Event {}: {} {}", type, event.id_proto(), std::to_string(event.selected().selected()));
|
||||
invoke_active_simulator()->get_UI_item(event.id_proto())->set_selected(event.selected().selected());
|
||||
break;
|
||||
}
|
||||
case Event_m::KindFields::CanSend: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, event.id_proto());
|
||||
invoke_active_simulator()
|
||||
->get_UI_item(event.id_proto())
|
||||
->can_send(event.canSend().frame().sid(), event.canSend().frame().dlc(),
|
||||
event.canSend().frame().payload());
|
||||
break;
|
||||
}
|
||||
case Event_m::KindFields::Clear: {
|
||||
SPDLOG_DEBUG("Event {}: {}", type, event.id_proto());
|
||||
invoke_active_simulator()->get_UI_item(event.id_proto())->clear();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
catch (const json::exception &e)
|
||||
{
|
||||
SPDLOG_ERROR("{} {}", __FUNCTION__, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "simulator_base.hpp"
|
||||
#include "ui_item.hpp"
|
||||
|
||||
Simulator_base::Simulator_base(std::string name, Communication *com, std::chrono::milliseconds interval,
|
||||
Simulator_base::Simulator_base(QString name, Communication *com, std::chrono::milliseconds interval,
|
||||
QObject *parent)
|
||||
: QObject(parent), m_name(name), m_timer(new QTimer(this)), m_interval(interval), m_com(com)
|
||||
{
|
||||
@@ -10,7 +10,7 @@ Simulator_base::Simulator_base(std::string name, Communication *com, std::chrono
|
||||
m_UI_items.reserve(50);
|
||||
}
|
||||
|
||||
std::string Simulator_base::name() const
|
||||
QString Simulator_base::name() const
|
||||
{
|
||||
// Get the name of the simulator
|
||||
return m_name;
|
||||
@@ -20,17 +20,17 @@ void Simulator_base::push_ui_item(UI_item *item)
|
||||
{
|
||||
// Add a UI item to the simulator
|
||||
connect(item, &UI_item::ui_changed, this, [this] { emit sim_changed(); });
|
||||
item->set_id(m_UI_items.size());
|
||||
m_UI_items.push_back(item);
|
||||
}
|
||||
|
||||
json Simulator_base::get_UI_items() const
|
||||
QList<UI_item_m> Simulator_base::get_UI_items() const
|
||||
{
|
||||
// Get the UI items
|
||||
json items;
|
||||
items["name"] = m_name;
|
||||
QList<UI_item_m> items;
|
||||
for (size_t i = 0; i < m_UI_items.size(); i++)
|
||||
{
|
||||
items["UI_items"].push_back(m_UI_items[i]->to_json(i));
|
||||
items.push_back(m_UI_items[i]->to_proto());
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
+10
-22
@@ -7,11 +7,8 @@
|
||||
#ifndef INTERNAL
|
||||
#include "ui.hpp"
|
||||
#else
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item_m);
|
||||
#endif
|
||||
|
||||
#define PUSH_UI_ITEM(item) push_ui_item(&item)
|
||||
@@ -75,15 +72,15 @@ class Simulator_base : public QObject
|
||||
* @param interval The interval of the timer (default is 100ms)
|
||||
* @param parent The parent QObject
|
||||
*/
|
||||
Simulator_base(std::string name, Communication *comms,
|
||||
Simulator_base(QString name, Communication *comms,
|
||||
std::chrono::milliseconds interval = std::chrono::milliseconds(100), QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Returns the name of the simulator
|
||||
*
|
||||
* @return std::string The name of the simulator
|
||||
* @return QString The name of the simulator
|
||||
*/
|
||||
std::string name() const;
|
||||
QString name() const;
|
||||
|
||||
/**
|
||||
* @brief This function adds a UI item to the simulator
|
||||
@@ -98,7 +95,7 @@ class Simulator_base : public QObject
|
||||
*
|
||||
* @return json The UI items in json format
|
||||
*/
|
||||
json get_UI_items() const;
|
||||
QList<UI_item_m> get_UI_items() const;
|
||||
|
||||
/**
|
||||
* @brief Get the UI item object by id
|
||||
@@ -112,20 +109,11 @@ class Simulator_base : public QObject
|
||||
* @brief Get the id of a UI item by pointer
|
||||
*
|
||||
* @param ptr A pointer to the UI item
|
||||
* @return size_t The id of the UI item, or -1 if not found
|
||||
* @return qsizetype The id of the UI item, or -1 if not found
|
||||
*/
|
||||
size_t ptr_to_id(UI_item *ptr) const
|
||||
qsizetype ptr_to_id(UI_item *ptr) const
|
||||
{
|
||||
size_t id = 0;
|
||||
while (id < m_UI_items.size())
|
||||
{
|
||||
if (m_UI_items[id] == ptr)
|
||||
{
|
||||
return id;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
return (size_t)-1;
|
||||
return m_UI_items.indexOf(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,12 +184,12 @@ class Simulator_base : public QObject
|
||||
* @brief The name of the simulator
|
||||
*
|
||||
*/
|
||||
std::string m_name;
|
||||
QString m_name;
|
||||
/**
|
||||
* @brief The UI items of the simulator
|
||||
*
|
||||
*/
|
||||
std::vector<UI_item *> m_UI_items;
|
||||
QList<UI_item *> m_UI_items;
|
||||
/**
|
||||
* @brief The timer for the simulator
|
||||
*
|
||||
|
||||
+41
-50
@@ -7,7 +7,6 @@
|
||||
#include <QDirIterator>
|
||||
#include <QLibrary>
|
||||
#include <QThread>
|
||||
#include <unordered_set>
|
||||
|
||||
typedef Simulator_base *(*Get_Sim)(Communication *, QObject *);
|
||||
|
||||
@@ -71,17 +70,17 @@ Simulators::Simulators(uint16_t port, QStringList can_devs, QStringList uart_dev
|
||||
lib.unload();
|
||||
continue;
|
||||
}
|
||||
m_simulators.insert(std::make_pair(widget->name(), widget));
|
||||
m_simulators.insert(widget->name(), widget);
|
||||
}
|
||||
|
||||
// Insert Debug sims here
|
||||
// INSERT_SIMULATOR(TEST_SIM);
|
||||
|
||||
connect(m_server, &Websocket::on_message, this, [this](QWebSocket *conn, QString message) {
|
||||
QString response = message_parser(message);
|
||||
if (response == "{}")
|
||||
connect(m_server, &Websocket::on_binary_message, this, [this](QWebSocket *conn, QByteArray message) {
|
||||
QByteArray response = message_parser(message);
|
||||
if (response.isEmpty())
|
||||
return;
|
||||
m_server->send(conn, response);
|
||||
m_server->send_binary(conn, response);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ Simulators::~Simulators()
|
||||
{
|
||||
}
|
||||
|
||||
std::string Simulators::active_simulator_name() const
|
||||
QString Simulators::active_simulator_name() const
|
||||
{
|
||||
return this->m_current_simulator;
|
||||
}
|
||||
@@ -101,14 +100,14 @@ void Simulators::start()
|
||||
SPDLOG_WARN("No simulators found");
|
||||
return;
|
||||
}
|
||||
if (this->m_current_simulator.empty())
|
||||
if (this->m_current_simulator.isEmpty())
|
||||
{
|
||||
SPDLOG_WARN("No active simulator");
|
||||
return;
|
||||
}
|
||||
|
||||
m_before = this->m_simulators.at(m_current_simulator)->get_UI_items();
|
||||
this->m_simulators.at(m_current_simulator)->start();
|
||||
m_before = this->m_simulators.value(m_current_simulator)->get_UI_items();
|
||||
this->m_simulators.value(m_current_simulator)->start();
|
||||
}
|
||||
|
||||
void Simulators::stop()
|
||||
@@ -118,16 +117,16 @@ void Simulators::stop()
|
||||
SPDLOG_WARN("No simulators found");
|
||||
return;
|
||||
}
|
||||
if (this->m_current_simulator.empty())
|
||||
if (this->m_current_simulator.isEmpty())
|
||||
{
|
||||
SPDLOG_WARN("No active simulator");
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_simulators.at(m_current_simulator)->stop();
|
||||
this->m_simulators.value(m_current_simulator)->stop();
|
||||
}
|
||||
|
||||
void Simulators::switch_simulator(std::string name)
|
||||
void Simulators::switch_simulator(QString name)
|
||||
{
|
||||
if (this->m_simulators.empty())
|
||||
{
|
||||
@@ -136,29 +135,31 @@ void Simulators::switch_simulator(std::string name)
|
||||
}
|
||||
if (this->m_simulators.find(name) == this->m_simulators.end())
|
||||
{
|
||||
SPDLOG_WARN("Simulator {} not found", name);
|
||||
SPDLOG_WARN("Simulator {} not found", name.toStdString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->m_current_simulator.empty())
|
||||
if (!this->m_current_simulator.isEmpty())
|
||||
{
|
||||
SPDLOG_INFO("Stopping current simulator {} and switching to {}", m_current_simulator, name);
|
||||
this->m_simulators.at(m_current_simulator)->stop();
|
||||
disconnect(m_simulators.at(m_current_simulator).get());
|
||||
SPDLOG_INFO("Stopping current simulator {} and switching to {}", m_current_simulator.toStdString(), name.toStdString());
|
||||
this->m_simulators.value(m_current_simulator)->stop();
|
||||
disconnect(m_simulators.value(m_current_simulator));
|
||||
}
|
||||
|
||||
this->m_current_simulator = name;
|
||||
connect(
|
||||
m_simulators.at(m_current_simulator).get(), &Simulator_base::sim_changed, this,
|
||||
m_simulators.value(m_current_simulator), &Simulator_base::sim_changed, this,
|
||||
[this] {
|
||||
auto json = changed_UI_items();
|
||||
if (!json.empty())
|
||||
auto changed = changed_UI_items();
|
||||
UI_items_m items;
|
||||
items.setItem(changed);
|
||||
if (!changed.isEmpty())
|
||||
{
|
||||
m_server->broadcast(QString::fromStdString(json.dump()));
|
||||
m_server->broadcast_binary(m_serializer.serialize(&items));
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(m_simulators.at(m_current_simulator).get(), &Simulator_base::log_signal, this,
|
||||
connect(m_simulators.value(m_current_simulator), &Simulator_base::log_signal, this,
|
||||
[](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},
|
||||
@@ -167,19 +168,14 @@ void Simulators::switch_simulator(std::string name)
|
||||
this->start();
|
||||
}
|
||||
|
||||
std::vector<std::string> Simulators::list_simulators() const
|
||||
QList<QString> Simulators::list_simulators() const
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (const auto &simulator : this->m_simulators)
|
||||
{
|
||||
names.push_back(simulator.first);
|
||||
}
|
||||
return names;
|
||||
return this->m_simulators.keys();
|
||||
}
|
||||
|
||||
bool Simulators::is_not_active() const
|
||||
{
|
||||
return this->m_current_simulator.empty();
|
||||
return this->m_current_simulator.isEmpty();
|
||||
}
|
||||
|
||||
Simulator_base *Simulators::invoke_active_simulator()
|
||||
@@ -189,45 +185,40 @@ Simulator_base *Simulators::invoke_active_simulator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (this->m_current_simulator.empty())
|
||||
if (this->m_current_simulator.isEmpty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_before = this->m_simulators.at(m_current_simulator)->get_UI_items();
|
||||
m_before = this->m_simulators.value(m_current_simulator)->get_UI_items();
|
||||
|
||||
return this->m_simulators.at(m_current_simulator).get();
|
||||
return this->m_simulators.value(m_current_simulator);
|
||||
}
|
||||
|
||||
json Simulators::changed_UI_items()
|
||||
QList<UI_item_m> Simulators::changed_UI_items()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
QList<UI_item_m> ret;
|
||||
|
||||
if (this->m_simulators.empty() || this->m_current_simulator.empty())
|
||||
return "{}"_json;
|
||||
if (this->m_simulators.empty() || this->m_current_simulator.isEmpty())
|
||||
return ret;
|
||||
|
||||
json after = this->m_simulators.at(m_current_simulator)->get_UI_items();
|
||||
auto after = this->m_simulators.value(m_current_simulator)->get_UI_items();
|
||||
|
||||
// Fast path: nothing at all changed
|
||||
if (after == m_before)
|
||||
return "{}"_json;
|
||||
return ret;
|
||||
|
||||
json changed;
|
||||
changed["event"]["type"] = "ui_changed";
|
||||
|
||||
const auto &ui_items = after["UI_items"];
|
||||
const auto &prev_ui_items = m_before["UI_items"]; // may be null on first call
|
||||
|
||||
const size_t count = ui_items.size();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
const qsizetype count = after.size();
|
||||
for (qsizetype i = 0; i < count; ++i)
|
||||
{
|
||||
// If item is new or any field changed -> send full current item
|
||||
if (i >= prev_ui_items.size() || ui_items[i] != prev_ui_items[i])
|
||||
if (i >= m_before.size() || after[i] != m_before[i])
|
||||
{
|
||||
changed["event"]["UI_items"].push_back(ui_items[i]);
|
||||
ret.push_back(after[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_before = std::move(after);
|
||||
return changed;
|
||||
return ret;
|
||||
}
|
||||
+17
-16
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include <map>
|
||||
#include <QMap>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <QProtobufSerializer>
|
||||
#include <messages.qpb.h>
|
||||
|
||||
#define INSERT_SIMULATOR(type) \
|
||||
m_simulators.insert(std::make_pair(type(&m_com).name(), std::make_unique<type>(&m_com, this)));
|
||||
@@ -14,8 +15,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(CAN_Wrapper);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QSerialPort);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(Simulator_base);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(Communication);
|
||||
|
||||
using json = nlohmann::json;
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(UI_item_m);
|
||||
|
||||
/**
|
||||
* @brief Class managing all simulators
|
||||
@@ -75,9 +75,9 @@ class Simulators : public QObject
|
||||
/**
|
||||
* @brief Get the name of the active simulator
|
||||
*
|
||||
* @return std::string The name of the active simulator
|
||||
* @return QString The name of the active simulator
|
||||
*/
|
||||
std::string active_simulator_name() const;
|
||||
QString active_simulator_name() const;
|
||||
/**
|
||||
* @brief Start the active simulator
|
||||
*
|
||||
@@ -93,13 +93,13 @@ class Simulators : public QObject
|
||||
*
|
||||
* @param name The name of the simulator to switch to
|
||||
*/
|
||||
void switch_simulator(std::string name);
|
||||
void switch_simulator(QString name);
|
||||
/**
|
||||
* @brief List all available simulators
|
||||
*
|
||||
* @return std::vector<std::string> A list of simulator names
|
||||
* @return std::vector<QString> A list of simulator names
|
||||
*/
|
||||
std::vector<std::string> list_simulators() const;
|
||||
QList<QString> list_simulators() const;
|
||||
/**
|
||||
* @brief Check if no simulator is active
|
||||
*
|
||||
@@ -120,7 +120,7 @@ class Simulators : public QObject
|
||||
*
|
||||
* @return json The changed UI items
|
||||
*/
|
||||
json changed_UI_items();
|
||||
QList<UI_item_m> changed_UI_items();
|
||||
|
||||
// Functions in message_parser.cpp
|
||||
/**
|
||||
@@ -129,27 +129,28 @@ class Simulators : public QObject
|
||||
* @param message The message to parse
|
||||
* @return QString The parsed message
|
||||
*/
|
||||
QString message_parser(QString message);
|
||||
QByteArray message_parser(QByteArray message);
|
||||
/**
|
||||
* @brief Parse a command in json format
|
||||
*
|
||||
* @param command The command to parse
|
||||
* @return json The parsed command
|
||||
*/
|
||||
json command_parser(json command);
|
||||
//json command_parser(json command);
|
||||
/**
|
||||
* @brief Handle an event in json format
|
||||
*
|
||||
* @param event The event to handle
|
||||
*/
|
||||
void event_handler(json event);
|
||||
void event_handler(Event_m event);
|
||||
|
||||
private:
|
||||
QThread *m_server_thread;
|
||||
Websocket *m_server;
|
||||
Communication *m_com;
|
||||
std::map<std::string, std::unique_ptr<Simulator_base>> m_simulators;
|
||||
std::string m_current_simulator = "";
|
||||
QMap<QString, Simulator_base*> m_simulators;
|
||||
QString m_current_simulator = "";
|
||||
std::mutex m_mutex;
|
||||
json m_before;
|
||||
QList<UI_item_m> m_before;
|
||||
QProtobufSerializer m_serializer;
|
||||
};
|
||||
|
||||
@@ -5,10 +5,10 @@ EXPORT_SIM(Test_Sim);
|
||||
Test_Sim::Test_Sim(Communication *com, QObject *parent)
|
||||
: Simulator_base("Test Sim", com, std::chrono::milliseconds(1000), parent),
|
||||
m_button("Off", Color::White, Color::Red),
|
||||
m_combobox(Color::White, Color::Black, {"Option 1", "Option 2", "Option 3"}, 0),
|
||||
m_combobox({"Option 1", "Option 2", "Option 3"}, 0),
|
||||
m_label("Label", Color::White, Color::Black), m_checkbox("Option 1", Color::Default, Color::Default),
|
||||
m_slider("Slider", Color::White, Color::Black, 0, 100, 0), m_dial("Dial", Color::White, Color::Black, 0, 100, 0),
|
||||
m_thermo("Thermo", "%", Color::White, Color::Black, 0, 100, 0), m_led("Led", Color::White, Color::Red),
|
||||
m_slider("Slider", 0, 100, 0), m_dial("Dial", 0, 100, 0),
|
||||
m_thermo("Thermo", "%", 0, 100, 0), m_led("Led", Color::White, Color::Red),
|
||||
m_table(4, 4, {"Row 1", "Row 2", "Row 3", "Row 4"}, {"Column 1", "Column 2", "Column 3", "Column 4"}),
|
||||
m_spinbox(0, 255, 0), m_double_spinbox(0, 255, 0), m_hex_spinbox(0, 255, 0),
|
||||
m_tab_widget({"Tab 1", "Tab 2", "Tab 3"}, 0), m_stacked_widget(3, 0), m_status_bar()
|
||||
@@ -39,7 +39,7 @@ Test_Sim::Test_Sim(Communication *com, QObject *parent)
|
||||
|
||||
for (size_t i = 0; i < m_table.capacity(); i++)
|
||||
{
|
||||
m_table.insert_item(i / 4, i % 4, QString("%0 %1").arg(i / 4).arg(i % 4).toStdString());
|
||||
m_table.insert_item(i / 4, i % 4, QString("%0 %1").arg(i / 4).arg(i % 4));
|
||||
}
|
||||
|
||||
QObject::connect(&m_button, &UI_button::clicked, this, [=, this] { button_clicked(&m_button); });
|
||||
@@ -87,14 +87,14 @@ void Test_Sim::slider_changed(UI_slider *id, double value)
|
||||
if (id == &m_slider)
|
||||
{
|
||||
LOG_INFO(QString("Test slider changed to %0").arg(value));
|
||||
m_label.set_text(std::to_string(value));
|
||||
m_label.set_text(QString::number(value));
|
||||
m_dial.set_value(value);
|
||||
m_thermo.set_value(value);
|
||||
m_plot.add_value(value);
|
||||
m_spinbox.set_value(value);
|
||||
m_double_spinbox.set_value(value);
|
||||
m_hex_spinbox.set_value(value);
|
||||
m_status_bar.show_message("Test slider changed to " + std::to_string(value));
|
||||
m_status_bar.show_message("Test slider changed to " + QString::number(value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+23
-3
@@ -60,7 +60,15 @@ Websocket::~Websocket()
|
||||
qDeleteAll(m_clients.begin(), m_clients.end());
|
||||
}
|
||||
|
||||
void Websocket::broadcast(QString message)
|
||||
void Websocket::broadcast_binary(QByteArray message)
|
||||
{
|
||||
foreach (QWebSocket *conn, m_clients)
|
||||
{
|
||||
conn->sendBinaryMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void Websocket::broadcast_text(QString message)
|
||||
{
|
||||
foreach (QWebSocket *conn, m_clients)
|
||||
{
|
||||
@@ -68,7 +76,12 @@ void Websocket::broadcast(QString message)
|
||||
}
|
||||
}
|
||||
|
||||
void Websocket::send(QWebSocket *conn, QString message)
|
||||
void Websocket::send_binary(QWebSocket *conn, QByteArray message)
|
||||
{
|
||||
conn->sendBinaryMessage(message);
|
||||
}
|
||||
|
||||
void Websocket::send_text(QWebSocket *conn, QString message)
|
||||
{
|
||||
conn->sendTextMessage(message);
|
||||
}
|
||||
@@ -77,16 +90,23 @@ void Websocket::onNewConnection()
|
||||
{
|
||||
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
|
||||
|
||||
connect(pSocket, &QWebSocket::binaryMessageReceived, this, &Websocket::processBinaryMessage);
|
||||
connect(pSocket, &QWebSocket::textMessageReceived, this, &Websocket::processTextMessage);
|
||||
connect(pSocket, &QWebSocket::disconnected, this, &Websocket::socketDisconnected);
|
||||
|
||||
m_clients << pSocket;
|
||||
}
|
||||
|
||||
void Websocket::processBinaryMessage(QByteArray message)
|
||||
{
|
||||
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
|
||||
emit on_binary_message(pClient, message);
|
||||
}
|
||||
|
||||
void Websocket::processTextMessage(QString message)
|
||||
{
|
||||
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
|
||||
emit on_message(pClient, message);
|
||||
emit on_text_message(pClient, message);
|
||||
}
|
||||
|
||||
void Websocket::socketDisconnected()
|
||||
|
||||
@@ -41,14 +41,16 @@ class Websocket : public QObject
|
||||
*
|
||||
* @param message The message to send
|
||||
*/
|
||||
void broadcast(QString message);
|
||||
void broadcast_binary(QByteArray message);
|
||||
void broadcast_text(QString message);
|
||||
/**
|
||||
* @brief Send a message to a specific client
|
||||
*
|
||||
* @param conn The client connection
|
||||
* @param message The message to send
|
||||
*/
|
||||
void send(QWebSocket *conn, QString message);
|
||||
void send_binary(QWebSocket *conn, QByteArray message);
|
||||
void send_text(QWebSocket *conn, QString message);
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a message is received from a client
|
||||
@@ -56,7 +58,8 @@ class Websocket : public QObject
|
||||
* @param conn The client connection
|
||||
* @param message The received message
|
||||
*/
|
||||
void on_message(QWebSocket *conn, QString message);
|
||||
void on_binary_message(QWebSocket *conn, QByteArray message);
|
||||
void on_text_message(QWebSocket *conn, QString message);
|
||||
/**
|
||||
* @brief Signal emitted when the server is closed
|
||||
*
|
||||
@@ -74,6 +77,7 @@ class Websocket : public QObject
|
||||
*
|
||||
* @param message The received message
|
||||
*/
|
||||
void processBinaryMessage(QByteArray message);
|
||||
void processTextMessage(QString message);
|
||||
/**
|
||||
* @brief Private Slot called when a client disconnects
|
||||
|
||||
Reference in New Issue
Block a user