add trigger support

This commit is contained in:
Carl Philipp Klemm 2025-10-13 13:59:35 +02:00
parent bccee9bd36
commit c11630e50a
5 changed files with 180 additions and 8 deletions

View file

@ -41,6 +41,8 @@ add_executable(${PROJECT_NAME}
mainwindow.ui mainwindow.ui
multiplexer.h multiplexer.h
multiplexer.cpp multiplexer.cpp
triggerwidget.cpp
triggerwidget.h
) )
set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE ON) set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE ON)
target_compile_options(${PROJECT_NAME} PUBLIC "-Wall") target_compile_options(${PROJECT_NAME} PUBLIC "-Wall")

View file

@ -2,6 +2,7 @@
#include <QMessageBox> #include <QMessageBox>
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "triggerwidget.h"
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -55,6 +56,20 @@ void MainWindow::enumerateDevices()
ui->channelLayout->addWidget(widget.get()); ui->channelLayout->addWidget(widget.get());
} }
} }
// Add trigger widgets
int triggerCount = eismultiplexer_get_trigger_count(multiplexer.get());
if (triggerCount > 0)
{
qDebug()<<"Adding triggers from device "<<serial;
for (int trigger = 0; trigger < triggerCount; trigger++)
{
std::shared_ptr<TriggerWidget> triggerWidget(new TriggerWidget(serial, trigger, multiplexer));
qDebug()<<"Added trigger widget from device "<<serial<<" trigger "<<trigger;
triggers.push_back(triggerWidget);
ui->channelLayout->addWidget(triggerWidget.get());
}
}
} }
else else
{ {
@ -65,7 +80,7 @@ void MainWindow::enumerateDevices()
} }
ui->channelLayout->addStretch(); 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) { for (const auto& widget : channels) {
// Populate gang combo with all other channels // Populate gang combo with all other channels
for (const auto& otherWidget : channels) { for (const auto& otherWidget : channels) {

View file

@ -1,3 +1,5 @@
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
@ -5,6 +7,7 @@
#include <memory> #include <memory>
#include "channelwidget.h" #include "channelwidget.h"
#include "triggerwidget.h"
namespace Ui namespace Ui
{ {
@ -13,19 +16,21 @@ class MainWindow;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
std::vector<std::shared_ptr<ChannelWidget>> channels; std::vector<std::shared_ptr<ChannelWidget>> channels;
Ui::MainWindow *ui; std::vector<std::shared_ptr<TriggerWidget>> triggers;
Ui::MainWindow *ui;
signals: signals:
void channelStateChanged(uint16_t device, uint16_t channel); void channelStateChanged(uint16_t device, uint16_t channel);
public: public:
explicit MainWindow(QWidget *parent = nullptr); explicit MainWindow(QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
private: private:
void enumerateDevices(); void enumerateDevices();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

105
triggerwidget.cpp Normal file
View file

@ -0,0 +1,105 @@
#include "triggerwidget.h"
#include <QDebug>
#include <QMessageBox>
TriggerWidget::TriggerWidget(uint16_t deviceSerial, uint16_t triggerNumber,
std::shared_ptr<struct eismultiplexer> 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);
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)
{
if (checked) {
// Set to input mode
if (eismultiplexer_set_trigger_state(multiplexer.get(), triggerNumber, TRIGGER_INPUT) < 0) {
QMessageBox::warning(this, tr("Trigger Configuration Failed"),
tr("Failed to set trigger %1 on device %2 to input mode").arg(triggerNumber).arg(deviceSerial));
qWarning() << "Failed to set trigger" << triggerNumber << "on device" << deviceSerial << "to input mode";
inputCheckbox.blockSignals(true);
inputCheckbox.setChecked(false);
inputCheckbox.blockSignals(false);
} else {
// When input is checked, level should be unchecked and disabled
levelCheckbox.blockSignals(true);
levelCheckbox.setChecked(false);
levelCheckbox.setEnabled(false);
levelCheckbox.blockSignals(false);
}
} else {
// Update the trigger state based on level checkbox
updateTriggerState();
}
}
void TriggerWidget::onLevelToggled(bool checked)
{
if (!inputCheckbox.isChecked()) {
// Only update if not in input mode
updateTriggerState();
}
}
void TriggerWidget::updateTriggerState()
{
trigger_state_t state = TRIGGER_LOW;
if (!inputCheckbox.isChecked() && levelCheckbox.isChecked()) {
state = TRIGGER_HIGH;
}
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;
}
}

45
triggerwidget.h Normal file
View file

@ -0,0 +1,45 @@
#ifndef TRIGGERWIDGET_H
#define TRIGGERWIDGET_H
#include <QWidget>
#include <QCheckBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <eismultiplexer.h>
#include <memory>
class TriggerWidget : public QWidget
{
Q_OBJECT
public:
explicit TriggerWidget(uint16_t deviceSerial, uint16_t triggerNumber,
std::shared_ptr<struct eismultiplexer> 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<struct eismultiplexer> multiplexer;
QCheckBox inputCheckbox;
QCheckBox levelCheckbox;
QLabel devicelabel;
QLabel triggerlabel;
QFrame line;
QVBoxLayout vlayout;
QHBoxLayout hlayout;
QVBoxLayout labellayout;
};
#endif // TRIGGERWIDGET_H