diff options
Diffstat (limited to 'hyperui/src/clockwidget.cpp')
-rw-r--r-- | hyperui/src/clockwidget.cpp | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/hyperui/src/clockwidget.cpp b/hyperui/src/clockwidget.cpp new file mode 100644 index 0000000..b6388b5 --- /dev/null +++ b/hyperui/src/clockwidget.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** 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 <QPainter> +#include <QDateTime> +#include <QRadialGradient> + +#include "global.h" +#include "dataresource.h" +#include "clockwidget.h" + + +class ClockEvent +{ +public: + ClockEvent(const QDateTime &begin, const QDateTime &end, + const QColor &color, const QString &text) + : begin(begin), end(end), color(color), text(text) { } + + QDateTime begin; + QDateTime end; + QColor color; + QString text; +}; + + +ClockWidget::ClockWidget(QGraphicsItem *parent) + : QGraphicsWidget(parent), + m_background(Resource::pixmap("idle_clock_structure.png")), + m_divLine(Resource::pixmap("idle_line.png")), + m_middleKnob(Resource::pixmap("idle_clock_pointers_middle.png")), + m_hourPointer(Resource::pixmap("idle_clock_pointer_hour.png")), + m_minutePointer(Resource::pixmap("idle_clock_pointer_minutes.png")) +{ + QFont defaultFont(Resource::stringValue("default/font-family")); + m_fontColor = QColor(Resource::stringValue("clock-widget/font-color")); + + m_dayFont = defaultFont; + m_dayFont.setBold(true); + m_dayFont.setPixelSize(Resource::intValue("clock-widget/day-font-size")); + + m_labelFont = defaultFont; + m_labelFont.setPixelSize(Resource::intValue("clock-widget/label-font-size")); + + m_weekDayFont = defaultFont; + m_weekDayFont.setPixelSize(Resource::intValue("clock-widget/wday-font-size")); + + m_labelHeight = Resource::intValue("clock-widget/label-height"); + m_labelPos = Resource::value("clock-widget/label-init-pos").toPoint(); + m_knobPoint = Resource::value("clock-widget/knob-pos").toPoint(); + m_middlePoint = Resource::value("clock-widget/middle-pos").toPoint(); + m_dayRect = Resource::value("clock-widget/day-label-rect").toRect(); + m_weekDayRect = Resource::value("clock-widget/wday-label-rect").toRect(); + m_eventsPixmapRect = Resource::value("clock-widget/events-pixmap-rect").toRect(); + m_eventsInnerOffset = Resource::intValue("clock-widget/events-inner-offset"); + m_eventsInnerDiameter = Resource::intValue("clock-widget/events-inner-diameter"); + + setMinimumSize(m_background.size()); + setMaximumSize(m_background.size()); + + connect(&m_timer, SIGNAL(timeout()), SLOT(updateTime())); + m_timer.start(Resource::intValue("clock-widget/update-timeout")); + + m_eventsPixmap = QPixmap(m_eventsPixmapRect.size()); +} + +ClockWidget::~ClockWidget() +{ + qDeleteAll(m_events); +} + +void ClockWidget::addEvent(const QDateTime &begin, const QDateTime &end, + const QColor &color, const QString &text) +{ + m_events.append(new ClockEvent(begin, end, color, text)); + updateEvents(); + update(); +} + +void ClockWidget::updateTime() +{ + update(); +} + +void ClockWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + // store and adjust render hints + const QPainter::RenderHints hints = painter->renderHints(); + painter->setRenderHints(hints | QPainter::SmoothPixmapTransform); + + // draw clock base pixmap + painter->drawPixmap(0, 0, m_background); + + // draw day information + const QDateTime &dateTime = QDateTime::currentDateTime(); + painter->setPen(m_fontColor); + painter->setFont(m_dayFont); + painter->drawText(m_dayRect, Qt::AlignHCenter | Qt::AlignVCenter, + dateTime.toString("dd")); + painter->setFont(m_weekDayFont); + painter->drawText(m_weekDayRect, Qt::AlignHCenter | Qt::AlignVCenter, + dateTime.toString("ddd").toUpper()); + + painter->drawPixmap(m_eventsPixmapRect.x(), m_eventsPixmapRect.y(), + m_eventsPixmap); + + // calculate min/hour pointer angles + const QTime &time = dateTime.time(); + const int hourAngle = 180 + qRound(30.0 * (time.hour() + time.minute() / 60.0)); + const int minuteAngle = 180 + qRound(6.0 * (time.minute() + time.second() / 60.0)); + + // paint minute pointer + painter->save(); + painter->translate(m_middlePoint); + painter->rotate(minuteAngle); + painter->drawPixmap(-m_minutePointer.width() / 2, 0, m_minutePointer); + painter->restore(); + + // paint hour pointer + painter->save(); + painter->translate(m_middlePoint); + painter->rotate(hourAngle); + painter->drawPixmap(-m_hourPointer.width() / 2, 0, m_hourPointer); + painter->restore(); + + // paint middle knob + painter->drawPixmap(m_knobPoint, m_middleKnob); + + int i = 0; + int bx = m_labelPos.x(); + int by = m_labelPos.y(); + int bw = m_divLine.width(); + + QString lastText; + QFont font = m_labelFont; + painter->drawPixmap(bx, by, m_divLine); + + // paint events descriptions + foreach (ClockEvent *event, m_events) { + // show different events + if (event->text == lastText) + continue; + + lastText = event->text; + + painter->setPen(event->color); + painter->setBrush(event->color); + painter->drawRoundedRect(bx + 4, by + 0.3 * m_labelHeight, + 0.1 * bw, 0.5 * m_labelHeight, 2, 2); + + font.setBold(true); + painter->setFont(font); + drawTextWithShadow(painter, bx + 0.13 * bw, by + 0.75 * m_labelHeight, + event->begin.toString("hh:mm"), Qt::white); + + font.setBold(false); + painter->setFont(font); + drawTextWithShadow(painter, bx + 0.3 * bw, by + 0.75 * m_labelHeight, + event->text, m_fontColor); + + painter->drawPixmap(bx, by + m_labelHeight, m_divLine); + + by += m_labelHeight; + + // show just two events + if (++i > 1) break; + } + + // restore render hints + painter->setRenderHints(hints); +} + + +void ClockWidget::updateEvents() +{ + // clear the cache + m_eventsPixmap.fill(Qt::transparent); + + QPainter painter(&m_eventsPixmap); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + + painter.setOpacity(0.9); + painter.setPen(Qt::NoPen); + + const int inner = m_eventsInnerOffset; + const int diameter = m_eventsInnerDiameter; + + foreach (ClockEvent *event, m_events) { + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + + // calculate start angle + const QTime &ta = event->begin.time(); + int ia = qRound(30.0 * (ta.hour() + ta.minute() / 60.0)); + + // calculate end angle + const QTime &tb = event->end.time(); + int ib = qRound(30.0 * (tb.hour() + tb.minute() / 60.0)) - ia; + + // drawPie parameters must be specified in 1/16th of a degree + // and it's counter-clockwise. so we must adjust to the right values. + ia = ia * -16 + 90 * 16; + ib = ib * -16; + + // draw the event pie + painter.setBrush(event->color); + painter.drawPie(0, 0, diameter, diameter, ia, ib); + + // draw some gradients to simulate light effects + QRadialGradient gradient(diameter / 2, diameter / 2, diameter / 2 - 35); + gradient.setColorAt(0.9, QColor::fromRgbF(1, 1, 1, 0.5)); + gradient.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.0)); + painter.setBrush(gradient); + painter.drawPie(0, 0, diameter, diameter, ia, ib); + + QRadialGradient gradient2(diameter / 2, diameter / 2, diameter / 2); + gradient2.setColorAt(0.98, QColor::fromRgbF(0, 0, 0, 0.0)); + gradient2.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.5)); + painter.setBrush(gradient2); + painter.drawPie(0, 0, diameter, diameter, ia, ib); + + QRadialGradient gradient3(diameter / 2, diameter / 2, diameter / 2); + gradient3.setColorAt(0, QColor::fromRgbF(1, 1, 1, 0.4)); + gradient3.setColorAt(1, QColor::fromRgbF(1, 1, 1, 0.0)); + + gradient3.setFocalPoint(100, 100); + painter.setBrush(gradient3); + painter.drawPie(0, 0, diameter, diameter, ia, ib); + } + + // clear the middle of the pies + painter.setBrush(Qt::transparent); + painter.setCompositionMode(QPainter::CompositionMode_Clear); + painter.drawPie(inner, inner, diameter - inner * 2, + diameter - inner * 2, 0, 360 * 16); +} |