MNE-CPP  beta 1.0
frequencyspectrumdelegate.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
43 
44 #include "frequencyspectrummodel.h"
45 
46 
47 //*************************************************************************************************************
48 //=============================================================================================================
49 // QT INCLUDES
50 //=============================================================================================================
51 
52 #include <QPainter>
53 #include <QPainterPath>
54 #include <QDebug>
55 #include <QThread>
56 #include <QTableView>
57 
58 //*************************************************************************************************************
59 //=============================================================================================================
60 // USED NAMESPACES
61 //=============================================================================================================
62 
63 using namespace XDISPLIB;
64 
65 //*************************************************************************************************************
66 //=============================================================================================================
67 // DEFINE MEMBER METHODS
68 //=============================================================================================================
69 
70 FrequencySpectrumDelegate::FrequencySpectrumDelegate(QTableView* m_pTableView,QObject *parent)
71 : QAbstractItemDelegate(parent)
72 , m_iScaleType(0)
73 {
74 
75  m_tableview = m_pTableView;
76 
77  m_tableview->setMouseTracking(true);
78 
79 }
80 
81 //*************************************************************************************************************
82 
84 {
85  m_iScaleType = ScaleType;
86 }
87 
88 
89 //*************************************************************************************************************
90 
91 void FrequencySpectrumDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
92 {
93  float t_fPlotHeight = option.rect.height();
94  switch(index.column()) {
95  case 0: { //chnames
96  painter->save();
97 
98  painter->rotate(-90);
99  painter->drawText(QRectF(-option.rect.y()-t_fPlotHeight,0,t_fPlotHeight,20),Qt::AlignCenter,index.model()->data(index,Qt::DisplayRole).toString());
100 
101  painter->restore();
102  break;
103  }
104  case 1: { //data plot
105  painter->save();
106 
107  //draw special background when channel is marked as bad
108 // QVariant v = index.model()->data(index,Qt::BackgroundRole);
109 // if(v.canConvert<QBrush>() && !(option.state & QStyle::State_Selected)) {
110 // QPointF oldBO = painter->brushOrigin();
111 // painter->setBrushOrigin(option.rect.topLeft());
112 // painter->fillRect(option.rect, qvariant_cast<QBrush>(v));
113 // painter->setBrushOrigin(oldBO);
114 // }
115 
116 // //Highlight selected channels
117 // if(option.state & QStyle::State_Selected) {
118 // QPointF oldBO = painter->brushOrigin();
119 // painter->setBrushOrigin(option.rect.topLeft());
120 // painter->fillRect(option.rect, option.palette.highlight());
121 // painter->setBrushOrigin(oldBO);
122 // }
123 
124  //Get data
125  QVariant variant = index.model()->data(index,Qt::DisplayRole);
126  RowVectorXd data = variant.value< RowVectorXd >();
127 
128 
129  const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model());
130 
131  if(data.size() > 0)
132  {
133  QPainterPath path(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor()-1,option.rect.y()));
134 
135  //Plot grid
136  painter->setRenderHint(QPainter::Antialiasing, false);
137  createGridPath(index, option, path, data);
138  createGridTick(index, option, painter);
139 
140  //capture the mouse
141  capturePoint(index, option, path, data, painter);
142 
143  painter->save();
144  QPen pen;
145  pen.setStyle(Qt::DotLine);
146  pen.setWidthF(0.5);
147  painter->setPen(pen);
148  painter->drawPath(path);
149  painter->restore();
150 
151 
152  //Plot data path
153  path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y()));
154 
155  createPlotPath(index, option, path, data);
156 
157  painter->save();
158  painter->translate(0,t_fPlotHeight/2);
159  painter->setRenderHint(QPainter::Antialiasing, true);
160 
161  if(option.state & QStyle::State_Selected)
162  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkRed : Qt::red, 1, Qt::SolidLine));
163  else
164  painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkGray : Qt::darkBlue, 1, Qt::SolidLine));
165 
166  painter->drawPath(path);
167  painter->restore();
168  }
169  painter->restore();
170  break;
171  }
172  }
173 
174 
175 
176 
177 }
178 
179 
180 //*************************************************************************************************************
181 
182 QSize FrequencySpectrumDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
183 {
184  QSize size;
185 
186  switch(index.column()) {
187  case 0:
188  size = QSize(20,option.rect.height());
189  break;
190  case 1:
191  RowVectorXd data = index.model()->data(index).value< RowVectorXd >();
192 // qint32 nsamples = (static_cast<const FrequencySpectrumModel*>(index.model()))->lastSample()-(static_cast<const FrequencySpectrumModel*>(index.model()))->firstSample();
193 
194 // size = QSize(nsamples*m_dDx,m_dPlotHeight);
195  Q_UNUSED(option);
196  break;
197  }
198 
199 
200  return size;
201 }
202 
203 //*************************************************************************************************************
204 
205 void FrequencySpectrumDelegate::rcvMouseLoc(int tableview_row, int mousex, int mousey, QRect visRect)
206 {
207 
208  if(mousex != m_mousex){
209 
210  m_tableview_row = tableview_row;
211  m_mousex = mousex;
212  m_mousey = mousey;
213  m_visRect = visRect;
214 
215  m_x_rate = (float)m_mousex/(float)m_visRect.width();
216 
217 
218  m_tableview->viewport()->repaint();
219  }
220 }
221 
222 //*************************************************************************************************************
223 
224 void FrequencySpectrumDelegate::capturePoint(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorXd& data, QPainter *painter) const
225 {
226  Q_UNUSED(option);
227  Q_UNUSED(path);
228 
229  if (m_tableview_row == index.row()){
230  const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model());
231 
232  qint32 i;
233 
234  RowVectorXd org_vecFreqScale = t_pModel->getFreqScale();
235  RowVectorXd vecFreqScale = t_pModel->getFreqScaleBound();
236 
237  qint32 lowerIdx = t_pModel->getLowerFrqBound();
238  qint32 upperIdx = t_pModel->getUpperFrqBound();
239 
240 
241  //qint32 numbins = vecFreqScale.size();// data.size();
242 
243  //qDebug() << "numbins" << numbins;
244  //qDebug() << "lowerIdx" << lowerIdx << "upperIdx" << upperIdx;
245 
246  // find the index for the current mouse cursor location
247  for(i = lowerIdx+1; i <= upperIdx; ++i) {
248 
249  //float tmp_rate = t_pModel->getFreqScale()[i]/t_pModel->getFreqScale()[numbins-1];
250 
251  float tmp_rate = (vecFreqScale[i] - vecFreqScale[lowerIdx])/(vecFreqScale[upperIdx]-vecFreqScale[lowerIdx]);
252 
253  if (tmp_rate > m_x_rate) { break;}
254  //qDebug()<<"tmp_rate"<<tmp_rate<<"m_x_rate"<<m_x_rate<<"i"<<i;
255  }
256 
257  /***************************************************
258  * Mouse moving showing the frequency and value
259  *
260  * *************************************************/
261 
262  unsigned short usPosY = m_visRect.bottom();
263  unsigned short usPosX = m_visRect.left();
264  unsigned short usHeight = m_visRect.height();
265  unsigned short usWidth = m_visRect.width();
266 
267  int iPosX = m_mousex;
268  int iPosY = m_mousey;
269 
270 
271  if(iPosX>usPosX && iPosX < usPosX+usWidth && iPosY > (usPosY - usHeight) && iPosY < usPosY )
272  {
273  //qDebug()<<" index row" << index.row()<< "i"<< i << "iPosX,iposY" << iPosX << iPosY << "usPosY"<<usPosY<<"usHeight"<<usHeight;
274  //Horizontal line
275  painter->setPen(QPen(Qt::gray, 1, Qt::DashLine));
276 
277  QPoint start(iPosX - 25, iPosY);//iStartY-5);//paint measure line vertical direction
278  QPoint end(iPosX + 25, iPosY);//iStartY+5);
279 
280 // painter->drawLine(start, end);
281 
282  //vertical line
283  start.setX(iPosX); start.setY(usPosY -usHeight); // iPosY - 25);//iStartY - 5);
284  end.setX(iPosX); end.setY(usPosY); //iPosY + 25);//iStartY + 5);
285  painter->drawLine(start, end);
286  // Draw text
287  painter->setPen(QPen(Qt::black, 1, Qt::SolidLine));
288 
289  // cal the frequency according to the iPosX
290  double fs = t_pModel->getInfo()->sfreq/2;
291 
292  //RowVectorXd vecFreqScale = t_pModel->getFreqScale();
293  //RowVectorXd vecFreqScale = t_pModel->getFreqScaleBound();
294  double freq;
295  if (m_iScaleType) // log
296  {
297  double max = log10(fs+1);
298  org_vecFreqScale *= max;
299 
300  freq = pow(10,org_vecFreqScale[i]) - 1;
301  }
302  else //normal
303  {
304  org_vecFreqScale *= fs;
305 
306  freq = org_vecFreqScale[i];
307 
308  }
309 
310  QString tx = QString("%1 [DB], %2 [Hz]").arg(data[i]).arg(freq);
311 
312  if (iPosX > usPosX + usWidth - tx.size()*8 )
313  painter->drawText(iPosX-tx.size()*8, iPosY-8, tx);// ToDo Precision should be part of preferences
314  else
315  painter->drawText(iPosX+8, iPosY-8, tx);// ToDo Precision should be part of preferences
316  }
317  }//correct row to plot
318 }
319 
320 //*************************************************************************************************************
321 
322 void FrequencySpectrumDelegate::createPlotPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorXd& data) const
323 {
324  const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model());
325 
326  float fMaxValue = data.maxCoeff();
327 
328  float fValue;
329  float fScaleY = option.rect.height()/(fMaxValue*0.5);
330 
331  float y_base = path.currentPosition().y();
332  QPointF qSamplePosition;
333 
334  qint32 lowerIdx = t_pModel->getLowerFrqBound();
335  qint32 upperIdx = t_pModel->getUpperFrqBound();
336 
337  //Move to initial starting point
338  if(data.size() > 0)
339  {
340  float val = 0;
341  fValue = val*fScaleY;
342 
343  float newY = y_base+fValue;
344 
345  qSamplePosition.setY(newY);
346  qSamplePosition.setX((double)option.rect.width()*t_pModel->getFreqScaleBound()[lowerIdx]);
347 
348  path.moveTo(qSamplePosition);
349  }
350 
351 
352  //create lines from one to the next sample
353  qint32 i;
354  for(i = lowerIdx+1; i <= upperIdx; ++i) {
355  float val = data[i]-data[0]; //remove first sample data[0] as offset
356  fValue = val*fScaleY;
357 
358  float newY = y_base+fValue;
359 
360  qSamplePosition.setY(newY);
361  qSamplePosition.setX((double)option.rect.width()*t_pModel->getFreqScaleBound()[i]);
362 
363  path.lineTo(qSamplePosition);
364  }
365 }
366 
367 
368 //*************************************************************************************************************
369 
370 void FrequencySpectrumDelegate::createGridPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorXd& data) const
371 {
372  Q_UNUSED(data)
373 
374  const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model());
375 
376  if(t_pModel->getInfo())
377  {
378  double nf = t_pModel->getInfo()->sfreq/2;
379 
380  qint32 numLines = (m_iScaleType)? (qint32)ceil(log10(nf)) : 5 ;
381 
382  QList<qint32> qListLineSamples;
383 
384  qListLineSamples << 0;
385 
386  if (m_iScaleType)
387  { // log
388  for(qint32 lineIdx = 0; lineIdx < numLines; ++lineIdx)
389  {
390  double val = pow(10,lineIdx);
391  qint32 idx = (qint32)floor(val / ((float)nf/(float)t_pModel->getNumStems()));
392  qListLineSamples.append(idx);
393  }
394  }
395  else{ // normal
396  for(qint32 lineIdx = 1; lineIdx < numLines; ++lineIdx)
397  {
398  double val = lineIdx*(nf/numLines);
399  qint32 idx = (qint32)floor(val / ((float)nf/(float)t_pModel->getNumStems()));
400  qListLineSamples.append(idx);
401  }
402 
403  }
404  //vertical lines
405  float yStart = option.rect.topLeft().y();
406 
407  float yEnd = option.rect.bottomRight().y();
408 
409  for(qint32 i = 0; i < qListLineSamples.size(); ++i) {
410  if(qListLineSamples[i] > t_pModel->getLowerFrqBound() && qListLineSamples[i] < t_pModel->getUpperFrqBound())
411  {
412  float x = (t_pModel->getFreqScaleBound()[qListLineSamples[i]])*option.rect.width();
413  path.moveTo(x,yStart);
414  path.lineTo(x,yEnd);
415  }
416  }
417 
418  }
419 }
420 
421 //*************************************************************************************************************
422 
423 void FrequencySpectrumDelegate::createGridTick(const QModelIndex &index, const QStyleOptionViewItem &option, QPainter *painter) const
424 {
425  const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model());
426 
427  if(t_pModel->getInfo())
428  {
429  double nf = t_pModel->getInfo()->sfreq/2;
430 
431  qint32 numLines = (m_iScaleType)? (qint32)ceil(log10(nf)) : 5 ;
432 
433  QList<qint32> qListLineSamples;
434 
435  qListLineSamples << 0;
436  if (m_iScaleType)
437  { // log
438  for(qint32 lineIdx = 0; lineIdx < numLines; ++lineIdx)
439  {
440  double val = pow(10,lineIdx);
441  qint32 idx = (qint32)floor(val / ((float)nf/(float)t_pModel->getNumStems()));
442  qListLineSamples.append(idx);
443  }
444  }
445  else
446  { // normal
447  for(qint32 lineIdx = 1; lineIdx < numLines; ++lineIdx)
448  {
449  double val = lineIdx*(nf/numLines);
450  qint32 idx = (qint32)floor(val / ((float)nf/(float)t_pModel->getNumStems()));
451  qListLineSamples.append(idx);
452  }
453 
454  }
455 
456  // XTick
457  float yStart = 1.0*option.rect.topLeft().y();
458 
459  if(qListLineSamples[0] > t_pModel->getLowerFrqBound() && qListLineSamples[0] < t_pModel->getUpperFrqBound())
460  {
461  double val = 0.0;
462  float x = (t_pModel->getFreqScaleBound()[qListLineSamples[0]])*option.rect.width();
463  painter->drawText(x,yStart,QString("%1Hz").arg(val));
464  }
465 
466  for(qint32 i = 1; i < qListLineSamples.size(); ++i) {
467  if(qListLineSamples[i] > t_pModel->getLowerFrqBound() && qListLineSamples[i] < t_pModel->getUpperFrqBound())
468  {
469  double val = (m_iScaleType)? pow(10,i-1) : t_pModel->getFreqScaleBound()[qListLineSamples[i]]*nf;
470  float x = (t_pModel->getFreqScaleBound()[qListLineSamples[i]])*option.rect.width();
471  painter->drawText(x,yStart,QString("%1Hz").arg(val));
472  }
473  }
474 
475  // YTick
476 
477 
478  }
479 }
480 
The FrequencySpectrumModel class implements the data access model for a real-time multi sample array ...
FrequencySpectrumDelegate(QTableView *m_pTableView, QObject *parent=0)
Declaration of the FrequencySpectrumModel Class.
void rcvMouseLoc(int row, int x, int y, QRect visRect)
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Declaration of the FrequencySpectrumDelegate Class.
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const