mirror of
https://github.com/Sani7/remote-ui.git
synced 2026-10-27 06:01:14 +01:00
Before git init
This commit is contained in:
@@ -34,5 +34,3 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
log-sim_us.txt
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(Simulator-CVS_I10 VERSION 0.1 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(magic_enum URL https://github.com/Neargye/magic_enum/releases/download/v0.9.6/magic_enum-v0.9.6.tar.gz DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
|
||||||
|
FetchContent_MakeAvailable(magic_enum)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Svg WebSockets)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Svg WebSockets)
|
||||||
|
|
||||||
|
add_subdirectory(qwt)
|
||||||
|
|
||||||
|
set(PROJECT_SOURCES
|
||||||
|
sim-cvs_i10.h
|
||||||
|
sim-cvs_i10.cpp
|
||||||
|
sim-cvs_i10_helper.cpp
|
||||||
|
sim-cvs_i10.ui
|
||||||
|
|
||||||
|
sim-can_debugger.h
|
||||||
|
sim-can_debugger.cpp
|
||||||
|
sim-can_debugger.ui
|
||||||
|
|
||||||
|
sim-scope_mux_tester.h
|
||||||
|
sim-scope_mux_tester.cpp
|
||||||
|
sim-scope_mux_tester.ui
|
||||||
|
|
||||||
|
simulatorbase.h
|
||||||
|
simulatorbase.cpp
|
||||||
|
helpers.h
|
||||||
|
helpers.cpp
|
||||||
|
IterableEnum.hpp
|
||||||
|
better_radiobutton.h
|
||||||
|
better_radiobutton.cpp
|
||||||
|
|
||||||
|
networkerror.h
|
||||||
|
networkerror.cpp
|
||||||
|
networkerror.ui
|
||||||
|
|
||||||
|
mainwindow.h
|
||||||
|
mainwindow.cpp
|
||||||
|
mainwindow.ui
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
|
qt_add_executable(Simulator-CVS_I10
|
||||||
|
MANUAL_FINALIZATION
|
||||||
|
${PROJECT_SOURCES}
|
||||||
|
)
|
||||||
|
# Define target properties for Android with Qt 6 as:
|
||||||
|
# set_property(TARGET Simulator-CVS_I10 APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||||
|
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||||
|
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||||
|
else()
|
||||||
|
if(ANDROID)
|
||||||
|
add_library(Simulator-CVS_I10 SHARED
|
||||||
|
${PROJECT_SOURCES}
|
||||||
|
)
|
||||||
|
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||||
|
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||||
|
else()
|
||||||
|
add_executable(Simulator-CVS_I10
|
||||||
|
${PROJECT_SOURCES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(Simulator-CVS_I10
|
||||||
|
PUBLIC
|
||||||
|
${PROJECT_BINARY_DIR}/
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(Simulator-CVS_I10 PRIVATE qwt Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::WebSockets)
|
||||||
|
|
||||||
|
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||||
|
# If you are developing for iOS or macOS you should consider setting an
|
||||||
|
# explicit, fixed bundle identifier manually though.
|
||||||
|
if(${QT_VERSION} VERSION_LESS 6.1.0)
|
||||||
|
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.Simulator-CVS_I10)
|
||||||
|
endif()
|
||||||
|
set_target_properties(Simulator-CVS_I10 PROPERTIES
|
||||||
|
${BUNDLE_ID_OPTION}
|
||||||
|
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||||
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||||
|
MACOSX_BUNDLE TRUE
|
||||||
|
WIN32_EXECUTABLE TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
install(TARGETS Simulator-CVS_I10
|
||||||
|
BUNDLE DESTINATION .
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(QT_VERSION_MAJOR EQUAL 6)
|
||||||
|
qt_finalize_executable(Simulator-CVS_I10)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
A way to iterate over enumerations as C++ template.
|
||||||
|
|
||||||
|
Copyright (c) 2023 Sander Speetjens
|
||||||
|
Licensed under the terms of the MIT license (given below).
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ITERABLE_ENUM_BEGIN(name) enum class name : int {
|
||||||
|
#define ITERABLE_ENUM_END ,end, begin = 0 }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Iterable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Iterable(T value = T::begin) : mValue(value) {}
|
||||||
|
Iterable(const Iterable& other) : mValue(other.mValue) {}
|
||||||
|
|
||||||
|
Iterable& operator++()
|
||||||
|
{
|
||||||
|
assert(mValue >= T::begin && mValue < T::end);
|
||||||
|
mValue = static_cast<T>(static_cast<int>(mValue) + 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator++(int)
|
||||||
|
{
|
||||||
|
Iterable prev = *this;
|
||||||
|
mValue = static_cast<T>(static_cast<int>(mValue) + 1);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable& operator--()
|
||||||
|
{
|
||||||
|
assert(mValue >= T::end && mValue < T::begin);
|
||||||
|
mValue = static_cast<T>(static_cast<int>(mValue) - 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator--(int)
|
||||||
|
{
|
||||||
|
Iterable prev = *this;
|
||||||
|
mValue = static_cast<T>(static_cast<int>(mValue) - 1);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator+(int i)
|
||||||
|
{
|
||||||
|
return static_cast<T>(static_cast<int>(mValue) + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator+(T i)
|
||||||
|
{
|
||||||
|
return static_cast<T>(static_cast<int>(mValue) + static_cast<int>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator-(int i)
|
||||||
|
{
|
||||||
|
return static_cast<T>(static_cast<int>(mValue) - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable operator-(T i)
|
||||||
|
{
|
||||||
|
return static_cast<T>(static_cast<int>(mValue) - static_cast<int>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator >(const T& other) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mValue) > static_cast<int>(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator >=(const T& other) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mValue) >= static_cast<int>(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator <(const T& other) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mValue) < static_cast<int>(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator <=(const T& other) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mValue) <= static_cast<int>(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator ==(const T& other) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mValue) == static_cast<int>(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const { return mValue != T::end; }
|
||||||
|
|
||||||
|
operator T() const { return mValue; }
|
||||||
|
operator T&() { return mValue; }
|
||||||
|
T val() const { return mValue; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T mValue;
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include "better_radiobutton.h"
|
||||||
|
|
||||||
|
Better_Radiobutton::Better_Radiobutton(QWidget* parent) :
|
||||||
|
QWidget{parent},
|
||||||
|
m_radiobuttons{}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Better_Radiobutton::Better_Radiobutton(std::vector<QString> names, QWidget* parent) :
|
||||||
|
QWidget{parent},
|
||||||
|
m_v_layout{new QVBoxLayout(this)},
|
||||||
|
m_radiobuttons{},
|
||||||
|
m_checked{""}
|
||||||
|
{
|
||||||
|
for (const auto& name : names) {
|
||||||
|
add_radiobutton(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Better_Radiobutton::add_radiobutton(QString name)
|
||||||
|
{
|
||||||
|
auto radiobutton = new QRadioButton(name, this);
|
||||||
|
m_radiobuttons.push_back(radiobutton);
|
||||||
|
m_v_layout->addWidget(radiobutton);
|
||||||
|
|
||||||
|
connect(radiobutton, &QRadioButton::toggled, this, [this, name, radiobutton] {
|
||||||
|
emit toggled(name);
|
||||||
|
if (radiobutton->isChecked()) {
|
||||||
|
m_checked = name;
|
||||||
|
emit checked(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Better_Radiobutton::isChecked() const
|
||||||
|
{
|
||||||
|
return m_checked;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef BETTER_RADIOBUTTON_H
|
||||||
|
#define BETTER_RADIOBUTTON_H
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QRadioButton>
|
||||||
|
|
||||||
|
class Better_Radiobutton : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Better_Radiobutton(QWidget* parent = nullptr);
|
||||||
|
explicit Better_Radiobutton(std::vector<QString>names, QWidget* partent = nullptr);
|
||||||
|
|
||||||
|
void add_radiobutton(QString name);
|
||||||
|
QString isChecked() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void toggled(QString name);
|
||||||
|
void checked(QString name);
|
||||||
|
private:
|
||||||
|
QVBoxLayout* m_v_layout;
|
||||||
|
std::vector<QRadioButton*> m_radiobuttons;
|
||||||
|
QString m_checked;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BETTER_RADIOBUTTON_H
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
void create_dial_needle(QwtDial* dial)
|
||||||
|
{
|
||||||
|
QwtDialSimpleNeedle* needle = new QwtDialSimpleNeedle(
|
||||||
|
QwtDialSimpleNeedle::Arrow, true, Qt::yellow,
|
||||||
|
QColor( Qt::gray ).lighter( 130 ) );
|
||||||
|
needle->setWidth(2);
|
||||||
|
dial->setNeedle( needle );
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_thermo_color(QwtSlider* slider, QColor color, QColor bg)
|
||||||
|
{
|
||||||
|
QString style = QString("#%1 { background-color: %2; color: %3;}").arg(slider->objectName(), bg.name(), color.name());
|
||||||
|
|
||||||
|
slider->setStyleSheet(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_button_color(QPushButton* button, QColor color, QColor bg)
|
||||||
|
{
|
||||||
|
QString style = QString("#%1 { background-color: %2; color: %3;}").arg(button->objectName(), bg.name(), color.name());
|
||||||
|
|
||||||
|
button->setStyleSheet(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_button_color(QPushButton* button, QString color, QString bg)
|
||||||
|
{
|
||||||
|
QString style = QString("#%1 { background-color: %2; color: %3;}").arg(button->objectName(), bg, color);
|
||||||
|
|
||||||
|
button->setStyleSheet(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor button_bg_color(QPushButton* button)
|
||||||
|
{
|
||||||
|
std::string input = button->styleSheet().toStdString();
|
||||||
|
QColor background_color;
|
||||||
|
|
||||||
|
// Find the position of "background-color:"
|
||||||
|
size_t bg_pos = input.find("background-color:");
|
||||||
|
if (bg_pos != std::string::npos) {
|
||||||
|
// Find the end position of the background color value
|
||||||
|
size_t bg_value_start = bg_pos + 17; // Length of "background-color:" is 17
|
||||||
|
size_t bg_value_end = input.find(";", bg_value_start);
|
||||||
|
if (bg_value_end != std::string::npos) {
|
||||||
|
background_color = QColor(input.substr(bg_value_start, bg_value_end - bg_value_start).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return background_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor button_color(QPushButton* button)
|
||||||
|
{
|
||||||
|
std::string input = button->styleSheet().toStdString();
|
||||||
|
QColor color;
|
||||||
|
|
||||||
|
// Find the position of "color:"
|
||||||
|
size_t color_pos = input.find(" color:");
|
||||||
|
if (color_pos != std::string::npos) {
|
||||||
|
// Find the end position of the text color value
|
||||||
|
size_t color_value_start = color_pos + 7; // Length of "color:" is 7
|
||||||
|
size_t color_value_end = input.find(";", color_value_start);
|
||||||
|
if (color_value_end != std::string::npos) {
|
||||||
|
color = QColor(input.substr(color_value_start, color_value_end - color_value_start).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_button_color(QPushButton* button)
|
||||||
|
{
|
||||||
|
button->setStyleSheet("");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_read_only(QWidget* widget)
|
||||||
|
{
|
||||||
|
return widget->testAttribute(Qt::WA_TransparentForMouseEvents) || (widget->focusPolicy() == Qt::NoFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_read_only(QWidget* widget, bool read_only)
|
||||||
|
{
|
||||||
|
widget->setAttribute(Qt::WA_TransparentForMouseEvents, read_only);
|
||||||
|
widget->setFocusPolicy(read_only ? Qt::NoFocus : Qt::StrongFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString network_reply_to_fix(QNetworkReply::NetworkError error)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
case QNetworkReply::NetworkError::ConnectionRefusedError:
|
||||||
|
return "Make sure the server is started ($ systemctl status unocan_server)";
|
||||||
|
break;
|
||||||
|
case QNetworkReply::NetworkError::HostNotFoundError:
|
||||||
|
return "Make sure the simulator is turned on";
|
||||||
|
break;
|
||||||
|
case QNetworkReply::NetworkError::InternalServerError:
|
||||||
|
return "Server had an oopsie, restart the client and if it fails again restart the server";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef HELPERS_H
|
||||||
|
#define HELPERS_H
|
||||||
|
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include <qwt_color_map.h>
|
||||||
|
#include <qwt_dial.h>
|
||||||
|
#include <qwt_dial_needle.h>
|
||||||
|
#include <qwt_plot.h>
|
||||||
|
#include <qwt_plot_curve.h>
|
||||||
|
#include <qwt_slider.h>
|
||||||
|
#include <qwt_series_data.h>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
void create_dial_needle(QwtDial* dial);
|
||||||
|
|
||||||
|
void set_thermo_color(QwtSlider* slider, QColor color, QColor bg);
|
||||||
|
void set_button_color(QPushButton* button, QColor color, QColor bg);
|
||||||
|
void set_button_color(QPushButton* button, QString color, QString bg);
|
||||||
|
QColor button_bg_color(QPushButton* button);
|
||||||
|
QColor button_color(QPushButton* button);
|
||||||
|
void reset_button_color(QPushButton* button);
|
||||||
|
void set_read_only(QWidget* widget, bool readOnly = true);
|
||||||
|
bool is_read_only(QWidget* widget);
|
||||||
|
QString network_reply_to_fix(QNetworkReply::NetworkError error);
|
||||||
|
|
||||||
|
#endif // HELPERS_H
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
MainWindow w;
|
||||||
|
w.show();
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
#include "sim-scope_mux_tester.h"
|
||||||
|
#include "sim-can_debugger.h"
|
||||||
|
#include "sim-cvs_i10.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow),
|
||||||
|
api(new OpenAPI::OAICANApiApi()),
|
||||||
|
error_dialog(new NetworkError(this)),
|
||||||
|
sims{{"CANDebugger", new Can_Debugger(api, this)},
|
||||||
|
{"Scope_Mux_Tester", new Scope_Mux_Tester(api, this)},
|
||||||
|
{"CVS_I10", new CVS_I10(api, this)}}
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
this->setWindowTitle("Simulator Selector");
|
||||||
|
connect(this, &MainWindow::quit, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
api->setNewServerForAllOperations(
|
||||||
|
//QUrl("http://localhost:1880"),
|
||||||
|
QUrl("https://cvs-i10.local/api"),
|
||||||
|
"No description provided",
|
||||||
|
QMap<QString, OpenAPI::OAIServerVariable>());
|
||||||
|
api->apiCanapiSimsGet();
|
||||||
|
|
||||||
|
//Default sim
|
||||||
|
defaultSim("CVS_I10");
|
||||||
|
|
||||||
|
connect(ui->pushButton, &QPushButton::clicked, this, [=]{open_sim(ui->comboBox->currentText());});
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
delete api;
|
||||||
|
delete error_dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setup_cb(void)
|
||||||
|
{
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiSimsGetSignal, this, [=](QList<QString> summary){Parse_Sims(summary);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiSimsGetSignalError, this, [=](QList<QString> summary, QNetworkReply::NetworkError error_type, const QString &error_str){Parse_Sims(summary, error_type, error_str);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimPutSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimPutSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){
|
||||||
|
apiCanapiUielements_bool_cb(false, error_type, error_str);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimGetSignal, this, [this](OpenAPI::OAISimulatorInfo summary){apiCanapiCurrentsimGet_cb(summary);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimGetSignalError, this, [this](OpenAPI::OAISimulatorInfo summary, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo(), error_type, error_str);});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showEvent( QShowEvent* event )
|
||||||
|
{
|
||||||
|
QWidget::showEvent( event );
|
||||||
|
setup_cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::hideEvent(QHideEvent* event)
|
||||||
|
{
|
||||||
|
QWidget::hideEvent(event);
|
||||||
|
disconnect(api, nullptr, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::defaultSim(QString name)
|
||||||
|
{
|
||||||
|
this->selected_sim_name = name;
|
||||||
|
this->default_sim = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::Parse_Sims(QList<QString> sims, QNetworkReply::NetworkError error_type, const QString error_str)
|
||||||
|
{
|
||||||
|
if (error_type) {
|
||||||
|
QD << "( " << error_type << "," << error_str << ")";
|
||||||
|
error_dialog->set_error(error_str + "\n" + network_reply_to_fix(error_type));
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
} if (sims.empty()) {
|
||||||
|
QD << " got called with invalid data and no error!";
|
||||||
|
error_dialog->set_error(QString(__FUNCTION__) + " got called with invalid data and no error!");
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sims.length(); i++)
|
||||||
|
{
|
||||||
|
ui->comboBox->addItem(sims[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QThread::msleep(30);
|
||||||
|
|
||||||
|
if (this->default_sim)
|
||||||
|
{
|
||||||
|
ui->comboBox->setCurrentText(this->selected_sim_name);
|
||||||
|
open_sim(this->selected_sim_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::open_sim(QString sim_name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
selected_sim = sims.at(sim_name);
|
||||||
|
this->selected_sim_name = sim_name;
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range& ex)
|
||||||
|
{
|
||||||
|
QD << "out_of_range::what(): " << ex.what();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api->apiCanapiCurrentsimGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::open_sim_window(void)
|
||||||
|
{
|
||||||
|
this->hide();
|
||||||
|
selected_sim->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::apiCanapiUielements_bool_cb(bool output, QNetworkReply::NetworkError error_type, QString error_str)
|
||||||
|
{
|
||||||
|
if (error_type) {
|
||||||
|
QD << "( " << Qt::hex << output << "," << error_type << "," << error_str << ")";
|
||||||
|
error_dialog->set_error(error_str + "\n" + network_reply_to_fix(error_type));
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
} if (!output) {
|
||||||
|
QD << " got called with invalid data and no error!";
|
||||||
|
error_dialog->set_error(QString(__FUNCTION__) + " got called with invalid data and no error!");
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
open_sim_window();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo summary, QNetworkReply::NetworkError error_type, QString error_str)
|
||||||
|
{
|
||||||
|
if (error_type) {
|
||||||
|
QD << "( " << summary.asJson() << "," << error_type << "," << error_str << ")";
|
||||||
|
error_dialog->set_error(error_str + "\n" + network_reply_to_fix(error_type));
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
} if (!summary.isValid()) {
|
||||||
|
QD << " got called with invalid data and no error!";
|
||||||
|
error_dialog->set_error(QString(__FUNCTION__) + " got called with invalid data and no error!");
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!summary.is_name_Set())
|
||||||
|
{
|
||||||
|
QD << "Name not set";
|
||||||
|
api->apiCanapiCurrentsimPut(selected_sim_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QD << "Current sim:" << summary.getName();
|
||||||
|
|
||||||
|
if (summary.getName() == selected_sim_name)
|
||||||
|
{
|
||||||
|
QD << "Name set and right";
|
||||||
|
open_sim_window();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QD << "Name set and wrong";
|
||||||
|
api->apiCanapiCurrentsimPut(selected_sim_name);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "OAICANApiApi.h"
|
||||||
|
#include "networkerror.h"
|
||||||
|
#include "simulatorbase.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
void defaultSim(QString name);
|
||||||
|
void Parse_Sims(QList<QString> sims, QNetworkReply::NetworkError error_type = QNetworkReply::NetworkError::NoError, QString error_str = QString());
|
||||||
|
void apiCanapiUielements_bool_cb(bool ret, QNetworkReply::NetworkError error_type = QNetworkReply::NetworkError::NoError, QString error_str = QString());
|
||||||
|
void apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo summary, QNetworkReply::NetworkError error_type = QNetworkReply::NetworkError::NoError, QString error_str = QString());
|
||||||
|
void open_sim_window(void);
|
||||||
|
void open_sim(QString sim_name);
|
||||||
|
void setup_cb(void);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit(void);
|
||||||
|
private:
|
||||||
|
void showEvent( QShowEvent* event );
|
||||||
|
void hideEvent(QHideEvent* event);
|
||||||
|
|
||||||
|
bool default_sim = false;
|
||||||
|
QString selected_sim_name;
|
||||||
|
QMainWindow* selected_sim;
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
OpenAPI::OAICANApiApi *api;
|
||||||
|
NetworkError* error_dialog;
|
||||||
|
|
||||||
|
std::map<QString, SimulatorBase*> sims;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<action name="actiontest">
|
||||||
|
<property name="text">
|
||||||
|
<string>test</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "networkerror.h"
|
||||||
|
#include "ui_networkerror.h"
|
||||||
|
|
||||||
|
NetworkError::NetworkError(QWidget* parent) : QDialog(parent), ui(new Ui::NetworkError) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
connect(ui->exit, &QPushButton::clicked, this, &QCoreApplication::quit, Qt::QueuedConnection);
|
||||||
|
connect(ui->close, &QPushButton::clicked, this, [=]{this->close();});
|
||||||
|
|
||||||
|
this->setWindowTitle("Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkError::set_error(QString error)
|
||||||
|
{
|
||||||
|
ui->Error->setText(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkError::~NetworkError() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef NETWORKERROR_H
|
||||||
|
#define NETWORKERROR_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class NetworkError;
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetworkError : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NetworkError(QWidget* parent = nullptr);
|
||||||
|
void set_error(QString error);
|
||||||
|
~NetworkError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::NetworkError* ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NETWORKERROR_H
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NetworkError</class>
|
||||||
|
<widget class="QDialog" name="NetworkError">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="title">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Oops, an error occured</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="Error">
|
||||||
|
<property name="text">
|
||||||
|
<string>Error...</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="close">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="exit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit Application</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
Submodule
+1
Submodule Qt/qwt added at aab5a9927c
@@ -0,0 +1,13 @@
|
|||||||
|
#include "sim-can_debugger.h"
|
||||||
|
#include "ui_sim-can_debugger.h"
|
||||||
|
|
||||||
|
Can_Debugger::Can_Debugger(OpenAPI::OAICANApiApi* api, QWidget *parent) :
|
||||||
|
SimulatorBase(api, parent),
|
||||||
|
ui(new Ui::Can_Debugger) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
this->setWindowTitle("CAN Debugger");
|
||||||
|
}
|
||||||
|
|
||||||
|
Can_Debugger::~Can_Debugger() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef SIM_CAN_DEBUGGER_H
|
||||||
|
#define SIM_CAN_DEBUGGER_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "simulatorbase.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class Can_Debugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Can_Debugger : public SimulatorBase {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Can_Debugger(OpenAPI::OAICANApiApi* api, QWidget *parent = nullptr);
|
||||||
|
~Can_Debugger();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Can_Debugger* ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SIM_CAN_DEBUGGER_H
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Can_Debugger</class>
|
||||||
|
<widget class="QMainWindow" name="Can_Debugger">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget"/>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
#include "simulatorbase.h"
|
||||||
|
|
||||||
|
SimulatorBase::SimulatorBase(OpenAPI::OAICANApiApi* api, QWidget* parent) :
|
||||||
|
QMainWindow{parent},
|
||||||
|
error_dialog(new NetworkError(this))
|
||||||
|
{
|
||||||
|
this->api = api;
|
||||||
|
timer_update = new QTimer(this);
|
||||||
|
timer_update->connect(timer_update, &QTimer::timeout, this, [=]{sim_update();});
|
||||||
|
refresh_rate = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::sim_update(void)
|
||||||
|
{
|
||||||
|
api->apiCanapiCurrentsimGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::showEvent( QShowEvent* event )
|
||||||
|
{
|
||||||
|
QWidget::showEvent( event );
|
||||||
|
QD << "Starting refresh timer";
|
||||||
|
setup_cb();
|
||||||
|
this->timer_update->start(refresh_rate);
|
||||||
|
closed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::closeEvent(QCloseEvent* event)
|
||||||
|
{
|
||||||
|
if (!closed)
|
||||||
|
{
|
||||||
|
QD << "Disconnecting callbacks";
|
||||||
|
QWidget::closeEvent(event);
|
||||||
|
this->timer_update->stop();
|
||||||
|
disconnect(api, nullptr, nullptr, nullptr);
|
||||||
|
this->parentWidget()->show();
|
||||||
|
}
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::setup_cb(void)
|
||||||
|
{
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsPushbuttonPostSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsPushbuttonPostSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiUielements_bool_cb(false, false, error_type, error_str);});
|
||||||
|
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsPushbuttonarrayPostSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsPushbuttonarrayPostSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiUielements_bool_cb(false, false, error_type, error_str);});
|
||||||
|
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsTextboxPostSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsTextboxPostSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiUielements_bool_cb(false, false, error_type, error_str);});
|
||||||
|
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsSliderPostSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsSliderPostSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiUielements_bool_cb(false, false, error_type, error_str);});
|
||||||
|
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsTogglearrayPostSignal, this, [this](bool output){apiCanapiUielements_bool_cb(output);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiUielementsTogglearrayPostSignalError, this, [this](bool output, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiUielements_bool_cb(false, false, error_type, error_str);});
|
||||||
|
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimGetSignal, this, [this](OpenAPI::OAISimulatorInfo summary){apiCanapiCurrentsimGet_cb(summary);});
|
||||||
|
connect(api, &OpenAPI::OAICANApiApi::apiCanapiCurrentsimGetSignalError, this, [this](OpenAPI::OAISimulatorInfo summary, QNetworkReply::NetworkError error_type, QString error_str){apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo(), error_type, error_str);});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::apiCanapiUielements_bool_cb(bool output, bool currentsim, QNetworkReply::NetworkError error_type, QString error_str)
|
||||||
|
{
|
||||||
|
if (error_type) {
|
||||||
|
QD << "( " << Qt::hex << output << "," << error_type << "," << error_str << ")";
|
||||||
|
error_dialog->set_error(error_str + "\n" + network_reply_to_fix(error_type));
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
} if (!output) {
|
||||||
|
QD << " got called with invalid data and no error!";
|
||||||
|
error_dialog->set_error(QString(__FUNCTION__) + " got called with invalid data and no error!");
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo summary, QNetworkReply::NetworkError error_type, QString error_str)
|
||||||
|
{
|
||||||
|
if (error_type) {
|
||||||
|
QD << "( " << summary.asJson() << "," << error_type << "," << error_str << ")";
|
||||||
|
error_dialog->set_error(error_str + "\n" + network_reply_to_fix(error_type));
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
} if (!summary.isValid()) {
|
||||||
|
QD << " got called with invalid data and no error!";
|
||||||
|
error_dialog->set_error(QString(__FUNCTION__) + " got called with invalid data and no error!");
|
||||||
|
error_dialog->open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OAISimulatorInfo_parser(summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::OAISimulatorInfo_parser(OpenAPI::OAISimulatorInfo input)
|
||||||
|
{
|
||||||
|
const OpenAPI::OAIClientUIItem* uiItem;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input.getUiItems().count(); i++)
|
||||||
|
{
|
||||||
|
uiItem = &(input.getUiItems().at(i));
|
||||||
|
|
||||||
|
if (uiItem->getType() == "UIButtonArray")
|
||||||
|
{
|
||||||
|
process_ui_button_array(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UILedArray")
|
||||||
|
{
|
||||||
|
process_ui_led_array(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UISlider")
|
||||||
|
{
|
||||||
|
process_ui_slider(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UITextbox")
|
||||||
|
{
|
||||||
|
process_ui_textbox(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UILabel")
|
||||||
|
{
|
||||||
|
process_ui_label(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UICombobox")
|
||||||
|
{
|
||||||
|
process_ui_combobox(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (uiItem->getType() == "UIRadioButton")
|
||||||
|
{
|
||||||
|
process_ui_radiobutton(uiItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_button_array(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QJsonObject state = uiItem->getState().asJsonObject();
|
||||||
|
QJsonArray state_array = state["buttonArray"].toArray();
|
||||||
|
for (size_t i = 0; i < state_array.count(); i++)
|
||||||
|
{
|
||||||
|
process_ui_button_array_element(state_array[i].toObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_led_array(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QJsonObject state = uiItem->getState().asJsonObject();
|
||||||
|
QJsonArray state_array = state["ledArray"].toArray();
|
||||||
|
for (size_t i = 0; i < state_array.count(); i++)
|
||||||
|
{
|
||||||
|
process_ui_led_array_element(state_array[i].toObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_label(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QLabel* label = id_to_label(uiItem->getName());
|
||||||
|
if (label == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_label returned null on " << uiItem->getName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString value = uiItem->getState().asJsonObject()["textString"].toString();
|
||||||
|
|
||||||
|
if (label->text() != value)
|
||||||
|
{
|
||||||
|
label->setText(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_slider(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
if (uiItem->getName().startsWith('t'))
|
||||||
|
{
|
||||||
|
QwtSlider* slider = id_to_slider(uiItem->getName());
|
||||||
|
QLabel* label = id_to_slider_label(uiItem->getName());
|
||||||
|
if (slider == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_slider returned null on " << uiItem->getName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = uiItem->getState().asJsonObject()["currentValue"].toDouble();
|
||||||
|
bool enable = uiItem->getState().asJsonObject()["enable"].toBool();
|
||||||
|
bool visible = uiItem->getState().asJsonObject()["visible"].toBool();
|
||||||
|
|
||||||
|
if (slider->value() != value)
|
||||||
|
{
|
||||||
|
if (label != nullptr)
|
||||||
|
{
|
||||||
|
label->setText(format_slider_value(uiItem->getName(), value));
|
||||||
|
}
|
||||||
|
slider->setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slider->isReadOnly() != !enable)
|
||||||
|
{
|
||||||
|
slider->setReadOnly(!enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slider->isVisible() != visible)
|
||||||
|
{
|
||||||
|
slider->setVisible(visible);
|
||||||
|
}
|
||||||
|
//TODO: Add color for scale
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uiItem->getName().startsWith('d'))
|
||||||
|
{
|
||||||
|
QwtDial* dial = id_to_dial(uiItem->getName());
|
||||||
|
QLabel* label = id_to_dial_label(uiItem->getName());
|
||||||
|
if (dial == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_dial returned null on " << uiItem->getName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = uiItem->getState().asJsonObject()["currentValue"].toDouble();
|
||||||
|
bool visible = uiItem->getState().asJsonObject()["visible"].toBool();
|
||||||
|
|
||||||
|
if (dial->value() != value)
|
||||||
|
{
|
||||||
|
if (label != nullptr)
|
||||||
|
{
|
||||||
|
label->setText(format_dial_value(uiItem->getName(), value));
|
||||||
|
}
|
||||||
|
dial->setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dial->isVisible() != visible)
|
||||||
|
{
|
||||||
|
dial->setVisible(visible);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_textbox(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QD << "Not implemented";
|
||||||
|
emit quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_combobox(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QComboBox* combobox = id_to_combobox(uiItem->getName());
|
||||||
|
if (combobox == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_combobox returned null on " << uiItem->getName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject state = uiItem->getState().asJsonObject();
|
||||||
|
QString selected = state["selected"].toString();
|
||||||
|
QJsonArray toggleArray = state["toggleArray"].toArray();
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < toggleArray.count(); i++)
|
||||||
|
{
|
||||||
|
QString item = toggleArray[i].toObject()["id"].toString();
|
||||||
|
if (combobox->findText(item) == -1)
|
||||||
|
combobox->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (combobox->currentText() != selected)
|
||||||
|
{
|
||||||
|
combobox->setCurrentText(selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_radiobutton(const OpenAPI::OAIClientUIItem* uiItem)
|
||||||
|
{
|
||||||
|
QD << "Not implemented";
|
||||||
|
emit quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_button_array_element(QJsonObject jsonObject)
|
||||||
|
{
|
||||||
|
//TODO: fix bgcolor and color
|
||||||
|
QPushButton* button = id_to_button(jsonObject["id"].toString());
|
||||||
|
|
||||||
|
if (button == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_button returned null on " << jsonObject["id"].toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor bg_color = QColor(jsonObject["color"].toString());
|
||||||
|
QString text = jsonObject["title"].toString();
|
||||||
|
bool enabled = jsonObject["enable"].toBool();
|
||||||
|
|
||||||
|
if (button->text() != text)
|
||||||
|
{
|
||||||
|
button->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button->isEnabled() != enabled)
|
||||||
|
{
|
||||||
|
button->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0x83, 0x91, 0x92))
|
||||||
|
{
|
||||||
|
reset_button_color(button);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0xFF, 0x00, 0x00))
|
||||||
|
{
|
||||||
|
set_button_color(button, QString("black"), QString("darkred"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0x00, 0xFF, 0x00))
|
||||||
|
{
|
||||||
|
set_button_color(button, QString("white"), QString("darkgreen"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0xFF8800))
|
||||||
|
{
|
||||||
|
set_button_color(button, QString("darkred"), QString("darkorange"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color != button_bg_color(button))
|
||||||
|
{
|
||||||
|
set_button_color(button, QColor(), bg_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorBase::process_ui_led_array_element(QJsonObject jsonObject)
|
||||||
|
{
|
||||||
|
QPushButton* led = id_to_led(jsonObject["id"].toString());
|
||||||
|
if (led == nullptr)
|
||||||
|
{
|
||||||
|
QD << "id_to_led returned null on " << jsonObject["id"].toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor bg_color = QColor(jsonObject["state"].toString());
|
||||||
|
QColor color = QColor(~bg_color.red(), ~bg_color.green(), ~bg_color.blue());
|
||||||
|
QString text = jsonObject["title"].toString();
|
||||||
|
|
||||||
|
if (false == is_read_only(led))
|
||||||
|
{
|
||||||
|
set_read_only(led);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text != led->text())
|
||||||
|
{
|
||||||
|
led->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0x83, 0x91, 0x92))
|
||||||
|
{
|
||||||
|
reset_button_color(led);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0xFF, 0x00, 0x00))
|
||||||
|
{
|
||||||
|
set_button_color(led, QString("black"), QString("darkred"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0x00, 0xFF, 0x00))
|
||||||
|
{
|
||||||
|
set_button_color(led, QString("white"), QString("darkgreen"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color == QColor(0xFF8800))
|
||||||
|
{
|
||||||
|
set_button_color(led, QString("darkred"), QString("darkorange"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg_color != button_bg_color(led))
|
||||||
|
{
|
||||||
|
set_button_color(led, color, bg_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef SIMULATORBASE_H
|
||||||
|
#define SIMULATORBASE_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QWidget>
|
||||||
|
#include "OAICANApiApi.h"
|
||||||
|
#include "networkerror.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include <magic_enum.hpp>
|
||||||
|
#include "IterableEnum.hpp"
|
||||||
|
|
||||||
|
#define QD qDebug() << "Debug:" << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << ":"
|
||||||
|
|
||||||
|
class SimulatorBase : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SimulatorBase(OpenAPI::OAICANApiApi* api, QWidget* parent = nullptr);
|
||||||
|
void setup_cb(void);
|
||||||
|
void sim_update(void);
|
||||||
|
virtual QLabel* id_to_label(QString name) {return nullptr;}
|
||||||
|
virtual QPushButton* id_to_led(QString name) {return nullptr;}
|
||||||
|
virtual QPushButton* id_to_button(QString name) {return nullptr;}
|
||||||
|
virtual QwtSlider* id_to_slider(QString name) {return nullptr;}
|
||||||
|
virtual QLabel* id_to_slider_label(QString name) {return nullptr;}
|
||||||
|
virtual QString format_slider_value(QString name, double val) {return QString();}
|
||||||
|
virtual QwtDial* id_to_dial(QString name) {return nullptr;}
|
||||||
|
virtual QLabel* id_to_dial_label(QString name) {return nullptr;}
|
||||||
|
virtual QString format_dial_value(QString name, double val) {return QString();}
|
||||||
|
virtual QComboBox* id_to_combobox(QString name) {return nullptr;}
|
||||||
|
virtual QTextEdit* id_to_textbox(QString name) {return nullptr;}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void quit();
|
||||||
|
protected:
|
||||||
|
void apiCanapiUielements_bool_cb(bool ret, bool currentsim = false, QNetworkReply::NetworkError error_type = QNetworkReply::NetworkError::NoError, QString error_str = QString());
|
||||||
|
void apiCanapiCurrentsimGet_cb(OpenAPI::OAISimulatorInfo output, QNetworkReply::NetworkError error_type = QNetworkReply::NetworkError::NoError, QString error_str = QString());
|
||||||
|
|
||||||
|
void OAISimulatorInfo_parser(OpenAPI::OAISimulatorInfo input);
|
||||||
|
void process_ui_button_array(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_led_array(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_label(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_slider(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_textbox(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_combobox(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_radiobutton(const OpenAPI::OAIClientUIItem* uiItem);
|
||||||
|
void process_ui_button_array_element(QJsonObject jsonObject);
|
||||||
|
void process_ui_led_array_element(QJsonObject jsonObject);
|
||||||
|
|
||||||
|
void showEvent(QShowEvent* event);
|
||||||
|
void closeEvent(QCloseEvent* event);
|
||||||
|
|
||||||
|
OpenAPI::OAICANApiApi* api;
|
||||||
|
|
||||||
|
QTimer* timer_update;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
NetworkError* error_dialog;
|
||||||
|
bool closed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SIMULATORBASE_H
|
||||||
Reference in New Issue
Block a user