31#include <QPainterPath>
47: QAbstractItemDelegate(parent)
56 m_tableview = m_pTableView;
57 m_tableview->setMouseTracking(
true);
64 m_iScaleType = ScaleType;
71 float t_fPlotHeight = option.rect.height();
72 switch (index.column()) {
77 painter->drawText(QRectF(-option.rect.y() - t_fPlotHeight, 0, t_fPlotHeight, 20), Qt::AlignCenter, index.model()->data(index, Qt::DisplayRole).toString());
103 QVariant variant = index.model()->data(index, Qt::DisplayRole);
104 RowVectorXd data = variant.value<RowVectorXd>();
108 if (data.size() > 0) {
109 QPainterPath path(QPointF(option.rect.x(), option.rect.y()));
112 painter->setRenderHint(QPainter::Antialiasing,
false);
113 createGridPath(index, option, path, data);
114 createGridTick(index, option, painter);
117 capturePoint(index, option, path, data, painter);
121 pen.setStyle(Qt::DotLine);
123 painter->setPen(pen);
124 painter->drawPath(path);
128 path = QPainterPath(QPointF(option.rect.x(), option.rect.y()));
130 createPlotPath(index, option, path, data);
133 painter->translate(0, t_fPlotHeight / 2);
134 painter->setRenderHint(QPainter::Antialiasing,
true);
136 if (option.state & QStyle::State_Selected)
137 painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkRed : Qt::red, 1, Qt::SolidLine));
139 painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkGray : Qt::darkBlue, 1, Qt::SolidLine));
141 painter->drawPath(path);
156 switch (index.column()) {
158 size = QSize(20, option.rect.height());
161 RowVectorXd data = index.model()->data(index).value<RowVectorXd>();
176 if (mousex != m_mousex) {
177 m_tableview_row = tableview_row;
182 m_x_rate = (float)m_mousex / (
float)m_visRect.width();
184 m_tableview->viewport()->repaint();
190void FrequencySpectrumDelegate::capturePoint(
const QModelIndex& index,
const QStyleOptionViewItem& option, QPainterPath& path, RowVectorXd& data, QPainter* painter)
const
195 if (m_tableview_row == index.row()) {
200 RowVectorXd org_vecFreqScale = t_pModel->
getFreqScale();
213 double dBestDistance = std::numeric_limits<double>::max();
214 for (qint32 j = lowerIdx; j <= upperIdx; ++j) {
215 const double dRate = (vecFreqScale[j] - vecFreqScale[lowerIdx]) / (vecFreqScale[upperIdx] - vecFreqScale[lowerIdx]);
216 if (std::abs(dRate - m_x_rate) < dBestDistance) {
217 dBestDistance = std::abs(dRate - m_x_rate);
227 unsigned short usPosY = m_visRect.bottom();
228 unsigned short usPosX = m_visRect.left();
229 unsigned short usHeight = m_visRect.height();
230 unsigned short usWidth = m_visRect.width();
232 int iPosX = m_mousex;
233 int iPosY = m_mousey;
235 if (iPosX > usPosX && iPosX < usPosX + usWidth && iPosY > (usPosY - usHeight) && iPosY < usPosY) {
238 painter->setPen(QPen(Qt::gray, 1, Qt::DashLine));
240 QPoint start(iPosX - 25, iPosY);
241 QPoint end(iPosX + 25, iPosY);
247 start.setY(usPosY - usHeight);
250 painter->drawLine(start, end);
252 painter->setPen(QPen(Qt::black, 1, Qt::SolidLine));
255 double fs = t_pModel->
getInfo()->sfreq / 2;
262 double max = log10(fs + 1);
263 org_vecFreqScale *= max;
265 freq = pow(10, org_vecFreqScale[i]) - 1;
268 org_vecFreqScale *= fs;
270 freq = org_vecFreqScale[i];
273 QString tx = QString(
"%1 [DB], %2 [Hz]").arg(data[i]).arg(freq);
275 if (iPosX > usPosX + usWidth - tx.size() * 8)
276 painter->drawText(iPosX - tx.size() * 8, iPosY - 8, tx);
278 painter->drawText(iPosX + 8, iPosY - 8, tx);
285void FrequencySpectrumDelegate::createPlotPath(
const QModelIndex& index,
const QStyleOptionViewItem& option, QPainterPath& path, RowVectorXd& data)
const
287 const FrequencySpectrumModel* t_pModel =
static_cast<const FrequencySpectrumModel*
>(index.model());
292 if (data.size() == 0 || upperIdx < lowerIdx) {
298 const double dMin = data.segment(lowerIdx, upperIdx - lowerIdx + 1).minCoeff();
299 const double dMax = data.segment(lowerIdx, upperIdx - lowerIdx + 1).maxCoeff();
300 const double dRange = (dMax > dMin) ? dMax - dMin : 1.0;
301 const double dScaleY = (option.rect.height() - 2.0) / dRange;
302 const double dYBottom = path.currentPosition().y() + option.rect.height() / 2.0 - 1.0;
304 for (qint32 i = lowerIdx; i <= upperIdx; ++i) {
305 const QPointF qSamplePosition(option.rect.x() + option.rect.width() * t_pModel->
getFreqScaleBound()[i],
306 dYBottom - (data[i] - dMin) * dScaleY);
308 path.moveTo(qSamplePosition);
310 path.lineTo(qSamplePosition);
317void FrequencySpectrumDelegate::createGridPath(
const QModelIndex& index,
const QStyleOptionViewItem& option, QPainterPath& path, RowVectorXd& data)
const
321 const FrequencySpectrumModel* t_pModel =
static_cast<const FrequencySpectrumModel*
>(index.model());
324 double nf = t_pModel->
getInfo()->sfreq / 2;
326 qint32 numLines = (m_iScaleType) ? (qint32)ceil(log10(nf)) : 5;
328 QList<qint32> qListLineSamples;
330 qListLineSamples << 0;
333 for (qint32 lineIdx = 0; lineIdx < numLines; ++lineIdx) {
334 double val = pow(10, lineIdx);
335 qint32 idx = (qint32)floor(val / ((
float)nf / (
float)t_pModel->
getNumStems()));
336 qListLineSamples.append(idx);
339 for (qint32 lineIdx = 1; lineIdx < numLines; ++lineIdx) {
340 double val = lineIdx * (nf / numLines);
341 qint32 idx = (qint32)floor(val / ((
float)nf / (
float)t_pModel->
getNumStems()));
342 qListLineSamples.append(idx);
346 float yStart = option.rect.topLeft().y();
348 float yEnd = option.rect.bottomRight().y();
350 for (qint32 i = 0; i < qListLineSamples.size(); ++i) {
352 float x = (t_pModel->
getFreqScaleBound()[qListLineSamples[i]]) * option.rect.width();
353 path.moveTo(x, yStart);
354 path.lineTo(x, yEnd);
362void FrequencySpectrumDelegate::createGridTick(
const QModelIndex& index,
const QStyleOptionViewItem& option, QPainter* painter)
const
364 const FrequencySpectrumModel* t_pModel =
static_cast<const FrequencySpectrumModel*
>(index.model());
367 double nf = t_pModel->
getInfo()->sfreq / 2;
369 qint32 numLines = (m_iScaleType) ? (qint32)ceil(log10(nf)) : 5;
371 QList<qint32> qListLineSamples;
373 qListLineSamples << 0;
375 for (qint32 lineIdx = 0; lineIdx < numLines; ++lineIdx) {
376 double val = pow(10, lineIdx);
377 qint32 idx = (qint32)floor(val / ((
float)nf / (
float)t_pModel->
getNumStems()));
378 qListLineSamples.append(idx);
381 for (qint32 lineIdx = 1; lineIdx < numLines; ++lineIdx) {
382 double val = lineIdx * (nf / numLines);
383 qint32 idx = (qint32)floor(val / ((
float)nf / (
float)t_pModel->
getNumStems()));
384 qListLineSamples.append(idx);
389 float yStart = 1.0 * option.rect.topLeft().y();
393 float x = (t_pModel->
getFreqScaleBound()[qListLineSamples[0]]) * option.rect.width();
394 painter->drawText(x, yStart, QString(
"%1Hz").arg(val));
397 for (qint32 i = 1; i < qListLineSamples.size(); ++i) {
399 double val = (m_iScaleType) ? pow(10, i - 1) : t_pModel->
getFreqScaleBound()[qListLineSamples[i]] * nf;
400 float x = (t_pModel->
getFreqScaleBound()[qListLineSamples[i]]) * option.rect.width();
401 painter->drawText(x, yStart, QString(
"%1Hz").arg(val));
Full FIFF measurement metadata: everything from FIFFB_MEAS / FIFFB_MEAS_INFO needed to interpret a re...
QAbstractItemDelegate painting one row of the DISPLIB::SpectrumView as a horizontal frequency band.
QAbstractTableModel storing per-channel FFT magnitudes for DISPLIB::SpectrumView.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
void setScaleType(qint8 ScaleType)
void rcvMouseLoc(int row, int x, int y, QRect visRect)
FrequencySpectrumDelegate(QTableView *m_pTableView, QObject *parent=0)
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
QAbstractTableModel storing per-channel FFT magnitudes for SpectrumView.
QSharedPointer< FIFFLIB::FiffInfo > getInfo() const
qint32 getLowerFrqBound() const
qint32 getUpperFrqBound() const
qint32 getNumStems() const
Eigen::RowVectorXd getFreqScaleBound() const
Eigen::RowVectorXd getFreqScale() const