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
+138
View File
@@ -0,0 +1,138 @@
/**
* @file PlotGrid.cpp
*/
#include "PlotGrid.h"
#include "PlotWidget.h"
#include "Hub.h"
#include <QVBoxLayout>
#include <QSplitter>
#include <QDateTime>
namespace shq {
static double nowSec() {
return QDateTime::currentMSecsSinceEpoch() / 1000.0;
}
PlotGrid::PlotGrid(Hub* hub, GlobalView* gv, QWidget* parent)
: QWidget(parent), hub_(hub), gv_(gv) {
/* Persistent pool: one PlotWidget per slot, fixed plotIdx (== zoom cache
* index). Plots beyond the current layout are simply not mounted. */
pool_.reserve(kMaxPlotSlots);
for (int i = 0; i < kMaxPlotSlots; i++) {
auto* p = new PlotWidget(hub_, gv_, i, this);
connect(hub_, &Hub::zoomReceived, p, &PlotWidget::onZoomReceived);
connect(hub_, &Hub::historyZoomReceived, p, &PlotWidget::onHistoryZoomReceived);
connect(hub_, &Hub::captureReceived, p, &PlotWidget::onCaptureReceived);
p->setParent(nullptr);
p->hide();
pool_.push_back(p);
}
auto* lay = new QVBoxLayout(this);
lay->setContentsMargins(0, 0, 0, 0);
rebuild();
}
void PlotGrid::setLayout(PlotLayout l) {
if (l == layout_) { return; }
layout_ = l;
rebuild();
}
void PlotGrid::rebuild() {
/* Detach every pooled plot from any previous splitter. */
for (auto* p : pool_) { p->setParent(this); p->hide(); }
/* Drop the old root splitter (if any). */
QLayout* lay = this->QWidget::layout();
QLayoutItem* item;
while ((item = lay->takeAt(0)) != nullptr) {
if (QWidget* w = item->widget()) {
if (qobject_cast<QSplitter*>(w)) { w->deleteLater(); }
}
delete item;
}
int cols, rows;
layoutDims(layout_, cols, rows);
auto* outer = new QSplitter(Qt::Vertical, this);
outer->setChildrenCollapsible(false);
outer->setHandleWidth(5);
plots_.clear();
for (int r = 0; r < rows; r++) {
QSplitter* rowSplit = outer;
if (cols > 1) {
rowSplit = new QSplitter(Qt::Horizontal, outer);
rowSplit->setChildrenCollapsible(false);
rowSplit->setHandleWidth(5);
}
for (int c = 0; c < cols; c++) {
int idx = r * cols + c;
PlotWidget* p = pool_[idx];
p->setParent(rowSplit);
p->show();
if (cols > 1) { rowSplit->addWidget(p); }
else { outer->addWidget(p); }
plots_.push_back(p);
}
if (cols > 1) { outer->addWidget(rowSplit); }
}
lay->addWidget(outer);
onModelChanged();
}
void PlotGrid::onModelChanged() { for (auto* p : plots_) { p->onModelChanged(); } }
void PlotGrid::onPauseChanged() { for (auto* p : plots_) { p->onPauseChanged(); } }
void PlotGrid::tick() { for (auto* p : plots_) { p->tick(); } }
void PlotGrid::goLive() {
for (auto* p : plots_) { p->setLive(true); }
}
void PlotGrid::setAllStoredX(double t0, double t1) {
if (t1 <= t0) { return; }
for (auto* p : plots_) { p->setLive(false); p->setStoredX(t0, t1); }
}
bool PlotGrid::anyNonLive() const {
for (auto* p : plots_) { if (!p->isLive()) { return true; } }
return false;
}
bool PlotGrid::currentRange(double& t0, double& t1) const {
for (auto* p : plots_) {
if (!p->isLive()) { t0 = p->xMin(); t1 = p->xMax(); return true; }
}
return false;
}
void PlotGrid::panAll(double frac) {
const double wallNow = nowSec();
for (auto* p : plots_) {
if (p->isLive()) { continue; }
double span = p->xMax() - p->xMin();
if (span <= 0.0) { continue; }
double d = span * frac;
double mn = p->xMin() + d, mx = p->xMax() + d;
if (mx > wallNow) { mx = wallNow; mn = mx - span; }
p->setStoredX(mn, mx);
}
}
void PlotGrid::jumpAllAgo(double secAgo) {
const double wallNow = nowSec();
for (auto* p : plots_) {
double span = p->xMax() - p->xMin();
if (span <= 0.0) { span = gv_->windowSec; }
p->setLive(false);
p->setStoredX(wallNow - secAgo - span, wallNow - secAgo);
}
}
} /* namespace shq */