diff options
Diffstat (limited to 'qfunctionconfigurator')
| -rw-r--r-- | qfunctionconfigurator/functionconfig.cpp | bin | 17350 -> 9271 bytes | |||
| -rw-r--r-- | qfunctionconfigurator/functionconfig.h | bin | 3888 -> 1964 bytes | |||
| -rw-r--r-- | qfunctionconfigurator/qfunctionconfigurator.cpp | 1421 | ||||
| -rw-r--r-- | qfunctionconfigurator/qfunctionconfigurator.h | 413 | 
4 files changed, 907 insertions, 927 deletions
| diff --git a/qfunctionconfigurator/functionconfig.cpp b/qfunctionconfigurator/functionconfig.cppBinary files differ index 243564d1..25d5599a 100644 --- a/qfunctionconfigurator/functionconfig.cpp +++ b/qfunctionconfigurator/functionconfig.cpp diff --git a/qfunctionconfigurator/functionconfig.h b/qfunctionconfigurator/functionconfig.hBinary files differ index 8dc9cf98..281007d6 100644 --- a/qfunctionconfigurator/functionconfig.h +++ b/qfunctionconfigurator/functionconfig.h diff --git a/qfunctionconfigurator/qfunctionconfigurator.cpp b/qfunctionconfigurator/qfunctionconfigurator.cpp index fe2ad49d..e143a536 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.cpp +++ b/qfunctionconfigurator/qfunctionconfigurator.cpp @@ -1,721 +1,700 @@ -/********************************************************************************
 -* FaceTrackNoIR		This program is a private project of some enthusiastic		*
 -*					gamers from Holland, who don't like to pay much for			*
 -*					head-tracking.												*
 -*																				*
 -* Copyright (C) 2012	Wim Vriend (Developing)									*
 -*						Ron Hendriks (Researching and Testing)					*
 -*																				*
 -* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				*
 -*																				*
 -* 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 3 of the License, or (at your		*
 -* option) any later version.													*
 -*																				*
 -* This program is distributed in the hope that it will be useful, but			*
 -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY	*
 -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for	*
 -* more details.																	*
 -*																				*
 -* You should have received a copy of the GNU General Public License along		*
 -* with this program; if not, see <http://www.gnu.org/licenses/>.				*
 -*																				*
 -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          *
 -* FaceTrackNoIR.																*
 -*																				*
 -* All credits for this nice piece of code should go to Stanislaw.				*
 -*																				*
 -* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					*
 -* Permission to use, copy, modify, and/or distribute this						*
 -* software for any purpose with or without fee is hereby granted,				*
 -* provided that the above copyright notice and this permission					*
 -* notice appear in all copies.													*
 -********************************************************************************/
 -/*
 -	Modifications (last one on top):
 -		20120830 - WVR: Changed functionality a bit. Now only draw the handles, when the function is drawn.
 -						Only check mouseMoves, when they occur 'in range'. Redraw the curve, when a resize occurs.
 -						Somehow, the curve was not drawn correctly, when this was not done (all points were too high). 
 -						After a 'Reset' this would disappear...
 -		20120828 - WVR: Removed bSkipText, which was used to not show a number below each vertical gridline.
 -*/
 -#include "qfunctionconfigurator.h"
 -#include <QPainter>
 -#include <QPaintEvent>
 -#include <QPainterPathStroker>
 -#include <QPainterPath>
 -#include <QBrush>
 -#include <QFileDialog>
 -#include <QPen>
 -#include <QMessageBox>
 -#include <QImage>
 -#include <QPixmap>
 -#include <QTimer>
 -
 -#include <QtDebug>
 -
 -#include <math.h>
 -
 -QFunctionConfigurator::~QFunctionConfigurator()
 -{
 -	WaitForSingleObject(_mutex, INFINITE);
 -	CloseHandle(_mutex);
 -	delete btnReset;
 -}
 -
 -static const int pointSize = 5;
 -
 -QFunctionConfigurator::QFunctionConfigurator(QWidget *parent)
 -    : QWidget(parent)
 -{
 -
 -	//
 -	// Defaults, for when the widget has no values different from the domXML()
 -	//
 -	MaxInput = 50;					// Maximum input limit
 -	MaxOutput = 180;				// Maximum output limit
 -	pPerEGU_Output = 1;				// Number of pixels, per EGU
 -	pPerEGU_Input = 4;				// Number of pixels, per EGU
 -	gDistEGU_Input = 5;				// Distance of gridlines
 -	gDistEGU_Output = 10;			// Distance of gridlines
 -
 -	
 -	// Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output)
 -	// This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..)
 -	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output);
 -
 -    setMouseTracking(true);
 -    moving = NULL;						// Pointer to the curve-point, that's being moved
 -	movingPoint = 1;				// Index of that same point
 -
 -	//
 -	// Add a Reset-button
 -	//
 -	btnReset = new QPushButton(QString("Reset"), this);
 -	connect(btnReset, SIGNAL(clicked()), this, SLOT(resetCurve()));
 -
 -	//
 -	// Variables for FunctionConfig
 -	//
 -	_config = 0;
 -	_points = QList<QPointF>();
 -	_draw_points = QList<QPointF>();
 -	_mutex = CreateMutex(NULL, false, NULL);
 -	_draw_background = true;
 -	_draw_function = true;
 -
 -//	qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created.";
 -
 -}
 -
 -//
 -// Attach an existing FunctionConfig to the Widget.
 -//
 -void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) {
 -QPointF currentPoint;
 -QPointF drawPoint;
 -qreal x;
 -
 -	WaitForSingleObject(_mutex, INFINITE);
 -	_config = config;
 -	_points = config->getPoints();
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -
 -	qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle();
 -	setCaption(config->getTitle());
 -
 -	//
 -	// Get the Function Points, one for each pixel in the horizontal range.
 -	// If the curve does not change, there is no need to run this code every time (it slows down drawing).
 -	//
 -	_draw_points.clear();
 -	for (int j = 0; j < MaxInput * pPerEGU_Input; j++) {
 -		//
 -		// Weird: not casting to float causes C++ to round the number...
 -		//
 -		x = (float) j / (float) pPerEGU_Input;
 -		currentPoint.setX ( x );
 -		currentPoint.setY (_config->getValue( x ));
 -		drawPoint = graphicalizePoint(currentPoint, "setConfig");
 -		if (withinRect(drawPoint, range)) {
 -			_draw_points.append(drawPoint);
 -//	qDebug() << "QFunctionConfigurator::setConfig _draw_Point to add = " << drawPoint;
 -		}
 -	}
 -	
 -	ReleaseMutex(_mutex);
 -	_draw_function = true;
 -	this->update();
 -}
 -
 -//
 -// Load the FunctionConfig (points) from the INI-file.
 -//
 -void QFunctionConfigurator::loadSettings(QString settingsFile) {
 -
 -	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file)
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -	qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile;
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -		_config->loadSettings(iniFile);
 -		setConfig(_config, settingsFile);
 -	}
 -	ReleaseMutex(_mutex);
 -}
 -
 -//
 -// Save the FunctionConfig (points) to the INI-file.
 -//
 -void QFunctionConfigurator::saveSettings(QString settingsFile) {
 -	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file)
 -	strSettingsFile = settingsFile;													// Remember for Reset()
 -	qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile;
 -
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -		_config->saveSettings(iniFile);
 -	}
 -	ReleaseMutex(_mutex);
 -}
 -
 -//
 -// Draw the Background for the graph, the gridlines and the gridpoints.
 -// The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up...
 -//
 -void QFunctionConfigurator::drawBackground(const QRectF &fullRect)
 -{
 -int i;
 -QRect scale;
 -
 -	qDebug() << "QFunctionConfigurator::drawBackground.";
 -
 -	_background = QPixmap(fullRect.width(), fullRect.height());
 -	QPainter painter(&_background);
 -
 -	painter.save();
 -	painter.setRenderHint(QPainter::Antialiasing);
 -	painter.fillRect(fullRect, colBackground);
 -	QColor bg_color(112, 154, 209);
 -	painter.fillRect(range, bg_color);
 -
 -	QFont font("ComicSans", 4);
 -    font.setPointSize(8);
 -    painter.setFont(font);
 -
 -    QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine);
 -
 -	//
 -	// Draw the Caption
 -	//
 -	if (_config) {
 -		strCaption = _config->getTitle();
 -	}
 -
 -	scale.setCoords(range.left(), 0, range.right(), 20);
 -	painter.drawText(scale, Qt::AlignCenter, strCaption);
 -
 -	//
 -	// Draw the horizontal grid
 -	//
 -	for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) {
 -		drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen);
 -		scale.setCoords(0, i - 5, range.left() - 5, i + 5);
 -		painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output));
 -	}
 -
 -	//
 -	// Draw the vertical guidelines
 -	//
 -	for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) {
 -		drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen);
 -		scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15);
 -		painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input)));
 -	}
 -
 -	scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35);
 -	painter.drawText(scale, Qt::AlignRight, strInputEGU);
 -
 -	//
 -	// Draw the EGU of the vertical axis (vertically!)
 -	//
 -	font.setPointSize(10);
 -	painter.translate(range.topLeft().x() - 35, range.topLeft().y());
 -	painter.rotate(90);
 -	painter.drawText(0,0,strOutputEGU );
 -
 -	//
 -	// Draw the two axis
 -	//
 -	pen.setWidth(2);
 -	pen.setColor( Qt::black );
 -	drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen);
 -	drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen);
 -
 -	painter.restore();
 -}
 -
 -
 -//
 -// Draw the Function for the graph, on a Pixmap.
 -//
 -void QFunctionConfigurator::drawFunction(const QRectF &fullRect)
 -{
 -	if (!_config)
 -		return;
 -int i;
 -QPointF prevPoint;
 -QPointF currentPoint;
 -
 -	//
 -	// Use the background picture to draw on.
 -	// ToDo: find out how to add Pixmaps, without getting it all green...
 -	//
 -	_function = QPixmap(_background);
 -	QPainter painter(&_function);
 -
 -	painter.save();
 -	painter.setRenderHint(QPainter::Antialiasing, false);
 -
 -	//
 -	// Draw the handles for the Points
 -	//
 -	for (i = 0; i < _points.size(); i++) {
 -		currentPoint = graphicalizePoint( _points[i], "drawFunction handles" );		// Get the next point and convert it to Widget measures 
 -	    drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120));
 -		lastPoint = currentPoint;											// Remember which point is the rightmost in the graph
 -//qDebug() << "QFunctionConfigurator::paintEvent, drawing handle for " << currentPoint;
 -	}
 -
 -
 -	QPen pen(colBezier, 2, Qt::SolidLine);
 -
 -	prevPoint = graphicalizePoint( QPointF(0,0), "drawFunction lines" );		// Start at the Axis
 -	double max = maxInputEGU();
 -	QPointF prev = graphicalizePoint(QPointF(0, 0));
 -    double step = 1 / (double) pixPerEGU_Input();
 -	for (double i = 0; i < max; i += step) {
 -	    double val = _config->getValue(i);
 -	    QPointF cur = graphicalizePoint(QPointF(i, val));
 -	    drawLine(&painter, prev, cur, pen);
 -		prev = cur;
 -	}
 -	painter.restore();
 -}
 -
 -//
 -// The Widget paints the surface every x msecs.
 -//
 -void QFunctionConfigurator::paintEvent(QPaintEvent *e)
 -{
 -QPointF prevPoint;
 -QPointF currentPoint;
 -QPointF actualPos;
 -int i;
 -
 -//	qDebug() << "QFunctionConfigurator::paintEvent.";
 -
 -	QPainter p(this);
 -    p.setRenderHint(QPainter::Antialiasing);
 -    p.setClipRect(e->rect());
 -
 -	if (_draw_background) {
 -		drawBackground(e->rect());						// Draw the static parts on a Pixmap
 -		p.drawPixmap(0, 0, _background);				// Paint the background
 -		_draw_background = false;
 -
 -		btnReset->move(e->rect().left(), e->rect().bottom() - btnReset->height() - 2);
 -	}
 -
 -	if (_draw_function) {
 -		drawFunction(e->rect());						// Draw the Function on a Pixmap
 -		_draw_function = false;
 -	}
 -	p.drawPixmap(0, 0, _function);						// Always draw the background and the function
 -
 -	QPen pen(Qt::white, 1, Qt::SolidLine);
 -
 -	//
 -	// Draw the Points, that make up the Curve
 -	//
 -	WaitForSingleObject(_mutex, INFINITE);
 -	if (_config) {
 -
 -		//
 -		// When moving, also draw a sketched version of the Function.
 -		//
 -		if (moving) {
 -			prevPoint = graphicalizePoint( QPointF(0,0), "paintEvent moving" );				// Start at the Axis
 -			for (i = 0; i < _points.size(); i++) {
 -				currentPoint = graphicalizePoint( _points[i], "paintEvent moving" );		// Get the next point and convert it to Widget measures 
 -				drawLine(&p, prevPoint, currentPoint, pen);
 -				prevPoint = currentPoint;
 -//	qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint;
 -			}
 -
 -			//
 -			// When moving, also draw a few help-lines, so positioning the point gets easier.
 -			//
 -			pen.setWidth(1);
 -			pen.setColor( Qt::white );
 -			pen.setStyle( Qt::DashLine );
 -			actualPos = graphicalizePoint(*moving, "paintEvent moving help line(s)");
 -			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
 -			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen);
 -		}
 -
 -		//
 -		// If the Tracker is active, the 'Last Point' it requested is recorded.
 -		// Show that point on the graph, with some lines to assist.
 -		// This new feature is very handy for tweaking the curves!
 -		//
 -		if (_config->getLastPoint( currentPoint )) {
 -
 -//	qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint;
 -
 -			actualPos = graphicalizePoint( currentPoint, "paintEvent tracking" );
 -			drawPoint(&p, actualPos, QColor(255, 0, 0, 120));
 -
 -			pen.setWidth(1);
 -			pen.setColor( Qt::black );
 -			pen.setStyle( Qt::SolidLine );
 -			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen);
 -			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen);
 -		}
 -
 -	}
 -	ReleaseMutex(_mutex);
 -
 -	//
 -	// Draw the delimiters
 -	//
 -	pen.setWidth(1);
 -	pen.setColor( Qt::white );
 -	pen.setStyle( Qt::SolidLine );
 -	drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen);
 -	drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen);
 -
 -	QTimer::singleShot(250, this, SLOT(update()));
 -}
 -
 -//
 -// Draw the handle, to move the Bezier-curve.
 -//
 -void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG )
 -{
 -    painter->save();
 -    painter->setPen(QColor(50, 100, 120, 200));
 -    painter->setBrush( colBG );
 -    painter->drawEllipse(QRectF(pos.x() - pointSize,
 -                                pos.y() - pointSize,
 -                                pointSize*2, pointSize*2));
 -    painter->restore();
 -}
 -
 -void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen)
 -{
 -    painter->save();
 -    painter->setPen(pen);
 -    painter->setBrush(Qt::NoBrush);
 -    painter->drawLine(start, end);
 -    painter->restore();
 -}
 -
 -//
 -// If the mousebutton is pressed, check if it is inside one of the Points.
 -// If so: start moving that Point, until mouse release.
 -//
 -void QFunctionConfigurator::mousePressEvent(QMouseEvent *e)
 -{
 -	//
 -	// First: check the left mouse-button
 -	//
 -	if (e->button() == Qt::LeftButton) {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		bool bTouchingPoint = false;
 -		movingPoint = -1;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent markContains" ), e->pos() ) ) {
 -					bTouchingPoint = true;
 -		            moving = &_points[i];
 -					movingPoint = i;
 -				}
 -			}
 -
 -			//
 -			// If the Left Mouse-button was clicked without touching a Point, add a new Point
 -			//
 -			if (!bTouchingPoint) {
 -				if (withinRect(e->pos(), range)) {
 -					_config->addPoint(normalizePoint(e->pos()));
 -					setConfig(_config, strSettingsFile);
 -					moving = NULL;
 -					emit CurveChanged( true );
 -				}
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -	}
 -
 -	//
 -	// Then: check the right mouse-button
 -	//
 -	if (e->button() == Qt::RightButton) {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		moving = NULL;
 -		movingPoint = -1;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent RightButton" ), e->pos() ) ) {
 -					movingPoint = i;
 -				}
 -			}
 -
 -			//
 -			// If the Right Mouse-button was clicked while touching a Point, remove the Point
 -			//
 -			if (movingPoint >= 0) {
 -				_config->removePoint(movingPoint);
 -				setConfig(_config, strSettingsFile);
 -				movingPoint = -1;
 -				emit CurveChanged( true );
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -	}
 -
 -}
 -
 -//
 -// If the mouse if moving, make sure the Bezier moves along.
 -// Of course, only when a Point is selected...
 -//
 -void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e)
 -{
 -
 -	if (moving) {
 -
 -		setCursor(Qt::ClosedHandCursor);		
 -
 -		//
 -		// Change the currently moving Point.
 -		//
 -		*moving = normalizePoint(e->pos());
 -		update();
 -    }
 -	else {
 -
 -		//
 -		// Check to see if the cursor is touching one of the points.
 -		//
 -		bool bTouchingPoint = false;
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -
 -			for (int i = 0; i < _points.size(); i++) {
 -				if ( markContains( graphicalizePoint( _points[i], "mouseMoveEvent" ), e->pos() ) ) {
 -					bTouchingPoint = true;
 -				}
 -			}
 -		}
 -		ReleaseMutex(_mutex);
 -
 -		if ( bTouchingPoint ) {
 -			setCursor(Qt::OpenHandCursor);
 -		}
 -		else {
 -			setCursor(Qt::ArrowCursor);
 -		}
 -
 -	}
 -}
 -
 -void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e)
 -{
 -    //qDebug()<<"releasing";
 -	if (moving > 0) {
 -		emit CurveChanged( true );
 -
 -		//
 -		// Update the Point in the _config
 -		//
 -		WaitForSingleObject(_mutex, INFINITE);
 -		if (_config) {
 -			_config->movePoint(movingPoint, normalizePoint(e->pos()));
 -			setConfig(_config, strSettingsFile);
 -		}
 -		ReleaseMutex(_mutex);
 -
 -	}
 -	setCursor(Qt::ArrowCursor);		
 -	moving = NULL;
 -    movingPoint = 0;
 -}
 -
 -//
 -// Determine if the mousebutton was pressed within the range of the Point.
 -//
 -bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const
 -{
 -    QRectF rect(pos.x() - pointSize,
 -                pos.y() - pointSize,
 -                pointSize*2, pointSize*2);
 -    QPainterPath path;
 -    path.addEllipse(rect);
 -    return path.contains(coord);
 -}
 -
 -bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect ) const
 -{
 -    QPainterPath path;
 -    path.addRect(rect);
 -    return path.contains(coord);
 -}
 -
 -//
 -// Convert the Point in the graph, to the real-life Point.
 -//
 -QPointF QFunctionConfigurator::normalizePoint(QPointF point) const
 -{
 -	QPointF norm;
 -
 -	norm.setX( (point.x() - range.left()) / pPerEGU_Input );
 -    norm.setY( (range.bottom() - point.y()) / pPerEGU_Output );
 -
 -	if (norm.x() > maxInputEGU())
 -		norm.setX(maxInputEGU());
 -	else if (norm.x() < 0)
 -		norm.setX(0);
 -	if (norm.y() > maxOutputEGU())
 -		norm.setY(maxOutputEGU());
 -	else if (norm.y() < 0)
 -		norm.setY(0);
 -
 -	return norm;
 -}
 -
 -//
 -// Convert the real-life Point into the graphical Point.
 -//
 -QPointF QFunctionConfigurator::graphicalizePoint(QPointF point, QString source) const
 -{
 -QPointF graph;
 -
 -	graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) );
 -	graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) );
 -
 -//	qDebug() << "QFunctionConfigurator::graphicalizePoint source = " << source << ", point = " << point << ", graph = " << graph;
 -
 -	return graph;
 -}
 -
 -void QFunctionConfigurator::setmaxInputEGU(int value)
 -{
 -    MaxInput = value;
 -	setMinimumWidth(MaxInput * pPerEGU_Input + 55);
 -//	resetCurve();
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -void QFunctionConfigurator::setmaxOutputEGU(int value)
 -{
 -    MaxOutput = value;
 -	setMinimumHeight(MaxOutput * pPerEGU_Output + 60);
 -//	resetCurve();
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined.
 -//
 -void QFunctionConfigurator::setpixPerEGU_Input(int value)
 -{
 -    pPerEGU_Input = value;
 -	setMinimumWidth(MaxInput * pPerEGU_Input + 55);
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined.
 -//
 -void QFunctionConfigurator::setpixPerEGU_Output(int value)
 -{
 -    pPerEGU_Output = value;
 -	setMinimumHeight(MaxOutput * pPerEGU_Output + 60);
 -	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 );
 -}
 -
 -//
 -// Define the distance of the grid 'in EGU' points.
 -//
 -void QFunctionConfigurator::setgridDistEGU_Input(int value)
 -{
 -    gDistEGU_Input = value;
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 -
 -//
 -// Define the distance of the grid 'in EGU' points.
 -//
 -void QFunctionConfigurator::setgridDistEGU_Output(int value)
 -{
 -    gDistEGU_Output = value;
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 -
 -void QFunctionConfigurator::setColorBezier(QColor color)
 -{
 -    colBezier = color;
 -    update();
 -}
 -void QFunctionConfigurator::setColorBackground(QColor color)
 -{
 -    colBackground = color;
 -    update();
 -}
 -
 -void QFunctionConfigurator::setInputEGU(QString egu)
 -{
 -    strInputEGU = egu;
 -    update();
 -}
 -void QFunctionConfigurator::setOutputEGU(QString egu)
 -{
 -    strOutputEGU = egu;
 -    update();
 -}
 -void QFunctionConfigurator::setCaption(QString cap)
 -{
 -    strCaption = cap;
 -    update();
 -}
 -
 -void QFunctionConfigurator::resizeEvent(QResizeEvent *e)
 -{
 -    QSize s = e->size();
 -	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output);
 -
 -	qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range;
 -
 -	if (_config) {
 -		setConfig(_config, strSettingsFile);
 -	}
 -	_draw_background = true;
 -	_draw_function = true;
 -	repaint();
 -}
 +/******************************************************************************** +* FaceTrackNoIR		This program is a private project of some enthusiastic		* +*					gamers from Holland, who don't like to pay much for			* +*					head-tracking.												* +*																				* +* Copyright (C) 2012	Wim Vriend (Developing)									* +*						Ron Hendriks (Researching and Testing)					* +*																				* +* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				* +*																				* +* 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 3 of the License, or (at your		* +* option) any later version.													* +*																				* +* This program is distributed in the hope that it will be useful, but			* +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY	* +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for	* +* more details.																	* +*																				* +* You should have received a copy of the GNU General Public License along		* +* with this program; if not, see <http://www.gnu.org/licenses/>.				* +*																				* +* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          * +* FaceTrackNoIR.																* +*																				* +* All credits for this nice piece of code should go to Stanislaw.				* +*																				* +* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					* +* Permission to use, copy, modify, and/or distribute this						* +* software for any purpose with or without fee is hereby granted,				* +* provided that the above copyright notice and this permission					* +* notice appear in all copies.													* +********************************************************************************/ +/* +	Modifications (last one on top): +		20120830 - WVR: Changed functionality a bit. Now only draw the handles, when the function is drawn. +						Only check mouseMoves, when they occur 'in range'. Redraw the curve, when a resize occurs. +						Somehow, the curve was not drawn correctly, when this was not done (all points were too high).  +						After a 'Reset' this would disappear... +		20120828 - WVR: Removed bSkipText, which was used to not show a number below each vertical gridline. +*/ +#include "qfunctionconfigurator/qfunctionconfigurator.h" +#include <QPainter> +#include <QPaintEvent> +#include <QPainterPathStroker> +#include <QPainterPath> +#include <QBrush> +#include <QFileDialog> +#include <QPen> +#include <QMessageBox> +#include <QImage> +#include <QPixmap> +#include <QTimer> + +#include <QtDebug> + +#include <math.h> + +QFunctionConfigurator::~QFunctionConfigurator() +{ +	delete btnReset; +} + +static const int pointSize = 5; + +QFunctionConfigurator::QFunctionConfigurator(QWidget *parent) +    : QWidget(parent) +{ + +	// +	// Defaults, for when the widget has no values different from the domXML() +	// +	MaxInput = 50;					// Maximum input limit +	MaxOutput = 180;				// Maximum output limit +	pPerEGU_Output = 1;				// Number of pixels, per EGU +	pPerEGU_Input = 4;				// Number of pixels, per EGU +	gDistEGU_Input = 5;				// Distance of gridlines +	gDistEGU_Output = 10;			// Distance of gridlines + +	 +	// Change compared to BezierConfigurator: X = horizontal (input), Y = vertical (output) +	// This will require the Curve-Dialog to be higher (which was the reason it was reversed in the first place..) +	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + +    setMouseTracking(true); +    moving = NULL;						// Pointer to the curve-point, that's being moved +	movingPoint = 1;				// Index of that same point + +	// +	// Add a Reset-button +	// +	btnReset = new QPushButton(QString("Reset"), this); +	connect(btnReset, SIGNAL(clicked()), this, SLOT(resetCurve())); + +	// +	// Variables for FunctionConfig +	// +	_config = 0; +	_points = QList<QPointF>(); +	_draw_points = QList<QPointF>(); +	_draw_background = true; +	_draw_function = true; + +//	qDebug() << "QFunctionConfigurator::QFunctionConfigurator object created."; + +} + +// +// Attach an existing FunctionConfig to the Widget. +// +void QFunctionConfigurator::setConfig(FunctionConfig* config, QString settingsFile) { +QPointF currentPoint; +QPointF drawPoint; +qreal x; + +	_config = config; +	_points = config->getPoints(); +	strSettingsFile = settingsFile;													// Remember for Reset() + +	qDebug() << "QFunctionConfigurator::setConfig" << config->getTitle(); +	setCaption(config->getTitle()); + +	// +	// Get the Function Points, one for each pixel in the horizontal range. +	// If the curve does not change, there is no need to run this code every time (it slows down drawing). +	// +	_draw_points.clear(); +	for (int j = 0; j < MaxInput * pPerEGU_Input; j++) { +		// +		// Weird: not casting to float causes C++ to round the number... +		// +		x = (float) j / (float) pPerEGU_Input; +		currentPoint.setX ( x ); +		currentPoint.setY (_config->getValue( x )); +		drawPoint = graphicalizePoint(currentPoint, "setConfig"); +		if (withinRect(drawPoint, range)) { +			_draw_points.append(drawPoint); +//	qDebug() << "QFunctionConfigurator::setConfig _draw_Point to add = " << drawPoint; +		} +	} +	 +	_draw_function = true; +	this->update(); +} + +// +// Load the FunctionConfig (points) from the INI-file. +// +void QFunctionConfigurator::loadSettings(QString settingsFile) { + +	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file) +	strSettingsFile = settingsFile;													// Remember for Reset() +	qDebug() << "QFunctionConfigurator::loadSettings = " << settingsFile; +	if (_config) { +		_config->loadSettings(iniFile); +		setConfig(_config, settingsFile); +	} +} + +// +// Save the FunctionConfig (points) to the INI-file. +// +void QFunctionConfigurator::saveSettings(QString settingsFile) { +	QSettings iniFile( settingsFile, QSettings::IniFormat );						// Application settings (in INI-file) +	strSettingsFile = settingsFile;													// Remember for Reset() +	qDebug() << "QFunctionConfigurator::saveSettings = " << settingsFile; + +	if (_config) { +		_config->saveSettings(iniFile); +	} +} + +// +// Draw the Background for the graph, the gridlines and the gridpoints. +// The static objects are drawn on a Pixmap, so it does not have to be repeated every paintEvent. Hope this speeds things up... +// +void QFunctionConfigurator::drawBackground(const QRectF &fullRect) +{ +int i; +QRect scale; + +	qDebug() << "QFunctionConfigurator::drawBackground."; + +	_background = QPixmap(fullRect.width(), fullRect.height()); +	QPainter painter(&_background); + +	painter.save(); +	painter.setRenderHint(QPainter::Antialiasing); +	painter.fillRect(fullRect, colBackground); +	QColor bg_color(112, 154, 209); +	painter.fillRect(range, bg_color); + +	QFont font("ComicSans", 4); +    font.setPointSize(8); +    painter.setFont(font); + +    QPen pen(QColor(55, 104, 170, 127), 1, Qt::SolidLine); + +	// +	// Draw the Caption +	// +	if (_config) { +		strCaption = _config->getTitle(); +	} + +	scale.setCoords(range.left(), 0, range.right(), 20); +	painter.drawText(scale, Qt::AlignCenter, strCaption); + +	// +	// Draw the horizontal grid +	// +	for (i = range.bottom() - gDistEGU_Output * pPerEGU_Output; i >= range.top(); i -= gDistEGU_Output * pPerEGU_Output) { +		drawLine(&painter, QPointF(40, i), QPointF(range.right(), i), pen); +		scale.setCoords(0, i - 5, range.left() - 5, i + 5); +		painter.drawText(scale, Qt::AlignRight, tr("%1").arg(((range.bottom() - i))/pPerEGU_Output)); +	} + +	// +	// Draw the vertical guidelines +	// +	for (i = range.left(); i <= range.right(); i += gDistEGU_Input * pPerEGU_Input) { +		drawLine(&painter, QPointF(i, range.top()), QPointF(i, range.bottom()), pen); +		scale.setCoords(i - 10, range.bottom() + 2, i + 10, range.bottom() + 15); +		painter.drawText(scale, Qt::AlignCenter, tr("%1").arg(abs(((range.left() - i))/pPerEGU_Input))); +	} + +	scale.setCoords(range.left(), range.bottom() + 20, range.right(), range.bottom() + 35); +	painter.drawText(scale, Qt::AlignRight, strInputEGU); + +	// +	// Draw the EGU of the vertical axis (vertically!) +	// +	font.setPointSize(10); +	painter.translate(range.topLeft().x() - 35, range.topLeft().y()); +	painter.rotate(90); +	painter.drawText(0,0,strOutputEGU ); + +	// +	// Draw the two axis +	// +	pen.setWidth(2); +	pen.setColor( Qt::black ); +	drawLine(&painter, range.topLeft() - QPointF(2,0), range.bottomLeft() - QPointF(2,0), pen); +	drawLine(&painter, range.bottomLeft(), range.bottomRight(), pen); + +	painter.restore(); +} + + +// +// Draw the Function for the graph, on a Pixmap. +// +void QFunctionConfigurator::drawFunction(const QRectF &fullRect) +{ +	if (!_config) +		return; +int i; +QPointF prevPoint; +QPointF currentPoint; + +	// +	// Use the background picture to draw on. +	// ToDo: find out how to add Pixmaps, without getting it all green... +	// +	_function = QPixmap(_background); +	QPainter painter(&_function); + +	painter.save(); +    painter.setRenderHint(QPainter::Antialiasing, true); + +	// +	// Draw the handles for the Points +	// +	for (i = 0; i < _points.size(); i++) { +		currentPoint = graphicalizePoint( _points[i], "drawFunction handles" );		// Get the next point and convert it to Widget measures  +	    drawPoint(&painter, currentPoint, QColor(200, 200, 210, 120)); +		lastPoint = currentPoint;											// Remember which point is the rightmost in the graph +//qDebug() << "QFunctionConfigurator::paintEvent, drawing handle for " << currentPoint; +	} + + +    QPen pen(colBezier, 1.5, Qt::SolidLine); + +	prevPoint = graphicalizePoint( QPointF(0,0), "drawFunction lines" );		// Start at the Axis +	double max = maxInputEGU(); +	QPointF prev = graphicalizePoint(QPointF(0, 0)); +    double step = 1 / (double) pixPerEGU_Input(); +	for (double i = 0; i < max; i += step) { +	    double val = _config->getValue(i); +	    QPointF cur = graphicalizePoint(QPointF(i, val)); +	    drawLine(&painter, prev, cur, pen); +		prev = cur; +	} +	painter.restore(); +} + +// +// The Widget paints the surface every x msecs. +// +void QFunctionConfigurator::paintEvent(QPaintEvent *e) +{ +QPointF prevPoint; +QPointF currentPoint; +QPointF actualPos; +int i; + +//	qDebug() << "QFunctionConfigurator::paintEvent."; + +	QPainter p(this); +    p.setRenderHint(QPainter::Antialiasing); +    p.setClipRect(e->rect()); + +	if (_draw_background) { +		drawBackground(e->rect());						// Draw the static parts on a Pixmap +		p.drawPixmap(0, 0, _background);				// Paint the background +		_draw_background = false; + +		btnReset->move(e->rect().left(), e->rect().bottom() - btnReset->height() - 2); +	} + +	if (_draw_function) { +		drawFunction(e->rect());						// Draw the Function on a Pixmap +		_draw_function = false; +	} +	p.drawPixmap(0, 0, _function);						// Always draw the background and the function + +	QPen pen(Qt::white, 1, Qt::SolidLine); + +	// +	// Draw the Points, that make up the Curve +	// +	if (_config) { + +		// +		// When moving, also draw a sketched version of the Function. +		// +		if (moving) { +			prevPoint = graphicalizePoint( QPointF(0,0), "paintEvent moving" );				// Start at the Axis +			for (i = 0; i < _points.size(); i++) { +				currentPoint = graphicalizePoint( _points[i], "paintEvent moving" );		// Get the next point and convert it to Widget measures  +				drawLine(&p, prevPoint, currentPoint, pen); +				prevPoint = currentPoint; +//	qDebug() << "QFunctionConfigurator::paintEvent, drawing while moving " << currentPoint; +			} + +			// +			// When moving, also draw a few help-lines, so positioning the point gets easier. +			// +			pen.setWidth(1); +			pen.setColor( Qt::white ); +			pen.setStyle( Qt::DashLine ); +			actualPos = graphicalizePoint(*moving, "paintEvent moving help line(s)"); +			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); +			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen); +		} + +		// +		// If the Tracker is active, the 'Last Point' it requested is recorded. +		// Show that point on the graph, with some lines to assist. +		// This new feature is very handy for tweaking the curves! +		// +		if (_config->getLastPoint( currentPoint )) { + +//	qDebug() << "QFunctionConfigurator::paintEvent, drawing tracked Point " << currentPoint; + +			actualPos = graphicalizePoint( currentPoint, "paintEvent tracking" ); +			drawPoint(&p, actualPos, QColor(255, 0, 0, 120)); + +			pen.setWidth(1); +			pen.setColor( Qt::black ); +			pen.setStyle( Qt::SolidLine ); +			drawLine(&p, QPoint(range.left(), actualPos.y()), QPoint(actualPos.x(), actualPos.y()), pen); +			drawLine(&p, QPoint(actualPos.x(), actualPos.y()), QPoint(actualPos.x(), range.bottom()), pen); +		} + +	} + +	// +	// Draw the delimiters +	// +	pen.setWidth(1); +	pen.setColor( Qt::white ); +	pen.setStyle( Qt::SolidLine ); +	drawLine(&p, QPoint(lastPoint.x(), range.top()), QPoint(lastPoint.x(), range.bottom()), pen); +	drawLine(&p, QPoint(range.left(), lastPoint.y()), QPoint(range.right(), lastPoint.y()), pen); + +    QTimer::singleShot(50, this, SLOT(update())); +} + +// +// Draw the handle, to move the Bezier-curve. +// +void QFunctionConfigurator::drawPoint(QPainter *painter, const QPointF &pos, QColor colBG ) +{ +    painter->save(); +    painter->setPen(QColor(50, 100, 120, 200)); +    painter->setBrush( colBG ); +    painter->drawEllipse(QRectF(pos.x() - pointSize, +                                pos.y() - pointSize, +                                pointSize*2, pointSize*2)); +    painter->restore(); +} + +void QFunctionConfigurator::drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen) +{ +    painter->save(); +    painter->setPen(pen); +    painter->setBrush(Qt::NoBrush); +    painter->drawLine(start, end); +    painter->restore(); +} + +// +// If the mousebutton is pressed, check if it is inside one of the Points. +// If so: start moving that Point, until mouse release. +// +void QFunctionConfigurator::mousePressEvent(QMouseEvent *e) +{ +	// +	// First: check the left mouse-button +	// +	if (e->button() == Qt::LeftButton) { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		bool bTouchingPoint = false; +		movingPoint = -1; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent markContains" ), e->pos() ) ) { +					bTouchingPoint = true; +		            moving = &_points[i]; +					movingPoint = i; +				} +			} + +			// +			// If the Left Mouse-button was clicked without touching a Point, add a new Point +			// +			if (!bTouchingPoint) { +				if (withinRect(e->pos(), range)) { +					_config->addPoint(normalizePoint(e->pos())); +					setConfig(_config, strSettingsFile); +					moving = NULL; +					emit CurveChanged( true ); +				} +			} +		} +	} + +	// +	// Then: check the right mouse-button +	// +	if (e->button() == Qt::RightButton) { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		moving = NULL; +		movingPoint = -1; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mousePressEvent RightButton" ), e->pos() ) ) { +					movingPoint = i; +				} +			} + +			// +			// If the Right Mouse-button was clicked while touching a Point, remove the Point +			// +			if (movingPoint >= 0) { +				_config->removePoint(movingPoint); +				setConfig(_config, strSettingsFile); +				movingPoint = -1; +				emit CurveChanged( true ); +			} +		} +	} + +} + +// +// If the mouse if moving, make sure the Bezier moves along. +// Of course, only when a Point is selected... +// +void QFunctionConfigurator::mouseMoveEvent(QMouseEvent *e) +{ + +	if (moving) { + +		setCursor(Qt::ClosedHandCursor);		 + +		// +		// Change the currently moving Point. +		// +		*moving = normalizePoint(e->pos()); +		update(); +    } +	else { + +		// +		// Check to see if the cursor is touching one of the points. +		// +		bool bTouchingPoint = false; +		if (_config) { + +			for (int i = 0; i < _points.size(); i++) { +				if ( markContains( graphicalizePoint( _points[i], "mouseMoveEvent" ), e->pos() ) ) { +					bTouchingPoint = true; +				} +			} +		} + +		if ( bTouchingPoint ) { +			setCursor(Qt::OpenHandCursor); +		} +		else { +			setCursor(Qt::ArrowCursor); +		} + +	} +} + +void QFunctionConfigurator::mouseReleaseEvent(QMouseEvent *e) +{ +    //qDebug()<<"releasing"; +	if (moving > 0) { +		emit CurveChanged( true ); + +		// +		// Update the Point in the _config +		// +		if (_config) { +			_config->movePoint(movingPoint, normalizePoint(e->pos())); +			setConfig(_config, strSettingsFile); +		} +	} +	setCursor(Qt::ArrowCursor);		 +	moving = NULL; +    movingPoint = 0; +} + +// +// Determine if the mousebutton was pressed within the range of the Point. +// +bool QFunctionConfigurator::markContains(const QPointF &pos, const QPointF &coord) const +{ +    QRectF rect(pos.x() - pointSize, +                pos.y() - pointSize, +                pointSize*2, pointSize*2); +    QPainterPath path; +    path.addEllipse(rect); +    return path.contains(coord); +} + +bool QFunctionConfigurator::withinRect( const QPointF &coord, const QRectF &rect ) const +{ +    QPainterPath path; +    path.addRect(rect); +    return path.contains(coord); +} + +// +// Convert the Point in the graph, to the real-life Point. +// +QPointF QFunctionConfigurator::normalizePoint(QPointF point) const +{ +	QPointF norm; + +	norm.setX( (point.x() - range.left()) / pPerEGU_Input ); +    norm.setY( (range.bottom() - point.y()) / pPerEGU_Output ); + +	if (norm.x() > maxInputEGU()) +		norm.setX(maxInputEGU()); +	else if (norm.x() < 0) +		norm.setX(0); +	if (norm.y() > maxOutputEGU()) +		norm.setY(maxOutputEGU()); +	else if (norm.y() < 0) +		norm.setY(0); + +	return norm; +} + +// +// Convert the real-life Point into the graphical Point. +// +QPointF QFunctionConfigurator::graphicalizePoint(QPointF point, QString source) const +{ +QPointF graph; + +	graph.setX( range.left() + (fabs(point.x()) * pPerEGU_Input) ); +	graph.setY( range.bottom() - (fabs(point.y()) * pPerEGU_Output) ); + +//	qDebug() << "QFunctionConfigurator::graphicalizePoint source = " << source << ", point = " << point << ", graph = " << graph; + +	return graph; +} + +void QFunctionConfigurator::setmaxInputEGU(int value) +{ +    MaxInput = value; +	setMinimumWidth(MaxInput * pPerEGU_Input + 55); +//	resetCurve(); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} +void QFunctionConfigurator::setmaxOutputEGU(int value) +{ +    MaxOutput = value; +	setMinimumHeight(MaxOutput * pPerEGU_Output + 60); +//	resetCurve(); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. +// +void QFunctionConfigurator::setpixPerEGU_Input(int value) +{ +    pPerEGU_Input = value; +	setMinimumWidth(MaxInput * pPerEGU_Input + 55); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// To make configuration more visibly attractive, the number of pixels 'per EGU' can be defined. +// +void QFunctionConfigurator::setpixPerEGU_Output(int value) +{ +    pPerEGU_Output = value; +	setMinimumHeight(MaxOutput * pPerEGU_Output + 60); +	resize( MaxInput * pPerEGU_Input + 55, MaxOutput * pPerEGU_Output + 60 ); +} + +// +// Define the distance of the grid 'in EGU' points. +// +void QFunctionConfigurator::setgridDistEGU_Input(int value) +{ +    gDistEGU_Input = value; +	_draw_background = true; +	_draw_function = true; +	repaint(); +} + +// +// Define the distance of the grid 'in EGU' points. +// +void QFunctionConfigurator::setgridDistEGU_Output(int value) +{ +    gDistEGU_Output = value; +	_draw_background = true; +	_draw_function = true; +	repaint(); +} + +void QFunctionConfigurator::setColorBezier(QColor color) +{ +    colBezier = color; +    update(); +} +void QFunctionConfigurator::setColorBackground(QColor color) +{ +    colBackground = color; +    update(); +} + +void QFunctionConfigurator::setInputEGU(QString egu) +{ +    strInputEGU = egu; +    update(); +} +void QFunctionConfigurator::setOutputEGU(QString egu) +{ +    strOutputEGU = egu; +    update(); +} +void QFunctionConfigurator::setCaption(QString cap) +{ +    strCaption = cap; +    update(); +} + +void QFunctionConfigurator::resizeEvent(QResizeEvent *e) +{ +	range = QRectF(40, 20, MaxInput * pPerEGU_Input, MaxOutput * pPerEGU_Output); + +	qDebug() << "QFunctionConfigurator::resizeEvent, name = " << strCaption << ",range = " << range; + +	if (_config) { +		setConfig(_config, strSettingsFile); +	} +	_draw_background = true; +	_draw_function = true; +	repaint(); +} diff --git a/qfunctionconfigurator/qfunctionconfigurator.h b/qfunctionconfigurator/qfunctionconfigurator.h index c467bc92..6ad810c1 100644 --- a/qfunctionconfigurator/qfunctionconfigurator.h +++ b/qfunctionconfigurator/qfunctionconfigurator.h @@ -1,206 +1,207 @@ -/********************************************************************************
 -* FaceTrackNoIR		This program is a private project of some enthusiastic		*
 -*					gamers from Holland, who don't like to pay much for			*
 -*					head-tracking.												*
 -*																				*
 -* Copyright (C) 2012	Wim Vriend (Developing)									*
 -*						Ron Hendriks (Researching and Testing)					*
 -*																				*
 -* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				*
 -*																				*
 -* 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 3 of the License, or (at your		*
 -* option) any later version.													*
 -*																				*
 -* This program is distributed in the hope that it will be useful, but			*
 -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY	*
 -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for	*
 -* more details.																	*
 -*																				*
 -* You should have received a copy of the GNU General Public License along		*
 -* with this program; if not, see <http://www.gnu.org/licenses/>.				*
 -*																				*
 -* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          *
 -* FaceTrackNoIR.																*
 -*																				*
 -* All credits for this nice piece of code should go to Stanislaw.				*
 -*																				*
 -* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					*
 -* Permission to use, copy, modify, and/or distribute this						*
 -* software for any purpose with or without fee is hereby granted,				*
 -* provided that the above copyright notice and this permission					*
 -* notice appear in all copies.													*
 -********************************************************************************/
 -#ifndef QFUNCTIONCONFIGURATOR_H
 -#define QFUNCTIONCONFIGURATOR_H
 -
 -#include <QtGui>
 -#include <QtDesigner/QDesignerExportWidget>
 -#include <QPointF>
 -#include "FunctionConfig.h"
 -
 -//
 -// The FunctionConfigurator Widget is used to display and configure a function (curve).
 -// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function.
 -//
 -// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the
 -// Widget and the Widget used to change the Function.
 -//
 -class QDESIGNER_WIDGET_EXPORT QFunctionConfigurator : public QWidget
 -{
 -	Q_OBJECT
 -    Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU);
 -    Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU);
 -    Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input);
 -    Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output);
 -    Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input);
 -    Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output);
 -
 -	Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier);
 -    Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground);
 -    Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU);
 -    Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU);
 -    Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption);
 -
 -	// Return the current value to Designer
 -	int maxInputEGU() const
 -    {
 -        return MaxInput;
 -    }
 -	int maxOutputEGU() const
 -    {
 -        return MaxOutput;
 -    }
 -	int pixPerEGU_Input() const
 -    {
 -        return pPerEGU_Input;
 -    }
 -	int pixPerEGU_Output() const
 -    {
 -        return pPerEGU_Output;
 -    }
 -	int gridDistEGU_Input() const
 -    {
 -        return gDistEGU_Input;
 -    }
 -	int gridDistEGU_Output() const
 -    {
 -        return gDistEGU_Output;
 -    }
 -
 -	// Return the current color to Designer
 -	QColor colorBezier() const
 -    {
 -        return colBezier;
 -    }
 -	// Return the current color to Designer
 -	QColor colorBackground() const
 -    {
 -        return colBackground;
 -    }
 -	// Return the current string to Designer
 -	QString stringInputEGU() const
 -    {
 -        return strInputEGU;
 -    }
 -	// Return the current string to Designer
 -	QString stringOutputEGU() const
 -    {
 -        return strOutputEGU;
 -    }
 -	// Return the current string to Designer
 -	QString stringCaption() const
 -    {
 -        return strCaption;
 -    }
 -
 -public:
 -	QFunctionConfigurator(QWidget *parent = 0);
 -	~QFunctionConfigurator();
 -	FunctionConfig* config();
 -
 -	void setConfig(FunctionConfig* config, QString settingsFile);		// Connect the FunctionConfig to the Widget.
 -	void loadSettings(QString settingsFile);							// Load the FunctionConfig (points) from the INI-file
 -	void saveSettings(QString settingsFile);							// Save the FunctionConfig (points) to the INI-file
 -
 -signals:
 -    void CurveChanged(bool);
 -
 -public slots:
 -    void setmaxInputEGU(int);
 -    void setmaxOutputEGU(int);
 -    void setpixPerEGU_Input(int);
 -    void setpixPerEGU_Output(int);
 -    void setgridDistEGU_Input(int);
 -    void setgridDistEGU_Output(int);
 -
 -    void setColorBezier(QColor);
 -    void setColorBackground(QColor);
 -    void setInputEGU(QString);
 -    void setOutputEGU(QString);
 -    void setCaption(QString);
 -
 -	void resetCurve() {
 -		qDebug() << "QFunctionConfigurator::resetCurve = " << strSettingsFile;
 -		loadSettings( strSettingsFile );
 -	}
 -
 -protected slots:
 -	void paintEvent(QPaintEvent *e);
 -	void mousePressEvent(QMouseEvent *e);
 -	void mouseMoveEvent(QMouseEvent *e);
 -	void mouseReleaseEvent(QMouseEvent *e);
 -      
 -protected:
 -	void drawBackground(const QRectF &rect);
 -	void drawFunction(const QRectF &rect);
 -	void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG );
 -	void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen);
 -	bool markContains(const QPointF &pt, const QPointF &coord) const;
 -//	bool withinRange( const QPointF &coord ) const;
 -	bool withinRect( const QPointF &coord, const QRectF &rect ) const;
 -
 -protected:
 -	virtual void resizeEvent(QResizeEvent *);
 -
 -private:
 -	QRectF  range;														// The actual rectangle for the Bezier-curve
 -	QPointF lastPoint;													// The right-most point of the Function
 -	QPointF normalizePoint (QPointF point) const;						// Convert the graphical Point to a real-life Point
 -	QPointF graphicalizePoint (QPointF point, QString source = "") const;	// Convert the Point to a graphical Point
 -
 -	QPointF *moving;
 -	int     movingPoint;
 -
 -	int MaxInput;					// Maximum input limit
 -	int MaxOutput;					// Maximum output limit
 -	int pPerEGU_Input;				// Number of pixels, per EGU of Input
 -	int pPerEGU_Output;				// Number of pixels, per EGU of Output
 -	int gDistEGU_Input;				// Distance of the grid, in EGU of Input
 -	int gDistEGU_Output;			// Distance of the grid, in EGU of Output
 -
 -	QColor colBezier;				// Color of Bezier curve
 -	QColor colBackground;			// Color of widget background
 -	QString strInputEGU;			// Engineering Units input (vertical axis)
 -	QString strOutputEGU;			// Engineering Units output (horizontal axis)
 -	QString strCaption;				// Caption of the graph
 -	QString strSettingsFile;		// Name of last read INI-file
 -	QPushButton *btnReset;			// Reset Curve
 -
 -	bool _draw_background;			// Flag to determine if the background should be (re-)drawn on the QPixmap
 -	QPixmap _background;			// Image of the static parts (axis, lines, etc.)
 -	bool _draw_function;			// Flag to determine if the function should be (re-)drawn on the QPixmap
 -	QPixmap _function;				// Image of the function (static unless edited by the user)
 -
 -	//
 -	// Properties of the CurveConfigurator Widget
 -	//
 -	QString _title;								// Title do display in Widget and to load Settings
 -	FunctionConfig* _config;
 -	QList<QPointF> _points;			// Function-points
 -	QList<QPointF> _draw_points;	// Curve-points needed for drawing
 -	HANDLE _mutex;
 -};
 -
 -#endif // QFUNCTIONCONFIGURATOR_H
 +/******************************************************************************** +* FaceTrackNoIR		This program is a private project of some enthusiastic		* +*					gamers from Holland, who don't like to pay much for			* +*					head-tracking.												* +*																				* +* Copyright (C) 2012	Wim Vriend (Developing)									* +*						Ron Hendriks (Researching and Testing)					* +*																				* +* Homepage	http://facetracknoir.sourceforge.net/home/default.htm				* +*																				* +* 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 3 of the License, or (at your		* +* option) any later version.													* +*																				* +* This program is distributed in the hope that it will be useful, but			* +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY	* +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for	* +* more details.																	* +*																				* +* You should have received a copy of the GNU General Public License along		* +* with this program; if not, see <http://www.gnu.org/licenses/>.				* +*																				* +* The FunctionConfigurator was made by Stanislaw Halik, and adapted to          * +* FaceTrackNoIR.																* +*																				* +* All credits for this nice piece of code should go to Stanislaw.				* +*																				* +* Copyright (c) 2011-2012, Stanislaw Halik <sthalik@misaki.pl>					* +* Permission to use, copy, modify, and/or distribute this						* +* software for any purpose with or without fee is hereby granted,				* +* provided that the above copyright notice and this permission					* +* notice appear in all copies.													* +********************************************************************************/ +#ifndef QFUNCTIONCONFIGURATOR_H +#define QFUNCTIONCONFIGURATOR_H + +#include <QWidget> +#include <QtGui> +#include <QtDesigner/QDesignerExportWidget> +#include <QPointF> +#include "qfunctionconfigurator/functionconfig.h" +#include "ftnoir_tracker_base/ftnoir_tracker_base.h" + +// +// The FunctionConfigurator Widget is used to display and configure a function (curve). +// The Function is used by FaceTrackNoIR to 'translate' the actual head-pose to the virtual headpose. Every axis is configured by a separate Function. +// +// The Function is coded in a separate Class and can exists, without the Widget. When the widget is displayed (therefore 'created'), the Function can be attached to the +// Widget and the Widget used to change the Function. +// +class FTNOIR_TRACKER_BASE_EXPORT QFunctionConfigurator : public QWidget +{ +	Q_OBJECT +    Q_PROPERTY(int maxInputEGU READ maxInputEGU WRITE setmaxInputEGU); +    Q_PROPERTY(int maxOutputEGU READ maxOutputEGU WRITE setmaxOutputEGU); +    Q_PROPERTY(int pixPerEGU_Input READ pixPerEGU_Input WRITE setpixPerEGU_Input); +    Q_PROPERTY(int pixPerEGU_Output READ pixPerEGU_Output WRITE setpixPerEGU_Output); +    Q_PROPERTY(int gridDistEGU_Input READ gridDistEGU_Input WRITE setgridDistEGU_Input); +    Q_PROPERTY(int gridDistEGU_Output READ gridDistEGU_Output WRITE setgridDistEGU_Output); + +	Q_PROPERTY(QColor colorBezier READ colorBezier WRITE setColorBezier); +    Q_PROPERTY(QColor colorBackground READ colorBackground WRITE setColorBackground); +    Q_PROPERTY(QString stringInputEGU READ stringInputEGU WRITE setInputEGU); +    Q_PROPERTY(QString stringOutputEGU READ stringOutputEGU WRITE setOutputEGU); +    Q_PROPERTY(QString stringCaption READ stringCaption WRITE setCaption); + +	// Return the current value to Designer +	int maxInputEGU() const +    { +        return MaxInput; +    } +	int maxOutputEGU() const +    { +        return MaxOutput; +    } +	int pixPerEGU_Input() const +    { +        return pPerEGU_Input; +    } +	int pixPerEGU_Output() const +    { +        return pPerEGU_Output; +    } +	int gridDistEGU_Input() const +    { +        return gDistEGU_Input; +    } +	int gridDistEGU_Output() const +    { +        return gDistEGU_Output; +    } + +	// Return the current color to Designer +	QColor colorBezier() const +    { +        return colBezier; +    } +	// Return the current color to Designer +	QColor colorBackground() const +    { +        return colBackground; +    } +	// Return the current string to Designer +	QString stringInputEGU() const +    { +        return strInputEGU; +    } +	// Return the current string to Designer +	QString stringOutputEGU() const +    { +        return strOutputEGU; +    } +	// Return the current string to Designer +	QString stringCaption() const +    { +        return strCaption; +    } + +public: +	QFunctionConfigurator(QWidget *parent = 0); +	~QFunctionConfigurator(); +	FunctionConfig* config(); + +	void setConfig(FunctionConfig* config, QString settingsFile);		// Connect the FunctionConfig to the Widget. +	void loadSettings(QString settingsFile);							// Load the FunctionConfig (points) from the INI-file +	void saveSettings(QString settingsFile);							// Save the FunctionConfig (points) to the INI-file + +signals: +    void CurveChanged(bool); + +public slots: +    void setmaxInputEGU(int); +    void setmaxOutputEGU(int); +    void setpixPerEGU_Input(int); +    void setpixPerEGU_Output(int); +    void setgridDistEGU_Input(int); +    void setgridDistEGU_Output(int); + +    void setColorBezier(QColor); +    void setColorBackground(QColor); +    void setInputEGU(QString); +    void setOutputEGU(QString); +    void setCaption(QString); + +	void resetCurve() { +		qDebug() << "QFunctionConfigurator::resetCurve = " << strSettingsFile; +		loadSettings( strSettingsFile ); +	} + +protected slots: +	void paintEvent(QPaintEvent *e); +	void mousePressEvent(QMouseEvent *e); +	void mouseMoveEvent(QMouseEvent *e); +	void mouseReleaseEvent(QMouseEvent *e); +       +protected: +	void drawBackground(const QRectF &rect); +	void drawFunction(const QRectF &rect); +	void drawPoint(QPainter *painter, const QPointF &pt, QColor colBG ); +	void drawLine(QPainter *painter, const QPointF &start, const QPointF &end, QPen pen); +	bool markContains(const QPointF &pt, const QPointF &coord) const; +//	bool withinRange( const QPointF &coord ) const; +	bool withinRect( const QPointF &coord, const QRectF &rect ) const; + +protected: +	virtual void resizeEvent(QResizeEvent *); + +private: +	QRectF  range;														// The actual rectangle for the Bezier-curve +	QPointF lastPoint;													// The right-most point of the Function +	QPointF normalizePoint (QPointF point) const;						// Convert the graphical Point to a real-life Point +	QPointF graphicalizePoint (QPointF point, QString source = "") const;	// Convert the Point to a graphical Point + +	QPointF *moving; +	int     movingPoint; + +	int MaxInput;					// Maximum input limit +	int MaxOutput;					// Maximum output limit +	int pPerEGU_Input;				// Number of pixels, per EGU of Input +	int pPerEGU_Output;				// Number of pixels, per EGU of Output +	int gDistEGU_Input;				// Distance of the grid, in EGU of Input +	int gDistEGU_Output;			// Distance of the grid, in EGU of Output + +	QColor colBezier;				// Color of Bezier curve +	QColor colBackground;			// Color of widget background +	QString strInputEGU;			// Engineering Units input (vertical axis) +	QString strOutputEGU;			// Engineering Units output (horizontal axis) +	QString strCaption;				// Caption of the graph +	QString strSettingsFile;		// Name of last read INI-file +	QPushButton *btnReset;			// Reset Curve + +	bool _draw_background;			// Flag to determine if the background should be (re-)drawn on the QPixmap +	QPixmap _background;			// Image of the static parts (axis, lines, etc.) +	bool _draw_function;			// Flag to determine if the function should be (re-)drawn on the QPixmap +	QPixmap _function;				// Image of the function (static unless edited by the user) + +	// +	// Properties of the CurveConfigurator Widget +	// +	QString _title;								// Title do display in Widget and to load Settings +	FunctionConfig* _config; +	QList<QPointF> _points;			// Function-points +	QList<QPointF> _draw_points;	// Curve-points needed for drawing +}; + +#endif // QFUNCTIONCONFIGURATOR_H | 
