30 #include <HbIconItem> |
30 #include <HbIconItem> |
31 #include <QAbstractItemModel> |
31 #include <QAbstractItemModel> |
32 #include "hglongpressvisualizer.h" |
32 #include "hglongpressvisualizer.h" |
33 #include <HbPinchGesture> |
33 #include <HbPinchGesture> |
34 #include <QGraphicsSceneMouseEvent> |
34 #include <QGraphicsSceneMouseEvent> |
|
35 #include <HbWidgetFeedback> |
35 |
36 |
36 static const qreal KCameraMaxYAngle(20); |
37 static const qreal KCameraMaxYAngle(20); |
37 static const qreal KSpringVelocityToCameraYAngleFactor(2); |
38 static const qreal KSpringVelocityToCameraYAngleFactor(2); |
38 |
39 |
39 HgGridContainer::HgGridContainer(QGraphicsItem *parent) : |
40 HgGridContainer::HgGridContainer(QGraphicsItem *parent) : |
44 mTempImageHeightForLineGrid(-1), |
45 mTempImageHeightForLineGrid(-1), |
45 mTempImageHeightFinal(-1), |
46 mTempImageHeightFinal(-1), |
46 mTempRowCount(-1), |
47 mTempRowCount(-1), |
47 mPinchEndAlreadyHandled(false), |
48 mPinchEndAlreadyHandled(false), |
48 mReactToOnlyPanGestures(false), |
49 mReactToOnlyPanGestures(false), |
49 mHorizontalRowCount(3), |
50 mHorizontalRowCount(2), |
50 mVerticalColumnCount(3), |
51 mVerticalColumnCount(3), |
51 mHorizontalPinchLevels(QPair<int,int>(2,3)), |
52 mHorizontalPinchLevels(QPair<int,int>(2,3)), |
52 mVerticalPinchLevels(QPair<int,int>(2,5)) |
53 mVerticalPinchLevels(QPair<int,int>(2,5)) |
53 { |
54 { |
54 mUserItemSize = QSize(120,120); |
55 mUserItemSize = QSize(120,120); |
55 mUserItemSpacing = QSize(0,0); |
56 mUserItemSpacing = QSize(1,1); |
56 } |
57 } |
57 |
58 |
58 HgGridContainer::~HgGridContainer() |
59 HgGridContainer::~HgGridContainer() |
59 { |
60 { |
60 } |
61 } |
122 updateSelectedItem(); |
123 updateSelectedItem(); |
123 } |
124 } |
124 |
125 |
125 HgMediaWallRenderer* HgGridContainer::createRenderer(Qt::Orientation scrollDirection) |
126 HgMediaWallRenderer* HgGridContainer::createRenderer(Qt::Orientation scrollDirection) |
126 { |
127 { |
127 |
|
128 HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this, scrollDirection, scrollDirection, false); |
128 HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this, scrollDirection, scrollDirection, false); |
129 renderer->enableCoverflowMode(false); |
129 renderer->enableCoverflowMode(false); |
130 renderer->setImageSize(mUserItemSize); |
130 renderer->setImageSize(mUserItemSize); |
131 const int rowCount = scrollDirection == Qt::Horizontal ? mHorizontalRowCount : mVerticalColumnCount; |
131 const int rowCount = scrollDirection == Qt::Horizontal ? mHorizontalRowCount : mVerticalColumnCount; |
132 renderer->setRowCount(rowCount, renderer->getImageSize(), false); |
132 renderer->setRowCount(rowCount, renderer->getImageSize(), false); |
133 renderer->enableReflections(false); |
133 renderer->enableReflections(mReflectionsEnabled && scrollDirection == Qt::Horizontal); |
134 renderer->setSpacing(mUserItemSpacing); |
134 renderer->setSpacing(mUserItemSpacing); |
135 renderer->setFrontCoverElevationFactor(0.5); |
|
136 |
135 |
137 return renderer; |
136 return renderer; |
138 } |
137 } |
139 |
138 |
140 qreal HgGridContainer::getCameraDistance(qreal springVelocity) |
139 qreal HgGridContainer::getCameraDistance(qreal springVelocity) |
155 |
154 |
156 bool HgGridContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex) |
155 bool HgGridContainer::handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex) |
157 { |
156 { |
158 Q_UNUSED(pos) |
157 Q_UNUSED(pos) |
159 |
158 |
160 if (mSelectionMode != HgWidget::NoSelection) { |
159 if (!mIgnoreGestureAction) { |
|
160 // This enables tactile and audio feedback |
|
161 HbWidgetFeedback::triggered(this, Hb::InstantPressed, 0); |
|
162 } |
|
163 |
|
164 if (!mIgnoreGestureAction && mSelectionMode != HgWidget::NoSelection) { |
161 return handleItemSelection(hitItem); |
165 return handleItemSelection(hitItem); |
162 } |
166 } |
163 |
167 |
164 if (!mIgnoreGestureAction) { |
168 if (!mIgnoreGestureAction) { |
165 selectItem(hitItemIndex); |
169 selectItem(hitItemIndex); |
228 |
232 |
229 if (hasItemAt(pos)) { |
233 if (hasItemAt(pos)) { |
230 switch (state) |
234 switch (state) |
231 { |
235 { |
232 case Qt::GestureStarted: |
236 case Qt::GestureStarted: |
233 { |
237 { |
234 // TODO IS THIS IF REALLY NEEDED |
238 // TODO IS THIS IF REALLY NEEDED |
235 if(mSpring.isActive()) { |
239 if(mSpring.isActive()) { |
236 qreal springPos = mSpring.pos().x(); |
240 qreal springPos = mSpring.pos().x(); |
237 int gridTotalHeightInImages = ceilf( mItems.count() / mRenderer->getRowCount() ); |
241 int gridTotalHeightInImages = ceilf( mItems.count() / mRenderer->getRowCount() ); |
238 qreal currentViewHeightInImages; |
242 qreal currentViewHeightInImages; |
361 bool eventHandled(false); |
365 bool eventHandled(false); |
362 |
366 |
363 QGesture* pinchGesture = event->gesture(Qt::PinchGesture); |
367 QGesture* pinchGesture = event->gesture(Qt::PinchGesture); |
364 if(mPinchEnabled && !mReactToOnlyPanGestures && pinchGesture) |
368 if(mPinchEnabled && !mReactToOnlyPanGestures && pinchGesture) |
365 { |
369 { |
|
370 mIgnoreGestureAction = true; |
366 HbPinchGesture* pinch = static_cast<HbPinchGesture *>(pinchGesture); |
371 HbPinchGesture* pinch = static_cast<HbPinchGesture *>(pinchGesture); |
367 switch (pinch->state()) |
372 switch (pinch->state()) |
368 { |
373 { |
369 case Qt::GestureUpdated: |
374 case Qt::GestureUpdated: |
370 handlePinchUpdate( pinch ); |
375 handlePinchUpdate( pinch ); |
374 mTempImageHeightForLineGrid = -1; //reset, just in case |
379 mTempImageHeightForLineGrid = -1; //reset, just in case |
375 mTempImageHeightFinal = -1; //reset, just in case |
380 mTempImageHeightFinal = -1; //reset, just in case |
376 iTargetRowCountList.clear(); |
381 iTargetRowCountList.clear(); |
377 mPinchingOngoing = true; |
382 mPinchingOngoing = true; |
378 mPinchEndAlreadyHandled = false; |
383 mPinchEndAlreadyHandled = false; |
|
384 stopLongPressWatcher(); |
|
385 if (mSpring.isActive()) { |
|
386 mSpring.cancel(); |
|
387 emit scrollingEnded(); |
|
388 } |
379 break; |
389 break; |
380 case Qt::GestureCanceled: |
390 case Qt::GestureCanceled: |
381 mPinchingOngoing = false; |
391 mPinchingOngoing = false; |
382 mPinchEndAlreadyHandled = true; |
392 mPinchEndAlreadyHandled = true; |
383 update(); //redraw |
393 update(); //redraw |
510 void HgGridContainer::effectFinished() |
520 void HgGridContainer::effectFinished() |
511 { |
521 { |
512 if (iFadeAnimation.direction() == QAbstractAnimation::Forward) { |
522 if (iFadeAnimation.direction() == QAbstractAnimation::Forward) { |
513 mRenderer->setRowCount(mTargetRowCount, mTargetImageSize); |
523 mRenderer->setRowCount(mTargetRowCount, mTargetImageSize); |
514 mRenderer->setImageSize(mTargetImageSize); |
524 mRenderer->setImageSize(mTargetImageSize); |
515 // mSpring.setDamping( mTargetRowCount != 3 ? |
|
516 // KSpringDampingScrolling*(mTargetRowCount-3)*4 : KSpringDampingScrolling ); |
|
517 // mSpring.setK( mTargetRowCount != 3 ? |
|
518 // KSpringKScrolling/((mTargetRowCount-3)*4) : KSpringKScrolling ); |
|
519 scrollTo(mSelectionModel->currentIndex()); |
525 scrollTo(mSelectionModel->currentIndex()); |
520 iFadeAnimation.setDirection(QAbstractAnimation::Backward); |
526 iFadeAnimation.setDirection(QAbstractAnimation::Backward); |
521 iFadeAnimation.start(); |
527 iFadeAnimation.start(); |
|
528 |
|
529 // Reflections are drawn only in horizontal scrolling mode. |
|
530 const bool reflectionsEnabled = mReflectionsEnabled && |
|
531 scrollDirection() == Qt::Horizontal; |
|
532 // reflections need to be recreated since row count changes. |
|
533 // reflections are created only to the bottom row. |
|
534 updateReflections(reflectionsEnabled,0,mItems.count()); |
522 } |
535 } |
523 } |
536 } |
524 |
537 |
525 void HgGridContainer::setRowCount(int count, Qt::Orientation scrollDirection) |
538 void HgGridContainer::setRowCount(int count, Qt::Orientation scrollDirection) |
526 { |
539 { |
536 return scrollDirection == Qt::Horizontal ? mHorizontalRowCount : mVerticalColumnCount; |
549 return scrollDirection == Qt::Horizontal ? mHorizontalRowCount : mVerticalColumnCount; |
537 } |
550 } |
538 |
551 |
539 void HgGridContainer::setOrientation(Qt::Orientation orientation, bool animate) |
552 void HgGridContainer::setOrientation(Qt::Orientation orientation, bool animate) |
540 { |
553 { |
541 HgContainer::setOrientation(orientation, animate); |
554 const int newRowCount = orientation == Qt::Horizontal ? |
542 |
555 mHorizontalRowCount : mVerticalColumnCount; |
543 if (orientation == Qt::Horizontal) { |
556 const bool rowCountChanges = currentRowCount() != newRowCount; |
544 mRenderer->enableReflections(false); |
557 |
545 mRenderer->setImageSize(mUserItemSize); |
558 // Disable orientation change animation if the row count also changes. |
546 if (currentRowCount() != mHorizontalRowCount) { |
559 HgContainer::setOrientation(orientation, animate && !rowCountChanges); |
547 mRenderer->setRowCount(mHorizontalRowCount, mUserItemSize, false); |
560 |
548 scrollTo(mSelectionModel->currentIndex()); |
561 mRenderer->setImageSize(mUserItemSize); |
549 } |
562 if (rowCountChanges) { |
550 } else { |
563 mRenderer->setRowCount(newRowCount, mUserItemSize, false); |
551 mRenderer->enableReflections(false); |
564 scrollTo(mSelectionModel->currentIndex()); |
552 mRenderer->setImageSize(mUserItemSize); |
565 } |
553 if (currentRowCount() != mVerticalColumnCount) { |
566 |
554 mRenderer->setRowCount(mVerticalColumnCount, mUserItemSize, false); |
567 // Reflections are drawn only in horizontal scrolling mode. |
555 scrollTo(mSelectionModel->currentIndex()); |
568 const bool reflectionsEnabled = mReflectionsEnabled && orientation == Qt::Horizontal; |
556 } |
569 mRenderer->enableReflections(reflectionsEnabled); |
557 } |
570 updateReflections(reflectionsEnabled,0,mItems.count()); |
558 } |
571 } |
559 |
572 |
560 void HgGridContainer::setPinchLevels(QPair<int,int> levels, Qt::Orientation scrollDirection) |
573 void HgGridContainer::setPinchLevels(QPair<int,int> levels, Qt::Orientation scrollDirection) |
561 { |
574 { |
562 if (scrollDirection == Qt::Horizontal) { |
575 if (scrollDirection == Qt::Horizontal) { |
570 { |
583 { |
571 return scrollDirection == Qt::Horizontal ? |
584 return scrollDirection == Qt::Horizontal ? |
572 mHorizontalPinchLevels : mVerticalPinchLevels; |
585 mHorizontalPinchLevels : mVerticalPinchLevels; |
573 } |
586 } |
574 |
587 |
|
588 void HgGridContainer::setReflectionsEnabled(bool reflectionsEnabled) |
|
589 { |
|
590 mReflectionsEnabled = reflectionsEnabled; |
|
591 mRenderer->enableReflections(reflectionsEnabled); |
|
592 } |
|
593 |
|
594 bool HgGridContainer::reflectionsEnabled() const |
|
595 { |
|
596 return mReflectionsEnabled; |
|
597 } |
|
598 |
|
599 void HgGridContainer::updateReflections(bool enable, int start, int end) |
|
600 { |
|
601 int first = qBound(0, start, mItems.count()-1); |
|
602 int last = qBound(0, end, mItems.count()-1); |
|
603 const int rowCount = currentRowCount(); |
|
604 for(;first<=last; first++){ |
|
605 HgWidgetItem* item = mItems.at(first); |
|
606 item->enableReflection(enable && ((first+1)%rowCount == 0)); |
|
607 } |
|
608 } |
|
609 |
|
610 void HgGridContainer::addItems(int start, int end) |
|
611 { |
|
612 HgContainer::addItems(start, end); |
|
613 if (mReflectionsEnabled && scrollDirection() == Qt::Horizontal) { |
|
614 updateReflections(true,start,mItems.count()); |
|
615 } |
|
616 } |
|
617 |
|
618 void HgGridContainer::removeItems(int start, int end) |
|
619 { |
|
620 HgContainer::removeItems(start,end); |
|
621 if (mReflectionsEnabled && scrollDirection() == Qt::Horizontal) { |
|
622 updateReflections(true,start,mItems.count()); |
|
623 } |
|
624 } |
|
625 |
|
626 void HgGridContainer::moveItems(int start, int end, int destination) |
|
627 { |
|
628 HgContainer::moveItems(start,end,destination); |
|
629 if (mReflectionsEnabled && scrollDirection() == Qt::Horizontal) { |
|
630 updateReflections(true,start,destination+(end-start)); |
|
631 } |
|
632 } |
|
633 |
575 // End of file |
634 // End of file |