c422c8f525d72d057d38fc1fbff955ae6f34c151
[debian/gnuradio] / gr-qtgui / src / lib / ConstellationDisplayPlot.cc
1 #ifndef CONSTELLATION_DISPLAY_PLOT_C
2 #define CONSTELLATION_DISPLAY_PLOT_C
3
4 #include <ConstellationDisplayPlot.h>
5
6 #include <qwt_scale_draw.h>
7 #include <qwt_legend.h>
8
9
10 class ConstellationDisplayZoomer: public QwtPlotZoomer
11 {
12 public:
13   ConstellationDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas)
14   {
15     setTrackerMode(QwtPicker::AlwaysOn);
16   }
17
18   virtual ~ConstellationDisplayZoomer(){
19
20   }
21   
22   virtual void updateTrackerText(){
23     updateDisplay();
24   }
25
26 protected:
27   virtual QwtText trackerText( const QwtDoublePoint& p ) const 
28   {
29     QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4));
30
31     return t;
32   }
33 };
34
35 ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent):QwtPlot(parent){
36   timespec_reset(&_lastReplot);
37
38   resize(parent->width(), parent->height());
39
40   _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
41
42   _numPoints = 1024;
43   _realDataPoints = new double[_numPoints];
44   _imagDataPoints = new double[_numPoints];
45
46   // Disable polygon clipping
47   QwtPainter::setDeviceClipping(false);
48   
49   // We don't need the cache here
50   canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
51   canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
52
53   QPalette palette;
54   palette.setColor(canvas()->backgroundRole(), QColor("white"));
55   canvas()->setPalette(palette);  
56
57   setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
58   setAxisScale(QwtPlot::xBottom, -1.0, 1.0);
59   setAxisTitle(QwtPlot::xBottom, "In-phase");
60
61   setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
62   setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
63   setAxisTitle(QwtPlot::yLeft, "Quadrature");
64
65   // Automatically deleted when parent is deleted
66   _plot_curve = new QwtPlotCurve("Constellation Points");
67   _plot_curve->attach(this);
68   _plot_curve->setPen(QPen(Qt::blue, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
69   _plot_curve->setStyle(QwtPlotCurve::Dots);
70   _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
71
72   memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
73   memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
74
75   replot();
76
77   _zoomer = new ConstellationDisplayZoomer(canvas());
78 #if QT_VERSION < 0x040000
79   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
80                           Qt::RightButton, Qt::ControlModifier);
81 #else
82   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
83                           Qt::RightButton, Qt::ControlModifier);
84 #endif
85   _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
86                           Qt::RightButton);
87
88   _panner = new QwtPlotPanner(canvas());
89   _panner->setAxisEnabled(QwtPlot::yRight, false);
90   _panner->setMouseButton(Qt::MidButton);
91
92   // Avoid jumping when labels with more/less digits
93   // appear/disappear when scrolling vertically
94
95   const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
96   QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
97   sd->setMinimumExtent( fm.width("100.00") );
98
99   const QColor c(Qt::darkRed);
100   _zoomer->setRubberBandPen(c);
101   _zoomer->setTrackerPen(c);
102
103   QwtLegend* legendDisplay = new QwtLegend(this);
104   legendDisplay->setItemMode(QwtLegend::CheckableItem);
105   insertLegend(legendDisplay);
106
107   connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
108 }
109
110 ConstellationDisplayPlot::~ConstellationDisplayPlot(){
111   delete[] _realDataPoints;
112   delete[] _imagDataPoints;
113
114   // _fft_plot_curves deleted when parent deleted
115   // _zoomer and _panner deleted when parent deleted
116 }
117
118
119
120 void ConstellationDisplayPlot::replot(){
121
122   const timespec startTime = get_highres_clock();
123   
124   QwtPlot::replot();
125
126   double differenceTime = (diff_timespec(get_highres_clock(), startTime));
127
128   differenceTime *= 99.0;
129   // Require at least a 10% duty cycle
130   if(differenceTime > (1.0/10.0)){
131     _displayIntervalTime = differenceTime;
132   }
133 }
134
135 void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
136   if(numDataPoints > 0){
137
138     if(numDataPoints != _numPoints){
139       _numPoints = numDataPoints;
140
141       delete[] _realDataPoints;
142       delete[] _imagDataPoints;
143       _realDataPoints = new double[_numPoints];
144       _imagDataPoints = new double[_numPoints];
145       
146       _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
147     }
148     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
149     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
150
151   }
152
153   // Allow at least a 50% duty cycle
154   if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
155     // Only replot the screen if it is visible
156     if(isVisible()){
157       replot();
158     }
159     _lastReplot = get_highres_clock();
160   }
161 }
162
163 void ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
164   plotItem->setVisible(!on);
165 }
166
167 #endif /* CONSTELLATION_DISPLAY_PLOT_C */