Changeset 15 in flair-src for trunk/tools/FlairGCS/src/Scope.cpp
- Timestamp:
- 04/08/16 15:40:57 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/FlairGCS/src/Scope.cpp
r10 r15 21 21 #define WHEEL_DIVIDOR 30 22 22 23 Scope::Scope(QString title,float ymin,float ymax,float view_size_s,unsigned int refresh_rate_ms,unsigned int history_size): QwtPlot() { 24 this->ymin=ymin; 25 this->ymax=ymax; 26 this->history_size=history_size; 27 this->view_size_s=view_size_s; 28 orig_view_size_s=view_size_s; 29 30 //scroll bar 31 scrollbar=new ScrollBar(Qt::Horizontal,canvas()); 32 connect(scrollbar,SIGNAL(valueChanged(Qt::Orientation,float,float)),this,SLOT(scrollBarMoved(Qt::Orientation,float,float))); 33 scrolling=true; 34 35 //minimum size; sinon widget trop grand 36 setMinimumHeight(10); 37 setMinimumWidth(1); 38 39 alignScales();//is it necessary? 40 41 // Initialize data 42 elapsed_time_s=0; 43 44 // Assign a title 45 setTitle(title); 46 47 // Axis 48 setAxisTitle(QwtPlot::xBottom, "Time (s)"); 49 setAxisScale(QwtPlot::xBottom,0, view_size_s); 50 51 setAxisTitle(QwtPlot::yLeft, "Values"); 52 setAxisScale(QwtPlot::yLeft, ymin, ymax); 53 54 // grid 55 QwtPlotGrid *grid = new QwtPlotGrid; 56 grid->setPen(QPen(Qt::black, 0, Qt::DotLine)); 57 grid->attach(this); 58 59 //zoomer 60 QwtPlotMagnifier * zoomer = new QwtPlotMagnifier(canvas()); 61 zoomer->setWheelModifiers( Qt::ControlModifier ); 62 zoomer->setMouseButton(Qt::NoButton); 63 zoomer->setAxisEnabled(xBottom,0); 64 65 //scroller 66 QwtPlotPanner *scroller =new QwtPlotPanner(canvas()); 67 scroller->setAxisEnabled(xBottom,0); 68 69 //legend 70 QwtLegend* new_legend=new QwtLegend(); 71 new_legend->setDefaultItemMode(QwtLegendData::Checkable); 72 insertLegend(new_legend, QwtPlot::BottomLegend); 73 74 connect( new_legend, SIGNAL( checked( const QVariant &, bool, int ) ), SLOT( legendChecked( const QVariant &, bool ) ) ); 75 76 QTimer *timer = new QTimer(this); 77 connect(timer, SIGNAL(timeout()), this, SLOT(replot())); 78 timer->start(refresh_rate_ms); 23 Scope::Scope(QString title, float ymin, float ymax, float view_size_s, 24 unsigned int refresh_rate_ms, unsigned int history_size) 25 : QwtPlot() { 26 this->ymin = ymin; 27 this->ymax = ymax; 28 this->history_size = history_size; 29 this->view_size_s = view_size_s; 30 orig_view_size_s = view_size_s; 31 32 // scroll bar 33 scrollbar = new ScrollBar(Qt::Horizontal, canvas()); 34 connect(scrollbar, SIGNAL(valueChanged(Qt::Orientation, float, float)), this, 35 SLOT(scrollBarMoved(Qt::Orientation, float, float))); 36 scrolling = true; 37 38 // minimum size; sinon widget trop grand 39 setMinimumHeight(10); 40 setMinimumWidth(1); 41 42 alignScales(); // is it necessary? 43 44 // Initialize data 45 elapsed_time_s = 0; 46 47 // Assign a title 48 setTitle(title); 49 50 // Axis 51 setAxisTitle(QwtPlot::xBottom, "Time (s)"); 52 setAxisScale(QwtPlot::xBottom, 0, view_size_s); 53 54 setAxisTitle(QwtPlot::yLeft, "Values"); 55 setAxisScale(QwtPlot::yLeft, ymin, ymax); 56 57 // grid 58 QwtPlotGrid *grid = new QwtPlotGrid; 59 grid->setPen(QPen(Qt::black, 0, Qt::DotLine)); 60 grid->attach(this); 61 62 // zoomer 63 QwtPlotMagnifier *zoomer = new QwtPlotMagnifier(canvas()); 64 zoomer->setWheelModifiers(Qt::ControlModifier); 65 zoomer->setMouseButton(Qt::NoButton); 66 zoomer->setAxisEnabled(xBottom, 0); 67 68 // scroller 69 QwtPlotPanner *scroller = new QwtPlotPanner(canvas()); 70 scroller->setAxisEnabled(xBottom, 0); 71 72 // legend 73 QwtLegend *new_legend = new QwtLegend(); 74 new_legend->setDefaultItemMode(QwtLegendData::Checkable); 75 insertLegend(new_legend, QwtPlot::BottomLegend); 76 77 connect(new_legend, SIGNAL(checked(const QVariant &, bool, int)), 78 SLOT(legendChecked(const QVariant &, bool))); 79 80 QTimer *timer = new QTimer(this); 81 connect(timer, SIGNAL(timeout()), this, SLOT(replot())); 82 timer->start(refresh_rate_ms); 79 83 } 80 84 81 85 Scope::~Scope() { 82 for(int i=0;i<curves.count();i++) {83 84 85 86 87 86 for (int i = 0; i < curves.count(); i++) { 87 free(curves.at(i)->data_x); 88 free(curves.at(i)->data_y); 89 delete curves.at(i)->plot; 90 free(curves.at(i)); 91 } 88 92 } 89 93 90 94 void Scope::resetXView(void) { 91 //setAxisScale(QwtPlot::xBottom,0, orig_view_size_s); 92 changeViewSize(orig_view_size_s); 93 } 94 95 void Scope::resetYView(void) { 96 setAxisScale(QwtPlot::yLeft, ymin, ymax); 97 } 95 // setAxisScale(QwtPlot::xBottom,0, orig_view_size_s); 96 changeViewSize(orig_view_size_s); 97 } 98 99 void Scope::resetYView(void) { setAxisScale(QwtPlot::yLeft, ymin, ymax); } 98 100 99 101 bool Scope::eventFilter(QObject *o, QEvent *e) { 100 switch(e->type()) { 101 case QEvent::Resize: { 102 const int fw = ((QwtPlotCanvas *)canvas())->frameWidth(); 103 104 QRect rect; 105 rect.setSize(((QResizeEvent *)e)->size()); 106 rect.setRect(rect.x() + fw, rect.y() + fw, 107 rect.width() - 2 * fw, rect.height() - 2 * fw); 108 109 scrollbar->setGeometry(0, 0, rect.width(), 10); 110 return true; 111 } 112 case QEvent::Wheel: { 113 //ctrl+wheel is already handled for y zoom 114 if(!(QApplication::keyboardModifiers() & Qt::ControlModifier)) { 115 QWheelEvent *wheelevent = static_cast<QWheelEvent *> (e); 116 if(view_size_s+wheelevent->delta()/WHEEL_DIVIDOR>0) changeViewSize(view_size_s+wheelevent->delta()/WHEEL_DIVIDOR); 117 } 118 return true; 119 } 120 default: 121 break; 122 } 123 return QwtPlot::eventFilter(o, e); 102 switch (e->type()) { 103 case QEvent::Resize: { 104 const int fw = ((QwtPlotCanvas *)canvas())->frameWidth(); 105 106 QRect rect; 107 rect.setSize(((QResizeEvent *)e)->size()); 108 rect.setRect(rect.x() + fw, rect.y() + fw, rect.width() - 2 * fw, 109 rect.height() - 2 * fw); 110 111 scrollbar->setGeometry(0, 0, rect.width(), 10); 112 return true; 113 } 114 case QEvent::Wheel: { 115 // ctrl+wheel is already handled for y zoom 116 if (!(QApplication::keyboardModifiers() & Qt::ControlModifier)) { 117 QWheelEvent *wheelevent = static_cast<QWheelEvent *>(e); 118 if (view_size_s + wheelevent->delta() / WHEEL_DIVIDOR > 0) 119 changeViewSize(view_size_s + wheelevent->delta() / WHEEL_DIVIDOR); 120 } 121 return true; 122 } 123 default: 124 break; 125 } 126 return QwtPlot::eventFilter(o, e); 124 127 } 125 128 126 129 void Scope::changeViewSize(float new_view_size_s) { 127 view_size_s=new_view_size_s; 128 129 if(scrolling==false) { 130 //4 cas: on utilise le temps au milieu de la vue actuelle 131 132 //le temps total est plus petit que le view_size_s, on affiche tout: 133 if(elapsed_time_s<view_size_s) { 134 scrolling=true; 135 } else { 136 double min=(min_scroll+max_scroll)/2-view_size_s/2; 137 double max=(min_scroll+max_scroll)/2+view_size_s/2; 138 //on va du debut jusqu'a view size 139 if( min<0) { 140 min=0; 141 max=view_size_s; 142 } 143 //on va de fin-viewsize jusqu'a la fin 144 if(max>elapsed_time_s) { 145 min=elapsed_time_s-view_size_s; 146 max=elapsed_time_s; 147 } 148 scrollbar->moveSlider(min,max);//move slider coupe le signal, on fait aussi le scrollbar 149 scrollBarMoved(Qt::Horizontal,min,max); 150 } 151 } 152 } 153 154 void Scope::legendChecked( const QVariant &itemInfo, bool on ) { 155 QwtPlotItem *plotItem=infoToItem(itemInfo); 156 if(plotItem) showCurve( plotItem, on ); 130 view_size_s = new_view_size_s; 131 132 if (scrolling == false) { 133 // 4 cas: on utilise le temps au milieu de la vue actuelle 134 135 // le temps total est plus petit que le view_size_s, on affiche tout: 136 if (elapsed_time_s < view_size_s) { 137 scrolling = true; 138 } else { 139 double min = (min_scroll + max_scroll) / 2 - view_size_s / 2; 140 double max = (min_scroll + max_scroll) / 2 + view_size_s / 2; 141 // on va du debut jusqu'a view size 142 if (min < 0) { 143 min = 0; 144 max = view_size_s; 145 } 146 // on va de fin-viewsize jusqu'a la fin 147 if (max > elapsed_time_s) { 148 min = elapsed_time_s - view_size_s; 149 max = elapsed_time_s; 150 } 151 scrollbar->moveSlider( 152 min, max); // move slider coupe le signal, on fait aussi le scrollbar 153 scrollBarMoved(Qt::Horizontal, min, max); 154 } 155 } 156 } 157 158 void Scope::legendChecked(const QVariant &itemInfo, bool on) { 159 QwtPlotItem *plotItem = infoToItem(itemInfo); 160 if (plotItem) 161 showCurve(plotItem, on); 157 162 } 158 163 159 164 void Scope::showCurve(QwtPlotItem *item, bool on) { 160 item->setVisible(on); 161 162 QwtLegend *lgd=qobject_cast<QwtLegend*>(legend()); 163 164 QList<QWidget*> legendWidgets=lgd->legendWidgets(itemToInfo(item)); 165 166 if(legendWidgets.size()==1) { 167 QwtLegendLabel *legendLabel=qobject_cast<QwtLegendLabel*>(legendWidgets[0]); 168 169 if(legendLabel) legendLabel->setChecked( on ); 170 } 171 } 172 173 int Scope::addCurve(QPen pen,QString legend) { 174 Curve* curve=(Curve*)malloc(sizeof(Curve)); 175 curve->data_x=(double*)calloc(history_size,sizeof(double)); 176 curve->data_y=(double*)calloc(history_size,sizeof(double)); 177 curve->index=0; 178 curve->min_index=0; 179 curve->max_index=0; 180 181 // Insert new curve 182 curve->plot=new QwtPlotCurve(legend); 183 curve->plot->attach(this); 184 curve->plot->setPen(pen); 185 curves.append(curve); 186 187 showCurve(curve->plot, true); 188 189 return curves.count()-1; 190 } 191 192 void Scope::updateCurve(Curve* curve) { 193 if(scrolling==true) { 194 curve->plot->setRawSamples(&curve->data_x[curve->min_index], &curve->data_y[curve->min_index], curve->max_index-curve->min_index); 195 } 196 197 if(curve->index==history_size) { 198 //printf("a revoir qd on arrive a la fin, il faudrait faire un realloc pour rien perdre\n"); 199 //attention le setrawdata s'attend a ce que l'adresse change pas, ce qui n'est pas le cas avec lerealloc 200 //il faudra refaire un setrawdata ici 201 curve->index=0; 202 curve->min_index=0; 203 scrolling=true; 204 } 205 206 //determine les index pour la visualisation 207 if(scrolling==true) { 208 curve->max_index=curve->index; 209 computeMinIndex(curve,elapsed_time_s-view_size_s); 210 } 211 212 scrollbar->setBase(0,elapsed_time_s); 213 if(scrolling==true) { 214 scrollbar->moveSlider(elapsed_time_s-view_size_s,elapsed_time_s); 215 216 if(elapsed_time_s<view_size_s) { 217 setAxisScale(QwtPlot::xBottom,0, view_size_s); 218 } else { 219 setAxisScale(QwtPlot::xBottom,elapsed_time_s-view_size_s, elapsed_time_s); 220 } 165 item->setVisible(on); 166 167 QwtLegend *lgd = qobject_cast<QwtLegend *>(legend()); 168 169 QList<QWidget *> legendWidgets = lgd->legendWidgets(itemToInfo(item)); 170 171 if (legendWidgets.size() == 1) { 172 QwtLegendLabel *legendLabel = 173 qobject_cast<QwtLegendLabel *>(legendWidgets[0]); 174 175 if (legendLabel) 176 legendLabel->setChecked(on); 177 } 178 } 179 180 int Scope::addCurve(QPen pen, QString legend) { 181 Curve *curve = (Curve *)malloc(sizeof(Curve)); 182 curve->data_x = (double *)calloc(history_size, sizeof(double)); 183 curve->data_y = (double *)calloc(history_size, sizeof(double)); 184 curve->index = 0; 185 curve->min_index = 0; 186 curve->max_index = 0; 187 188 // Insert new curve 189 curve->plot = new QwtPlotCurve(legend); 190 curve->plot->attach(this); 191 curve->plot->setPen(pen); 192 curves.append(curve); 193 194 showCurve(curve->plot, true); 195 196 return curves.count() - 1; 197 } 198 199 void Scope::updateCurve(Curve *curve) { 200 if (scrolling == true) { 201 curve->plot->setRawSamples(&curve->data_x[curve->min_index], 202 &curve->data_y[curve->min_index], 203 curve->max_index - curve->min_index); 204 } 205 206 if (curve->index == history_size) { 207 // printf("a revoir qd on arrive a la fin, il faudrait faire un realloc pour 208 // rien perdre\n"); 209 // attention le setrawdata s'attend a ce que l'adresse change pas, ce qui 210 // n'est pas le cas avec lerealloc 211 // il faudra refaire un setrawdata ici 212 curve->index = 0; 213 curve->min_index = 0; 214 scrolling = true; 215 } 216 217 // determine les index pour la visualisation 218 if (scrolling == true) { 219 curve->max_index = curve->index; 220 computeMinIndex(curve, elapsed_time_s - view_size_s); 221 } 222 223 scrollbar->setBase(0, elapsed_time_s); 224 if (scrolling == true) { 225 scrollbar->moveSlider(elapsed_time_s - view_size_s, elapsed_time_s); 226 227 if (elapsed_time_s < view_size_s) { 228 setAxisScale(QwtPlot::xBottom, 0, view_size_s); 221 229 } else { 222 scrollbar->moveSlider(min_scroll,max_scroll); 223 } 230 setAxisScale(QwtPlot::xBottom, elapsed_time_s - view_size_s, 231 elapsed_time_s); 232 } 233 } else { 234 scrollbar->moveSlider(min_scroll, max_scroll); 235 } 224 236 } 225 237 226 238 void Scope::alignScales(void) { 227 // The code below shows how to align the scales to 228 // the canvas frame, but is also a good example demonstrating 229 // why the spreaded API needs polishing. 230 /* 231 plot->canvas()->setFrameStyle(QFrame::Box | QFrame::Plain ); 232 plot->canvas()->setLineWidth(1); 233 */ 234 for(int i = 0;i<QwtPlot::axisCnt;i++) { 235 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i); 236 if(scaleWidget) scaleWidget->setMargin(0); 237 238 QwtScaleDraw *scaleDraw=(QwtScaleDraw *)axisScaleDraw(i); 239 if(scaleDraw) scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); 240 } 241 } 242 243 void Scope::scrollBarMoved(Qt::Orientation o, float min, float max) 244 { 245 min_scroll=min; 246 max_scroll=max; 247 248 if(max==scrollbar->maxBaseValue()) { 249 scrolling=true; 239 // The code below shows how to align the scales to 240 // the canvas frame, but is also a good example demonstrating 241 // why the spreaded API needs polishing. 242 /* 243 plot->canvas()->setFrameStyle(QFrame::Box | QFrame::Plain ); 244 plot->canvas()->setLineWidth(1); 245 */ 246 for (int i = 0; i < QwtPlot::axisCnt; i++) { 247 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i); 248 if (scaleWidget) 249 scaleWidget->setMargin(0); 250 251 QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i); 252 if (scaleDraw) 253 scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false); 254 } 255 } 256 257 void Scope::scrollBarMoved(Qt::Orientation o, float min, float max) { 258 min_scroll = min; 259 max_scroll = max; 260 261 if (max == scrollbar->maxBaseValue()) { 262 scrolling = true; 263 } else { 264 scrolling = false; 265 setAxisScale(QwtPlot::xBottom, min, max); 266 267 // determine les index pour la visualisation 268 for (int i = 0; i < curves.count(); i++) { 269 computeMinIndex(curves.at(i), min); 270 computeMaxIndex(curves.at(i), max); 271 curves.at(i)->plot->setRawSamples( 272 &curves.at(i)->data_x[curves.at(i)->min_index], 273 &curves.at(i)->data_y[curves.at(i)->min_index], 274 curves.at(i)->max_index - curves.at(i)->min_index); 275 } 276 } 277 } 278 279 // TODO: faire une dichotomie 280 void Scope::computeMinIndex(Curve *curve, float displayed_min_time) { 281 if (curve->data_x[curve->index] > displayed_min_time) { 282 if (curve->data_x[curve->min_index] < displayed_min_time) { 283 while (curve->data_x[curve->min_index] < displayed_min_time && 284 curve->min_index != curve->index) 285 curve->min_index++; 250 286 } else { 251 scrolling=false; 252 setAxisScale(QwtPlot::xBottom,min,max); 253 254 //determine les index pour la visualisation 255 for(int i=0;i<curves.count();i++) { 256 computeMinIndex(curves.at(i),min); 257 computeMaxIndex(curves.at(i),max); 258 curves.at(i)->plot->setRawSamples(&curves.at(i)->data_x[curves.at(i)->min_index], &curves.at(i)->data_y[curves.at(i)->min_index], curves.at(i)->max_index-curves.at(i)->min_index); 259 } 260 } 261 } 262 263 //TODO: faire une dichotomie 264 void Scope::computeMinIndex(Curve* curve,float displayed_min_time) { 265 if(curve->data_x[curve->index]>displayed_min_time) { 266 if(curve->data_x[curve->min_index]<displayed_min_time) { 267 while(curve->data_x[curve->min_index]<displayed_min_time && curve->min_index!=curve->index) curve->min_index++; 268 } else { 269 while(curve->data_x[curve->min_index]>displayed_min_time && curve->min_index!=0) curve->min_index--; 270 } 271 } 272 } 273 274 void Scope::computeMaxIndex(Curve* curve,float displayed_max_time) { 275 if(curve->data_x[curve->max_index]<displayed_max_time) { 276 while(curve->data_x[curve->max_index]<displayed_max_time && curve->max_index!=curve->index) curve->max_index++; 277 } else { 278 while(curve->data_x[curve->max_index]>displayed_max_time) curve->max_index--; 279 } 280 } 287 while (curve->data_x[curve->min_index] > displayed_min_time && 288 curve->min_index != 0) 289 curve->min_index--; 290 } 291 } 292 } 293 294 void Scope::computeMaxIndex(Curve *curve, float displayed_max_time) { 295 if (curve->data_x[curve->max_index] < displayed_max_time) { 296 while (curve->data_x[curve->max_index] < displayed_max_time && 297 curve->max_index != curve->index) 298 curve->max_index++; 299 } else { 300 while (curve->data_x[curve->max_index] > displayed_max_time) 301 curve->max_index--; 302 } 303 }
Note:
See TracChangeset
for help on using the changeset viewer.