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