/**************************************************************************** ** ** 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 #include 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 &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 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); } }