ganeswidgets/src/hgcoverflowcontainer.cpp
changeset 0 89c329efa980
child 1 e48454f237ca
equal deleted inserted replaced
-1:000000000000 0:89c329efa980
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QGesture>
       
    19 #include <QPainter>
       
    20 #include <hblabel.h>
       
    21 #include "hgcoverflowcontainer.h"
       
    22 #include "hgmediawallrenderer.h"
       
    23 #include "hgwidgetitem.h"
       
    24 #include "trace.h"
       
    25 
       
    26 
       
    27 static const qreal KCameraMaxYAngle(20);
       
    28 static const qreal KSpringVelocityToCameraYAngleFactor(2);
       
    29 static const int   KLabelMargin(4);
       
    30 
       
    31 HgCoverflowContainer::HgCoverflowContainer(
       
    32     QGraphicsItem* parent) : HgContainer(parent),
       
    33     mTitleLabel(0),
       
    34     mDescriptionLabel(0),
       
    35     mTitlePosition(HgMediawall::PositionAboveImage),
       
    36     mDescriptionPosition(HgMediawall::PositionNone),
       
    37     mCenterIconTop(0),
       
    38     mPrevPos(-1)
       
    39 {
       
    40     mTitleLabel = new HbLabel(this);
       
    41     mTitleLabel->setZValue(zValue()+1);
       
    42     mTitleLabel->setAlignment(Qt::AlignCenter);
       
    43     mTitleLabel->setVisible(false);
       
    44 
       
    45     mDescriptionLabel = new HbLabel(this);
       
    46     mDescriptionLabel->setZValue(zValue()+1);
       
    47     mDescriptionLabel->setAlignment(Qt::AlignCenter);
       
    48     mDescriptionLabel->setVisible(false);
       
    49 }
       
    50 
       
    51 HgCoverflowContainer::~HgCoverflowContainer()
       
    52 {
       
    53 }
       
    54 
       
    55 // events
       
    56 void HgCoverflowContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
    57 {
       
    58     HgContainer::paint(painter, option, widget);
       
    59 }
       
    60 
       
    61 void HgCoverflowContainer::resizeEvent(QGraphicsSceneResizeEvent *event)
       
    62 {
       
    63     FUNC_LOG;
       
    64 
       
    65     HbWidget::resizeEvent(event);
       
    66 
       
    67     QSizeF s(size());
       
    68     qreal side = qMin(s.height()/1.8, s.width()/1.8);
       
    69     INFO("Setting image size to:" << side << "," << side);
       
    70     mRenderer->setImageSize(QSizeF(side, side));
       
    71     mCenterIconTop = (s.height()-side)/2;
       
    72 
       
    73     positionLabels();
       
    74 }
       
    75 
       
    76 // from HgContainer
       
    77 HgMediaWallRenderer* HgCoverflowContainer::createRenderer()
       
    78 {
       
    79     HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this);
       
    80     renderer->setImageSize(QSizeF(200, 200));
       
    81     renderer->enableCoverflowMode(true);
       
    82     renderer->setRowCount(1, renderer->getImageSize(), false);
       
    83     renderer->enableReflections(true);
       
    84     renderer->setSpacing(QSizeF(1,1));
       
    85     renderer->setFrontCoverElevationFactor(0.5);
       
    86     return renderer;
       
    87 }
       
    88 
       
    89 qreal HgCoverflowContainer::getCameraDistance(qreal springVelocity)
       
    90 {
       
    91     return qAbs(springVelocity * 0.01f);
       
    92 }
       
    93 
       
    94 qreal HgCoverflowContainer::getCameraRotationY(qreal springVelocity)
       
    95 {
       
    96     return qBound(-KCameraMaxYAngle, springVelocity * KSpringVelocityToCameraYAngleFactor, KCameraMaxYAngle);
       
    97 }
       
    98 
       
    99 void HgCoverflowContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
       
   100 {
       
   101     Q_UNUSED(pos)
       
   102 
       
   103     if (qAbs(qreal(hitItemIndex) - mSpring.pos().x()) < 0.01f)
       
   104     {
       
   105         emit activated(hitItem->modelIndex());
       
   106     }
       
   107     else
       
   108     {
       
   109         mSpring.animateToPos(QPointF(hitItemIndex, 0));
       
   110     }
       
   111 }
       
   112 
       
   113 void HgCoverflowContainer::handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex)
       
   114 {
       
   115     Q_UNUSED(hitItemIndex)
       
   116 
       
   117     emit longPressed(hitItem->modelIndex(), pos);
       
   118 }
       
   119 
       
   120 void HgCoverflowContainer::onScrollPositionChanged(qreal pos)
       
   121 {
       
   122     HgContainer::onScrollPositionChanged(pos);
       
   123 
       
   124     if (mPrevPos != (int)pos) {
       
   125         mPrevPos = (int)pos;
       
   126         HgWidgetItem* item = itemByIndex((int)pos);
       
   127         if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
       
   128             mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
       
   129         }            
       
   130     }
       
   131 }
       
   132 
       
   133 void HgCoverflowContainer::handleCurrentChanged(const QModelIndex &current)
       
   134 {
       
   135     FUNC_LOG;
       
   136 
       
   137     if (current.isValid()) {
       
   138         updateLabels(current.row());
       
   139     }
       
   140 }
       
   141 
       
   142 void HgCoverflowContainer::itemDataChanged(const int &firstIndex, const int &lastIndex)
       
   143 {
       
   144     FUNC_LOG;
       
   145     HANDLE_ERROR_NULL(mSelectionModel); // If model has been set, also is selection model
       
   146 
       
   147     HgContainer::itemDataChanged(firstIndex, lastIndex);
       
   148 
       
   149     if (mSelectionModel->currentIndex().isValid()) {
       
   150         int current = mSelectionModel->currentIndex().row();
       
   151         if (firstIndex <= current && current <= lastIndex) {
       
   152             updateLabels(current);
       
   153         }
       
   154     }
       
   155 }
       
   156 
       
   157 void HgCoverflowContainer::setTitlePosition(HgMediawall::LabelPosition position)
       
   158 {
       
   159     FUNC_LOG;
       
   160 
       
   161     if (mTitlePosition != position) {
       
   162         mTitlePosition = position;
       
   163         positionLabels();
       
   164     }
       
   165 }
       
   166 
       
   167 HgMediawall::LabelPosition HgCoverflowContainer::titlePosition() const
       
   168 {
       
   169     FUNC_LOG;
       
   170 
       
   171     return mTitlePosition;
       
   172 }
       
   173 
       
   174 void HgCoverflowContainer::setDescriptionPosition(HgMediawall::LabelPosition position)
       
   175 {
       
   176     FUNC_LOG;
       
   177 
       
   178     if (mDescriptionPosition != position) {
       
   179         mDescriptionPosition = position;
       
   180         positionLabels();
       
   181     }
       
   182 }
       
   183 
       
   184 HgMediawall::LabelPosition HgCoverflowContainer::descriptionPosition() const
       
   185 {
       
   186     FUNC_LOG;
       
   187 
       
   188     return mDescriptionPosition;
       
   189 }
       
   190 
       
   191 void HgCoverflowContainer::setTitleFontSpec(const HbFontSpec &fontSpec)
       
   192 {
       
   193     FUNC_LOG;
       
   194 
       
   195     if (!mTitleLabel) return;
       
   196     if (mTitleLabel->fontSpec() != fontSpec) {
       
   197         mTitleLabel->setFontSpec(fontSpec);
       
   198         positionLabels();
       
   199     }
       
   200 }
       
   201 
       
   202 HbFontSpec HgCoverflowContainer::titleFontSpec() const
       
   203 {
       
   204     FUNC_LOG;
       
   205 
       
   206     if (!mTitleLabel) return HbFontSpec();
       
   207     return mTitleLabel->fontSpec();
       
   208 }
       
   209 
       
   210 void HgCoverflowContainer::setDescriptionFontSpec(const HbFontSpec &fontSpec)
       
   211 {
       
   212     FUNC_LOG;
       
   213 
       
   214     if (!mDescriptionLabel) return;
       
   215     if (mDescriptionLabel->fontSpec() != fontSpec) {
       
   216         mDescriptionLabel->setFontSpec(fontSpec);
       
   217         positionLabels();
       
   218     }
       
   219 }
       
   220 
       
   221 HbFontSpec HgCoverflowContainer::descriptionFontSpec() const
       
   222 {
       
   223     FUNC_LOG;
       
   224 
       
   225     if (!mDescriptionLabel) return HbFontSpec();
       
   226     return mDescriptionLabel->fontSpec();
       
   227 }
       
   228 
       
   229 void HgCoverflowContainer::positionLabels()
       
   230 {
       
   231     FUNC_LOG;
       
   232     HANDLE_ERROR_NULL(mTitleLabel);
       
   233     HANDLE_ERROR_NULL(mDescriptionLabel);
       
   234     HANDLE_ERROR_NULL(mSelectionModel);
       
   235 
       
   236     int height = size().height();
       
   237     int width = size().width();
       
   238     int titleHeight = QFontMetrics(mTitleLabel->effectiveFontSpec().font()).height();
       
   239     int descriptionHeight = QFontMetrics(mDescriptionLabel->effectiveFontSpec().font()).height();
       
   240 
       
   241     if (mTitlePosition == HgMediawall::PositionAboveImage &&
       
   242         mDescriptionPosition == HgMediawall::PositionAboveImage) {
       
   243         mTitleLabel->setGeometry(QRectF(
       
   244             0,
       
   245             qMax(KLabelMargin, mCenterIconTop-2*KLabelMargin-titleHeight-descriptionHeight),
       
   246             width, titleHeight));
       
   247         mDescriptionLabel->setGeometry(QRectF(
       
   248             0,
       
   249             mTitleLabel->geometry().bottom()+KLabelMargin,
       
   250             width, descriptionHeight));
       
   251     }
       
   252     else if (mTitlePosition == HgMediawall::PositionBelowImage &&
       
   253              mDescriptionPosition == HgMediawall::PositionBelowImage) {
       
   254         mDescriptionLabel->setGeometry(QRectF(
       
   255             0,
       
   256             height-descriptionHeight-KLabelMargin,
       
   257             width, descriptionHeight));
       
   258         mTitleLabel->setGeometry(QRectF(
       
   259             0,
       
   260             mDescriptionLabel->geometry().top()-titleHeight-KLabelMargin,
       
   261             width, titleHeight));
       
   262     }
       
   263     else {
       
   264         if (mTitlePosition == HgMediawall::PositionAboveImage) {
       
   265             mTitleLabel->setGeometry(QRectF(
       
   266                 0,
       
   267                 qMax(KLabelMargin, mCenterIconTop-KLabelMargin-titleHeight),
       
   268                 width, titleHeight));
       
   269         }
       
   270         else if (mTitlePosition == HgMediawall::PositionBelowImage) {
       
   271             mTitleLabel->setGeometry(QRectF(
       
   272                 0,
       
   273                 height-titleHeight-KLabelMargin,
       
   274                 width, titleHeight));
       
   275         }
       
   276 
       
   277         if (mDescriptionPosition == HgMediawall::PositionAboveImage) {
       
   278             mDescriptionLabel->setGeometry(QRectF(
       
   279                 0,
       
   280                 qMax(KLabelMargin, mCenterIconTop-KLabelMargin-descriptionHeight),
       
   281                 width, descriptionHeight));
       
   282         }
       
   283         else if (mDescriptionPosition == HgMediawall::PositionBelowImage) {
       
   284             mDescriptionLabel->setGeometry(QRectF(
       
   285                 0,
       
   286                 height-descriptionHeight-KLabelMargin,
       
   287                 width, descriptionHeight));
       
   288         }
       
   289     }
       
   290 
       
   291     mTitleLabel->setVisible(mTitlePosition != HgMediawall::PositionNone);
       
   292     mDescriptionLabel->setVisible(mDescriptionPosition != HgMediawall::PositionNone);
       
   293 
       
   294     INFO("Title geometry:" << mTitleLabel->geometry() << "visible:" << mTitleLabel->isVisible());
       
   295     INFO("Description geometry:" << mDescriptionLabel->geometry() << "visible:" << mDescriptionLabel->isVisible());
       
   296 
       
   297     if (mSelectionModel->currentIndex().isValid()) {
       
   298         updateLabels(mSelectionModel->currentIndex().row());
       
   299     }
       
   300 }
       
   301 
       
   302 void HgCoverflowContainer::updateLabels(int itemIndex)
       
   303 {
       
   304     FUNC_LOG;
       
   305     HANDLE_ERROR_NULL(mTitleLabel);
       
   306     HANDLE_ERROR_NULL(mDescriptionLabel);
       
   307 
       
   308     if (itemIndex >= 0 && itemIndex < mItems.count()) {
       
   309         mTitleLabel->setPlainText(mItems.at(itemIndex)->title());
       
   310         mDescriptionLabel->setPlainText(mItems.at(itemIndex)->description());
       
   311     }
       
   312 }
       
   313 
       
   314 void HgCoverflowContainer::scrollToPosition(const QPointF& pos, bool animate)
       
   315 {
       
   316     QPointF p = pos;
       
   317     p.setX((int)pos.x());
       
   318     HgContainer::scrollToPosition(p,animate);
       
   319 }