// %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 #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, uint16_t period) : DataRemote(plot_name, "UsSensorPlot", parent, enabled, period) { visible_widget = new QWidget(); parent->addWidget(visible_widget, row, col); QVBoxLayout* layout = new QVBoxLayout(visible_widget); plot = new QwtPlot(NULL); plot->setEnabled(enabled); 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 //scroll bar scrollbar=new QScrollBar(Qt::Horizontal); scrollbar->setSingleStep(1); scrollbar->setRange(0,0); scrolling=true; connect(scrollbar,SIGNAL(valueChanged(int)),this,SLOT(scrollBarMoved(int))); layout->addWidget(scrollbar); layout->addWidget(plot); 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); // 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)); 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); 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); 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); for(int i=0;icanvas()) { 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,uint16_t nb_buffering,bool big_endian) { plot->setEnabled(IsEnabled()); if (IsEnabled() == false || RefreshRate_ms() != period) return; measure_t measure; measure.dy = (double *)malloc(nbSamples* sizeof(double)); if (datasType == "float") { float *data=(float*)*buf; for (int i = 0; i < nbSamples; i++) { measure.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++) { measure.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++) { measure.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++) { measure.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++) { measure.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); measure.firstPeakStartIndex=data[0]; measure.firstPeakEndIndex=data[1]; measure.secondPeakStartIndex=data[2]; measure.secondPeakEndIndex=data[3]; measures.append(measure); scrollbar->setRange(0,measures.count()-1); if(scrolling) { scrollbar->blockSignals(true);//block valuechanged signal scrollbar->setValue(measures.count()-1); scrollbar->blockSignals(false); plotMeasure(measures.count()-1); } } void UsSensorPlot::plotMeasure(int index) { firstPeakStart->setValue( QPointF(measures.at(index).firstPeakStartIndex,measures.at(index).dy[measures.at(index).firstPeakStartIndex] ) ); firstPeakEnd->setValue( QPointF(measures.at(index).firstPeakEndIndex,measures.at(index).dy[measures.at(index).firstPeakEndIndex] ) ); secondPeakStart->setValue( QPointF(measures.at(index).secondPeakStartIndex,measures.at(index).dy[measures.at(index).secondPeakStartIndex] ) ); secondPeakEnd->setValue( QPointF(measures.at(index).secondPeakEndIndex,measures.at(index).dy[measures.at(index).secondPeakEndIndex] ) ); // Attach (don't copy) data datas->setRawSamples(dx,measures.at(index).dy, nbSamples); 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); } } } void UsSensorPlot::scrollBarMoved(int value) { if(value==scrollbar->maximum()) { scrolling=true; } else { scrolling=false; } plotMeasure(value); }