Implemented qt port + e2e

This commit is contained in:
Martino Ferrari
2026-06-26 09:11:10 +02:00
parent 0d7d8f396b
commit 4702d0a217
146 changed files with 57272 additions and 128 deletions
+175
View File
@@ -0,0 +1,175 @@
/**
* @file TriggerBar.cpp
*/
#include "TriggerBar.h"
#include "Hub.h"
#include "Theme.h"
#include <QHBoxLayout>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <QSlider>
#include <QLabel>
#include <QPushButton>
#include <QRadioButton>
#include <QButtonGroup>
#include <cmath>
namespace shq {
/* Window presets (100 us .. 10 s), mirrors the web UI. */
static const double kWinVals[] = {1e-4, 1e-3, 1e-2, 1e-1, 1.0, 10.0};
static const char* kWinLabels[] = {"100 us", "1 ms", "10 ms", "100 ms", "1 s", "10 s"};
static const int kNumWins = 6;
static const char* kEdgeWire[] = {"rising", "falling", "both"};
TriggerBar::TriggerBar(Hub* hub, QWidget* parent)
: QWidget(parent), hub_(hub) {
auto* lay = new QHBoxLayout(this);
lay->setContentsMargins(6, 2, 6, 2);
lay->setSpacing(6);
lay->addWidget(new QLabel("Trig:", this));
sigCombo_ = new QComboBox(this);
sigCombo_->setMinimumWidth(150);
lay->addWidget(sigCombo_);
edgeCombo_ = new QComboBox(this);
edgeCombo_->addItems({"Rising", "Falling", "Both"});
lay->addWidget(edgeCombo_);
lay->addWidget(new QLabel("Thr", this));
thrSpin_ = new QDoubleSpinBox(this);
thrSpin_->setRange(-1e12, 1e12);
thrSpin_->setDecimals(6);
thrSpin_->setMaximumWidth(100);
lay->addWidget(thrSpin_);
lay->addWidget(new QLabel("Win", this));
winCombo_ = new QComboBox(this);
for (int i = 0; i < kNumWins; i++) { winCombo_->addItem(kWinLabels[i]); }
winCombo_->setCurrentIndex(3); /* 100 ms */
lay->addWidget(winCombo_);
lay->addWidget(new QLabel("Pre", this));
preSlider_ = new QSlider(Qt::Horizontal, this);
preSlider_->setRange(0, 100);
preSlider_->setValue(20);
preSlider_->setMaximumWidth(90);
lay->addWidget(preSlider_);
preLbl_ = new QLabel("20%", this);
preLbl_->setMinimumWidth(34);
lay->addWidget(preLbl_);
normRadio_ = new QRadioButton("Norm", this);
singleRadio_ = new QRadioButton("1x", this);
normRadio_->setChecked(true);
auto* grp = new QButtonGroup(this);
grp->addButton(normRadio_);
grp->addButton(singleRadio_);
lay->addWidget(normRadio_);
lay->addWidget(singleRadio_);
badge_ = new QLabel("[IDLE]", this);
badge_->setMinimumWidth(90);
lay->addWidget(badge_);
armBtn_ = new QPushButton("Arm", this);
disarmBtn_ = new QPushButton("Disarm", this);
stopBtn_ = new QPushButton("Stop", this);
lay->addWidget(armBtn_);
lay->addWidget(disarmBtn_);
lay->addWidget(stopBtn_);
trigTimeLbl_ = new QLabel("", this);
trigTimeLbl_->setStyleSheet("color:#a6adc8;");
lay->addWidget(trigTimeLbl_);
lay->addStretch(1);
/* ── Wiring ── */
auto cfg = [this]() { if (!updating_) { pullFromUi(); sendConfig(); } };
connect(sigCombo_, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [cfg](int){ cfg(); });
connect(edgeCombo_, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [cfg](int){ cfg(); });
connect(thrSpin_, &QDoubleSpinBox::editingFinished, this, cfg);
connect(winCombo_, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [cfg](int){ cfg(); });
connect(preSlider_, &QSlider::valueChanged, this, [this](int v) {
preLbl_->setText(QString("%1%").arg(v));
});
connect(preSlider_, &QSlider::sliderReleased, this, cfg);
connect(normRadio_, &QRadioButton::toggled, this, [cfg](bool){ cfg(); });
connect(armBtn_, &QPushButton::clicked, this, [this]() {
pullFromUi(); sendConfig(); hub_->sendArm();
});
connect(disarmBtn_, &QPushButton::clicked, this, [this]() {
hub_->sendDisarm();
});
connect(stopBtn_, &QPushButton::clicked, this, [this]() {
auto& t = hub_->trigger();
t.stopped = !t.stopped;
hub_->sendTrigStop(t.stopped);
});
refreshSignals();
onTriggerStateChanged();
}
void TriggerBar::pullFromUi() {
auto& t = hub_->trigger();
t.signalKey = sigCombo_->currentData().toString().toStdString();
t.edge = edgeCombo_->currentIndex();
t.threshold = thrSpin_->value();
t.windowSec = kWinVals[winCombo_->currentIndex()];
t.prePercent = preSlider_->value();
t.single = singleRadio_->isChecked();
}
void TriggerBar::sendConfig() {
auto& t = hub_->trigger();
if (t.signalKey.empty()) { return; }
hub_->sendSetTrigger(t.signalKey, kEdgeWire[t.edge], t.threshold,
t.windowSec, t.prePercent,
t.single ? "single" : "normal");
}
void TriggerBar::refreshSignals() {
updating_ = true;
QString prev = sigCombo_->currentData().toString();
sigCombo_->clear();
for (const auto& src : hub_->sources()) {
for (const auto& sig : src.signals) {
QString key = QString::fromStdString(src.id + ":" + sig.meta.name);
sigCombo_->addItem(key, key);
}
}
int idx = sigCombo_->findData(prev);
if (idx >= 0) { sigCombo_->setCurrentIndex(idx); }
updating_ = false;
}
void TriggerBar::onTriggerStateChanged() {
const auto& t = hub_->trigger();
QString badge; QColor c;
if (t.status == "armed") { badge = "[ARMED]"; c = col::yellow(); }
else if (t.status == "collecting") { badge = "[COLLECTING]"; c = col::blue(); }
else if (t.status == "triggered") { badge = "[TRIGGERED]"; c = col::green(); }
else { badge = "[IDLE]"; c = col::overlay0(); }
badge_->setText(badge);
badge_->setStyleSheet(QString("color:%1; font-weight:bold;").arg(c.name()));
stopBtn_->setVisible(!t.single);
stopBtn_->setText(t.stopped ? "Run" : "Stop");
if (t.hasTrigTime && (t.status == "collecting" || t.status == "triggered")) {
trigTimeLbl_->setText(QString("t=%1").arg(t.trigTime, 0, 'f', 6));
} else {
trigTimeLbl_->clear();
}
}
} /* namespace shq */