diff options
Diffstat (limited to 'weather/src/forecaststars.cpp')
-rw-r--r-- | weather/src/forecaststars.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/weather/src/forecaststars.cpp b/weather/src/forecaststars.cpp new file mode 100644 index 0000000..97379dc --- /dev/null +++ b/weather/src/forecaststars.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: openBossa - INdT (renato.chencarek@openbossa.org) +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** the openBossa stream from INdT (renato.chencarek@openbossa.org). +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "forecaststars.h" +#include "settings.h" +#include "pixmaploader.h" + +#include <QTime> +#include <QPropertyAnimation> + +typedef struct +{ + const char * const prefix; + const qreal radius; + QString name() const { return prefix; } + QPixmap pic() const { return PixmapLoader::getPic(name()); } + +private: + +} StarObjectData; + +static const int StarTypesCount = 3; +static StarObjectData StarObjectsData[StarTypesCount] = { + {"star_01", 0.30000}, + {"star_02", 0.22428}, + {"star_03", 0.16666} +}; + +// ForecastStars + +ForecastStars::Star::Star(int type, QGraphicsItem *parent) + : QGraphicsPixmapItem(StarObjectsData[type].pic(), parent) + , starType(type) +{ + setOpacity(0.0); + hide(); +} + +ForecastStars::ForecastStars(int count, QGraphicsItem *parent) + : QGraphicsItem(parent) + , m_progress(1.0) +{ + setFlag(QGraphicsItem::ItemHasNoContents, true); + qsrand(QTime(0, 0).secsTo(QTime::currentTime()) * qrand()); + for (int i = 0; i < count; ++i) + m_starts.append(new Star(qrand() % 3, this)); +} + +int ForecastStars::loadImages() +{ + for (int i = 0; i < StarTypesCount;++i) + PixmapLoader::load(StarObjectsData[i].name()); + return StarTypesCount; +} + +QAbstractAnimation *ForecastStars::getAnimation() +{ + QPropertyAnimation *result = new QPropertyAnimation(this, "progress"); + result->setStartValue(0.0); + result->setEndValue(1.0); + result->setEasingCurve(QEasingCurve::OutBack); + result->setDuration(m_starts.count() * 100); + connect(result, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), + this, SLOT(animationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + return result; +} + +void ForecastStars::animationStateChanged(QAbstractAnimation::State newState, + QAbstractAnimation::State oldState) +{ + if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) { + foreach (Star *star, m_starts) { + star->setOpacity(0.0); + star->show(); + } + } +} + +void ForecastStars::setRect(QRectF rect) +{ + setPos(rect.topLeft()); + m_boundingRect = rect; + m_boundingRect.moveTo(0.0, 0.0); + updateStarsPositions(); +} + +QRectF ForecastStars::boundingRect () const +{ + return m_boundingRect; +} + +QRectF ForecastStars::rect() const +{ + QRectF result(m_boundingRect); + result.moveTo(pos()); + return result; +} + +void ForecastStars::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget) +{ + Q_UNUSED(painter); + Q_UNUSED(opt); + Q_UNUSED(widget); +} + +void ForecastStars::setProgress(qreal progress) +{ + m_progress = progress; + const qreal delta = 1.0 / qreal(m_starts.count()); + + for (int i = 0; i < m_starts.count(); ++i) { + qreal val = progress - i * delta; + m_starts[i]->setOpacity(val < 0.0 ? 0.0 : val > delta ? 1.0 : val / delta); + } +} + +bool ForecastStars::checkColision(const QRectF &rect1, qreal radius1, + const QRectF &rect2, qreal radius2) +{ + QPointF p1(rect1.left() + rect1.width() / 2.0, rect1.top() + rect1.height() / 2.0); + QPointF p2(rect2.left() + rect2.width() / 2.0, rect2.top() + rect2.height() / 2.0); + qreal min = radius1 + radius2; + return qAbs(p1.x() - p2.x()) > min && qAbs(p1.y() - p2.y()) > min; +} + +bool ForecastStars::checkColision(Star *item1, Star *item2) +{ + QRectF r1 = item1->boundingRect(); + r1.moveTo(item1->pos()); + qreal radius1 = item1->boundingRect().width() * StarObjectsData[item1->starType].radius; + + QRectF r2 = item2->boundingRect(); + r2.moveTo(item2->pos()); + qreal radius2 = item2->boundingRect().width() * StarObjectsData[item2->starType].radius; + + return checkColision(r1, radius1, r2, radius2); +} + +bool ForecastStars::checkColision(Star *star, const QList<Star*> &items) +{ + foreach(Star *item, items) { + if (!checkColision(star, item)) + return false; + } + return true; +} + +QPointF ForecastStars::getRandomPos(const QRectF &border) +{ + return QPointF(qreal(qrand()) / qreal(RAND_MAX) * border.width() + border.left(), + qreal(qrand()) / qreal(RAND_MAX) * border.height() + border.top()); +} + +void ForecastStars::updateStarsPositions() +{ + QList<Star*> items; + qsrand(QTime(0, 0).secsTo(QTime::currentTime()) * qrand()); + foreach(Star *star, m_starts) { + const QRectF rect(boundingRect()); + const QRectF starRect(star->boundingRect()); + const QPointF topLeft(rect.left() - starRect.left(), rect.top() - starRect.top()); + const QPointF bottomRight(rect.right() - starRect.right(), + rect.bottom() - starRect.bottom()); + const QRectF border(topLeft, bottomRight); + + int tries = 10; + do + star->setPos(getRandomPos(border)); + while (tries-- && !checkColision(star, items)); + items.append(star); + } +} |