// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} #include "UsSensorPlot.h" #include "Layout.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include UsSensorPlot::UsSensorPlot(Layout *parent, int row, int col, QString plot_name, QString y_name, float ymin, float ymax, uint32_t nbSamples,QString datasType,bool enabled, int period) : DataRemote(plot_name, "UsSensorPlot", parent, enabled, period) { plot = new QwtPlot(NULL); plot->setEnabled(enabled); parent->addWidget(plot, row, col); visible_widget = plot; this->nbSamples=nbSamples; this->datasType=datasType; #if QT_VERSION >= 0x040000 #ifdef Q_WS_X11 /* Qt::WA_PaintOnScreen is only supported for X11, but leads to substantial bugs with Qt 4.2.x/Windows */ plot->canvas()->setAttribute(Qt::WA_PaintOnScreen, true); #endif #endif alignScales(); // Assign a title plot->setTitle(plot_name); // Axis plot->setAxisTitle(QwtPlot::xBottom, "samples"); setXAxisScale(0, nbSamples-1); plot->setAxisTitle(QwtPlot::yLeft, y_name); setYAxisScale(ymin, ymax); //QwtPlotRescaler *rescaler = new QwtPlotRescaler(plot->canvas()); //rescaler->setRescalePolicy(QwtPlotRescaler::Fixed); /* rescaler->setReferenceAxis(QwtPlot::xBottom); rescaler->setAspectRatio(QwtPlot::yLeft, 1.0);*/ // grid QwtPlotGrid *grid = new QwtPlotGrid; grid->setPen(QPen(Qt::black, 0, Qt::DotLine)); grid->attach(plot); // zoomer QwtPlotMagnifier *zoomer = new QwtPlotMagnifier(plot->canvas()); zoomer->setMouseButton(Qt::RightButton, Qt::ControlModifier); // scroller QwtPlotPanner *scroller = new QwtPlotPanner(plot->canvas()); plot->canvas()->installEventFilter(this); dx = (double *)malloc(nbSamples* sizeof(double)); dy = (double *)malloc(nbSamples* sizeof(double)); for (int i = 0; i < nbSamples; i++) dx[i] = i; // Insert new curve datas = new QwtPlotCurve(); datas->attach(plot); datas->setPen(QPen(QColor(255, 0, 0, 255))); datas->setVisible(true); // Attach (don't copy) data datas->setRawSamples(dx,dy, nbSamples); if (datasType == "float") { receivesize += sizeof(float); } else if (datasType == "int8_t" || datasType == "uint8_t") { receivesize += sizeof(int8_t); } else if (datasType == "int16_t" || datasType == "uint16_t") { receivesize += sizeof(int16_t); } else { fprintf(stderr,"UsSensorPlot::unknown type %s\n", datasType.toLocal8Bit().constData()); } firstPeakStart = new QwtPlotMarker(); QwtSymbol* s1=new QwtSymbol( QwtSymbol::Diamond, Qt::blue, Qt::NoPen, QSize( 10, 10 ) ); firstPeakStart->setSymbol(s1); //m->setLabel("toto" ); firstPeakStart->attach( plot ); firstPeakEnd = new QwtPlotMarker(); QwtSymbol* s2=new QwtSymbol( QwtSymbol::Diamond, Qt::blue, Qt::NoPen, QSize( 10, 10 ) ); firstPeakEnd->setSymbol(s2); firstPeakEnd->attach( plot ); secondPeakStart = new QwtPlotMarker(); QwtSymbol* s3=new QwtSymbol( QwtSymbol::Diamond, Qt::black, Qt::NoPen, QSize( 10, 10 ) ); secondPeakStart->setSymbol(s3); secondPeakStart->attach( plot ); secondPeakEnd = new QwtPlotMarker(); QwtSymbol* s4=new QwtSymbol( QwtSymbol::Diamond, Qt::black, Qt::NoPen, QSize( 10, 10 ) ); secondPeakEnd->setSymbol(s4); secondPeakEnd->attach( plot ); } UsSensorPlot::~UsSensorPlot() { free(dx); free(dy); } void UsSensorPlot::XmlEvent(QDomElement dom) { XmlSetup(dom); } bool UsSensorPlot::eventFilter(QObject *o, QEvent *e) { if (o == plot->canvas()) { switch (e->type()) { case QEvent::MouseButtonPress: { mousePressEvent((QMouseEvent *)e); break; } default: break; } } return plot->eventFilter(o, e); } void UsSensorPlot::setXAxisScale(float xmin, float xmax) { xmin_orig = xmin; xmax_orig = xmax; plot->setAxisScale(QwtPlot::xBottom, xmin_orig, xmax_orig); } void UsSensorPlot::setYAxisScale(float ymin, float ymax) { ymin_orig = ymin; ymax_orig = ymax; plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig); } // // Set a plain canvas frame and align the scales to it // void UsSensorPlot::alignScales(void) { // The code below shows how to align the scales to // the canvas frame, but is also a good example demonstrating // why the spreaded API needs polishing. /* plot->canvas()->setFrameStyle(QFrame::Box | QFrame::Plain ); plot->canvas()->setLineWidth(1); */ for (int i = 0; i < QwtPlot::axisCnt; i++) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)plot->axisWidget(i); if (scaleWidget) scaleWidget->setMargin(0); QwtScaleDraw *scaleDraw = (QwtScaleDraw *)plot->axisScaleDraw(i); if (scaleDraw) scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); } } void UsSensorPlot::BufEvent(char **buf, int *buf_size, uint16_t period,bool big_endian) { plot->setEnabled(IsEnabled()); if (IsEnabled() == false || RefreshRate_ms() != period) return; if (datasType == "float") { float *data=(float*)*buf; for (int i = 0; i < nbSamples; i++) { dy[i]=data[i]; } *buf += nbSamples*sizeof(float); } else if (datasType == "int8_t") { int8_t *data=(int8_t*)*buf; for (int i = 0; i < nbSamples; i++) { dy[i]=data[i]; } *buf += nbSamples*sizeof(int8_t); } else if (datasType == "uint8_t") { uint8_t *data=(uint8_t*)*buf; for (int i = 0; i < nbSamples; i++) { dy[i]=data[i]; } *buf += nbSamples*sizeof(uint8_t); } else if (datasType == "int16_t") { int16_t *data=(int16_t*)*buf; for (int i = 0; i < nbSamples; i++) { dy[i]=data[i]; } *buf += nbSamples*sizeof(int16_t); } else if (datasType == "uint16_t") { uint16_t *data=(uint16_t*)*buf; for (int i = 0; i < nbSamples; i++) { dy[i]=data[i]; } *buf += nbSamples*sizeof(uint16_t); } else { fprintf(stderr,"UsSensorPlot::DrawDatas type non connu %s\n",datasType.toLocal8Bit().constData()); } uint16_t *data=(uint16_t*)*buf; *buf += 4*sizeof(uint16_t); firstPeakStart->setValue( QPointF( data[0], dy[data[0]] ) ); firstPeakEnd->setValue( QPointF( data[1], dy[data[1]] ) ); secondPeakStart->setValue( QPointF( data[2], dy[data[2]] ) ); secondPeakEnd->setValue( QPointF( data[3], dy[data[3]] ) ); plot->replot(); } // context menu void UsSensorPlot::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::RightButton) { QMenu *menu = new QMenu("nom", plot); // ajout des actions QAction *a, *z; a = menu->addAction("reset zoom"); menu->addSeparator(); appendmenu(menu); z = execmenu(plot, menu, event->globalPos()); delete menu; if (z == a) { // zoom to original size plot->setAxisScale(QwtPlot::yLeft, ymin_orig, ymax_orig); plot->setAxisScale(QwtPlot::xBottom, xmin_orig, xmax_orig); } } }