diff --git a/CMakeLists.txt b/CMakeLists.txt index cc85769..a5c3161 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,8 @@ add_executable(${PROJECT_NAME} mainwindow.ui multiplexer.h multiplexer.cpp + triggerwidget.cpp + triggerwidget.h ) set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE ON) target_compile_options(${PROJECT_NAME} PUBLIC "-Wall") diff --git a/mainwindow.cpp b/mainwindow.cpp index f764d9a..379cd2b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3,6 +3,7 @@ #include #include "mainwindow.h" #include "ui_mainwindow.h" +#include "triggerwidget.h" MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), @@ -64,6 +65,20 @@ void MainWindow::enumerateDevices() ui->channelLayout->addWidget(widget.get()); } } + + // Add trigger widgets + int triggerCount = eismultiplexer_get_trigger_count(multiplexer.get()); + if (triggerCount > 0) + { + qDebug()<<"Adding triggers from device "< triggerWidget(new TriggerWidget(serial, trigger, multiplexer)); + qDebug()<<"Added trigger widget from device "<channelLayout->addWidget(triggerWidget.get()); + } + } } else { @@ -74,7 +89,7 @@ void MainWindow::enumerateDevices() } ui->channelLayout->addStretch(); - // Second pass: populate gang combos and connect signals + // Second pass: populate gang combos and connect signals for channels for (const auto& widget : channels) { // Populate gang combo with all other channels for (const auto& otherWidget : channels) { diff --git a/mainwindow.h b/mainwindow.h index 090ecb0..7373d2b 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,3 +1,5 @@ + + #ifndef MAINWINDOW_H #define MAINWINDOW_H @@ -8,6 +10,7 @@ #include #include "channelwidget.h" +#include "triggerwidget.h" namespace Ui { @@ -16,23 +19,25 @@ class MainWindow; class MainWindow : public QMainWindow { - Q_OBJECT - std::vector> channels; - Ui::MainWindow *ui; + Q_OBJECT + std::vector> channels; + std::vector> triggers; + Ui::MainWindow *ui; QCodeEditor codeEditor; QPythonHighlighter highligter; QPythonCompleter completer; signals: - void channelStateChanged(uint16_t device, uint16_t channel); + void channelStateChanged(uint16_t device, uint16_t channel); public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); private: - void enumerateDevices(); + void enumerateDevices(); void generateExample(); }; #endif // MAINWINDOW_H + diff --git a/triggerwidget.cpp b/triggerwidget.cpp new file mode 100644 index 0000000..efa6627 --- /dev/null +++ b/triggerwidget.cpp @@ -0,0 +1,95 @@ + + +#include "triggerwidget.h" +#include +#include +#include + +TriggerWidget::TriggerWidget(uint16_t deviceSerial, uint16_t triggerNumber, + std::shared_ptr multiplexer, + QWidget *parent): + QWidget(parent), + deviceSerial(deviceSerial), + triggerNumber(triggerNumber), + multiplexer(multiplexer), + inputCheckbox("Input"), + levelCheckbox("Level"), + devicelabel(QString::asprintf("Device %04u", deviceSerial)), + triggerlabel(QString::asprintf("Trigger %u", triggerNumber)) +{ + hlayout.addLayout(&labellayout); + vlayout.addLayout(&hlayout); + + inputCheckbox.setChecked(true); + levelCheckbox.setEnabled(false); + + labellayout.addWidget(&devicelabel); + labellayout.addWidget(&triggerlabel); + + line.setFrameShape(QFrame::HLine); + line.setFrameShadow(QFrame::Sunken); + vlayout.addWidget(&line); + + hlayout.addStretch(); + hlayout.addWidget(&inputCheckbox); + hlayout.addWidget(&levelCheckbox); + + connect(&inputCheckbox, &QCheckBox::toggled, this, &TriggerWidget::onInputToggled); + connect(&levelCheckbox, &QCheckBox::toggled, this, &TriggerWidget::onLevelToggled); + + setFixedHeight(96); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + setLayout(&vlayout); + + // Initialize trigger state + updateTriggerState(); +} + +TriggerWidget::~TriggerWidget() +{ +} + +uint16_t TriggerWidget::getDeviceSerial() const +{ + return deviceSerial; +} + +uint16_t TriggerWidget::getTriggerNumber() const +{ + return triggerNumber; +} + +void TriggerWidget::onInputToggled(bool checked) +{ + updateTriggerState(); +} + +void TriggerWidget::onLevelToggled(bool checked) +{ + updateTriggerState(); +} + +void TriggerWidget::updateTriggerState() +{ + trigger_state_t state; + if(inputCheckbox.isChecked()) + { + levelCheckbox.blockSignals(true); + levelCheckbox.setChecked(false); + levelCheckbox.setEnabled(false); + levelCheckbox.blockSignals(false); + } + else + { + levelCheckbox.setEnabled(true); + state = levelCheckbox.isChecked() ? TRIGGER_HIGH : TRIGGER_LOW; + } + + if (eismultiplexer_set_trigger_state(multiplexer.get(), triggerNumber, state) < 0) { + QMessageBox::warning(this, tr("Trigger Configuration Failed"), + tr("Failed to set trigger %1 on device %2").arg(triggerNumber).arg(deviceSerial)); + qWarning() << "Failed to set trigger" << triggerNumber << "on device" << deviceSerial; + } +} + diff --git a/triggerwidget.h b/triggerwidget.h new file mode 100644 index 0000000..718ed1b --- /dev/null +++ b/triggerwidget.h @@ -0,0 +1,45 @@ + +#ifndef TRIGGERWIDGET_H +#define TRIGGERWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +class TriggerWidget : public QWidget +{ + Q_OBJECT + +public: + explicit TriggerWidget(uint16_t deviceSerial, uint16_t triggerNumber, + std::shared_ptr multiplexer, + QWidget *parent = nullptr); + ~TriggerWidget() override; + + uint16_t getDeviceSerial() const; + uint16_t getTriggerNumber() const; + +private slots: + void onInputToggled(bool checked); + void onLevelToggled(bool checked); + void updateTriggerState(); + +private: + uint16_t deviceSerial; + uint16_t triggerNumber; + std::shared_ptr multiplexer; + QCheckBox inputCheckbox; + QCheckBox levelCheckbox; + QLabel devicelabel; + QLabel triggerlabel; + QFrame line; + QVBoxLayout vlayout; + QHBoxLayout hlayout; + QVBoxLayout labellayout; +}; + +#endif // TRIGGERWIDGET_H