diff --git a/client/src/proxgui.h b/client/src/proxgui.h index 56d0d9574f..99c69af948 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -44,7 +44,7 @@ void ExitGraphics(void); extern double g_CursorScaleFactor; extern char g_CursorScaleFactorUnit[11]; extern double g_PlotGridX, g_PlotGridY, g_PlotGridXdefault, g_PlotGridYdefault, g_GridOffset; -extern uint32_t g_CursorCPos, g_CursorDPos, g_GraphStart, g_GraphStop; +extern uint32_t g_CursorCPos, g_CursorDPos, g_GraphStart, g_GraphStart_old, g_GraphStop; extern int CommandFinished; extern int offline; extern bool g_GridLocked; diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 1c9a05d117..94a102bf5b 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -49,6 +49,7 @@ static int s_Buff[MAX_GRAPH_TRACE_LEN]; static bool gs_useOverlays = false; static int gs_absVMax = 0; static uint32_t startMax; // Maximum offset in the graph (right side of graph) +static uint32_t startMaxOld; static uint32_t PageWidth; // How many samples are currently visible on this 'page' / graph static int unlockStart = 0; @@ -372,6 +373,18 @@ void ProxWidget::vchange_dthr_down(int v) { RepaintGraphWindow(); } +void ProxWidget::updateNavSlider() { + navSlider->blockSignals(true); + navSlider->setValue(g_GraphStart); + navSlider->setMaximum(startMax); + // for startMaxOld < g_GraphStart or startMax < g_GraphStart_old + navSlider->setValue(g_GraphStart); + navSlider->setMaximum(startMax); + // for click + navSlider->setPageStep(startMax / 10); + navSlider->blockSignals(false); +} + ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { this->master = master; @@ -406,10 +419,20 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { // Set up the plot widget, which does the actual plotting plot = new Plot(this); + navSlider = new QSlider(this); QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(plot); + layout->addWidget(plot, 1); + layout->addWidget(navSlider); setLayout(layout); + navSlider->setOrientation(Qt::Horizontal); + plot->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + navSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QObject::connect(navSlider, SIGNAL(valueChanged(int)), plot, SLOT(MoveTo(int))); + QObject::connect(plot, SIGNAL(startMaxChanged(uint32_t)), this, SLOT(updateNavSlider(void))); + QObject::connect(plot, SIGNAL(graphStartChanged(uint32_t)), this, SLOT(updateNavSlider(void))); + // plot window title QString pt = QString("[*]Plot [ %1 ]").arg(g_conn.serial_port_name); setWindowTitle(pt); @@ -809,6 +832,16 @@ void Plot::paintEvent(QPaintEvent *event) { ); painter.setPen(WHITE); painter.drawText(20, infoRect.bottom() - 3, str); + + if (startMaxOld != startMax) { + emit startMaxChanged(startMax); + } + startMaxOld = startMax; + + if (g_GraphStart != g_GraphStart_old) { + emit graphStartChanged(g_GraphStart); + } + g_GraphStart_old = g_GraphStart; } Plot::Plot(QWidget *parent) : QWidget(parent), g_GraphPixelsPerPoint(1) { @@ -868,6 +901,22 @@ void Plot::Zoom(double factor, uint32_t refX) { } } +void Plot::MoveTo(uint32_t pos) { + if (g_GraphTraceLen == 0) return; + g_GraphStart = pos; + + QObject* signalSender = sender(); + if (signalSender != nullptr && signalSender != this) { + // Update if it's triggered by a signal from other object + this->update(); + } +} + +void Plot::MoveTo(int pos) { + MoveTo((uint32_t)((pos >= 0) ? pos : 0)); + // sender() is still valid in the inner call +} + void Plot::Move(int offset) { if (g_GraphTraceLen == 0) return; if (offset > 0) { // Move right diff --git a/client/src/proxguiqt.h b/client/src/proxguiqt.h index ac19a99c96..8b3891c4a5 100644 --- a/client/src/proxguiqt.h +++ b/client/src/proxguiqt.h @@ -38,6 +38,8 @@ class ProxWidget; * @brief The actual plot, black area were we paint the graph */ class Plot: public QWidget { + Q_OBJECT; //needed for slot/signal classes + private: QWidget *master; double g_GraphPixelsPerPoint; // How many visual pixels are between each sample point (x axis) @@ -55,16 +57,24 @@ class Plot: public QWidget { public: Plot(QWidget *parent = 0); + public slots: + void Zoom(double factor, uint32_t refX); + void MoveTo(uint32_t pos); + void MoveTo(int pos); + void Move(int offset); + protected: void paintEvent(QPaintEvent *event); void closeEvent(QCloseEvent *event); - void Zoom(double factor, uint32_t refX); - void Move(int offset); void Trim(void); void wheelEvent(QWheelEvent *event); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event) { mouseMoveEvent(event); } void keyPressEvent(QKeyEvent *event); + + signals: + void startMaxChanged(uint32_t startMax); + void graphStartChanged(uint32_t graphStart); }; class ProxGuiQT; @@ -97,6 +107,7 @@ class ProxWidget : public QWidget { Plot *plot; Ui::Form *opsController; SliderWidget *controlWidget; + QSlider *navSlider; public: ProxWidget(QWidget *parent = 0, ProxGuiQT *master = NULL); @@ -120,6 +131,7 @@ class ProxWidget : public QWidget { void vchange_askedge(int v); void vchange_dthr_up(int v); void vchange_dthr_down(int v); + void updateNavSlider(void); }; class WorkerThread : public QThread { diff --git a/client/src/ui.c b/client/src/ui.c index 2281497c15..153b26ecd6 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -52,6 +52,7 @@ char g_CursorScaleFactorUnit[11] = {0}; double g_PlotGridX = 0, g_PlotGridY = 0, g_PlotGridXdefault = 64, g_PlotGridYdefault = 64; uint32_t g_CursorCPos = 0, g_CursorDPos = 0, g_GraphStop = 0; uint32_t g_GraphStart = 0; // Starting point/offset for the left side of the graph +uint32_t g_GraphStart_old = 0; double g_GraphPixelsPerPoint = 1.f; // How many visual pixels are between each sample point (x axis) static bool flushAfterWrite = false; double g_GridOffset = 0;