# HG changeset patch # User Hasan Yavuz Ă–ZDERYA # Date 2017-08-27 13:37:16 # Node ID 87e2b55fa199baa79322efa0ec5f3b0241f4d5f8 # Parent 7d24a4ccef20d1756bbe2437fe4ee47675be49a8 # Parent c6e0a9f56224ff131b97d21cc7abb70cf883856d Merge with scrollbar-exp diff --git a/src/framebufferseries.cpp b/src/framebufferseries.cpp --- a/src/framebufferseries.cpp +++ b/src/framebufferseries.cpp @@ -27,7 +27,7 @@ FrameBufferSeries::FrameBufferSeries(Fra _xmax = 1; _buffer = buffer; int_index_start = 0; - int_index_end = 0; + int_index_end = _buffer->size(); } void FrameBufferSeries::setXAxis(bool asIndex, double xmin, double xmax) @@ -85,6 +85,6 @@ void FrameBufferSeries::setRectOfInteres int_index_end = ceil(bsize * (rect.right()-_xmin) / xsize)+1; } - int_index_start = std::max(int_index_start, (size_t) 0); - int_index_end = std::min(_buffer->size(), int_index_end); + int_index_start = std::max(int_index_start, 0); + int_index_end = std::min((int) _buffer->size(), int_index_end); } diff --git a/src/framebufferseries.h b/src/framebufferseries.h --- a/src/framebufferseries.h +++ b/src/framebufferseries.h @@ -52,8 +52,8 @@ private: double _xmin; double _xmax; - size_t int_index_start; ///< starting index of "rectangle of interest" - size_t int_index_end; ///< ending index of "rectangle of interest" + int int_index_start; ///< starting index of "rectangle of interest" + int int_index_end; ///< ending index of "rectangle of interest" }; #endif // FRAMEBUFFERSERIES_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -151,6 +151,9 @@ MainWindow::MainWindow(QWidget *parent) connect(&plotControlPanel, &PlotControlPanel::xScaleChanged, plotMan, &PlotManager::setXAxis); + connect(&plotControlPanel, &PlotControlPanel::plotWidthChanged, + plotMan, &PlotManager::setPlotWidth); + QObject::connect(ui->actionClear, SIGNAL(triggered(bool)), this, SLOT(clearPlot())); @@ -226,6 +229,7 @@ MainWindow::MainWindow(QWidget *parent) plotMan->setXAxis(plotControlPanel.xAxisAsIndex(), plotControlPanel.xMin(), plotControlPanel.xMax()); plotMan->setNumOfSamples(numOfSamples); + plotMan->setPlotWidth(plotControlPanel.plotWidth()); // Init sps (sample per second) counter spsLabel.setText("0sps"); diff --git a/src/plot.cpp b/src/plot.cpp --- a/src/plot.cpp +++ b/src/plot.cpp @@ -39,6 +39,7 @@ Plot::Plot(QWidget* parent) : isAutoScaled = true; symbolSize = 0; numOfSamples = 1; + plotWidth = 1; showSymbols = Plot::ShowSymbolsAuto; QObject::connect(&zoomer, &Zoomer::unzoomed, this, &Plot::unzoomed); @@ -109,17 +110,18 @@ void Plot::setXAxis(double xMin, double _xMin = xMin; _xMax = xMax; + zoomer.setXLimits(xMin, xMax); zoomer.zoom(0); // unzoom // set axis - setAxisScale(QwtPlot::xBottom, xMin, xMax); + // setAxisScale(QwtPlot::xBottom, xMin, xMax); replot(); // Note: if we don't replot here scale at startup isn't set correctly // reset zoom base - auto base = zoomer.zoomBase(); - base.setLeft(xMin); - base.setRight(xMax); - zoomer.setZoomBase(base); + // auto base = zoomer.zoomBase(); + // base.setLeft(xMin); + // base.setRight(xMax); + // zoomer.setZoomBase(base); onXScaleChanged(); } @@ -301,7 +303,8 @@ void Plot::calcSymbolSize() auto scaleDist = sw->scaleDraw()->scaleMap().sDist(); auto fullScaleDist = zoomer.zoomBase().width(); auto zoomRate = fullScaleDist / scaleDist; - float samplesInView = numOfSamples / zoomRate; + float plotWidthNumSamp = abs(numOfSamples * plotWidth / (_xMax - _xMin)); + float samplesInView = plotWidthNumSamp / zoomRate; int symDisPx = round(paintDist / samplesInView); if (symDisPx < SYMBOL_SHOW_AT_WIDTH) @@ -347,3 +350,9 @@ void Plot::setNumOfSamples(unsigned valu numOfSamples = value; onXScaleChanged(); } + +void Plot::setPlotWidth(double width) +{ + plotWidth = width; + zoomer.setHViewSize(width); +} diff --git a/src/plot.h b/src/plot.h --- a/src/plot.h +++ b/src/plot.h @@ -73,6 +73,8 @@ public slots: void setNumOfSamples(unsigned value); + void setPlotWidth(double width); + protected: /// update the display of symbols depending on `symbolSize` void updateSymbols(); @@ -82,6 +84,7 @@ private: double yMin, yMax; double _xMin, _xMax; unsigned numOfSamples; + double plotWidth; int symbolSize; Zoomer zoomer; ScaleZoomer sZoomer; diff --git a/src/plotcontrolpanel.cpp b/src/plotcontrolpanel.cpp --- a/src/plotcontrolpanel.cpp +++ b/src/plotcontrolpanel.cpp @@ -29,7 +29,7 @@ #include "setting_defines.h" /// Confirm if #samples is being set to a value greater than this -const int NUMSAMPLES_CONFIRM_AT = 10000; +const int NUMSAMPLES_CONFIRM_AT = 1000000; /// Used for scale range selection combobox struct Range @@ -89,6 +89,9 @@ PlotControlPanel::PlotControlPanel(QWidg connect(ui->spXmin, SIGNAL(valueChanged(double)), this, SLOT(onXScaleChanged())); + connect(ui->spPlotWidth, SIGNAL(valueChanged(int)), + this, SLOT(onPlotWidthChanged())); + // init scale range preset list for (int nbits = 8; nbits <= 24; nbits++) // signed binary formats { @@ -275,6 +278,7 @@ void PlotControlPanel::onIndexChecked(bo emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value()); } + emit plotWidthChanged(plotWidth()); } void PlotControlPanel::onXScaleChanged() @@ -282,9 +286,29 @@ void PlotControlPanel::onXScaleChanged() if (!xAxisAsIndex()) { emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value()); + emit plotWidthChanged(plotWidth()); } } +double PlotControlPanel::plotWidth() const +{ + double value = ui->spPlotWidth->value(); + if (!xAxisAsIndex()) + { + // scale by xmin and xmax + auto xmax = ui->spXmax->value(); + auto xmin = ui->spXmin->value(); + double scale = (xmax - xmin) / _numOfSamples; + value *= scale; + } + return value; +} + +void PlotControlPanel::onPlotWidthChanged() +{ + emit plotWidthChanged(plotWidth()); +} + void PlotControlPanel::setChannelInfoModel(ChannelInfoModel* model) { ui->tvChannelInfo->setModel(model); @@ -362,6 +386,7 @@ void PlotControlPanel::saveSettings(QSet { settings->beginGroup(SettingGroup_Plot); settings->setValue(SG_Plot_NumOfSamples, numOfSamples()); + settings->setValue(SG_Plot_PlotWidth, ui->spPlotWidth->value()); settings->setValue(SG_Plot_IndexAsX, xAxisAsIndex()); settings->setValue(SG_Plot_XMax, xMax()); settings->setValue(SG_Plot_XMin, xMin()); @@ -376,6 +401,8 @@ void PlotControlPanel::loadSettings(QSet settings->beginGroup(SettingGroup_Plot); ui->spNumOfSamples->setValue( settings->value(SG_Plot_NumOfSamples, numOfSamples()).toInt()); + ui->spPlotWidth->setValue( + settings->value(SG_Plot_PlotWidth, ui->spPlotWidth->value()).toInt()); ui->cbIndex->setChecked( settings->value(SG_Plot_IndexAsX, xAxisAsIndex()).toBool()); ui->spXmax->setValue(settings->value(SG_Plot_XMax, xMax()).toDouble()); diff --git a/src/plotcontrolpanel.h b/src/plotcontrolpanel.h --- a/src/plotcontrolpanel.h +++ b/src/plotcontrolpanel.h @@ -46,6 +46,8 @@ public: bool xAxisAsIndex() const; double xMax() const; double xMin() const; + /// Returns the plot width adjusted for x axis scaling. + double plotWidth() const; void setChannelInfoModel(ChannelInfoModel* model); @@ -58,6 +60,7 @@ signals: void numOfSamplesChanged(int value); void yScaleChanged(bool autoScaled, double yMin = 0, double yMax = 1); void xScaleChanged(bool asIndex, double xMin = 0, double xMax = 1); + void plotWidthChanged(double width); private: Ui::PlotControlPanel *ui; @@ -80,6 +83,7 @@ private slots: void onRangeSelected(); void onIndexChecked(bool checked); void onXScaleChanged(); + void onPlotWidthChanged(); }; #endif // PLOTCONTROLPANEL_H diff --git a/src/plotcontrolpanel.ui b/src/plotcontrolpanel.ui --- a/src/plotcontrolpanel.ui +++ b/src/plotcontrolpanel.ui @@ -7,7 +7,7 @@ 0 0 706 - 187 + 195 @@ -132,15 +132,30 @@ + + + - Number Of Samples: + Buffer Size: + + + 100 + 0 + + + + + 100 + 16777215 + + - length of X axis + Length of acquisition as number of samples false @@ -149,14 +164,14 @@ 2 - 1000000 + 10000000 1000 - + Index as X AXis @@ -166,7 +181,7 @@ - + @@ -237,7 +252,7 @@ - + Auto Scale Y Axis @@ -247,7 +262,7 @@ - + @@ -318,16 +333,57 @@ - + Select Range Preset: - + + + + + + + + Plot Width: + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Width of X axis as maximum number of samples that are shown in plot + + + false + + + 2 + + + 100000 + + + 1000 + + + diff --git a/src/plotmanager.cpp b/src/plotmanager.cpp --- a/src/plotmanager.cpp +++ b/src/plotmanager.cpp @@ -46,6 +46,7 @@ PlotManager::PlotManager(QWidget* plotAr isDemoShown = false; _infoModel = infoModel; _numOfSamples = 1; + _plotWidth = 1; showSymbols = Plot::ShowSymbolsAuto; emptyPlot = NULL; @@ -316,6 +317,7 @@ Plot* PlotManager::addPlotWidget() plot->setNumOfSamples(_numOfSamples); plot->setSymbols(showSymbols); + plot->setPlotWidth(_plotWidth); if (_xAxisAsIndex) { plot->setXAxis(0, _numOfSamples); @@ -542,6 +544,15 @@ void PlotManager::setNumOfSamples(unsign } } +void PlotManager::setPlotWidth(double width) +{ + _plotWidth = width; + for (auto plot : plotWidgets) + { + plot->setPlotWidth(width); + } +} + PlotViewSettings PlotManager::viewSettings() const { return PlotViewSettings( diff --git a/src/plotmanager.h b/src/plotmanager.h --- a/src/plotmanager.h +++ b/src/plotmanager.h @@ -88,6 +88,8 @@ public slots: void flashSnapshotOverlay(); /// Should be called to update zoom base void setNumOfSamples(unsigned value); + /// Maximum width of X axis (limit of hscroll) + void setPlotWidth(double width); private: bool isMulti; @@ -106,6 +108,7 @@ private: double _xMin; double _xMax; unsigned _numOfSamples; + double _plotWidth; Plot::ShowSymbols showSymbols; // menu actions diff --git a/src/scrollzoomer.cpp b/src/scrollzoomer.cpp --- a/src/scrollzoomer.cpp +++ b/src/scrollzoomer.cpp @@ -42,6 +42,10 @@ ScrollZoomer::ScrollZoomer( QWidget *can d_vScrollData( NULL ), d_inZoom( false ) { + xMin = 0.; + xMax = 10000.; + hViewSize = 10000; + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) d_alignCanvasToScales[ axis ] = false; @@ -50,6 +54,8 @@ ScrollZoomer::ScrollZoomer( QWidget *can d_hScrollData = new ScrollData; d_vScrollData = new ScrollData; + hscrollmove = false; + vscrollmove = false; } ScrollZoomer::~ScrollZoomer() @@ -59,6 +65,37 @@ ScrollZoomer::~ScrollZoomer() delete d_hScrollData; } +void ScrollZoomer::setXLimits(double min, double max) +{ + xMin = min; + xMax = max; + setZoomBase(); +} + +void ScrollZoomer::setHViewSize(double size) +{ + hViewSize = size; + setZoomBase(); +} + +void ScrollZoomer::setZoomBase(bool doReplot) +{ + QwtPlotZoomer::setZoomBase(doReplot); + auto zb = zoomBase(); + auto zs = zoomStack(); + zb.setRight(xMax); + if ((xMax - xMin) < hViewSize) + { + zb.setLeft(xMin); + } + else + { + zb.setLeft(xMax-hViewSize); + } + zs[0] = zb; + setZoomStack(zs); +} + void ScrollZoomer::rescale() { QwtScaleWidget *xScale = plot()->axisWidget( xAxis() ); @@ -112,7 +149,45 @@ void ScrollZoomer::rescale() } } - QwtPlotZoomer::rescale(); + // NOTE: Below snippet is copied from QwtPlotZoomer::rescale() just so that + // we can refrain from updating y axis when moving horizontal scrollbar, so + // that auto-scale isn't disrupted. Also we don't want to jump around in + // x-axis when moving vertical scroll. + { + QwtPlot *plt = plot(); + if ( !plt ) + return; + + const QRectF &rect = zoomStack()[zoomRectIndex()]; + if ( rect != scaleRect() ) + { + const bool doReplot = plt->autoReplot(); + plt->setAutoReplot( false ); + + if (!vscrollmove) + { + double x1 = rect.left(); + double x2 = rect.right(); + if ( !plt->axisScaleDiv( xAxis() ).isIncreasing() ) + qSwap( x1, x2 ); + + plt->setAxisScale( xAxis(), x1, x2 ); + } + + if (!hscrollmove) + { + double y1 = rect.top(); + double y2 = rect.bottom(); + if ( !plt->axisScaleDiv( yAxis() ).isIncreasing() ) + qSwap( y1, y2 ); + + plt->setAxisScale( yAxis(), y1, y2 ); + + plt->setAutoReplot( doReplot ); + } + plt->replot(); + } + } updateScrollBars(); } @@ -237,6 +312,11 @@ bool ScrollZoomer::eventFilter( QObject layoutScrollBars( rect ); break; } + case QEvent::Show: + { + layoutScrollBars( canvas()->contentsRect() ); + break; + } case QEvent::ChildRemoved: { const QObject *child = @@ -265,8 +345,8 @@ bool ScrollZoomer::needScrollBar( Qt::Or if ( orientation == Qt::Horizontal ) { mode = d_hScrollData->mode; - baseMin = zoomBase().left(); - baseMax = zoomBase().right(); + baseMin = xMin; + baseMax = xMax; zoomMin = zoomRect().left(); zoomMax = zoomRect().right(); } @@ -323,7 +403,7 @@ void ScrollZoomer::updateScrollBars() ScrollBar *sb = scrollBar( Qt::Horizontal ); sb->setPalette( plot()->palette() ); sb->setInverted( !plot()->axisScaleDiv( xAxis ).isIncreasing() ); - sb->setBase( zoomBase().left(), zoomBase().right() ); + sb->setBase( xMin, xMax ); sb->moveSlider( zoomRect().left(), zoomRect().right() ); if ( !sb->isVisibleTo( canvas() ) ) @@ -462,9 +542,17 @@ void ScrollZoomer::scrollBarMoved( Q_UNUSED( max ); if ( o == Qt::Horizontal ) + { + hscrollmove = true; moveTo( QPointF( min, zoomRect().top() ) ); + hscrollmove = false; + } else + { + vscrollmove = true; moveTo( QPointF( zoomRect().left(), min ) ); + vscrollmove = false; + } Q_EMIT zoomed( zoomRect() ); } @@ -487,3 +575,30 @@ int ScrollZoomer::oppositeAxis( int axis return axis; } + +void ScrollZoomer::moveTo( const QPointF &pos ) +{ + // QwtPlotZoomer::moveTo(pos); + // return; + + double x = pos.x(); + double y = pos.y(); + + if ( x < xMin ) + x = xMin; + if ( x > xMax - zoomRect().width() ) + x = xMax - zoomRect().width(); + + if ( y < zoomBase().top() ) + y = zoomBase().top(); + if ( y > zoomBase().bottom() - zoomRect().height() ) + y = zoomBase().bottom() - zoomRect().height(); + + if ( x != zoomRect().left() || y != zoomRect().top() ) + { + auto zs = zoomStack(); + zs[zoomRectIndex()].moveTo( x, y ); + setZoomStack(zs, zoomRectIndex()); + rescale(); + } +} diff --git a/src/scrollzoomer.h b/src/scrollzoomer.h --- a/src/scrollzoomer.h +++ b/src/scrollzoomer.h @@ -50,8 +50,14 @@ public: virtual bool eventFilter( QObject *, QEvent * ); + void setXLimits(double min, double max); + void setHViewSize(double size); + virtual void setZoomBase(bool doReplot = true); virtual void rescale(); +public Q_SLOTS: + virtual void moveTo( const QPointF & ); + protected: virtual ScrollBar *scrollBar( Qt::Orientation ); virtual void updateScrollBars(); @@ -61,6 +67,10 @@ private Q_SLOTS: void scrollBarMoved( Qt::Orientation o, double min, double max ); private: + QRectF d_limits; + double xMin, xMax; + double hViewSize; + bool needScrollBar( Qt::Orientation ) const; int oppositeAxis( int ) const; @@ -71,6 +81,8 @@ private: bool d_inZoom; bool d_alignCanvasToScales[ QwtPlot::axisCnt ]; + bool hscrollmove; + bool vscrollmove; }; #endif diff --git a/src/setting_defines.h b/src/setting_defines.h --- a/src/setting_defines.h +++ b/src/setting_defines.h @@ -79,6 +79,7 @@ const char SG_Channels_Visible[] = "visi // plot settings keys const char SG_Plot_NumOfSamples[] = "numOfSamples"; +const char SG_Plot_PlotWidth[] = "plotWidth"; const char SG_Plot_IndexAsX[] = "indexAsX"; const char SG_Plot_XMax[] = "xMax"; const char SG_Plot_XMin[] = "xMin";