MNE-CPP  0.1.9
A Framework for Electrophysiology
rtfiffrawviewdelegate.cpp
Go to the documentation of this file.
1 //=============================================================================================================
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "rtfiffrawviewdelegate.h"
43 #include "rtfiffrawviewmodel.h"
44 #include "../rtfiffrawview.h"
45 
46 #include "../scalingview.h"
47 
48 //=============================================================================================================
49 // QT INCLUDES
50 //=============================================================================================================
51 
52 #include <QPainter>
53 #include <QDebug>
54 #include <QPainterPath>
55 
56 //=============================================================================================================
57 // EIGEN INCLUDES
58 //=============================================================================================================
59 
60 //=============================================================================================================
61 // USED NAMESPACES
62 //=============================================================================================================
63 
64 using namespace DISPLIB;
65 
66 //=============================================================================================================
67 // DEFINE MEMBER METHODS
68 //=============================================================================================================
69 
71 : QAbstractItemDelegate(parent)
72 , m_pParent(parent)
73 , m_dMaxValue(0.0)
74 , m_dScaleY(0.0)
75 , m_iActiveRow(0)
76 , m_iUpperItemIndex(0)
77 {
78 }
79 
80 //=============================================================================================================
81 
82 void RtFiffRawViewDelegate::initPainterPaths(const QAbstractTableModel *model)
83 {
84  for(int i = 0; i<model->rowCount(); i++)
85  m_painterPaths.append(QPainterPath());
86 
87  // Init pens
88  QColor colorMarker(233,0,43);
89  colorMarker.setAlpha(160);
90 
91  m_penMarker = QPen(colorMarker, 2, Qt::DashLine);
92 
93  m_penGrid = QPen(Qt::black, 1, Qt::DashLine);
94  m_penTimeSpacers = QPen(Qt::black, 1, Qt::DashLine);
95 
96  m_penFreeze = QPen(Qt::darkGray, 1, Qt::SolidLine);
97  m_penFreezeSelected = QPen(Qt::darkRed, 1, Qt::SolidLine);
98 
99  m_penFreezeBad = QPen(Qt::darkGray, 0.1, Qt::SolidLine);
100  m_penFreezeSelectedBad = QPen(Qt::darkRed, 1, Qt::SolidLine);
101 
102  m_penNormal = QPen(Qt::darkBlue, 1, Qt::SolidLine);
103  m_penNormalSelected = QPen(Qt::red, 1, Qt::SolidLine);
104 
105  m_penNormalBad = QPen(Qt::darkBlue, 0.1, Qt::SolidLine);
106  m_penNormalSelectedBad = QPen(Qt::red, 1, Qt::SolidLine);
107 }
108 
109 //=============================================================================================================
110 
111 void createPaths(const QModelIndex &index,
112  const QStyleOptionViewItem &option,
113  QPainterPath &path,
114  QPainterPath &lastPath,
115  QPointF &ellipsePos,
116  QPointF &markerPosition,
117  QString &amplitude,
118  const QVector<float> &data,
119  const QVector<float> &lastData)
120 {
121  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
122 
123  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
124  qint32 kind = t_pModel->getKind(index.row());
125 
126  float fMaxValue = DISPLIB::getScalingValue(t_pModel->getScaling(), kind, t_pModel->getUnit(index.row()));
127 
128  float dValue;
129  float dScaleY = option.rect.height()/(2*fMaxValue);
130 
131  float y_base = path.currentPosition().y();
132  QPointF qSamplePosition;
133 
134  float dDx = ((float)option.rect.width()) / t_pModel->getMaxSamples();
135 
136  //Move to initial starting point
137  if(data.size() > 0)
138  {
139 // float val = data[0];
140  dValue = 0;//(val-data[0])*dScaleY;
141 
142  float newY = y_base-dValue;//Reverse direction -> plot the right way
143 
144  qSamplePosition.setY(newY);
145  qSamplePosition.setX(path.currentPosition().x());
146 
147  path.moveTo(qSamplePosition);
148  }
149 
150  //create lines from one to the next sample
151  qint32 i;
152  for(i = 1; i < data.size(); ++i) {
153  float val = data[i] - data[0]; //remove first sample data[0] as offset
154  dValue = val*dScaleY;
155  //qDebug()<<"val"<<val<<"dScaleY"<<dScaleY<<"dValue"<<dValue;
156 
157  float newY = y_base-dValue;//Reverse direction -> plot the right way
158 
159  qSamplePosition.setY(newY);
160  qSamplePosition.setX(path.currentPosition().x()+dDx);
161 
162  path.lineTo(qSamplePosition);
163 
164  //Create ellipse position
165  if(i == (qint32)(markerPosition.x()/dDx)) {
166  ellipsePos.setX(path.currentPosition().x()+dDx);
167  ellipsePos.setY(newY+(option.rect.height()/2));
168 
169  amplitude = QString::number(data[i]);
170  }
171  }
172 
173  //create lines from one to the next sample for last path
174  qint32 sample_offset = t_pModel->numVLines() + 1;
175  qSamplePosition.setX(qSamplePosition.x() + dDx*sample_offset);
176 
177  //start painting from first sample value
178  float val = lastData[i] - lastData[0]; //remove first sample lastData[0] as offset
179  dValue = val*dScaleY;
180  float newY = y_base-dValue;
181  qSamplePosition.setY(newY);
182 
183  lastPath.moveTo(qSamplePosition);
184 
185  for(i += sample_offset; i < lastData.size(); ++i) {
186  val = lastData[i] - lastData[0]; //remove first sample lastData[0] as offset
187  dValue = val*dScaleY;
188 
189  newY = y_base-dValue;
190 
191  qSamplePosition.setY(newY);
192  qSamplePosition.setX(lastPath.currentPosition().x()+dDx);
193 
194  lastPath.lineTo(qSamplePosition);
195 
196  //Create ellipse position
197  if(i == (qint32)(markerPosition.x()/dDx)) {
198  ellipsePos.setX(lastPath.currentPosition().x()+dDx);
199  ellipsePos.setY(newY+(option.rect.height()/2));
200 
201  amplitude = QString::number(lastData[i]);
202  }
203  }
204 }
205 
206 //=============================================================================================================
207 
208 void RtFiffRawViewDelegate::paint(QPainter *painter,
209  const QStyleOptionViewItem &option,
210  const QModelIndex &index) const
211 {
212  float t_fPlotHeight = option.rect.height();
213  painter->setRenderHint(QPainter::Antialiasing, true);
214 
215  switch(index.column()) {
216  case 0: { //chnames
217  painter->save();
218 
219  painter->rotate(-90);
220  painter->drawText(QRectF(-option.rect.y()-t_fPlotHeight,0,t_fPlotHeight,20),Qt::AlignCenter,index.model()->data(index,Qt::DisplayRole).toString());
221 
222  painter->restore();
223  break;
224  }
225 
226  case 1: { //data plot
227  QBrush backgroundBrush = index.model()->data(index, Qt::BackgroundRole).value<QBrush>();
228  bool bIsBadChannel = index.model()->data(index.model()->index(index.row(), 2), Qt::DisplayRole).toBool();
229 
230  // Plot background based on user chosen color
231  // This is a rather ugly hack in order to cope with QOpenGLWidget's/QtableView's problem when setting a background color
232  if (index.row() == m_iUpperItemIndex) {
233  painter->save();
234  painter->setBrushOrigin(option.rect.topLeft());
235  QRect rect = option.rect;
236  rect.setHeight(2000);
237  painter->fillRect(rect, backgroundBrush);
238  painter->restore();
239  }
240 
241  // Draw special background when channel is marked as bad
242  if(bIsBadChannel) {
243  painter->save();
244  QBrush brush(QColor(254,74,93,40));
245  painter->setBrushOrigin(option.rect.topLeft());
246  painter->fillRect(option.rect, brush);
247  painter->restore();
248  }
249 
250 // //Highlight selected channels
251 // if(option.state & QStyle::State_Selected) {
252 // QPointF oldBO = painter->brushOrigin();
253 // painter->setBrushOrigin(option.rect.topLeft());
254 // painter->fillRect(option.rect, option.palette.highlight());
255 // painter->setBrushOrigin(oldBO);
256 // }
257 
258  //Get data
259  QVariant variant = index.model()->data(index,Qt::DisplayRole);
260  RowVectorPair data = variant.value<RowVectorPair>();
261 
262  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
263 
264  if(data.second > 0) {
265  QPainterPath path(QPointF(option.rect.x(),option.rect.y()));
266 
267 // //Plot hovering marker
268 // createMarkerPath(option, path);
269 
270 // painter->save();
271 // painter->setPen(m_penMarker);
272 // painter->drawPath(path);
273 // painter->restore();
274 
275  //Plot grid
276  createGridPath(index, option, path, data);
277 
278  painter->save();
279  painter->setPen(m_penGrid);
280  painter->drawPath(path);
281  painter->restore();
282 
283  //Plot time spacers
284  createTimeSpacersPath(index, option, path, data);
285 
286  painter->save();
287  painter->setPen(m_penTimeSpacers);
288  painter->drawPath(path);
289  painter->restore();
290 
291  //Plot detected triggers
292  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
293  painter->save();
294  createTriggerPath(painter, index, option, path, data);
295  painter->restore();
296 
297  //Plot trigger threshold
298  if(index.row() == t_pModel->getCurrentTriggerIndex() &&
299  t_pModel->triggerDetectionActive()) {
300  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
301  QPointF textPosition;
302  createTriggerThresholdPath(index, option, path, data, textPosition);
303 
304  painter->save();
305  painter->setPen(QPen(Qt::red, 1, Qt::DashLine));
306  painter->drawPath(path);
307  painter->drawText(textPosition, QString("%1 Threshold").arg(t_pModel->getTriggerName()));
308  painter->restore();
309  }
310 
311  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
312 
313  //Plot data path
314  createPlotPath(index, option, path, data);
315 
316  painter->setRenderHint(QPainter::Antialiasing, true);
317  painter->save();
318  painter->translate(0, t_fPlotHeight/2);
319 
320  if(bIsBadChannel) {
321  if(t_pModel->isFreezed()) {
322  if(option.state & QStyle::State_Selected)
323  painter->setPen(m_penFreezeSelectedBad);
324  else
325  painter->setPen(m_penFreezeBad);
326  } else {
327  if(option.state & QStyle::State_Selected)
328  painter->setPen(m_penNormalSelectedBad);
329  else
330  painter->setPen(m_penNormalBad);
331  }
332  } else {
333  if(t_pModel->isFreezed()) {
334  if(option.state & QStyle::State_Selected)
335  painter->setPen(m_penFreezeSelected);
336  else
337  painter->setPen(m_penFreeze);
338  } else {
339  if(option.state & QStyle::State_Selected)
340  painter->setPen(m_penNormalSelected);
341  else
342  painter->setPen(m_penNormal);
343  }
344  }
345 
346  painter->drawPath(path);
347  painter->restore();
348 
349  //Plot current position marker
350  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
351  createCurrentPositionMarkerPath(index, option, path);
352 
353  painter->save();
354  painter->setPen(m_penMarker);
355  painter->drawPath(path);
356  painter->restore();
357 
358  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
359  createMarkerPath(index, option, path);
360 
361  painter->save();
362  painter->setPen(QPen(Qt::green, 1, Qt::SolidLine));
363  painter->drawPath(path);
364  painter->restore();
365  }
366  break;
367  }
368  }
369 }
370 
371 //=============================================================================================================
372 
373 QSize RtFiffRawViewDelegate::sizeHint(const QStyleOptionViewItem &option,
374  const QModelIndex &index) const
375 {
376  QSize size = option.rect.size();
377 
378  switch(index.column()) {
379  case 0:
380  size = QSize(20,option.rect.height());
381  break;
382  case 1:
383  QList< QVector<float> > data = index.model()->data(index).value< QList<QVector<float> > >();
384 // qint32 nsamples = (static_cast<const RtFiffRawViewModel*>(index.model()))->lastSample()-(static_cast<const RtFiffRawViewModel*>(index.model()))->firstSample();
385 // size = QSize(nsamples*m_dDx,m_dPlotHeight);
386  Q_UNUSED(option);
387  break;
388  }
389 
390  return size;
391 }
392 
393 //=============================================================================================================
394 
396  int activeRow)
397 {
398  m_markerPosition = position;
399  m_iActiveRow = activeRow;
400 }
401 
402 //=============================================================================================================
403 
404 void RtFiffRawViewDelegate::setSignalColor(const QColor& signalColor)
405 {
406  m_penNormal.setColor(signalColor);
407  m_penNormalBad.setColor(signalColor);
408 }
409 
410 //=============================================================================================================
411 
413 {
414  return m_penNormal.color();
415 }
416 
417 //=============================================================================================================
418 
420 {
421  m_iUpperItemIndex = iUpperItemIndex;
422 }
423 
424 //=============================================================================================================
425 
426 void RtFiffRawViewDelegate::createPlotPath(const QModelIndex &index,
427  const QStyleOptionViewItem &option,
428  QPainterPath& path,
429  const RowVectorPair &data) const
430 {
431  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
432  int iPlotSizePx = option.rect.width();
433  int iNumSamples = t_pModel->getMaxSamples();
434  double dPixelsPerSample = static_cast<double>(iPlotSizePx) / static_cast<double>(iNumSamples);
435 
436  // locate time-cursor
437  int iTimeCursorSample = t_pModel->getCurrentSampleIndex();
438  double firstValuePreviousPlot = t_pModel->getLastBlockFirstValue(index.row());
439 
440  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
441  double dMaxYValueEstimate = t_pModel->getMaxValueFromRawViewModel(index.row());
442  double dScaleY = option.rect.height()/(2 * dMaxYValueEstimate);
443  double dChannelOffset = path.currentPosition().y();
444 
445 // qDebug() << " - - - - - - - - - - - - - - - - - - - - - ";
446 // qDebug() << " iPlotSizePx = " << iPlotSizePx;
447 // qDebug() << " iNumSamples = " << iNumSamples;
448 // qDebug() << " dPixelsPerSample = " << dPixelsPerSample;
449 // qDebug() << " iTimeCursorSample = " << iTimeCursorSample;
450 // qDebug() << " firstValuePreviousPlot = " << firstValuePreviousPlot;
451 
452 // qDebug() << " dMaxYValueEstimate = " << dMaxYValueEstimate;
453 // qDebug() << " dScaleY = " << dScaleY;
454 // qDebug() << " dChannelOffset = " << dChannelOffset;
455 
456  //Move to initial starting point
457  path.moveTo(calcPoint(path, 0., 0., dChannelOffset, dScaleY));
458  double dY(0);
459 
460  //The plot works as a rolling time-cursor, ploting data on top of previous runs.
461  //You always plot one whole window of data, between first sample and numSamplesToPlot (or data.second)
462  //Even if the only change is a new block of samples to the left of the time-cursor.
463  //At any time, to the left of the time-cursor you have the most recent data (A part) corresponding to the current roll
464  //To the right of the time-cursor, you have data corresponding to the previous roll.
465  for(int j = 0; j < data.second; ++j) {
466  if(j < iTimeCursorSample) {
467  //A part
468  dY = data.first[j] - data.first[0];
469  } else {
470  //B part
471  dY = data.first[j] - firstValuePreviousPlot;
472  }
473  path.lineTo(calcPoint(path, dPixelsPerSample, dY, dChannelOffset, dScaleY));
474  }
475 }
476 
477 //=============================================================================================================
478 
479 void RtFiffRawViewDelegate::createCurrentPositionMarkerPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path) const
480 {
481  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
482 
483  float currentSampleIndex = option.rect.x()+t_pModel->getCurrentSampleIndex();
484  float dDx = ((float)option.rect.width()) / t_pModel->getMaxSamples();
485  currentSampleIndex = currentSampleIndex*dDx;
486 
487  float yStart = option.rect.topLeft().y();
488  float yEnd = option.rect.bottomRight().y();
489 
490  path.moveTo(currentSampleIndex,yStart);
491  path.lineTo(currentSampleIndex,yEnd);
492 }
493 
494 //=============================================================================================================
495 
496 void RtFiffRawViewDelegate::createGridPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorPair &data) const
497 {
498  Q_UNUSED(data)
499 
500  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
501 
502  if(t_pModel->numVLines() > 0)
503  {
504  //vertical lines
505  float distance = float (option.rect.width())/(t_pModel->numVLines()+1);
506 
507  float yStart = option.rect.topLeft().y();
508 
509  float yEnd = option.rect.bottomRight().y();
510 
511  for(qint8 i = 0; i < t_pModel->numVLines(); ++i) {
512  float x = distance*(i+1);
513  path.moveTo(x,yStart);
514  path.lineTo(x,yEnd);
515  }
516  }
517 }
518 
519 //=============================================================================================================
520 
521 void RtFiffRawViewDelegate::createTimeSpacersPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorPair &data) const
522 {
523  Q_UNUSED(data)
524 
525  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
526 
527  if(t_pModel->getNumberOfTimeSpacers() > 0)
528  {
529  //vertical lines
530  float distanceSec = float (option.rect.width())/(t_pModel->numVLines()+1);
531  float distanceSpacers = distanceSec/(t_pModel->getNumberOfTimeSpacers()+1);
532 
533  float yStart = option.rect.topLeft().y();
534 
535  float yEnd = option.rect.bottomRight().y();
536 
537  for(qint8 t = 0; t < t_pModel->numVLines()+1; ++t) {
538  for(qint8 i = 0; i < t_pModel->getNumberOfTimeSpacers(); ++i) {
539  float x = (distanceSec*t)+(distanceSpacers*(i+1));
540  path.moveTo(x,yStart);
541  path.lineTo(x,yEnd);
542  }
543  }
544  }
545 }
546 
547 //=============================================================================================================
548 
549 void RtFiffRawViewDelegate::createTriggerPath(QPainter *painter,
550  const QModelIndex &index,
551  const QStyleOptionViewItem &option,
552  QPainterPath& path,
553  RowVectorPair &data) const
554 {
555  Q_UNUSED(data)
556  Q_UNUSED(path)
557 
558  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
559 
560  QList<QPair<int,double> > detectedTriggers = t_pModel->getDetectedTriggers();
561  QList<QPair<int,double> > detectedTriggersOld = t_pModel->getDetectedTriggersOld();
562  QMap<double, QColor> mapTriggerTypeColors = t_pModel->getTriggerColor();
563 
564  float yStart = option.rect.topLeft().y();
565  float yEnd = option.rect.bottomRight().y();
566  float dDx = ((float)option.rect.width()) / t_pModel->getMaxSamples();
567 
568  int currentSampleIndex = t_pModel->getCurrentSampleIndex();
569 
570  //Newly detected triggers
571  for(int u = 0; u < detectedTriggers.size(); ++u) {
572  QPainterPath path;
573 
574  int triggerPos = detectedTriggers[u].first;
575 
576  painter->save();
577  if(mapTriggerTypeColors.contains(detectedTriggers[u].second)) {
578  painter->setPen(QPen(mapTriggerTypeColors[detectedTriggers[u].second], 1.5, Qt::SolidLine));
579  }
580 
581  if(triggerPos <= currentSampleIndex + t_pModel->getCurrentOverlapAddDelay()) {
582  path.moveTo(triggerPos*dDx,yStart);
583  path.lineTo(triggerPos*dDx,yEnd);
584  }
585 
586  painter->drawPath(path);
587  painter->restore();
588  }
589 
590  //Old detected triggers
591  for(int u = 0; u < detectedTriggersOld.size(); ++u) {
592  QPainterPath path;
593 
594  int triggerPos = detectedTriggersOld[u].first;
595 
596  if(triggerPos >= currentSampleIndex + t_pModel->getCurrentOverlapAddDelay()) {
597  painter->save();
598 
599  if(mapTriggerTypeColors.contains(detectedTriggersOld[u].second)) {
600  painter->setPen(QPen(mapTriggerTypeColors[detectedTriggersOld[u].second], 1.5, Qt::SolidLine));
601  }
602 
603  path.moveTo(triggerPos*dDx,yStart);
604  path.lineTo(triggerPos*dDx,yEnd);
605 
606  painter->drawPath(path);
607  painter->restore();
608  }
609  }
610 }
611 
612 //=============================================================================================================
613 
614 void RtFiffRawViewDelegate::createTriggerThresholdPath(const QModelIndex &index,
615  const QStyleOptionViewItem &option,
616  QPainterPath& path,
617  RowVectorPair &data,
618  QPointF &textPosition) const
619 {
620  Q_UNUSED(data)
621 
622  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
623 
624  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
625  qint32 kind = t_pModel->getKind(index.row());
626  double dMaxValue = 1e-9f;
627 
628  switch(kind) {
629  case FIFFV_STIM_CH: {
630  dMaxValue = 5.0;
631  if(t_pModel->getScaling().contains(FIFFV_STIM_CH))
632  dMaxValue = t_pModel->getScaling()[FIFFV_STIM_CH];
633  break;
634  }
635  }
636 
637  double dScaleY = option.rect.height()/(2*dMaxValue);
638  double triggerThreshold = -1*(t_pModel->getTriggerThreshold());
639 
640  path.moveTo(option.rect.topLeft().x(), option.rect.topLeft().y()+option.rect.height()/2+dScaleY*triggerThreshold);
641  path.lineTo(option.rect.topRight().x(), option.rect.topLeft().y()+option.rect.height()/2+dScaleY*triggerThreshold);
642 
643  textPosition = QPointF(option.rect.topLeft().x()+5, option.rect.topLeft().y()+option.rect.height()/2+dScaleY*triggerThreshold-5);
644 }
645 
646 //=============================================================================================================
647 
648 void RtFiffRawViewDelegate::createMarkerPath(const QModelIndex &index,
649  const QStyleOptionViewItem &option,
650  QPainterPath& path) const
651 {
652  const RtFiffRawViewModel* t_pModel = static_cast<const RtFiffRawViewModel*>(index.model());
653 
654  int iOffset = t_pModel->getFirstSampleOffset();
655  int iTimeCursorSample = t_pModel->getCurrentSampleIndex();
656  int iMaxSample = t_pModel->getMaxSamples();
657 
658  double dDx = static_cast<double>(option.rect.width()) / static_cast<double>(iMaxSample);
659 
660  float yStart = option.rect.topLeft().y();
661  float yEnd = option.rect.bottomRight().y();
662 
663  int iEarliestDrawnSample = iOffset - iMaxSample + iTimeCursorSample;
664  int iLatestDrawnSample = iOffset + iTimeCursorSample;
665 
666  auto events = t_pModel->getEventsToDisplay(iEarliestDrawnSample, iLatestDrawnSample);
667 
668  for(auto& e : *events)
669  {
670  int iEventSample = e.sample;
671  int iLastStartingSample = iOffset - iMaxSample;
672  int iDrawPositionInSamples = (iEventSample - iLastStartingSample) % iMaxSample;
673 
674  float iPositionInPixels = static_cast<float>(iDrawPositionInSamples) * dDx;
675 
676  path.moveTo(iPositionInPixels,yStart);
677  path.lineTo(iPositionInPixels,yEnd);
678  }
679 }
680 
681 //=============================================================================================================
682 
683 QPointF RtFiffRawViewDelegate::calcPoint(QPainterPath& path,
684  const double dx,
685  const double y,
686  const double yBase,
687  const double yScale) const
688 {
689  double x = path.currentPosition().x() + dx;
690  double yScaled = -((yScale * y) - yBase);//- because y pixels grow downwards.
691 
692 // qDebug() << " x = " << x;
693 // qDebug() << " y = " << yScaled;
694 
695  return QPointF(x, yScaled);
696 }
697 
698 //=============================================================================================================
QList< QPair< int, double > > getDetectedTriggers() const
DISPSHARED_EXPORT float getScalingValue(const QMap< qint32, float > &qMapChScaling, int iChannelKind, int iChannelUnit)
FIFFLIB::fiff_int_t getKind(qint32 row) const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
The RtFiffRawViewModel class implements the data access model for a real-time multi sample array data...
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Declaration of the RtFiffRawViewModel Class.
void initPainterPaths(const QAbstractTableModel *model)
QList< QPair< int, double > > getDetectedTriggersOld() const
std::unique_ptr< std::vector< EVENTSLIB::Event > > getEventsToDisplay(int iBegin, int iEnd) const
void markerMoved(QPoint position, int activeRow)
double getMaxValueFromRawViewModel(int row) const
void setSignalColor(const QColor &signalColor)
Declaration of the RtFiffRawViewDelegate Class.
FIFFLIB::fiff_int_t getUnit(qint32 row) const
void setUpperItemIndex(int iUpperItemIndex)
The RtFiffRawView class provides a real-time channel view display.
Definition: rtfiffrawview.h:97
const QMap< qint32, float > & getScaling() const
QMap< double, QColor > getTriggerColor() const
RtFiffRawViewDelegate(RtFiffRawView *parent=0)
double getLastBlockFirstValue(int row) const