summaryrefslogtreecommitdiff
path: root/gr-qtgui/src/lib/ConstellationDisplayPlot.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-qtgui/src/lib/ConstellationDisplayPlot.cc')
-rw-r--r--gr-qtgui/src/lib/ConstellationDisplayPlot.cc167
1 files changed, 167 insertions, 0 deletions
diff --git a/gr-qtgui/src/lib/ConstellationDisplayPlot.cc b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc
new file mode 100644
index 000000000..c422c8f52
--- /dev/null
+++ b/gr-qtgui/src/lib/ConstellationDisplayPlot.cc
@@ -0,0 +1,167 @@
+#ifndef CONSTELLATION_DISPLAY_PLOT_C
+#define CONSTELLATION_DISPLAY_PLOT_C
+
+#include <ConstellationDisplayPlot.h>
+
+#include <qwt_scale_draw.h>
+#include <qwt_legend.h>
+
+
+class ConstellationDisplayZoomer: public QwtPlotZoomer
+{
+public:
+ ConstellationDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas)
+ {
+ setTrackerMode(QwtPicker::AlwaysOn);
+ }
+
+ virtual ~ConstellationDisplayZoomer(){
+
+ }
+
+ virtual void updateTrackerText(){
+ updateDisplay();
+ }
+
+protected:
+ virtual QwtText trackerText( const QwtDoublePoint& p ) const
+ {
+ QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4));
+
+ return t;
+ }
+};
+
+ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(parent){
+ timespec_reset(&_lastReplot);
+
+ resize(parent->width(), parent->height());
+
+ _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
+
+ _numPoints = 1024;
+ _realDataPoints = new double[_numPoints];
+ _imagDataPoints = new double[_numPoints];
+
+ // Disable polygon clipping
+ QwtPainter::setDeviceClipping(false);
+
+ // We don't need the cache here
+ canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
+ canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
+
+ QPalette palette;
+ palette.setColor(canvas()->backgroundRole(), QColor("white"));
+ canvas()->setPalette(palette);
+
+ setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
+ setAxisScale(QwtPlot::xBottom, -1.0, 1.0);
+ setAxisTitle(QwtPlot::xBottom, "In-phase");
+
+ setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
+ setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
+ setAxisTitle(QwtPlot::yLeft, "Quadrature");
+
+ // Automatically deleted when parent is deleted
+ _plot_curve = new QwtPlotCurve("Constellation Points");
+ _plot_curve->attach(this);
+ _plot_curve->setPen(QPen(Qt::blue, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+ _plot_curve->setStyle(QwtPlotCurve::Dots);
+ _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
+
+ memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
+ memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
+
+ replot();
+
+ _zoomer = new ConstellationDisplayZoomer(canvas());
+#if QT_VERSION < 0x040000
+ _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
+ Qt::RightButton, Qt::ControlModifier);
+#else
+ _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
+ Qt::RightButton, Qt::ControlModifier);
+#endif
+ _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
+ Qt::RightButton);
+
+ _panner = new QwtPlotPanner(canvas());
+ _panner->setAxisEnabled(QwtPlot::yRight, false);
+ _panner->setMouseButton(Qt::MidButton);
+
+ // Avoid jumping when labels with more/less digits
+ // appear/disappear when scrolling vertically
+
+ const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
+ QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
+ sd->setMinimumExtent( fm.width("100.00") );
+
+ const QColor c(Qt::darkRed);
+ _zoomer->setRubberBandPen(c);
+ _zoomer->setTrackerPen(c);
+
+ QwtLegend* legendDisplay = new QwtLegend(this);
+ legendDisplay->setItemMode(QwtLegend::CheckableItem);
+ insertLegend(legendDisplay);
+
+ connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
+}
+
+ConstellationDisplayPlot::~ConstellationDisplayPlot(){
+ delete[] _realDataPoints;
+ delete[] _imagDataPoints;
+
+ // _fft_plot_curves deleted when parent deleted
+ // _zoomer and _panner deleted when parent deleted
+}
+
+
+
+void ConstellationDisplayPlot::replot(){
+
+ const timespec startTime = get_highres_clock();
+
+ QwtPlot::replot();
+
+ double differenceTime = (diff_timespec(get_highres_clock(), startTime));
+
+ differenceTime *= 99.0;
+ // Require at least a 10% duty cycle
+ if(differenceTime > (1.0/10.0)){
+ _displayIntervalTime = differenceTime;
+ }
+}
+
+void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
+ if(numDataPoints > 0){
+
+ if(numDataPoints != _numPoints){
+ _numPoints = numDataPoints;
+
+ delete[] _realDataPoints;
+ delete[] _imagDataPoints;
+ _realDataPoints = new double[_numPoints];
+ _imagDataPoints = new double[_numPoints];
+
+ _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
+ }
+ memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
+ memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
+
+ }
+
+ // Allow at least a 50% duty cycle
+ if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
+ // Only replot the screen if it is visible
+ if(isVisible()){
+ replot();
+ }
+ _lastReplot = get_highres_clock();
+ }
+}
+
+void ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
+ plotItem->setVisible(!on);
+}
+
+#endif /* CONSTELLATION_DISPLAY_PLOT_C */