ganeswidgets/src/HgContainer.cpp
changeset 1 e48454f237ca
parent 0 89c329efa980
child 2 49c70dcc3f17
equal deleted inserted replaced
0:89c329efa980 1:e48454f237ca
    55     mDragged(false),
    55     mDragged(false),
    56     mFramesDragged(0),
    56     mFramesDragged(0),
    57     mHitItemView(NULL),
    57     mHitItemView(NULL),
    58     mLongPressVisualizer(NULL),
    58     mLongPressVisualizer(NULL),
    59     mLongPressTimer(NULL),
    59     mLongPressTimer(NULL),
    60     mHitItemIndex(NULL)
    60     mHitItemIndex(NULL),
    61 {
    61     mItemSizePolicy(HgWidget::ItemSizeUserDefined),
    62     FUNC_LOG;
    62     mOrientation(Qt::Vertical)
    63     
    63 {
       
    64     FUNC_LOG;
       
    65 
    64     grabGesture(Qt::PanGesture);
    66     grabGesture(Qt::PanGesture);
    65     grabGesture(Qt::TapGesture);
    67     grabGesture(Qt::TapGesture);
    66     grabGesture(Qt::TapAndHoldGesture);
    68     grabGesture(Qt::TapAndHoldGesture);
    67 }
    69 }
    68 
    70 
    69 HgContainer::~HgContainer()
    71 HgContainer::~HgContainer()
    70 {
    72 {
    71     FUNC_LOG;
    73     FUNC_LOG;
    72 
    74 
    73     for (QList<HgWidgetItem*>::iterator i = mItems.begin(); i != mItems.end(); ++i) {
    75     qDeleteAll(mItems);
    74         delete (*i);
       
    75     }
       
    76     mItems.clear();
    76     mItems.clear();
    77     delete mMarkImage;
    77     delete mMarkImage;
    78     delete mRenderer;
    78     delete mRenderer;
    79 }
    79 }
    80 
    80 
    81 void HgContainer::setItemCount(int itemCount)
    81 void HgContainer::setItemCount(int itemCount)
    82 {
    82 {
    83     FUNC_LOG;
    83     FUNC_LOG;
    84 
    84 
       
    85     qDeleteAll(mItems);
    85     mItems.clear();
    86     mItems.clear();
    86     for (int i=0; i<itemCount; i++) {
    87     for (int i=0; i<itemCount; i++) {
    87         HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
    88         HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
    88         mItems.append(item);
    89         mItems.append(item);
    89     }
    90     }
   205 
   206 
   206 Qt::Orientation HgContainer::orientation() const
   207 Qt::Orientation HgContainer::orientation() const
   207 {
   208 {
   208     FUNC_LOG;
   209     FUNC_LOG;
   209 
   210 
   210     return mRenderer->getOrientation();
   211     return mOrientation;
   211 }
   212 }
   212 
   213 
   213 void HgContainer::setOrientation(Qt::Orientation orientation, bool animate)
   214 void HgContainer::setOrientation(Qt::Orientation orientation, bool animate)
   214 {
   215 {
   215     FUNC_LOG;
   216     FUNC_LOG;
   216 
   217 
   217     mRenderer->setOrientation(orientation, animate);
   218     mOrientation = orientation;
       
   219     mRenderer->setOrientation(orientation, false);
   218 }
   220 }
   219 
   221 
   220 void HgContainer::scrollToPosition(qreal value, bool animate)
   222 void HgContainer::scrollToPosition(qreal value, bool animate)
   221 {
   223 {
   222     FUNC_LOG;
   224     FUNC_LOG;
   239 
   241 
   240 void HgContainer::scrollTo(const QModelIndex &index)
   242 void HgContainer::scrollTo(const QModelIndex &index)
   241 {
   243 {
   242     FUNC_LOG;
   244     FUNC_LOG;
   243 
   245 
   244     if (index.isValid()) {
   246     if (index.isValid() && mRenderer->getRowCount() > 0) {
   245         scrollToPosition(QPointF(index.row(), index.column()), false);
   247         scrollToPosition(QPointF(index.row()/mRenderer->getRowCount(), 0), false);
   246     }
   248     }
   247 }
   249 }
   248 
   250 
   249 void HgContainer::itemDataChanged(const QModelIndex &firstIndex, const QModelIndex &lastIndex)
   251 void HgContainer::itemDataChanged(const QModelIndex &firstIndex, const QModelIndex &lastIndex)
   250 {
   252 {
   262 }
   264 }
   263 
   265 
   264 void HgContainer::addItems(int start, int end)
   266 void HgContainer::addItems(int start, int end)
   265 {
   267 {
   266     FUNC_LOG;
   268     FUNC_LOG;
       
   269     HANDLE_ERROR_NULL(mSelectionModel);
   267 
   270 
   268     int first = qBound(0, start, mItems.count()-1);
   271     int first = qBound(0, start, mItems.count()-1);
   269     int last = qBound(0, end, mItems.count()-1);
   272     int last = qBound(0, end, mItems.count()-1);
   270     for (int i = 0; i <= end-start; i++) {
   273     for (int i = 0; i <= end-start; i++) {
   271         HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
   274         HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
   272         mItems.insert(start, item);
   275         mItems.insert(start, item);
   273     }
   276     }
       
   277     scrollTo(mSelectionModel->currentIndex());
   274 }
   278 }
   275 
   279 
   276 void HgContainer::removeItems(int start, int end)
   280 void HgContainer::removeItems(int start, int end)
   277 {
   281 {
   278     FUNC_LOG;
   282     FUNC_LOG;
       
   283     HANDLE_ERROR_NULL(mSelectionModel);
   279 
   284 
   280     int first = qBound(0, start, mItems.count()-1);
   285     int first = qBound(0, start, mItems.count()-1);
   281     int last = qBound(0, end, mItems.count()-1);
   286     int last = qBound(0, end, mItems.count()-1);
   282     for (int i = last; i >= first; i--) {
   287     for (int i = last; i >= first; i--) {
   283         delete mItems.at(i);
   288         delete mItems.at(i);
   284         mItems.removeAt(i);
   289         mItems.removeAt(i);
   285     }
   290     }
       
   291     scrollTo(mSelectionModel->currentIndex());
   286 }
   292 }
   287 
   293 
   288 void HgContainer::moveItems(int start, int end, int destination)
   294 void HgContainer::moveItems(int start, int end, int destination)
   289 {
   295 {
   290     FUNC_LOG;
   296     FUNC_LOG;
       
   297     HANDLE_ERROR_NULL(mSelectionModel);
   291 
   298 
   292     int first = qBound(0, start, mItems.count()-1);
   299     int first = qBound(0, start, mItems.count()-1);
   293     int last = qBound(0, end, mItems.count()-1);
   300     int last = qBound(0, end, mItems.count()-1);
   294     int target = qBound(0, destination, mItems.count()-1);
   301     int target = qBound(0, destination, mItems.count()-1);
   295 
   302 
   302         for (int i = 0; i <= last-first; i++) {
   309         for (int i = 0; i <= last-first; i++) {
   303             mItems.move(last-i, target);
   310             mItems.move(last-i, target);
   304         }
   311         }
   305     }
   312     }
   306     // else do nothing
   313     // else do nothing
       
   314     scrollTo(mSelectionModel->currentIndex());
   307 }
   315 }
   308 
   316 
   309 int HgContainer::imageCount() const
   317 int HgContainer::imageCount() const
   310 {
   318 {
   311     return mItems.count();
   319     return mItems.count();
   335     return 0;
   343     return 0;
   336 }
   344 }
   337 
   345 
   338 void HgContainer::updateBySpringPosition()
   346 void HgContainer::updateBySpringPosition()
   339 {
   347 {
   340     update();
       
   341 
       
   342     // spring works always in one dimension, that is, x coord.
   348     // spring works always in one dimension, that is, x coord.
   343     qreal pos = mSpring.pos().x();
   349     qreal pos = mSpring.pos().x();
   344 
   350 
   345     onScrollPositionChanged(pos);
   351     onScrollPositionChanged(pos);
   346 
   352 
   347     emit scrollPositionChanged(pos, mAnimateUsingScrollBar);
   353     emit scrollPositionChanged(pos, mAnimateUsingScrollBar);
       
   354     update();
   348 }
   355 }
   349 
   356 
   350 void HgContainer::redraw()
   357 void HgContainer::redraw()
   351 {
   358 {
   352     update();
   359     update();
   354 
   361 
   355 void HgContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
   362 void HgContainer::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
   356 {
   363 {
   357     Q_UNUSED(option)
   364     Q_UNUSED(option)
   358     Q_UNUSED(widget)
   365     Q_UNUSED(widget)
   359 
       
   360     if (mSpring.updatePositionIfNeeded())
   366     if (mSpring.updatePositionIfNeeded())
   361     {
   367     {
   362         // spring works always in one dimension, that is, x coord.
   368         // spring works always in one dimension, that is, x coord.
   363         qreal pos = mSpring.pos().x();
   369         qreal pos = mSpring.pos().x();
   364         onScrollPositionChanged(pos);
   370         onScrollPositionChanged(pos);
   365         emit scrollPositionChanged(pos, mAnimateUsingScrollBar);        
   371         emit scrollPositionChanged(pos, true);        
   366     }
   372     }
   367     
   373 
   368     QRectF vp = painter->viewport();
   374     QRectF vp = painter->viewport();
   369     QRectF rts = mapRectToScene(rect());
   375     QRectF rts = mapRectToScene(drawableRect());
   370     QRectF r;
   376     QRectF r;
   371 
   377 
   372     // transform rectangle to vg space &
   378     // transform rectangle to vg space &
   373     // rotate rendering according to orientation
   379     // rotate rendering according to orientation
   374     if (mainWindow()->orientation() == Qt::Horizontal) {
   380     if (mOrientation == Qt::Horizontal) {
   375         r = QRectF(vp.width()-(rts.height()+rts.top()), rts.left(), rts.height(), rts.width());
   381         r = QRectF(vp.width()-(rts.height()+rts.top()), rts.left(), rts.height(), rts.width());
       
   382 
       
   383         mRenderer->setRect(r);
       
   384 
   376         mRenderer->setCameraRotationZ(-90);
   385         mRenderer->setCameraRotationZ(-90);
   377     }
   386     }
   378     else {
   387     else {
   379         r = QRectF(rts.left(), vp.height()-(rts.height()+rts.top()), rts.width(), rts.height());
   388         r = QRectF(rts.left(), vp.height()-(rts.height()+rts.top()), rts.width(), rts.height());
   380         mRenderer->setCameraRotationZ(0);
   389         mRenderer->setCameraRotationZ(0);
       
   390 
       
   391         mRenderer->setRect(r);
       
   392         
       
   393         if (!mSpring.isActive() && mSpring.pos().x() > worldWidth())
       
   394             boundSpring();
   381     }
   395     }
   382 
   396 
   383     // interpolate spring velocity towards zero, this is done
   397     // interpolate spring velocity towards zero, this is done
   384     // so that spring velocity for rendering doesn't drop directly to
   398     // so that spring velocity for rendering doesn't drop directly to
   385     // zero when dragging starts
   399     // zero when dragging starts
   391     }
   405     }
   392 
   406 
   393     // setup rendering and draw the current view
   407     // setup rendering and draw the current view
   394     mRenderer->setCameraDistance(getCameraDistance(springVel));
   408     mRenderer->setCameraDistance(getCameraDistance(springVel));
   395     mRenderer->setCameraRotationY(getCameraRotationY(springVel));
   409     mRenderer->setCameraRotationY(getCameraRotationY(springVel));
   396     mRenderer->setRect(r);
       
   397     mRenderer->draw(mSpring.startPos(), mSpring.pos(), mSpring.endPos(),
   410     mRenderer->draw(mSpring.startPos(), mSpring.pos(), mSpring.endPos(),
   398                     springVel, painter);
   411                     springVel, painter);
   399         
   412 
   400 }
   413 }
   401 
   414 
   402 void HgContainer::resizeEvent(QGraphicsSceneResizeEvent *event)
   415 void HgContainer::resizeEvent(QGraphicsSceneResizeEvent *event)
   403 {
   416 {
   404     FUNC_LOG;
   417     FUNC_LOG;
   414 
   427 
   415 void HgContainer::gestureEvent(QGestureEvent *event)
   428 void HgContainer::gestureEvent(QGestureEvent *event)
   416 {
   429 {
   417     FUNC_LOG;
   430     FUNC_LOG;
   418 
   431 
       
   432     bool eventHandled(false);
   419     // Event may contain more than one gesture type
   433     // Event may contain more than one gesture type
   420     if (QGesture *gesture = event->gesture(Qt::TapAndHoldGesture)) {
   434     if (QGesture *gesture = event->gesture(Qt::TapAndHoldGesture)) {
   421         QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture *>(gesture);
   435         QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture *>(gesture);
   422         handleLongTap(tapAndHold->state(),
   436         if (handleLongTap(tapAndHold->state(),
   423             mapFromScene(event->mapToGraphicsScene(tapAndHold->position())));
   437                 mapFromScene(event->mapToGraphicsScene(tapAndHold->position())))) {
       
   438         }
   424     }
   439     }
   425     else if (QGesture *gesture = event->gesture(Qt::TapGesture)) {
   440     else if (QGesture *gesture = event->gesture(Qt::TapGesture)) {
   426         // Tap and hold is not working yet in HW, tap gesture is delivered instead
   441         // Tap and hold is not working yet in HW, tap gesture is delivered instead
   427         QTapGesture *tap = static_cast<QTapGesture *>(gesture);
   442         QTapGesture *tap = static_cast<QTapGesture *>(gesture);
   428         handleTap(tap->state(),
   443         eventHandled = handleTap(tap->state(),
   429             mapFromScene(event->mapToGraphicsScene(tap->position())));
   444             mapFromScene(event->mapToGraphicsScene(tap->position())));
   430     }
   445     }
   431     else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
   446     else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
   432         handlePanning(static_cast<QPanGesture*>(pan));
   447         eventHandled = handlePanning(static_cast<QPanGesture*>(pan));
       
   448     }
       
   449 
       
   450     if (eventHandled) {
       
   451         event->accept();
       
   452         event->accept(Qt::TapAndHoldGesture);
       
   453         event->accept(Qt::TapGesture);
       
   454         event->accept(Qt::PanGesture);
       
   455     }
       
   456     else {
       
   457         event->ignore();
       
   458         event->ignore(Qt::TapAndHoldGesture);
       
   459         event->ignore(Qt::TapGesture);
       
   460         event->ignore(Qt::PanGesture);
   433     }
   461     }
   434 }
   462 }
   435 
   463 
   436 void HgContainer::init(Qt::Orientation scrollDirection)
   464 void HgContainer::init(Qt::Orientation scrollDirection)
   437 {
   465 {
   438     FUNC_LOG;
   466     FUNC_LOG;
   439 
   467 
   440     mRenderer = createRenderer();
   468     mRenderer = createRenderer(scrollDirection);
   441     if (mRenderer->coverflowModeEnabled())
   469     mOrientation = scrollDirection;
   442         mRenderer->setOrientation(Qt::Horizontal, false);
   470 
   443     else
       
   444         mRenderer->setOrientation(scrollDirection, false);
       
   445         
       
   446     mQuadRenderer = mRenderer->getRenderer();
   471     mQuadRenderer = mRenderer->getRenderer();
   447 
   472 
   448     QImage markImage(":/images/mark.svg");
   473     QImage markImage(":/images/mark.svg");
   449     if (markImage.isNull()) {
   474     if (markImage.isNull()) {
   450         ERROR("Failed to load :/images/mark.svg");
   475         ERROR("Failed to load :/images/mark.svg");
   452     mMarkImage = mQuadRenderer->createNativeImage();
   477     mMarkImage = mQuadRenderer->createNativeImage();
   453     HANDLE_ERROR_NULL(mMarkImage);
   478     HANDLE_ERROR_NULL(mMarkImage);
   454     if (mMarkImage) {
   479     if (mMarkImage) {
   455         mMarkImage->setImage(markImage);
   480         mMarkImage->setImage(markImage);
   456     }
   481     }
   457 
   482     
   458     connect(&mSpring, SIGNAL(updated()), SLOT(updateBySpringPosition()));
   483     connect(&mSpring, SIGNAL(updated()), SLOT(updateBySpringPosition()));
   459     connect(&mSpring, SIGNAL(ended()), SLOT(onScrollingEnded()));
       
   460     connect(&mSpring, SIGNAL(ended()), SIGNAL(scrollingEnded()));
   484     connect(&mSpring, SIGNAL(ended()), SIGNAL(scrollingEnded()));
   461     connect(&mSpring, SIGNAL(started()), SIGNAL(scrollingStarted()));
   485     connect(&mSpring, SIGNAL(started()), SIGNAL(scrollingStarted()));
   462     connect(mRenderer, SIGNAL(renderingNeeded()), SLOT(redraw()));
   486     connect(mRenderer, SIGNAL(renderingNeeded()), SLOT(redraw()));
   463 
   487 
   464 }
   488 }
   498 
   522 
   499     mSpring.animateToPos(QPointF(x, 0));
   523     mSpring.animateToPos(QPointF(x, 0));
   500 
   524 
   501 }
   525 }
   502 
   526 
   503 void HgContainer::handlePanning(QPanGesture *gesture)
   527 bool HgContainer::handlePanning(QPanGesture *gesture)
   504 {
   528 {
   505     mAnimateUsingScrollBar = false;
   529     mAnimateUsingScrollBar = false;
   506     initSpringForScrolling();
   530     initSpringForScrolling();
   507 
   531 
   508     qreal pos = mSpring.pos().x();
   532     qreal pos = mSpring.pos().x();
   509     qreal delta(0);
   533     qreal delta(0);
   510     qreal itemSide(0);
   534     qreal itemSide(0);
   511 
   535 
   512     if (mRenderer->getOrientation() == mainWindow()->orientation()) {
   536     if (mOrientation == mRenderer->getOrientation()) {
   513         delta = gesture->delta().y();
   537         delta = gesture->delta().y();
   514     }
   538     }
   515     else {
   539     else {
   516         delta = gesture->delta().x();
   540         delta = gesture->delta().x();
   517     }
   541     }
   542 
   566 
   543             qreal newPosition = mDrag.update(delta, pos, itemSide);
   567             qreal newPosition = mDrag.update(delta, pos, itemSide);
   544             if (qAbs(newPosition - mSpring.pos().x()) > 0.01f)
   568             if (qAbs(newPosition - mSpring.pos().x()) > 0.01f)
   545             {
   569             {
   546                 mSpring.gotoPos(QPointF(newPosition, 0));
   570                 mSpring.gotoPos(QPointF(newPosition, 0));
       
   571                 emit scrollPositionChanged(newPosition,true);
   547                 update();
   572                 update();
   548             }
   573             }
   549         }
   574         }
   550     }
   575     }
   551     else if (mDragged && gesture->state() == Qt::GestureFinished) {
   576     else if (mDragged && gesture->state() == Qt::GestureFinished) {
   564         }
   589         }
   565     }
   590     }
   566     else if (gesture->state() == Qt::GestureCanceled) {
   591     else if (gesture->state() == Qt::GestureCanceled) {
   567         boundSpring();
   592         boundSpring();
   568     }
   593     }
   569 }
   594 
   570 
   595     return true;
   571 
   596 }
   572 
   597 
   573 void HgContainer::handleTap(Qt::GestureState state, const QPointF &pos)
   598 bool HgContainer::handleTap(Qt::GestureState state, const QPointF &pos)
   574 {
   599 {
   575     FUNC_LOG;
   600     FUNC_LOG;
   576 
   601 
   577     if (state == Qt::GestureStarted) {
   602     if (state == Qt::GestureStarted) {
   578         mTapDuration.start();
   603         if (hasItemAt(pos)) {
   579 
   604             mTapDuration.start();
   580         startLongPressWatcher(pos);
   605             startLongPressWatcher(pos);
       
   606             return true;
       
   607         }
       
   608         return false;
   581     }
   609     }
   582     else if (state == Qt::GestureCanceled)
   610     else if (state == Qt::GestureCanceled)
   583     {
   611     {
   584         stopLongPressWatcher();
   612         stopLongPressWatcher();
       
   613 
       
   614         if (hasItemAt(pos)) {
       
   615             return true;
       
   616         }
       
   617         return false;
   585     }
   618     }
   586     else if (state == Qt::GestureFinished) {
   619     else if (state == Qt::GestureFinished) {
   587 
       
   588         stopLongPressWatcher();
   620         stopLongPressWatcher();
   589         handleItemAction(pos, mTapDuration.elapsed() > KLongTapDuration ? LongTap : NormalTap);
   621         return handleItemAction(pos, mTapDuration.elapsed() > KLongTapDuration ? LongTap : NormalTap);
   590     }
   622     }
   591 }
   623 
   592 
   624     return false;
   593 void HgContainer::handleLongTap(Qt::GestureState state, const QPointF &pos)
   625 }
   594 {
   626 
   595     FUNC_LOG;
   627 bool HgContainer::handleLongTap(Qt::GestureState state, const QPointF &pos)
   596 
   628 {
   597     mAnimateUsingScrollBar = false;
   629     FUNC_LOG;
   598     initSpringForScrolling();
   630 
   599 
   631     if (hasItemAt(pos)) {
   600     if (state == Qt::GestureFinished) {
   632         mAnimateUsingScrollBar = false;
   601         handleItemAction(pos, LongTap);
   633         initSpringForScrolling();
   602     }
   634 
       
   635         if (state == Qt::GestureFinished) {
       
   636             handleItemAction(pos, LongTap);
       
   637         }
       
   638         return true;
       
   639     }
       
   640 
       
   641     return false;
   603 }
   642 }
   604 
   643 
   605 /*!
   644 /*!
   606     Handle tap, lang tap and double tap action.
   645     Handle tap, lang tap and double tap action.
   607     Finds out the item in the tap position and sends out suitable signal,
   646     Finds out the item in the tap position and sends out suitable signal,
   608     Sets the item as the current item and in multiselection mode toggles the
   647     Sets the item as the current item and in multiselection mode toggles the
   609     item selection status.
   648     item selection status.
   610 */
   649 */
   611 void HgContainer::handleItemAction(const QPointF &pos, ItemActionType action)
   650 bool HgContainer::handleItemAction(const QPointF &pos, ItemActionType action)
   612 {
   651 {
   613     FUNC_LOG;
   652     FUNC_LOG;
   614 
   653 
   615     // If there is content, mSelectionModel must always exist - either default or client-provided
   654     // If there is content, mSelectionModel must always exist - either default or client-provided
   616     if (!mSelectionModel) return;
   655     if (!mSelectionModel) return false;
   617 
   656 
   618     mHitItem = getItemAt(pos, mHitItemIndex);
   657     mHitItem = getItemAt(pos, mHitItemIndex);
   619     if (mHitItem)
   658     if (mHitItem)
   620     {
   659     {
   621         int index = mHitItemIndex;
   660         int index = mHitItemIndex;
   622 
   661 
   623 
       
   624         HgWidgetItem* item = itemByIndex(index);
   662         HgWidgetItem* item = itemByIndex(index);
   625         if (item && action != DoubleTap) {
   663         if (item && action != DoubleTap) {
   626             mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
       
   627 
       
   628             if (action == LongTap) {
   664             if (action == LongTap) {
   629                 INFO("Long tap:" << item->modelIndex().row());
   665                 INFO("Long tap:" << item->modelIndex().row());
       
   666                 mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   630 
   667 
   631                 if (!mRenderer->coverflowModeEnabled())
   668                 if (!mRenderer->coverflowModeEnabled())
   632                     selectItem();
   669                     selectItem();
   633 
   670 
   634                 emit longPressed(item->modelIndex(), pos);
   671                 emit longPressed(item->modelIndex(), pos);
   635             }
   672             }
   636             else if (mSelectionMode == HgWidget::MultiSelection) {
   673             else if (mSelectionMode == HgWidget::MultiSelection) {
       
   674                 mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   637                 INFO("Select:" << item->modelIndex().row());
   675                 INFO("Select:" << item->modelIndex().row());
   638                 mSelectionModel->select(item->modelIndex(), QItemSelectionModel::Toggle);
   676                 mSelectionModel->select(item->modelIndex(), QItemSelectionModel::Toggle);
   639                 update(); // It would be enough to update the item
   677                 update(); // It would be enough to update the item
   640             }
   678             }
   641             else if (mSelectionMode == HgWidget::SingleSelection) {
   679             else if (mSelectionMode == HgWidget::SingleSelection) {
       
   680                 mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   642                 INFO("Select:" << item->modelIndex().row());
   681                 INFO("Select:" << item->modelIndex().row());
   643                 mSelectionModel->select(item->modelIndex(), QItemSelectionModel::ClearAndSelect);
   682                 mSelectionModel->select(item->modelIndex(), QItemSelectionModel::ClearAndSelect);
   644                 update(); // It would be enough to update the item
   683                 update(); // It would be enough to update the item
   645             }
   684             }
   646             else if (mSelectionMode == HgWidget::ContiguousSelection) {
   685             else if (mSelectionMode == HgWidget::ContiguousSelection) {
       
   686                 mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   647                 QModelIndex newSelected = item->modelIndex();
   687                 QModelIndex newSelected = item->modelIndex();
   648                 QModelIndexList oldSelection = mSelectionModel->selectedIndexes();
   688                 QModelIndexList oldSelection = mSelectionModel->selectedIndexes();
   649                 INFO("Select:" << newSelected.row());
   689                 INFO("Select:" << newSelected.row());
   650                 if (oldSelection.count() > 0 && !mSelectionModel->isSelected(newSelected)) {
   690                 if (oldSelection.count() > 0 && !mSelectionModel->isSelected(newSelected)) {
   651                     if (newSelected.row() < oldSelection.front().row()) {
   691                     if (newSelected.row() < oldSelection.front().row()) {
   667 
   707 
   668                 if (mRenderer->coverflowModeEnabled())
   708                 if (mRenderer->coverflowModeEnabled())
   669                 {
   709                 {
   670                     if (qAbs(qreal(index) - mSpring.pos().x()) < 0.01f)
   710                     if (qAbs(qreal(index) - mSpring.pos().x()) < 0.01f)
   671                     {
   711                     {
       
   712                         mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   672                         emit activated(item->modelIndex());
   713                         emit activated(item->modelIndex());
   673                     }
   714                     }
   674                     else
   715                     else
   675                     {
   716                     {
   676                         mSpring.animateToPos(QPointF(index, 0));
   717                         mSpring.animateToPos(QPointF(index, 0));
   677                     }
   718                     }
   678                 }
   719                 }
   679                 else
   720                 else
   680                 {
   721                 {
       
   722                     mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   681                     selectItem();
   723                     selectItem();
   682                     emit activated(item->modelIndex());
   724                     emit activated(item->modelIndex());
   683                 }
   725                 }
   684 
       
   685             }
   726             }
   686         }
   727         }
       
   728 
       
   729         return true;
   687     }
   730     }
   688     else {
   731     else {
   689         INFO("No quad at pos:" << pos);
   732         INFO("No quad at pos:" << pos);
   690 
   733 
   691         unselectItem();
   734         unselectItem();
       
   735         return false;
   692     }
   736     }
   693 }
   737 }
   694 
   738 
   695 bool HgContainer::getItemPoints(int index, QPolygonF& points)
   739 bool HgContainer::getItemPoints(int index, QPolygonF& points)
   696 {
   740 {
   720 
   764 
   721 void HgContainer::itemDataChanged(const int &firstIndex, const int &lastIndex)
   765 void HgContainer::itemDataChanged(const int &firstIndex, const int &lastIndex)
   722 {
   766 {
   723     FUNC_LOG;
   767     FUNC_LOG;
   724 
   768 
       
   769     // if screen is frequently updated no need to update now.
       
   770     if (mSpring.isActive() || mDragged ) return;
       
   771     
   725     // TODO FIX THIS FUNCTION!!!!!!!!!!!!!!!!!!!!!!
   772     // TODO FIX THIS FUNCTION!!!!!!!!!!!!!!!!!!!!!!
   726 
   773 
   727     int firstItemOnScreen = 0, lastItemOnScreen = 0;
   774     int firstItemOnScreen = 0, lastItemOnScreen = 0;
   728     firstItemOnScreen = mSpring.pos().x();
   775     firstItemOnScreen = mSpring.pos().x();
   729     firstItemOnScreen *= rowCount();
   776     firstItemOnScreen *= rowCount();
   730 
   777 
   731     // This code doesnt take into count if there is some empty space at the
   778     int itemsOnScreen = mRenderer->getVisibleQuads().count();
   732     // beginning or at the end of the widget
       
   733 
       
   734     int itemsOnScreen = 0;
       
   735     if (mRenderer->getOrientation() == Qt::Vertical) {
       
   736         itemsOnScreen = this->rect().height()/mRenderer->getImageSize().height();
       
   737         itemsOnScreen += rowCount();
       
   738     }
       
   739     else {
       
   740         // Doesnt work here. Use some magic for now.
       
   741         itemsOnScreen = this->rect().width()/mRenderer->getImageSize().width();
       
   742         itemsOnScreen += 4;
       
   743     }
       
   744     itemsOnScreen *= rowCount();
       
   745     lastItemOnScreen = firstItemOnScreen+itemsOnScreen;
   779     lastItemOnScreen = firstItemOnScreen+itemsOnScreen;
   746 
   780 
   747     if ((firstIndex >= firstItemOnScreen && firstIndex <= lastItemOnScreen) ||
   781     if ((firstIndex >= firstItemOnScreen && firstIndex < lastItemOnScreen) ||
   748         (lastIndex >= firstItemOnScreen && lastIndex <= lastItemOnScreen)) {
   782         (lastIndex >= firstItemOnScreen && lastIndex < lastItemOnScreen)) {
   749         update( this->rect() );
   783         update();
   750     }
   784     }
   751 }
   785 }
   752 
   786 
   753 void HgContainer::selectItem()
   787 void HgContainer::selectItem()
   754 {
   788 {
   755     // TODO: replace this with own selection implementation
   789     // TODO: replace this with own selection implementation
   756 
   790     if (mHitItemIndex < 0 && mHitItemIndex >= mItems.count())
       
   791         return;
       
   792     
   757     if (mHitItemView)
   793     if (mHitItemView)
   758     {
   794     {
   759         delete mHitItemView;
   795         delete mHitItemView;
   760         mHitItemView = NULL;
   796         mHitItemView = NULL;
   761     }
   797     }
   762 
   798     
   763     mHitItemView = new HbGridViewItem(this);
   799     mHitItemView = new HbGridViewItem(this);
   764     mHitItemView->setVisible(false);
   800     mHitItemView->setVisible(false);
   765 
   801     mHitItemView->setPos(QPointF(0,0));
   766     QModelIndex modelIndex = mItems[mHitItemIndex]->modelIndex();
   802     mHitItemView->setPressed(true, false);
   767     const QAbstractItemModel* model = modelIndex.model();
   803 
   768     mHitItemView->resize(mRenderer->getImageSize().width() + 10,
   804     const QImage& image = mItems[mHitItemIndex]->image()->getQImage();
   769         mRenderer->getImageSize().height() + 10);
   805     if (image.isNull())
   770 
   806     {
   771     QVariant iconVariant = model->data(modelIndex, Qt::DecorationRole);
   807         mHitItemView->setVisible(false);
   772     mHitItemPixmap = iconVariant.value<QPixmap>();
   808         return;
   773     HbIcon icon(mHitItemPixmap);
   809     }
   774 
   810     
       
   811     QPixmap pixmap = QPixmap::fromImage(image);        
       
   812     HbIcon icon(pixmap.scaled(mRenderer->getImageSize().toSize(), Qt::IgnoreAspectRatio));    
   775     QGraphicsItem* item = mHitItemView->style()->createPrimitive(HbStyle::P_GridViewItem_icon, mHitItemView);
   813     QGraphicsItem* item = mHitItemView->style()->createPrimitive(HbStyle::P_GridViewItem_icon, mHitItemView);
   776     HbIconItem *iconItem = static_cast<HbIconItem*>(item);
   814     HbIconItem *iconItem = static_cast<HbIconItem*>(item);
       
   815     iconItem->setAlignment(Qt::AlignCenter);
       
   816     iconItem->setAspectRatioMode(Qt::IgnoreAspectRatio);    
   777     iconItem->setIcon(icon);
   817     iconItem->setIcon(icon);
   778     iconItem->setAlignment(Qt::AlignCenter);
   818 
   779     iconItem->setAspectRatioMode(Qt::KeepAspectRatio);
   819     mHitItemView->resize(mRenderer->getImageSize().width(),
   780 
   820         mRenderer->getImageSize().height());
   781     mHitItemView->setModelIndex(modelIndex);
       
   782     mHitItemView->setPos(QPointF(-10,-10));
       
   783     mHitItemView->setPressed(true, false);
       
   784     mHitItemView->updatePrimitives();
       
   785 
       
   786 }
   821 }
   787 
   822 
   788 void HgContainer::updateSelectedItem()
   823 void HgContainer::updateSelectedItem()
   789 {
   824 {
   790     if (!mHitItemView || mHitItemIndex == -1)
   825     if (!mHitItemView || mHitItemIndex == -1)
   796         // the item was not rendered, we must hide
   831         // the item was not rendered, we must hide
   797         // our qt item
   832         // our qt item
   798         mHitItemView->setVisible(false);
   833         mHitItemView->setVisible(false);
   799     }
   834     }
   800 
   835 
   801     if (mHitItemPixmap.isNull())
       
   802     {
       
   803         mHitItemView->setVisible(false);
       
   804         return;
       
   805     }
       
   806 
       
   807     QPolygonF img;
   836     QPolygonF img;
   808     img.append(QPointF(0,mHitItemPixmap.height()));
   837     img.append(QPointF(3,mHitItemView->boundingRect().height()-3));
   809     img.append(QPointF(mHitItemPixmap.width(),mHitItemPixmap.height()));
   838     img.append(QPointF(mHitItemView->boundingRect().width()-3,mHitItemView->boundingRect().height()-3));
   810     img.append(QPointF(mHitItemPixmap.width(),0));
   839     img.append(QPointF(mHitItemView->boundingRect().width()-3,3));
   811     img.append(QPointF(0,0));
   840     img.append(QPointF(3,3));
   812 
   841 
   813     QTransform t;
   842     QTransform t;
   814     QTransform::quadToQuad(img, points, t);
   843     QTransform::quadToQuad(img, points, t);
   815 
   844 
   816     mHitItemView->setTransform(t);
   845     mHitItemView->setTransform(t);
   820 void HgContainer::unselectItem()
   849 void HgContainer::unselectItem()
   821 {
   850 {
   822     mHitItemIndex = -1;
   851     mHitItemIndex = -1;
   823     if (mHitItemView)
   852     if (mHitItemView)
   824     {
   853     {
   825         mHitItemView->setPressed(false, false);
       
   826         mHitItemView->setVisible(false);
   854         mHitItemView->setVisible(false);
   827     }
   855     }
   828 }
   856 }
   829 
   857 
   830 void HgContainer::updateLongPressVisualizer()
   858 void HgContainer::updateLongPressVisualizer()
   831 {
   859 {
   832     int elapsed = mLongTapDuration.elapsed();
   860     int elapsed = mLongTapDuration.elapsed();
   833     
   861 
   834     if (elapsed > 80)
   862     if (elapsed > 80)
   835     {    
   863     {
   836         int frame = 100.0f * qreal(elapsed - 80) / qreal(KLongTapDuration - 80);
   864         int frame = 100.0f * qreal(elapsed - 80) / qreal(KLongTapDuration - 80);
   837         mLongPressVisualizer->setFrame(frame);
   865         mLongPressVisualizer->setFrame(frame);
   838     }
   866     }
   839 }
   867 }
   840 
   868 
   841 void HgContainer::updateByCurrentIndex(const QModelIndex &current)
   869 void HgContainer::updateByCurrentIndex(const QModelIndex &current)
   842 {
   870 {
   843     handleCurrentChanged(current);
   871     handleCurrentChanged(current);
       
   872 }
       
   873 
       
   874 bool HgContainer::hasItemAt(const QPointF& pos)
       
   875 {
       
   876     int dummy;
       
   877     HgWidgetItem *item = getItemAt(pos, dummy);
       
   878     if (item) {
       
   879         return item->modelIndex().isValid();
       
   880     }
       
   881     return false;
   844 }
   882 }
   845 
   883 
   846 HgWidgetItem* HgContainer::getItemAt(const QPointF& pos, int& index)
   884 HgWidgetItem* HgContainer::getItemAt(const QPointF& pos, int& index)
   847 {
   885 {
   848     QPointF p = mapQtToVg(pos);
   886     QPointF p = mapQtToVg(pos);
   889 }
   927 }
   890 
   928 
   891 QTransform HgContainer::qtToVgTransform() const
   929 QTransform HgContainer::qtToVgTransform() const
   892 {
   930 {
   893     QTransform t;
   931     QTransform t;
   894     if (mainWindow()->orientation() == Qt::Vertical)
   932     if (mOrientation == Qt::Vertical)
   895     {
   933     {
   896         t.translate(0, rect().height());
   934         t.translate(0, drawableRect().bottom());
   897         t.scale(1, -1);
   935         t.scale(1, -1);
   898     }
   936     }
   899     else // horizontal
   937     else // horizontal
   900     {
   938     {
   901         t.translate(rect().height(), 0);
   939         t.translate(drawableRect().bottom(), 0);
   902         t.scale(-1, 1);
   940         t.scale(-1, 1);
   903         t.translate(0, rect().width());
   941         t.translate(0, drawableRect().right());
   904         t.rotate(-90, Qt::ZAxis);
   942         t.rotate(-90, Qt::ZAxis);
   905     }
   943     }
   906     return t;
   944     return t;
   907 }
   945 }
   908 
   946 
   947 {
   985 {
   948     Q_UNUSED(current)
   986     Q_UNUSED(current)
   949     // By default do nothing
   987     // By default do nothing
   950 }
   988 }
   951 
   989 
   952 void HgContainer::onScrollingEnded()
   990 QRectF HgContainer::drawableRect() const
   953 {
   991 {
   954 /*    int index;
   992     return rect();
   955     HgWidgetItem* item = getItemAt(rect().center(), index);
   993 }
   956     if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
   994 
   957         mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
   995 void HgContainer::setDefaultImage(QImage defaultImage)
   958     }*/    
   996 {
   959 }
   997     HgQuadRenderer *renderer = mRenderer->getRenderer();
   960 
   998     if (renderer) {
       
   999         QImage scaled = defaultImage.scaled(mRenderer->getImageSize().toSize());
       
  1000         renderer->setDefaultImage(scaled);
       
  1001     }
       
  1002 }
       
  1003 
       
  1004 void HgContainer::setItemSizePolicy(HgWidget::ItemSizePolicy policy)
       
  1005 {
       
  1006     if (policy != mItemSizePolicy)
       
  1007     {
       
  1008         mItemSizePolicy = policy;
       
  1009         
       
  1010         updateItemSizeAndSpacing();
       
  1011     }
       
  1012 }
       
  1013 
       
  1014 HgWidget::ItemSizePolicy HgContainer::itemSizePolicy() const
       
  1015 {
       
  1016     return mItemSizePolicy;
       
  1017 }
       
  1018 
       
  1019 void HgContainer::setItemSize(const QSizeF& size)
       
  1020 {
       
  1021     mUserItemSize = size;
       
  1022     updateItemSizeAndSpacing();
       
  1023 }
       
  1024 
       
  1025 QSizeF HgContainer::itemSize() const
       
  1026 {
       
  1027     return mRenderer->getImageSize();
       
  1028 }
       
  1029 
       
  1030 void HgContainer::setItemSpacing(const QSizeF& spacing)
       
  1031 {
       
  1032     mUserItemSpacing = spacing;
       
  1033     updateItemSizeAndSpacing();
       
  1034 }
       
  1035 
       
  1036 QSizeF HgContainer::itemSpacing() const
       
  1037 {
       
  1038     return mRenderer->getSpacing();
       
  1039 }
       
  1040 
       
  1041 void HgContainer::updateItemSizeAndSpacing()
       
  1042 {    
       
  1043     if (mItemSizePolicy == HgWidget::ItemSizeUserDefined)
       
  1044     {
       
  1045         mRenderer->setImageSize(mUserItemSize);
       
  1046         mRenderer->setSpacing(mUserItemSpacing);
       
  1047     }
       
  1048 }
       
  1049 
       
  1050 QSizeF HgContainer::getAutoItemSize() const
       
  1051 {
       
  1052     return mUserItemSize;
       
  1053 }
       
  1054 
       
  1055 QSizeF HgContainer::getAutoItemSpacing() const
       
  1056 {
       
  1057     return mUserItemSpacing;
       
  1058 }
       
  1059 
       
  1060 Qt::Orientation HgContainer::scrollDirection() const
       
  1061 {
       
  1062     return mRenderer->getOrientation();
       
  1063 }
       
  1064 
       
  1065 qreal HgContainer::scrollPosition() const
       
  1066 {
       
  1067     return mSpring.pos().x();
       
  1068 }
       
  1069