Merging qtgui branch-r9068:9837: this ads a qtgui_sink_c and qtgui_sink_f that displa...
[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   setAxisScale(QwtPlot::yLeft, -1.0, 1.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
129
130 void TimeDomainDisplayPlot::replot(){
131
132   const timespec startTime = get_highres_clock();
133   
134   QwtPlot::replot();
135
136   double differenceTime = (diff_timespec(get_highres_clock(), startTime));
137
138   differenceTime *= 99.0;
139   // Require at least a 10% duty cycle
140   if(differenceTime > (1.0/10.0)){
141     _displayIntervalTime = differenceTime;
142   }
143 }
144
145 void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
146   if(numDataPoints > 0){
147
148     if(numDataPoints != _numPoints){
149       _numPoints = numDataPoints;
150
151       delete[] _realDataPoints;
152       delete[] _imagDataPoints;
153       delete[] _xAxisPoints;
154       _realDataPoints = new double[_numPoints];
155       _imagDataPoints = new double[_numPoints];
156       _xAxisPoints = new double[_numPoints];
157       
158       _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
159       _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
160
161       _resetXAxisPoints();
162     }
163     memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
164     memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
165
166   }
167
168   // Allow at least a 50% duty cycle
169   if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
170     // Only replot the screen if it is visible
171     if(isVisible()){
172       replot();
173     }
174     _lastReplot = get_highres_clock();
175   }
176 }
177
178 void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag){
179   _imag_plot_curve->setVisible(visibleFlag);
180 }
181
182 void TimeDomainDisplayPlot::_resetXAxisPoints(){
183   for(long loc = 0; loc < _numPoints; loc++){
184     _xAxisPoints[loc] = loc;
185   }
186   setAxisScale(QwtPlot::xBottom, 0, _numPoints);
187 }
188
189 void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
190   plotItem->setVisible(!on);
191 }
192
193 #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */