80bf4503f50fb3edb6ca17a06d01c931cf8b1201
[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)
36   : QwtPlot(parent)
37 {
38   timespec_reset(&_lastReplot);
39
40   resize(parent->width(), parent->height());
41
42   _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
43
44   _numPoints = 1024;
45   _penSize = 5;
46   _realDataPoints = new double[_numPoints];
47   _imagDataPoints = new double[_numPoints];
48
49   // Disable polygon clipping
50   QwtPainter::setDeviceClipping(false);
51   
52   // We don't need the cache here
53   canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
54   canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
55
56   QPalette palette;
57   palette.setColor(canvas()->backgroundRole(), QColor("white"));
58   canvas()->setPalette(palette);  
59
60   setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
61   //setAxisScale(QwtPlot::xBottom, -1.0, 1.0);
62   set_xaxis(-2.0, 2.0);
63   setAxisTitle(QwtPlot::xBottom, "In-phase");
64
65   setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
66   //setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
67   set_yaxis(-2.0, 2.0);
68   setAxisTitle(QwtPlot::yLeft, "Quadrature");
69
70   // Automatically deleted when parent is deleted
71   _plot_curve = new QwtPlotCurve("Constellation Points");
72   _plot_curve->attach(this);
73   _plot_curve->setPen(QPen(Qt::blue, _penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
74   _plot_curve->setStyle(QwtPlotCurve::Dots);
75   _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
76
77   memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
78   memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
79
80   replot();
81
82   _zoomer = new ConstellationDisplayZoomer(canvas());
83 #if QT_VERSION < 0x040000
84   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
85                           Qt::RightButton, Qt::ControlModifier);
86 #else
87   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
88                           Qt::RightButton, Qt::ControlModifier);
89 #endif
90   _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
91                           Qt::RightButton);
92
93   _panner = new QwtPlotPanner(canvas());
94   _panner->setAxisEnabled(QwtPlot::yRight, false);
95   _panner->setMouseButton(Qt::MidButton);
96
97   // Avoid jumping when labels with more/less digits
98   // appear/disappear when scrolling vertically
99
100   const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
101   QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
102   sd->setMinimumExtent( fm.width("100.00") );
103
104   const QColor c(Qt::darkRed);
105   _zoomer->setRubberBandPen(c);
106   _zoomer->setTrackerPen(c);
107
108   connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), 
109           this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
110 }
111
112 ConstellationDisplayPlot::~ConstellationDisplayPlot()
113 {
114   delete[] _realDataPoints;
115   delete[] _imagDataPoints;
116
117   // _fft_plot_curves deleted when parent deleted
118   // _zoomer and _panner deleted when parent deleted
119 }
120
121 void 
122 ConstellationDisplayPlot::set_pen_size(int size)
123 {
124   if(size > 0 && size < 30){
125     _penSize = size;
126     _plot_curve->setPen(QPen(Qt::blue, _penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
127   }
128 }
129
130
131 void
132 ConstellationDisplayPlot::set_xaxis(double min, double max)
133 {
134   setAxisScale(QwtPlot::xBottom, min, max);
135 }
136
137 void
138 ConstellationDisplayPlot::set_yaxis(double min, double max)
139 {
140   setAxisScale(QwtPlot::yLeft, min, max);
141 }
142
143 void
144 ConstellationDisplayPlot::set_axis(double xmin, double xmax,
145                                    double ymin, double ymax)
146 {
147   set_xaxis(xmin, xmax);
148   set_yaxis(ymin, ymax);
149 }
150
151 void ConstellationDisplayPlot::replot(){
152
153   const timespec startTime = get_highres_clock();
154   
155   QwtPlot::replot();
156
157   double differenceTime = (diff_timespec(get_highres_clock(), startTime));
158
159   differenceTime *= 99.0;
160   // Require at least a 10% duty cycle
161   if(differenceTime > (1.0/10.0)){
162     _displayIntervalTime = differenceTime;
163   }
164 }
165
166 void
167 ConstellationDisplayPlot::resizeSlot( QSize *s )
168 {
169   resize(s->width(), s->height());
170 }
171
172 void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints,
173                                            const double* imagDataPoints,
174                                            const int64_t numDataPoints)
175 {
176   if(numDataPoints > 0){
177
178     if(numDataPoints != _numPoints){
179       _numPoints = numDataPoints;
180
181       delete[] _realDataPoints;
182       delete[] _imagDataPoints;
183       _realDataPoints = new double[_numPoints];
184       _imagDataPoints = new double[_numPoints];
185       
186       _plot_curve->setRawData(_realDataPoints, _imagDataPoints, _numPoints);
187     }
188     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
189     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
190
191   }
192
193   // Allow at least a 50% duty cycle
194   if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
195     // Only replot the screen if it is visible
196     if(isVisible()){
197       replot();
198     }
199     _lastReplot = get_highres_clock();
200   }
201 }
202
203 void
204 ConstellationDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on)
205 {
206   plotItem->setVisible(!on);
207 }
208
209 #endif /* CONSTELLATION_DISPLAY_PLOT_C */