view widgets/Plotter.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents e006f4a57f86
children
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*	Sound Access	
		EASAIER client application.	
		Silogic 2007. Benoit Rigolleau. 
	
	This program is free software; you can redistribute it and/or    
	modify it under the terms of the GNU General Public License as    
	published by the Free Software Foundation; either version 2 of the    
	License, or (at your option) any later version.  See the file    
	COPYING included with this distribution for more information.
*/

#include  "Plotter.h"  
#include <math.h>
#include <QtGui>

Plotter::Plotter(QWidget *parent):
m_signalWidth(400),
m_signalHeight(120),
m_margin(5),
m_curveMaskActive(false),
m_enableDrawCurve(false)
{
	//m_curveMask = new int[m_signalWidth];
	for(int i = 0 ; i < m_signalWidth ; i++){
		m_curveMask.push_back(0);
	}
	m_oldCurveMask = m_curveMask;

	setMinimumSize(QSize(m_signalWidth + 2*m_margin, m_signalHeight + 2*m_margin + 10));

	refreshPixmap();

}

void Plotter::setCurveData(const QVector<QPoint> &data){
	m_curve = data;
	refreshPixmap();
}

void Plotter::setCurve(float * curve)
{
	m_curve.clear();
	for (int i=0; i< m_signalWidth; i++)
	{
		int m = m_signalHeight*2/3 +(int) floor(curve[i]/0.1);
		m_curve.push_back(QPoint(i, m));
	}
	refreshPixmap();
}

void Plotter::clearCurve(){
	m_curve.clear();
	refreshPixmap();
}

void Plotter::paintEvent(QPaintEvent *event){
	QStylePainter painter(this);
    painter.drawPixmap(0, 0, m_pixmap);
}

void Plotter::resizeEvent(QResizeEvent *event){
	refreshPixmap();
}

void Plotter::mousePressEvent(QMouseEvent *event){
	QRect rect(m_margin, m_margin,
               m_signalWidth , m_signalHeight );

	if (m_enableDrawCurve)
	{
		if (event->button() == Qt::LeftButton) {
			if (rect.contains(event->pos())) {
				m_curveMaskActive = true;
				int x = event->pos().x()- m_margin;
				int y = event->pos().y()- m_margin;
				m_curveMask[x] = y;
				m_lastPoint.setX(x);
				m_lastPoint.setY(y);
				setCursor(Qt::CrossCursor);
				refreshPixmap();
			}
		}
	}
}

void Plotter::mouseMoveEvent(QMouseEvent *event){
	QRect rect(m_margin, m_margin,
               m_signalWidth  , m_signalHeight);

	if (m_enableDrawCurve)
	{
		if(m_curveMaskActive && rect.contains(event->pos())){
			int x = event->pos().x() - m_margin;
			int y = event->pos().y() - m_margin;
			if(y>m_signalHeight-1)
				y= m_signalHeight-1;
			if(x>m_signalWidth-1)
				y= m_signalWidth-1;
			int xlast = m_lastPoint.x();
			int ylast = m_lastPoint.y();

			//regul mask curve
			int minx, maxx, miny, maxy;
			if(x>xlast){
				minx = xlast;
				maxx = x;
			}else{
				minx = x;
				maxx = xlast;
			}
			if(y>ylast){
				miny = ylast;
				maxy = y;
			}else{
				miny = y;
				maxy = ylast;
			}

			if((maxx - minx)>1){
				double incr = (double)(maxy - miny)/(double)(maxx - minx);
				if(x>xlast){
					for (int i = xlast + 1 ; i < x ; i++){
						if(ylast > y){
							m_curveMask[i] = ylast - (i-xlast)*incr;
						}else{
							m_curveMask[i] = ylast + (i-xlast)*incr;
						}
					}
				}else{
					for (int i = xlast - 1 ; i > x ; i--){
						if(ylast > y){
							m_curveMask[i] = ylast + (i-xlast)*incr;
						}else{
							m_curveMask[i] = ylast - (i-xlast)*incr;
						}
					}
				}
			}
			m_curveMask[x] = y;
			m_lastPoint.setX(x);
			m_lastPoint.setY(y);
			refreshPixmap();
			emit filterChanged(m_curveMask);
		}
	}
}

void Plotter::mouseReleaseEvent(QMouseEvent *event){
	if (m_enableDrawCurve)
	{
		if ((event->button() == Qt::LeftButton) && m_curveMaskActive) {
			m_curveMaskActive = false;
			unsetCursor();
			//emit filterChanged(m_curveMask);
		}
	}
}

void Plotter::drawGrid(QPainter *painter){
	QPixmap pm(":icons/grid.png");
	painter->setPen(Qt::white);
	painter->drawPixmap(0,0,pm);
	

	/**VLines **************/ 

	// middle line
	painter->drawLine(m_signalWidth/2+m_margin, m_margin, m_signalWidth/2+m_margin , m_signalHeight + m_margin);
	//quater lines
	painter->drawLine(m_signalWidth/4+m_margin, m_margin, m_signalWidth/4+m_margin , m_signalHeight + m_margin);
	painter->drawLine(3*m_signalWidth/4+m_margin, m_margin, 3*m_signalWidth/4+m_margin , m_signalHeight + m_margin);
	
	// border lines
	painter->drawLine(m_margin, m_margin, m_margin , m_signalHeight + m_margin);
	painter->drawLine(m_signalWidth+m_margin, m_margin, m_signalWidth+m_margin , m_signalHeight + m_margin);

	/** HLines *************/


	/** Labels *************/
	painter->setPen(Qt::darkGray);
	painter->drawText(0, m_signalHeight+2*m_margin+10, "10Hz");
	painter->drawText(m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "100Hz");
	painter->drawText(m_signalWidth/2 -10, m_signalHeight+2*m_margin+10, "1000Hz");
	painter->drawText(3*m_signalWidth/4 -10, m_signalHeight+2*m_margin+10, "10000Hz");
	painter->drawText(m_signalWidth -22, m_signalHeight+2*m_margin+10, "22KHz");


}

void Plotter::drawCurve(QPainter *painter){
	//painter->setRenderHint (QPainter::Antialiasing, true );
	QPolygonF polyline(m_signalWidth);

	for(int i = 0 ; i < m_curve.count() ; i++){
		int m = m_curve.at(i).y();	// Calculates pixel coordinate and Plots FFT (in green)
		if (m>m_signalHeight){m = m_signalHeight;}
		if (m<0){m = 0;}
		int y= m_signalHeight - m;
		polyline[i] = QPoint(m_curve.at(i).x() + m_margin, /*m_curve.at(i).y()*/y + m_margin);
	}

	painter->setPen(Qt::green);
    painter->drawPolyline(polyline);

}

void Plotter::drawMaskCurve(QPainter *painter){

	painter->setRenderHint (QPainter::Antialiasing, true );
	
	QPolygonF polyline(m_signalWidth);

	for(int i = 0 ; i < m_signalWidth ; i++){
		polyline[i] = QPoint(i+m_margin, m_curveMask[i]+m_margin);
	}
	painter->setPen(Qt::red);
    painter->drawPolyline(polyline);
}

void Plotter::refreshPixmap(){
    m_pixmap = QPixmap(size());
    m_pixmap.fill(this, 0, 0);

    QPainter painter(&m_pixmap);
    painter.initFrom(this);
    drawGrid(&painter);
    drawCurve(&painter);
	drawMaskCurve(&painter);
    update();
}

void Plotter::setMargin(int margin){
	m_margin = margin;
}

void Plotter::setFilter(float* filter)
{

	m_curveMask.clear();
	for (int i=0; i<m_signalWidth; i++)
	{
		m_curveMask.push_back((int) (m_signalHeight - filter[i]*(m_signalHeight/2-1)));
	}
	refreshPixmap();
}

void Plotter::enableDrawCurve(bool enable)
{
	if(enable!=m_enableDrawCurve){
		QVector<float> aux = m_curveMask;
		m_curveMask = m_oldCurveMask;
		m_oldCurveMask = aux;
		refreshPixmap();
		if(enable){
			emit filterChanged(m_curveMask);
		}
	}
	m_enableDrawCurve = enable;
}