kde-extraapps/kdeplasma-addons/applets/eyes/eyes.cpp
2015-02-27 11:02:43 +00:00

188 lines
6.2 KiB
C++

/***************************************************************************
* Copyright 2008-2009 by Olivier Goffart <ogoffart@kde.org> *
* *
* 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. *
* *
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "eyes.h"
#include <QPainter>
#include <QGraphicsView>
#include <Plasma/Theme>
#include <KDebug>
#include <math.h>
Eyes::Eyes(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args) , timerInterval(50), previousMousePos(-1,-1)
{
resize(192, 128);
m_svg = new Plasma::Svg(this);
m_svg->setImagePath(QLatin1String( "widgets/eyes" ));
m_svg->setContainsMultipleImages(true);
rightPupil = new Plasma::SvgWidget(this);
rightPupil->setSvg(m_svg);
rightPupil->setElementID(QLatin1String( "rightPupil" ));
leftPupil = new Plasma::SvgWidget(this);
leftPupil->setSvg(m_svg);
leftPupil->setElementID(QLatin1String( "leftPupil" ));
timerId = startTimer(50);
setAspectRatioMode(Plasma::IgnoreAspectRatio);
setHasConfigurationInterface(false);
}
Eyes::~Eyes()
{
}
void Eyes::constraintsEvent(Plasma::Constraints constraints)
{
Q_UNUSED(constraints)
if (constraints & Plasma::FormFactorConstraint) {
setBackgroundHints(NoBackground);
}
if (constraints & Plasma::SizeConstraint) {
if(formFactor() == Plasma::Vertical) {
setMinimumSize(QSizeF(0, boundingRect().width()/1.5));
setMaximumSize(QSizeF(-1, boundingRect().width()/1.5));
} else if(formFactor() == Plasma::Horizontal) {
setMinimumSize(QSizeF(boundingRect().height()*1.5,0));
setMaximumSize(QSizeF(boundingRect().height()*1.5,-1));
} else {
setMinimumSize(QSizeF());
setMaximumSize(QSizeF());
}
double pupilSize = qMin( qMin(boundingRect().width()/2, boundingRect().height()) / 5,
(boundingRect().width()/2 + boundingRect().height()) / 12);
leftPupil->resize(pupilSize, pupilSize);
rightPupil->resize(pupilSize, pupilSize);
}
previousMousePos = QPoint(-1,-1);
}
void Eyes::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option,
const QRect &contentsRect)
{
Q_UNUSED(option)
QRect rect = contentsRect;
rect.setWidth(rect.width()/2 - 2);
m_svg->paint(p, rect, QLatin1String( "leftEye" ));
rect.translate(rect.width() + 2*2 , 0);
m_svg->paint(p, rect, QLatin1String( "rightEye" ));
}
static QPointF pupilPos( const QRectF &eyesRect, const QPointF &mousePos)
{
const QPointF vect = mousePos - eyesRect.center(); //cursor position relative to the center of the eyes
const qreal abs_vect = vect.x() * vect.x() + vect.y() * vect.y();
if (qFuzzyCompare(vect.x() + 1 , qreal(1.0))) {
if (vect.y() > eyesRect.height()/2) {
return eyesRect.center() + QPoint( 0, eyesRect.height()/2);
} else if (vect.y() < -eyesRect.height()/2) {
return eyesRect.center() + QPoint( 0, -eyesRect.height()/2);
} else {
return mousePos;
}
}
const qreal a = eyesRect.width() / 2;
const qreal b = eyesRect.height() / 2;
const qreal tan_alpha = vect.y() / vect.x();
/*
the pupil need to be on the intersection between the line
y = x * tan_alpha
and the ellipse
x^2/a^2 + y^2/b^2
*/
qreal x = a*b / sqrt(b*b + a*a * tan_alpha*tan_alpha);
if (vect.x() < 0) {
x = -x;
}
const qreal y = x*tan_alpha;
if (abs_vect < (x * x) + (y * y)) {
return mousePos;
}
return eyesRect.center() + QPointF(x, y);
}
void Eyes::timerEvent(QTimerEvent *e)
{
if (e->timerId() != timerId) {
Plasma::Applet::timerEvent(e);
return;
}
QPoint absMousePos = QCursor::pos();
if (absMousePos == previousMousePos) {
if (timerInterval > 300)
return;
timerInterval += 50;
killTimer(timerId);
timerId = startTimer(timerInterval);
return;
}
if (timerInterval != 50) {
timerInterval = 50;
killTimer(timerId);
timerId = startTimer(timerInterval);
}
QGraphicsView *myview = view();
if (!myview) {
return;
}
previousMousePos = absMousePos;
//cursor position relative to the item coordonate
QPointF mousePos = mapFromScene( myview->mapToScene( myview->mapFromGlobal( absMousePos ) ) );
const QRectF bounding = boundingRect();
const qreal paddingX = bounding.width() / 9;
const qreal paddingY = bounding.height() / 5;
QRectF eyesRect = boundingRect();
// left pupil
eyesRect.setWidth(eyesRect.width()/2 - 2);
leftPupil->setPos(pupilPos(eyesRect.adjusted(paddingX,paddingY,-paddingX,-paddingY), mousePos)
- leftPupil->boundingRect().center());
//right pupil
eyesRect.translate(eyesRect.width() + 2*2 , 0);
rightPupil->setPos(pupilPos(eyesRect.adjusted(paddingX,paddingY,-paddingX,-paddingY), mousePos)
- rightPupil->boundingRect().center());
}
#include "moc_eyes.cpp"