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