diff options
Diffstat (limited to 'hyperui/contactlist.cpp')
-rw-r--r-- | hyperui/contactlist.cpp | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/hyperui/contactlist.cpp b/hyperui/contactlist.cpp new file mode 100644 index 0000000..63fcd92 --- /dev/null +++ b/hyperui/contactlist.cpp @@ -0,0 +1,415 @@ +/**************************************************************************** +** +** 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 <QGraphicsLinearLayout> +#include <QGraphicsSceneMouseEvent> + +#include "dataresource.h" +#include "contactlist.h" +#include "contactresource.h" + +#include "label.h" +#include "scrollarea.h" +#include "pixmapwidget.h" + + +class LetterScroll : public PixmapWidget +{ + Q_OBJECT + +public: + LetterScroll(ContactList *list); + + void mousePressEvent(QGraphicsSceneMouseEvent *e); + void mouseMoveEvent(QGraphicsSceneMouseEvent *e); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *e); + +signals: + void letterPressed(char c); + +private: + void gotoPosition(int offset); + + char lastChar; + ContactList *list; + QGraphicsPixmapItem *marker; + QGraphicsSimpleTextItem *markerLabel; +}; + + +LetterScroll::LetterScroll(ContactList *list) + : PixmapWidget(Resource::pixmap("list_abc.png")), + lastChar(0), + list(list) +{ + marker = new QGraphicsPixmapItem(Resource::pixmap("list_abcmarker.png"), this); + marker->setX(-marker->boundingRect().width()); + marker->hide(); + + markerLabel = new QGraphicsSimpleTextItem(marker); + markerLabel->setBrush(Qt::white); + markerLabel->setText(QString()); + markerLabel->setX(0.08 * marker->boundingRect().width()); + markerLabel->setY(0.07 * marker->boundingRect().height()); + + QFont font(Resource::stringValue("default/font-family")); + font.setPixelSize(Resource::intValue("contact-list/marker-font-size")); + markerLabel->setFont(font); + + setMinimumSize(preferredSize()); + setMaximumSize(preferredSize()); +} + +void LetterScroll::mousePressEvent(QGraphicsSceneMouseEvent *e) +{ + gotoPosition(e->pos().y()); + marker->show(); +} + +void LetterScroll::mouseMoveEvent(QGraphicsSceneMouseEvent *e) +{ + gotoPosition(e->pos().y()); +} + +void LetterScroll::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + marker->hide(); + lastChar = 0; +} + +void LetterScroll::gotoPosition(int y) +{ + static const char *letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#"; + + // assume monospaced letters + int len = strlen(letters); + int index = y / (size().height() / len); + int center = marker->boundingRect().height() / 2; + + int value = qBound<int>(-center, y - center, size().height() - center); + marker->setY(value); + + if (index >= 0 && index < len) { + const char c = letters[index]; + markerLabel->setText(QString(c)); + marker->setOpacity(list->containsLetter(c) ? 1.0 : 0.3); + + if (lastChar != c) { + lastChar = c; + emit letterPressed(c); + } + } +} + + +class ContactLabel : public QGraphicsWidget +{ + Q_OBJECT + +public: + ContactLabel(const QString &text, QGraphicsItem *parent = 0); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + +private: + QString text; + QPixmap divisor; + QColor color; +}; + +ContactLabel::ContactLabel(const QString &text, QGraphicsItem *parent) + : QGraphicsWidget(parent), + text(text), + divisor(Resource::pixmap("list_divisor.png")), + color(Resource::stringValue("contact-list/label-font-color")) +{ + QFont font(Resource::stringValue("default/font-family")); + font.setPixelSize(Resource::intValue("contact-list/label-font-size")); + setFont(font); + + setMinimumHeight(Resource::intValue("contact-list/label-height")); +} + +void ContactLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + painter->setPen(color); + painter->setFont(font()); + painter->drawText(size().width() * 0.03, + size().height() * 0.80, text); + + painter->drawPixmap(0, size().height() - divisor.height(), divisor); +} + + + +class ContactPhoto : public QGraphicsWidget +{ + Q_OBJECT + +public: + ContactPhoto(int index, ContactList *list); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *e); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *e); + +private: + int m_index; + Label *m_label; + ContactList *m_list; + PixmapWidget *m_photo; + QColor m_color; +}; + +ContactPhoto::ContactPhoto(int index, ContactList *list) + : QGraphicsWidget(list), + m_index(index), + m_list(list), + m_color(Resource::stringValue("contact-list/thumb-bg-color")) +{ + m_label = new Label(); + + const QString &photoPath = ContactResource::photo(index); + m_photo = new PixmapWidget(Resource::pixmap(photoPath)); + + QFont font(Resource::stringValue("default/font-family")); + font.setBold(true); + font.setPixelSize(Resource::intValue("contact-list/thumb-font-size")); + + m_label->setFont(font); + m_label->setText(ContactResource::name(index)); + + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical); + layout->setSpacing(1); + layout->setContentsMargins(3, 3, 3, 3); + layout->addItem(m_photo); + layout->addItem(m_label); + + setLayout(layout); + + setMinimumHeight(Resource::intValue("contact-list/thumb-height")); +} + +void ContactPhoto::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + painter->fillRect(boundingRect(), m_color); +} + +void ContactPhoto::mousePressEvent(QGraphicsSceneMouseEvent *) +{ + +} + +void ContactPhoto::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + emit m_list->contactClicked(m_index); +} + + + +class ContactListItem : public QGraphicsWidget +{ +public: + ContactListItem(int index, ContactList *parent); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *e); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *e); + +private: + int m_index; + QFont m_font; + QString m_text; + QString m_phone; + ContactList *m_list; + QPixmap m_icon; + QPixmap m_divisor; + int m_nameFontSize; + int m_phoneFontSize; +}; + + +ContactListItem::ContactListItem(int index, ContactList *list) + : QGraphicsWidget(list), + m_index(index), + m_list(list), + m_icon(Resource::pixmap("list_icon_chat.png")), + m_divisor(Resource::pixmap("list_divisor.png")), + m_nameFontSize(Resource::intValue("contact-list/list-item-name-font-size")), + m_phoneFontSize(Resource::intValue("contact-list/list-item-phone-font-size")) +{ + m_font = QFont(Resource::stringValue("default/font-family")); + setMinimumHeight(Resource::intValue("contact-list/list-item-height")); + + m_text = ContactResource::name(index); + m_phone = ContactResource::phone(index); +} + +void ContactListItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + const int w = boundingRect().width(); + const int h = boundingRect().height(); + + painter->setPen(Qt::white); + + m_font.setBold(true); + m_font.setPixelSize(m_nameFontSize); + painter->setFont(m_font); + painter->drawText(w * 0.12, h * 0.40, m_text); + + m_font.setBold(false); + m_font.setPixelSize(m_phoneFontSize); + painter->setFont(m_font); + painter->drawText(w * 0.12, h * 0.75, m_phone); + + painter->drawPixmap(0, h * 0.15, m_icon); + + painter->drawPixmap(0, boundingRect().height() - m_divisor.height(), m_divisor); +} + +void ContactListItem::mousePressEvent(QGraphicsSceneMouseEvent *) +{ + +} + +void ContactListItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + emit m_list->contactClicked(m_index); +} + + + + +ContactList::ContactList(QGraphicsItem *parent) + : QGraphicsWidget(parent) +{ + setFlag(QGraphicsItem::ItemHasNoContents); + + QGraphicsWidget *contents = new QGraphicsWidget(this); + + PixmapWidget *scroll = new LetterScroll(this); + connect(scroll, SIGNAL(letterPressed(char)), SLOT(letterPressed(char))); + + QGraphicsLinearLayout *contentsLayout = new QGraphicsLinearLayout(Qt::Vertical); + contentsLayout->setSpacing(0); + contentsLayout->setContentsMargins(7, 0, 7, 0); + + QGraphicsLinearLayout * topLayout = new QGraphicsLinearLayout(Qt::Horizontal); + topLayout->setSpacing(3); + topLayout->setContentsMargins(0, 0, 0, 0); + topLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + const int totalContacts = ContactResource::count(); + + // just get 3 contacts with photo + for (int i = 0, k = 0; k < 3 && i < totalContacts; i++) { + const QString &photo = ContactResource::photo(i); + + if (!photo.isEmpty()) { + k++; + topLayout->addItem(new ContactPhoto(i, this)); + } + } + + contentsLayout->addItem(topLayout); + + char lastChar = 0; + for (int i = 0; i < totalContacts; i++) { + const QString &name = ContactResource::name(i); + + if (name.isEmpty()) + continue; + + const char c = name.at(0).toLatin1(); + + if (lastChar != c) { + lastChar = c; + ContactLabel *label = new ContactLabel(QString(c)); + contentsLayout->addItem(label); + m_labels[c] = label; + } + + contentsLayout->addItem(new ContactListItem(i, this)); + } + + contents->setLayout(contentsLayout); + + m_scrollArea = new ScrollArea(); + m_scrollArea->setWidget(contents); + + scroll->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + m_scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + + layout->addItem(m_scrollArea); + layout->addItem(scroll); + setLayout(layout); +} + +bool ContactList::containsLetter(char c) const +{ + return m_labels.contains(c); +} + +void ContactList::letterPressed(char c) +{ + if (m_labels.contains(c)) { + m_scrollArea->stopKinetic(); + // XXX: check first letter + m_scrollArea->setOffset(c == 'A' ? 0 : m_labels[c]->y()); + } +} + +#include "contactlist.moc" |