MNE-CPP  beta 1.0
realtimemultisamplearraydelegate.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
42 
44 
45 
46 //*************************************************************************************************************
47 //=============================================================================================================
48 // QT INCLUDES
49 //=============================================================================================================
50 
51 #include <QPainter>
52 #include <QPainterPath>
53 #include <QDebug>
54 #include <QThread>
55 
56 
57 //*************************************************************************************************************
58 //=============================================================================================================
59 // USED NAMESPACES
60 //=============================================================================================================
61 
62 using namespace XDISPLIB;
63 
64 
65 //*************************************************************************************************************
66 //=============================================================================================================
67 // DEFINE MEMBER METHODS
68 //=============================================================================================================
69 
71 : QAbstractItemDelegate(parent)
72 {
73 
74 }
75 
76 
77 //*************************************************************************************************************
78 
79 void RealTimeMultiSampleArrayDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
80 {
81  float t_fPlotHeight = option.rect.height();
82  switch(index.column()) {
83  case 0: { //chnames
84  painter->save();
85 
86  painter->rotate(-90);
87  painter->drawText(QRectF(-option.rect.y()-t_fPlotHeight,0,t_fPlotHeight,20),Qt::AlignCenter,index.model()->data(index,Qt::DisplayRole).toString());
88 
89  painter->restore();
90  break;
91  }
92  case 1: { //data plot
93  painter->save();
94 
95  //draw special background when channel is marked as bad
96 // QVariant v = index.model()->data(index,Qt::BackgroundRole);
97 // if(v.canConvert<QBrush>() && !(option.state & QStyle::State_Selected)) {
98 // QPointF oldBO = painter->brushOrigin();
99 // painter->setBrushOrigin(option.rect.topLeft());
100 // painter->fillRect(option.rect, qvariant_cast<QBrush>(v));
101 // painter->setBrushOrigin(oldBO);
102 // }
103 
104 // //Highlight selected channels
105 // if(option.state & QStyle::State_Selected) {
106 // QPointF oldBO = painter->brushOrigin();
107 // painter->setBrushOrigin(option.rect.topLeft());
108 // painter->fillRect(option.rect, option.palette.highlight());
109 // painter->setBrushOrigin(oldBO);
110 // }
111 
112  //Get data
113  QVariant variant = index.model()->data(index,Qt::DisplayRole);
114  QList< QVector<float> > data = variant.value< QList< QVector<float> > >();
115 
116 
117  const RealTimeMultiSampleArrayModel* t_pModel = static_cast<const RealTimeMultiSampleArrayModel*>(index.model());
118 
119  if(data.size() > 0)
120  {
121  // const RealTimeMultiSampleArrayModel* t_rtmsaModel = (static_cast<const RealTimeMultiSampleArrayModel*>(index.model()));
122 
123  QPainterPath path(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor()-1,option.rect.y()));
124 
125  //Plot grid
126  painter->setRenderHint(QPainter::Antialiasing, false);
127  createGridPath(index, option, path, data);
128 
129  painter->save();
130  QPen pen;
131  pen.setStyle(Qt::DotLine);
132  pen.setWidthF(0.5);
133  painter->setPen(pen);
134  painter->drawPath(path);
135  painter->restore();
136 
137  //Plot data path
138  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
139  QPainterPath lastPath(QPointF(option.rect.x(),option.rect.y()));
140 
141  createPlotPath(index, option, path, lastPath, data[0], data[1]);
142 
143  painter->save();
144  painter->translate(0,t_fPlotHeight/2);
145  painter->setRenderHint(QPainter::Antialiasing, true);
146 
147  if(option.state & QStyle::State_Selected)
148  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkRed : Qt::red, 1, Qt::SolidLine));
149  else
150  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkGray : Qt::darkBlue, 1, Qt::SolidLine));
151 
152  painter->drawPath(path);
153  painter->restore();
154 
155  //Plot last data path
156  painter->translate(0,t_fPlotHeight/2);
157  painter->setRenderHint(QPainter::Antialiasing, true);
158  if(option.state & QStyle::State_Selected)
159  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkRed : Qt::red, 1, Qt::SolidLine));
160  else
161  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkGray : Qt::darkBlue, 1, Qt::SolidLine));
162  painter->drawPath(lastPath);
163 
164  painter->restore();
165  }
166  break;
167  }
168  }
169 
170 }
171 
172 
173 //*************************************************************************************************************
174 
175 QSize RealTimeMultiSampleArrayDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
176 {
177  QSize size;
178 
179  switch(index.column()) {
180  case 0:
181  size = QSize(20,option.rect.height());
182  break;
183  case 1:
184  QList< QVector<float> > data = index.model()->data(index).value< QList<QVector<float> > >();
185 // qint32 nsamples = (static_cast<const RealTimeMultiSampleArrayModel*>(index.model()))->lastSample()-(static_cast<const RealTimeMultiSampleArrayModel*>(index.model()))->firstSample();
186 
187 // size = QSize(nsamples*m_dDx,m_dPlotHeight);
188  Q_UNUSED(option);
189  break;
190  }
191 
192 
193  return size;
194 }
195 
196 
197 //*************************************************************************************************************
198 
199 void RealTimeMultiSampleArrayDelegate::createPlotPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, QPainterPath& lastPath, QVector<float>& data, QVector<float>& lastData) const
200 {
201  const RealTimeMultiSampleArrayModel* t_pModel = static_cast<const RealTimeMultiSampleArrayModel*>(index.model());
202 
203  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
204  qint32 kind = t_pModel->getKind(index.row());
205  float fMaxValue = 1e-9f;
206 
207  switch(kind) {
208  case FIFFV_MEG_CH: {
209  qint32 unit =t_pModel->getUnit(index.row());
210  if(unit == FIFF_UNIT_T_M) {
211  fMaxValue = 1e-10f;
212  if(t_pModel->getScaling().contains(FIFF_UNIT_T_M))
213  fMaxValue = t_pModel->getScaling()[FIFF_UNIT_T_M];
214  }
215  else if(unit == FIFF_UNIT_T)
216  {
217  if(t_pModel->getCoil(index.row()) == FIFFV_COIL_BABY_MAG)
218  fMaxValue = 1e-11f;
219  else
220  fMaxValue = 1e-11f;
221 
222  if(t_pModel->getScaling().contains(FIFF_UNIT_T))
223  fMaxValue = t_pModel->getScaling()[FIFF_UNIT_T];
224  }
225  break;
226  }
227 
228  case FIFFV_REF_MEG_CH: { /*11/04/14 Added by Limin: MEG reference channel */
229  fMaxValue = 1e-11f;
230  if(t_pModel->getScaling().contains(FIFF_UNIT_T))
231  fMaxValue = t_pModel->getScaling()[FIFF_UNIT_T];
232  break;
233  }
234  case FIFFV_EEG_CH: {
235  fMaxValue = 1e-4f;
236  if(t_pModel->getScaling().contains(FIFFV_EEG_CH))
237  fMaxValue = t_pModel->getScaling()[FIFFV_EEG_CH];
238  break;
239  }
240  case FIFFV_EOG_CH: {
241  fMaxValue = 1e-3f;
242  if(t_pModel->getScaling().contains(FIFFV_EOG_CH))
243  fMaxValue = t_pModel->getScaling()[FIFFV_EOG_CH];
244  break;
245  }
246  case FIFFV_STIM_CH: {
247  fMaxValue = 5;
248  if(t_pModel->getScaling().contains(FIFFV_STIM_CH))
249  fMaxValue = t_pModel->getScaling()[FIFFV_STIM_CH];
250  break;
251  }
252  case FIFFV_MISC_CH: {
253  fMaxValue = 1e-3f;
254  if(t_pModel->getScaling().contains(FIFFV_MISC_CH))
255  fMaxValue = t_pModel->getScaling()[FIFFV_MISC_CH];
256  break;
257  }
258  }
259 
260  float fValue;
261  float fScaleY = option.rect.height()/(2*fMaxValue);
262 
263  float y_base = path.currentPosition().y();
264  QPointF qSamplePosition;
265 
266  float fDx = ((float)option.rect.width()) / t_pModel->getMaxSamples();
267 
268  //Move to initial starting point
269  if(data.size() > 0)
270  {
271 // float val = data[0];
272  fValue = 0;//(val-data[0])*fScaleY;
273 
274  float newY = y_base-fValue;//Reverse direction -> plot the right way
275 
276  qSamplePosition.setY(newY);
277  qSamplePosition.setX(path.currentPosition().x());
278 
279  path.moveTo(qSamplePosition);
280  }
281 
282  //create lines from one to the next sample
283  qint32 i;
284  for(i = 1; i < data.size(); ++i) {
285  float val = data[i] - data[0]; //remove first sample data[0] as offset
286  fValue = val*fScaleY;
287  //qDebug()<<"val"<<val<<"fScaleY"<<fScaleY<<"fValue"<<fValue;
288 
289  float newY = y_base-fValue;//Reverse direction -> plot the right way
290 
291  qSamplePosition.setY(newY);
292  qSamplePosition.setX(path.currentPosition().x()+fDx);
293 
294  path.lineTo(qSamplePosition);
295  }
296 
297  //create lines from one to the next sample for last path
298  qint32 sample_offset = t_pModel->numVLines() + 1;
299  qSamplePosition.setX(qSamplePosition.x() + fDx*sample_offset);
300  lastPath.moveTo(qSamplePosition);
301 
302  for(i += sample_offset; i < lastData.size(); ++i) {
303  float val = lastData[i] - lastData[0]; //remove first sample lastData[0] as offset
304  fValue = val*fScaleY;
305 
306  float newY = y_base-fValue;
307 
308  qSamplePosition.setY(newY);
309  qSamplePosition.setX(lastPath.currentPosition().x()+fDx);
310 
311  lastPath.lineTo(qSamplePosition);
312  }
313 }
314 
315 
316 //*************************************************************************************************************
317 
318 void RealTimeMultiSampleArrayDelegate::createGridPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, QList< QVector<float> >& data) const
319 {
320  Q_UNUSED(data)
321 
322  const RealTimeMultiSampleArrayModel* t_pModel = static_cast<const RealTimeMultiSampleArrayModel*>(index.model());
323 
324  if(t_pModel->numVLines() > 0)
325  {
326  //horizontal lines
327  float distance = option.rect.width()/(t_pModel->numVLines()+1);
328 
329  float yStart = option.rect.topLeft().y();
330 
331  float yEnd = option.rect.bottomRight().y();
332 
333  for(qint8 i = 0; i < t_pModel->numVLines(); ++i) {
334  float x = distance*(i+1);
335  path.moveTo(x,yStart);
336  path.lineTo(x,yEnd);
337  }
338  }
339 }
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
const QMap< qint32, float > & getScaling() const
The RealTimeMultiSampleArrayModel class implements the data access model for a real-time multi sample...
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Declaration of the RealTimeMultiSampleArrayDelegate Class.
Declaration of the RealTimeMultiSampleArrayModel Class.
#define FIFFV_COIL_BABY_MAG
#define FIFF_UNIT_T_M