summaryrefslogtreecommitdiffstats
path: root/weather/src/forecaststars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'weather/src/forecaststars.cpp')
-rw-r--r--weather/src/forecaststars.cpp200
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);
+ }
+}