diff --git a/CMakeLists.txt b/CMakeLists.txt index e86a2c3..ed9bb60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,50 +1,35 @@ + cmake_minimum_required(VERSION 3.14) -project(eismuliplexer-qt) - -set(CMAKE_PROJECT_VERSION_MAJOR 0) -set(CMAKE_PROJECT_VERSION_MINOR 9) -set(CMAKE_PROJECT_VERSION_PATCH 0) - -add_compile_definitions(VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}) -add_compile_definitions(VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}) -add_compile_definitions(VERSION_PATCH=${CMAKE_PROJECT_VERSION_PATCH}) - -if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - message(FATAL_ERROR "Windows builds have to be cross compiled on UNIX") -endif() - -message("Platform " ${CMAKE_SYSTEM_NAME}) -if(WIN32) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/release-win.sh ${CMAKE_CURRENT_BINARY_DIR}/release.sh @ONLY) - add_custom_target(package - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/release.sh - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Createing release archive" - VERBATIM) -endif(WIN32) +# Set the project name +project(eismultiplexer-qt) +# Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -find_package(PkgConfig REQUIRED) -pkg_check_modules(EISMULIPLEXER REQUIRED eismuliplexer) +# Find Qt6 find_package(Qt6 REQUIRED COMPONENTS Widgets) -find_package(Qt6 REQUIRED COMPONENTS Core) +# Enable automoc for Qt meta-object compiler set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) -add_executable(${PROJECT_NAME} +# Include the libeismultiplexer library +include_directories(/workspace/libeismultiplexer) +link_directories(/workspace/libeismultiplexer/build) + +# Add the application executable +add_executable(eismultiplexer-qt main.cpp + mainwindow.cpp + mainwindow.h channelwidget.cpp channelwidget.h - mainwindow.h - mainwindow.cpp - mainwindow.ui - multiplexer.h - multiplexer.cpp ) -target_compile_options(${PROJECT_NAME} PUBLIC "-Wall") -target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets Qt6::Core ${EISMULIPLEXER_LIBRARIES}) -#target_include_directories(${PROJECT_NAME} PUBLIC ${EISMULIPLEXER_INCLUDE_DIRS}) +target_compile_options(eismultiplexer-qt PUBLIC "-Wall") + +# Link Qt Widgets +target_link_libraries(eismultiplexer-qt Qt6::Widgets eismultiplexer) + +# Include directories +target_include_directories(eismultiplexer-qt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/channelwidget.cpp b/channelwidget.cpp index ae259fc..b5df245 100644 --- a/channelwidget.cpp +++ b/channelwidget.cpp @@ -1,97 +1,78 @@ + + + #include "channelwidget.h" #include #include -ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, - std::shared_ptr multiplexer, +ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, QWidget *parent) - : - QWidget(parent), - deviceSerial(deviceSerial), - channelNumber(channelNumber), - multiplexer(multiplexer), - checkbox("Enable"), - devicelabel(QString::asprintf("Device %04u", deviceSerial)), - channellabel(QString::asprintf("Channel %u", channelNumber)), - ganglabel("Ganged:") + : QWidget(parent), deviceSerial(deviceSerial), channelNumber(channelNumber), multiplexer(multiplexer) { - hlayout.addLayout(&labellayout); - vlayout.addLayout(&hlayout); + // Create layout + QHBoxLayout* layout = new QHBoxLayout(this); - labellayout.addWidget(&devicelabel); - labellayout.addWidget(&channellabel); + // Create label with device serial and channel number + label = new QLabel(QString("Device %1, Channel %2").arg(deviceSerial).arg(channelNumber), this); + layout->addWidget(label); - line.setGeometry(QRect(320, 150, 118, 3)); - line.setFrameShape(QFrame::HLine); - line.setFrameShadow(QFrame::Sunken); - vlayout.addWidget(&line); + // Create checkbox + checkbox = new QCheckBox(this); + layout->addWidget(checkbox); - gangcombo.addItem("Unganged"); + // Connect checkbox signal + connect(checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled); - hlayout.addStretch(); - hlayout.addWidget(&ganglabel); - hlayout.addWidget(&gangcombo); - hlayout.addWidget(&checkbox); - connect(&checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled); - - setFixedHeight(96); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - - setLayout(&vlayout); + // Set layout + setLayout(layout); } ChannelWidget::~ChannelWidget() { - // Nothing to clean up + // Nothing to clean up } uint16_t ChannelWidget::getDeviceSerial() const { - return deviceSerial; + return deviceSerial; } uint16_t ChannelWidget::getChannelNumber() const { - return channelNumber; + return channelNumber; } bool ChannelWidget::isChecked() const { - return checkbox.isChecked(); + return checkbox->isChecked(); } void ChannelWidget::onChannelToggled(bool checked) { - if (checked) - { - // Emit signal before actually turning on the channel - emit channelAboutToBeTurnedOn(deviceSerial, channelNumber); - } + if (checked) { + // Emit signal before actually turning on the channel + emit channelAboutToBeTurnedOn(deviceSerial, channelNumber); + } - channel_t channelFlag = static_cast(1 << channelNumber); - if (checked) - { - if (eismultiplexer_connect_channel(multiplexer.get(), channelFlag) < 0) - { - QMessageBox::warning(this, tr("Connection Failed"), - tr("Failed to connect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); - qWarning() << "Failed to connect channel" << channelNumber << "on device" << deviceSerial; - checkbox.blockSignals(true); - checkbox.setChecked(false); - setEnabled(false); // Gray out the widget - } - } - else - { - if (eismultiplexer_disconnect_channel(multiplexer.get(), channelFlag) < 0) - { - QMessageBox::warning(this, tr("Disconnection Failed"), - tr("Failed to disconnect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); - qWarning() << "Failed to disconnect channel" << channelNumber << "on device" << deviceSerial; - checkbox.blockSignals(true); - checkbox.setChecked(true); - setEnabled(false); // Gray out the widget - } - } + channel_t channelFlag = static_cast(1 << channelNumber); + if (checked) { + if (eismultiplexer_connect_channel(multiplexer.get(), channelFlag) < 0) { + QMessageBox::warning(this, tr("Connection Failed"), + tr("Failed to connect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); + qWarning() << "Failed to connect channel" << channelNumber << "on device" << deviceSerial; + checkbox->blockSignals(true); + checkbox->setChecked(false); + setEnabled(false); // Gray out the widget + } + } else { + if (eismultiplexer_disconnect_channel(multiplexer.get(), channelFlag) < 0) { + QMessageBox::warning(this, tr("Disconnection Failed"), + tr("Failed to disconnect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); + qWarning() << "Failed to disconnect channel" << channelNumber << "on device" << deviceSerial; + checkbox->blockSignals(true); + checkbox->setChecked(true); + setEnabled(false); // Gray out the widget + } + } } diff --git a/channelwidget.h b/channelwidget.h index 08762a6..0c10019 100644 --- a/channelwidget.h +++ b/channelwidget.h @@ -5,43 +5,34 @@ #include #include #include -#include #include #include class ChannelWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, - std::shared_ptr multiplexer, - QWidget *parent = nullptr); - ~ChannelWidget() override; + explicit ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, + QWidget *parent = nullptr); + ~ChannelWidget() override; - uint16_t getDeviceSerial() const; - uint16_t getChannelNumber() const; - bool isChecked() const; + uint16_t getDeviceSerial() const; + uint16_t getChannelNumber() const; + bool isChecked() const; signals: - void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); + void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); private slots: - void onChannelToggled(bool checked); + void onChannelToggled(bool checked); private: - uint16_t deviceSerial; - uint16_t channelNumber; - std::shared_ptr multiplexer; - QCheckBox checkbox; - QLabel devicelabel; - QLabel channellabel; - QLabel ganglabel; - QComboBox gangcombo; - QFrame line; - QVBoxLayout vlayout; - QHBoxLayout hlayout; - QVBoxLayout labellayout; + uint16_t deviceSerial; + uint16_t channelNumber; + std::shared_ptr multiplexer; + QCheckBox* checkbox; + QLabel* label; }; #endif // CHANNELWIDGET_H diff --git a/main.cpp b/main.cpp index fb4d5b4..6bbb0be 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,11 @@ + #include #include "mainwindow.h" int main(int argc, char *argv[]) { - QApplication app(argc, argv); - MainWindow window; - window.show(); - return app.exec(); + QApplication app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 99a5739..6a97402 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,68 +1,85 @@ -#include -#include #include "mainwindow.h" -#include "ui_mainwindow.h" +#include +#include +#include +#include MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) + : QMainWindow(parent) { - ui->setupUi(this); - enumerateDevices(); - - connect(ui->actionQuit, &QAction::triggered, this, [this]() - { - close(); - }); + setupUi(); + enumerateDevices(); } MainWindow::~MainWindow() { - delete ui; + // Clean up all channel widgets + for (auto widget : channelWidgets) { + delete widget; + } } +void MainWindow::setupUi() +{ + // Create central widget and main layout + centralWidget = new QWidget(this); + mainLayout = new QVBoxLayout(centralWidget); + + // Create scroll area + scrollArea = new QScrollArea(this); + scrollContent = new QWidget(); + scrollLayout = new QVBoxLayout(scrollContent); + + // Set up scroll area properties + scrollArea->setWidget(scrollContent); + scrollArea->setWidgetResizable(true); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + // Add scroll area to main layout + mainLayout->addWidget(scrollArea); + + // Set central widget + setCentralWidget(centralWidget); + setWindowTitle("EIS Multiplexer Controller"); +} + +void MainWindow::onChannelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber) +{} + void MainWindow::enumerateDevices() { - size_t count = 0; - uint16_t* serials = eismultiplexer_list_available_devices(&count); + size_t count = 0; + uint16_t* serials = eismultiplexer_list_available_devices(&count); - if (!serials || count == 0) - { - QMessageBox::warning(nullptr, tr("No Devices Found"), - tr("No EIS multiplexer devices were found. Please connect a device and try again.")); - qWarning() << "No EIS multiplexer devices found"; - exit(0); - return; - } + if (!serials || count == 0) { + QMessageBox::warning(this, tr("No Devices Found"), + tr("No EIS multiplexer devices were found. Please connect a device and try again.")); + qWarning() << "No EIS multiplexer devices found"; + close(); + return; + } - for (size_t i = 0; i < count; i++) - { - uint16_t serial = serials[i]; - std::shared_ptr multiplexer(new struct eismultiplexer); - if (eismultiplexer_connect(multiplexer.get(), serial) >= 0) - { - uint16_t channelCount = 0; - qDebug()<<"Adding channels from device "<= 0) - { - for (uint16_t channel = 0; channel < channelCount; channel++) - { - std::shared_ptr widget(new ChannelWidget(serial, channel, multiplexer)); - qDebug()<<"Added widget from device "<channelLayout->addWidget(widget.get()); - } - } - } - else - { - QMessageBox::warning(this, tr("Connection Failed"), - tr("Failed to connect to device with serial %1").arg(serial)); - qWarning() << "Failed to connect to device with serial" << serial; - } - ui->channelLayout->addStretch(); - } - ui->statusbar->showMessage("Ready"); + for (size_t i = 0; i < count; i++) { + uint16_t serial = serials[i]; + std::shared_ptr multiplexer(new struct eismultiplexer); + if (eismultiplexer_connect(multiplexer.get(), serial) >= 0) { + uint16_t channelCount = 0; + qDebug()<<"Adding channels from device "<= 0) { + for (uint16_t channel = 0; channel < channelCount; channel++) { + ChannelWidget* widget = new ChannelWidget(serial, channel, multiplexer.get()); + qDebug()<<"Added widget from device "<addWidget(widget); + } + } + } else { + QMessageBox::warning(this, tr("Connection Failed"), + tr("Failed to connect to device with serial %1").arg(serial)); + qWarning() << "Failed to connect to device with serial" << serial; + } + } - free(serials); + free(serials); } + diff --git a/mainwindow.h b/mainwindow.h index cb1a19c..4426a48 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,31 +1,42 @@ + + #ifndef MAINWINDOW_H #define MAINWINDOW_H #include -#include - +#include +#include +#include +#include #include "channelwidget.h" -namespace Ui -{ -class MainWindow; -} +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE class MainWindow : public QMainWindow { - Q_OBJECT - std::vector> channels; - Ui::MainWindow *ui; - -signals: - void channelStateChanged(uint16_t device, uint16_t channel); + Q_OBJECT public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow() override; + +private slots: + void onChannelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); private: - void enumerateDevices(); + void enumerateDevices(); + void setupUi(); + + QWidget *centralWidget; + QVBoxLayout *mainLayout; + QScrollArea *scrollArea; + QWidget *scrollContent; + QVBoxLayout *scrollLayout; + + std::vector channelWidgets; }; #endif // MAINWINDOW_H + diff --git a/mainwindow.ui b/mainwindow.ui deleted file mode 100644 index 53aca8f..0000000 --- a/mainwindow.ui +++ /dev/null @@ -1,68 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 800 - 600 - - - - EisMultiplexer-Qt - - - - - - - true - - - - - 0 - 0 - 788 - 537 - - - - - - - - - - - - - - - - 0 - 0 - 800 - 29 - - - - - File - - - - - - - - - Quit - - - - - - diff --git a/multiplexer.cpp b/multiplexer.cpp deleted file mode 100644 index 3e1c8e0..0000000 --- a/multiplexer.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "multiplexer.h" - -Multiplexer::Multiplexer(QObject *parent) - : QObject{parent} -{} - -Multiplexer::~Multiplexer() -{ - for(auto& multiplexer : multiplexers) - eismultiplexer_disconnect(multiplexer.get()); -} - -void Multiplexer::probe() -{ - -} diff --git a/multiplexer.h b/multiplexer.h deleted file mode 100644 index 32a04ec..0000000 --- a/multiplexer.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MULTIPLEXER_H -#define MULTIPLEXER_H - -#include -#include "eismultiplexer.h" - -class Multiplexer : public QObject -{ - Q_OBJECT - std::vector> multiplexers; - std::vector channelStates; - -public: - explicit Multiplexer(QObject *parent = nullptr); - ~Multiplexer(); - void probe(); - -signals: - void foundDevice(std::shared_ptr); -}; - -#endif // MULTIPLEXER_H