Imported Upstream version 3.2.2
[debian/gnuradio] / gr-qtgui / src / lib / TimeDomainDisplayPlot.cc
1 #ifndef TIME_DOMAIN_DISPLAY_PLOT_C
2 #define TIME_DOMAIN_DISPLAY_PLOT_C
3
4 #include <TimeDomainDisplayPlot.h>
5
6 #include <qwt_scale_draw.h>
7 #include <qwt_legend.h>
8
9
10 class TimeDomainDisplayZoomer: public QwtPlotZoomer
11 {
12 public:
13   TimeDomainDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas)
14   {
15     setTrackerMode(QwtPicker::AlwaysOn);
16   }
17
18   virtual ~TimeDomainDisplayZoomer(){
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 TimeDomainDisplayPlot::TimeDomainDisplayPlot(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   _xAxisPoints = 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   setAxisScale(QwtPlot::xBottom, 0, _numPoints);
60   setAxisTitle(QwtPlot::xBottom, "Sample Number");
61
62   setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
63   set_yaxis(-2.0, 2.0);
64   setAxisTitle(QwtPlot::yLeft, "Normalized Voltage");
65
66   // Automatically deleted when parent is deleted
67   _real_plot_curve = new QwtPlotCurve("Real Data");
68   _real_plot_curve->attach(this);
69   _real_plot_curve->setPen(QPen(Qt::blue));
70   _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
71
72   _imag_plot_curve = new QwtPlotCurve("Imaginary Data");
73   _imag_plot_curve->attach(this);
74   _imag_plot_curve->setPen(QPen(Qt::magenta));
75   _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
76   // _imag_plot_curve->setVisible(false);
77
78   memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
79   memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
80   memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
81
82   _resetXAxisPoints();
83
84   replot();
85
86   _zoomer = new TimeDomainDisplayZoomer(canvas());
87 #if QT_VERSION < 0x040000
88   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
89                           Qt::RightButton, Qt::ControlModifier);
90 #else
91   _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
92                           Qt::RightButton, Qt::ControlModifier);
93 #endif
94   _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
95                           Qt::RightButton);
96
97   _panner = new QwtPlotPanner(canvas());
98   _panner->setAxisEnabled(QwtPlot::yRight, false);
99   _panner->setMouseButton(Qt::MidButton);
100
101   // Avoid jumping when labels with more/less digits
102   // appear/disappear when scrolling vertically
103
104   const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
105   QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
106   sd->setMinimumExtent( fm.width("100.00") );
107
108   const QColor c(Qt::darkRed);
109   _zoomer->setRubberBandPen(c);
110   _zoomer->setTrackerPen(c);
111
112   QwtLegend* legendDisplay = new QwtLegend(this);
113   legendDisplay->setItemMode(QwtLegend::CheckableItem);
114   insertLegend(legendDisplay);
115
116   connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
117 }
118
119 TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){
120   delete[] _realDataPoints;
121   delete[] _imagDataPoints;
122   delete[] _xAxisPoints;
123
124   // _fft_plot_curves deleted when parent deleted
125   // _zoomer and _panner deleted when parent deleted
126 }
127
128 void
129 TimeDomainDisplayPlot::set_yaxis(double min, double max)
130 {
131   setAxisScale(QwtPlot::yLeft, min, max);
132 }
133
134 void TimeDomainDisplayPlot::replot(){
135
136   const timespec startTime = get_highres_clock();
137   
138   QwtPlot::replot();
139
140   double differenceTime = (diff_timespec(get_highres_clock(), startTime));
141
142   differenceTime *= 99.0;
143   // Require at least a 10% duty cycle
144   if(differenceTime > (1.0/10.0)){
145     _displayIntervalTime = differenceTime;
146   }
147 }
148
149 void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
150   if(numDataPoints > 0){
151
152     if(numDataPoints != _numPoints){
153       _numPoints = numDataPoints;
154
155       delete[] _realDataPoints;
156       delete[] _imagDataPoints;
157       delete[] _xAxisPoints;
158       _realDataPoints = new double[_numPoints];
159       _imagDataPoints = new double[_numPoints];
160       _xAxisPoints = new double[_numPoints];
161       
162       _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
163       _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
164
165       _resetXAxisPoints();
166     }
167     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
168     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
169
170   }
171
172   // Allow at least a 50% duty cycle
173   if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
174     // Only replot the screen if it is visible
175     if(isVisible()){
176       replot();
177     }
178     _lastReplot = get_highres_clock();
179   }
180 }
181
182 void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag){
183   _imag_plot_curve->setVisible(visibleFlag);
184 }
185
186 void TimeDomainDisplayPlot::_resetXAxisPoints(){
187   for(long loc = 0; loc < _numPoints; loc++){
188     _xAxisPoints[loc] = loc;
189   }
190   setAxisScale(QwtPlot::xBottom, 0, _numPoints);
191 }
192
193 void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
194   plotItem->setVisible(!on);
195 }
196
197 #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */