benoitrigolleau@211: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ benoitrigolleau@211: benoitrigolleau@211: /* Sound Access benoitrigolleau@211: EASAIER client application. benoitrigolleau@211: Silogic 2007. Benoit Rigolleau. benoitrigolleau@211: benoitrigolleau@211: This program is free software; you can redistribute it and/or benoitrigolleau@211: modify it under the terms of the GNU General Public License as benoitrigolleau@211: published by the Free Software Foundation; either version 2 of the benoitrigolleau@211: License, or (at your option) any later version. See the file benoitrigolleau@211: COPYING included with this distribution for more information. benoitrigolleau@211: */ benoitrigolleau@211: benoitrigolleau@211: #include "Plotter.h" benoitrigolleau@231: #include benoitrigolleau@211: #include benoitrigolleau@211: benoitrigolleau@211: Plotter::Plotter(QWidget *parent): benoitrigolleau@211: m_signalWidth(400), lbajardsilogic@233: m_signalHeight(120), benoitrigolleau@211: m_margin(5), lbajardsilogic@235: m_curveMaskActive(false), lbajardsilogic@235: m_enableDrawCurve(false) benoitrigolleau@211: { lbajardsilogic@229: //m_curveMask = new int[m_signalWidth]; benoitrigolleau@211: for(int i = 0 ; i < m_signalWidth ; i++){ lbajardsilogic@229: m_curveMask.push_back(0); benoitrigolleau@211: } benoitrigolleau@240: m_oldCurveMask = m_curveMask; benoitrigolleau@211: benoitrigolleau@240: setMinimumSize(QSize(m_signalWidth + 2*m_margin, m_signalHeight + 2*m_margin + 10)); benoitrigolleau@211: benoitrigolleau@211: refreshPixmap(); benoitrigolleau@211: benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::setCurveData(const QVector &data){ benoitrigolleau@211: m_curve = data; benoitrigolleau@211: refreshPixmap(); benoitrigolleau@211: } benoitrigolleau@211: lbajardsilogic@229: void Plotter::setCurve(float * curve) lbajardsilogic@229: { lbajardsilogic@229: m_curve.clear(); benoitrigolleau@231: for (int i=0; i< m_signalWidth; i++) lbajardsilogic@229: { lbajardsilogic@233: int m = m_signalHeight*2/3 +(int) floor(curve[i]/0.1); lbajardsilogic@233: m_curve.push_back(QPoint(i, m)); lbajardsilogic@229: } lbajardsilogic@229: refreshPixmap(); lbajardsilogic@229: } lbajardsilogic@229: benoitrigolleau@211: void Plotter::clearCurve(){ benoitrigolleau@211: m_curve.clear(); benoitrigolleau@211: refreshPixmap(); benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::paintEvent(QPaintEvent *event){ benoitrigolleau@211: QStylePainter painter(this); benoitrigolleau@211: painter.drawPixmap(0, 0, m_pixmap); benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::resizeEvent(QResizeEvent *event){ benoitrigolleau@211: refreshPixmap(); benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::mousePressEvent(QMouseEvent *event){ benoitrigolleau@211: QRect rect(m_margin, m_margin, benoitrigolleau@239: m_signalWidth , m_signalHeight ); benoitrigolleau@211: lbajardsilogic@235: if (m_enableDrawCurve) lbajardsilogic@235: { lbajardsilogic@235: if (event->button() == Qt::LeftButton) { lbajardsilogic@235: if (rect.contains(event->pos())) { lbajardsilogic@235: m_curveMaskActive = true; lbajardsilogic@235: int x = event->pos().x()- m_margin; lbajardsilogic@235: int y = event->pos().y()- m_margin; lbajardsilogic@235: m_curveMask[x] = y; lbajardsilogic@235: m_lastPoint.setX(x); lbajardsilogic@235: m_lastPoint.setY(y); lbajardsilogic@235: setCursor(Qt::CrossCursor); lbajardsilogic@235: refreshPixmap(); lbajardsilogic@235: } lbajardsilogic@235: } lbajardsilogic@235: } benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::mouseMoveEvent(QMouseEvent *event){ benoitrigolleau@211: QRect rect(m_margin, m_margin, benoitrigolleau@239: m_signalWidth , m_signalHeight); benoitrigolleau@211: lbajardsilogic@235: if (m_enableDrawCurve) lbajardsilogic@235: { lbajardsilogic@235: if(m_curveMaskActive && rect.contains(event->pos())){ lbajardsilogic@235: int x = event->pos().x() - m_margin; lbajardsilogic@235: int y = event->pos().y() - m_margin; lbajardsilogic@235: if(y>m_signalHeight-1) lbajardsilogic@235: y= m_signalHeight-1; lbajardsilogic@235: if(x>m_signalWidth-1) lbajardsilogic@235: y= m_signalWidth-1; lbajardsilogic@235: int xlast = m_lastPoint.x(); lbajardsilogic@235: int ylast = m_lastPoint.y(); benoitrigolleau@211: lbajardsilogic@235: //regul mask curve lbajardsilogic@235: int minx, maxx, miny, maxy; lbajardsilogic@235: if(x>xlast){ lbajardsilogic@235: minx = xlast; lbajardsilogic@235: maxx = x; lbajardsilogic@235: }else{ lbajardsilogic@235: minx = x; lbajardsilogic@235: maxx = xlast; lbajardsilogic@235: } lbajardsilogic@235: if(y>ylast){ lbajardsilogic@235: miny = ylast; lbajardsilogic@235: maxy = y; lbajardsilogic@235: }else{ lbajardsilogic@235: miny = y; lbajardsilogic@235: maxy = ylast; lbajardsilogic@235: } benoitrigolleau@211: lbajardsilogic@235: if((maxx - minx)>1){ lbajardsilogic@235: double incr = (double)(maxy - miny)/(double)(maxx - minx); lbajardsilogic@235: if(x>xlast){ lbajardsilogic@235: for (int i = xlast + 1 ; i < x ; i++){ lbajardsilogic@235: if(ylast > y){ lbajardsilogic@235: m_curveMask[i] = ylast - (i-xlast)*incr; lbajardsilogic@235: }else{ lbajardsilogic@235: m_curveMask[i] = ylast + (i-xlast)*incr; lbajardsilogic@235: } benoitrigolleau@211: } lbajardsilogic@235: }else{ lbajardsilogic@235: for (int i = xlast - 1 ; i > x ; i--){ lbajardsilogic@235: if(ylast > y){ lbajardsilogic@235: m_curveMask[i] = ylast + (i-xlast)*incr; lbajardsilogic@235: }else{ lbajardsilogic@235: m_curveMask[i] = ylast - (i-xlast)*incr; lbajardsilogic@235: } benoitrigolleau@211: } benoitrigolleau@211: } benoitrigolleau@211: } lbajardsilogic@235: m_curveMask[x] = y; lbajardsilogic@235: m_lastPoint.setX(x); lbajardsilogic@235: m_lastPoint.setY(y); lbajardsilogic@235: refreshPixmap(); benoitrigolleau@240: emit filterChanged(m_curveMask); benoitrigolleau@211: } benoitrigolleau@211: } benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::mouseReleaseEvent(QMouseEvent *event){ lbajardsilogic@235: if (m_enableDrawCurve) lbajardsilogic@235: { lbajardsilogic@235: if ((event->button() == Qt::LeftButton) && m_curveMaskActive) { lbajardsilogic@235: m_curveMaskActive = false; lbajardsilogic@235: unsetCursor(); benoitrigolleau@240: //emit filterChanged(m_curveMask); lbajardsilogic@235: } lbajardsilogic@235: } benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::drawGrid(QPainter *painter){ benoitrigolleau@211: QPixmap pm(":icons/grid.png"); benoitrigolleau@240: painter->setPen(Qt::white); benoitrigolleau@211: painter->drawPixmap(0,0,pm); benoitrigolleau@240: benoitrigolleau@240: benoitrigolleau@240: /**VLines **************/ benoitrigolleau@240: benoitrigolleau@240: // middle line benoitrigolleau@240: painter->drawLine(m_signalWidth/2+m_margin, m_margin, m_signalWidth/2+m_margin , m_signalHeight + m_margin); benoitrigolleau@240: //quater lines benoitrigolleau@240: painter->drawLine(m_signalWidth/4+m_margin, m_margin, m_signalWidth/4+m_margin , m_signalHeight + m_margin); benoitrigolleau@240: painter->drawLine(3*m_signalWidth/4+m_margin, m_margin, 3*m_signalWidth/4+m_margin , m_signalHeight + m_margin); benoitrigolleau@240: benoitrigolleau@240: // border lines benoitrigolleau@240: painter->drawLine(m_margin, m_margin, m_margin , m_signalHeight + m_margin); benoitrigolleau@240: painter->drawLine(m_signalWidth+m_margin, m_margin, m_signalWidth+m_margin , m_signalHeight + m_margin); benoitrigolleau@240: benoitrigolleau@240: /** HLines *************/ benoitrigolleau@240: benoitrigolleau@240: benoitrigolleau@240: /** Labels *************/ benoitrigolleau@240: painter->setPen(Qt::darkGray); benoitrigolleau@240: painter->drawText(0, m_signalHeight+2*m_margin+10, "10Hz"); benoitrigolleau@240: painter->drawText(m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "100Hz"); benoitrigolleau@240: painter->drawText(m_signalWidth/2 -10, m_signalHeight+2*m_margin+10, "1000Hz"); benoitrigolleau@240: painter->drawText(3*m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "10000Hz"); benoitrigolleau@240: painter->drawText(m_signalWidth -22, m_signalHeight+2*m_margin+10, "22KHz"); benoitrigolleau@240: benoitrigolleau@240: benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::drawCurve(QPainter *painter){ benoitrigolleau@231: //painter->setRenderHint (QPainter::Antialiasing, true ); benoitrigolleau@211: QPolygonF polyline(m_signalWidth); benoitrigolleau@231: benoitrigolleau@211: for(int i = 0 ; i < m_curve.count() ; i++){ lbajardsilogic@233: int m = m_curve.at(i).y(); // Calculates pixel coordinate and Plots FFT (in green) benoitrigolleau@231: if (m>m_signalHeight){m = m_signalHeight;} benoitrigolleau@231: if (m<0){m = 0;} benoitrigolleau@231: int y= m_signalHeight - m; benoitrigolleau@231: polyline[i] = QPoint(m_curve.at(i).x() + m_margin, /*m_curve.at(i).y()*/y + m_margin); benoitrigolleau@211: } benoitrigolleau@231: benoitrigolleau@211: painter->setPen(Qt::green); benoitrigolleau@211: painter->drawPolyline(polyline); benoitrigolleau@239: benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::drawMaskCurve(QPainter *painter){ benoitrigolleau@211: benoitrigolleau@220: painter->setRenderHint (QPainter::Antialiasing, true ); benoitrigolleau@220: benoitrigolleau@211: QPolygonF polyline(m_signalWidth); benoitrigolleau@211: benoitrigolleau@211: for(int i = 0 ; i < m_signalWidth ; i++){ benoitrigolleau@211: polyline[i] = QPoint(i+m_margin, m_curveMask[i]+m_margin); benoitrigolleau@211: } benoitrigolleau@211: painter->setPen(Qt::red); benoitrigolleau@211: painter->drawPolyline(polyline); benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::refreshPixmap(){ benoitrigolleau@211: m_pixmap = QPixmap(size()); benoitrigolleau@211: m_pixmap.fill(this, 0, 0); benoitrigolleau@211: benoitrigolleau@211: QPainter painter(&m_pixmap); benoitrigolleau@211: painter.initFrom(this); benoitrigolleau@211: drawGrid(&painter); benoitrigolleau@211: drawCurve(&painter); benoitrigolleau@211: drawMaskCurve(&painter); benoitrigolleau@211: update(); benoitrigolleau@211: } benoitrigolleau@211: benoitrigolleau@211: void Plotter::setMargin(int margin){ benoitrigolleau@211: m_margin = margin; lbajardsilogic@232: } lbajardsilogic@232: lbajardsilogic@232: void Plotter::setFilter(float* filter) lbajardsilogic@232: { benoitrigolleau@240: lbajardsilogic@232: m_curveMask.clear(); lbajardsilogic@232: for (int i=0; i aux = m_curveMask; benoitrigolleau@240: m_curveMask = m_oldCurveMask; benoitrigolleau@240: m_oldCurveMask = aux; benoitrigolleau@240: refreshPixmap(); benoitrigolleau@240: if(enable){ benoitrigolleau@240: emit filterChanged(m_curveMask); benoitrigolleau@240: } benoitrigolleau@240: } lbajardsilogic@235: m_enableDrawCurve = enable; benoitrigolleau@211: }