diff -r 89c329efa980 -r e48454f237ca ganeswidgets/src/HgContainer.cpp --- a/ganeswidgets/src/HgContainer.cpp Mon Apr 19 14:40:06 2010 +0300 +++ b/ganeswidgets/src/HgContainer.cpp Mon May 03 13:32:54 2010 +0300 @@ -57,10 +57,12 @@ mHitItemView(NULL), mLongPressVisualizer(NULL), mLongPressTimer(NULL), - mHitItemIndex(NULL) + mHitItemIndex(NULL), + mItemSizePolicy(HgWidget::ItemSizeUserDefined), + mOrientation(Qt::Vertical) { FUNC_LOG; - + grabGesture(Qt::PanGesture); grabGesture(Qt::TapGesture); grabGesture(Qt::TapAndHoldGesture); @@ -70,9 +72,7 @@ { FUNC_LOG; - for (QList::iterator i = mItems.begin(); i != mItems.end(); ++i) { - delete (*i); - } + qDeleteAll(mItems); mItems.clear(); delete mMarkImage; delete mRenderer; @@ -82,6 +82,7 @@ { FUNC_LOG; + qDeleteAll(mItems); mItems.clear(); for (int i=0; igetOrientation(); + return mOrientation; } void HgContainer::setOrientation(Qt::Orientation orientation, bool animate) { FUNC_LOG; - mRenderer->setOrientation(orientation, animate); + mOrientation = orientation; + mRenderer->setOrientation(orientation, false); } void HgContainer::scrollToPosition(qreal value, bool animate) @@ -241,8 +243,8 @@ { FUNC_LOG; - if (index.isValid()) { - scrollToPosition(QPointF(index.row(), index.column()), false); + if (index.isValid() && mRenderer->getRowCount() > 0) { + scrollToPosition(QPointF(index.row()/mRenderer->getRowCount(), 0), false); } } @@ -264,6 +266,7 @@ void HgContainer::addItems(int start, int end) { FUNC_LOG; + HANDLE_ERROR_NULL(mSelectionModel); int first = qBound(0, start, mItems.count()-1); int last = qBound(0, end, mItems.count()-1); @@ -271,11 +274,13 @@ HgWidgetItem* item = new HgWidgetItem(mQuadRenderer); mItems.insert(start, item); } + scrollTo(mSelectionModel->currentIndex()); } void HgContainer::removeItems(int start, int end) { FUNC_LOG; + HANDLE_ERROR_NULL(mSelectionModel); int first = qBound(0, start, mItems.count()-1); int last = qBound(0, end, mItems.count()-1); @@ -283,11 +288,13 @@ delete mItems.at(i); mItems.removeAt(i); } + scrollTo(mSelectionModel->currentIndex()); } void HgContainer::moveItems(int start, int end, int destination) { FUNC_LOG; + HANDLE_ERROR_NULL(mSelectionModel); int first = qBound(0, start, mItems.count()-1); int last = qBound(0, end, mItems.count()-1); @@ -304,6 +311,7 @@ } } // else do nothing + scrollTo(mSelectionModel->currentIndex()); } int HgContainer::imageCount() const @@ -337,14 +345,13 @@ void HgContainer::updateBySpringPosition() { - update(); - // spring works always in one dimension, that is, x coord. qreal pos = mSpring.pos().x(); onScrollPositionChanged(pos); emit scrollPositionChanged(pos, mAnimateUsingScrollBar); + update(); } void HgContainer::redraw() @@ -356,28 +363,35 @@ { Q_UNUSED(option) Q_UNUSED(widget) - if (mSpring.updatePositionIfNeeded()) { // spring works always in one dimension, that is, x coord. qreal pos = mSpring.pos().x(); onScrollPositionChanged(pos); - emit scrollPositionChanged(pos, mAnimateUsingScrollBar); + emit scrollPositionChanged(pos, true); } - + QRectF vp = painter->viewport(); - QRectF rts = mapRectToScene(rect()); + QRectF rts = mapRectToScene(drawableRect()); QRectF r; // transform rectangle to vg space & // rotate rendering according to orientation - if (mainWindow()->orientation() == Qt::Horizontal) { + if (mOrientation == Qt::Horizontal) { r = QRectF(vp.width()-(rts.height()+rts.top()), rts.left(), rts.height(), rts.width()); + + mRenderer->setRect(r); + mRenderer->setCameraRotationZ(-90); } else { r = QRectF(rts.left(), vp.height()-(rts.height()+rts.top()), rts.width(), rts.height()); mRenderer->setCameraRotationZ(0); + + mRenderer->setRect(r); + + if (!mSpring.isActive() && mSpring.pos().x() > worldWidth()) + boundSpring(); } // interpolate spring velocity towards zero, this is done @@ -393,10 +407,9 @@ // setup rendering and draw the current view mRenderer->setCameraDistance(getCameraDistance(springVel)); mRenderer->setCameraRotationY(getCameraRotationY(springVel)); - mRenderer->setRect(r); mRenderer->draw(mSpring.startPos(), mSpring.pos(), mSpring.endPos(), springVel, painter); - + } void HgContainer::resizeEvent(QGraphicsSceneResizeEvent *event) @@ -416,20 +429,35 @@ { FUNC_LOG; + bool eventHandled(false); // Event may contain more than one gesture type if (QGesture *gesture = event->gesture(Qt::TapAndHoldGesture)) { QTapAndHoldGesture *tapAndHold = static_cast(gesture); - handleLongTap(tapAndHold->state(), - mapFromScene(event->mapToGraphicsScene(tapAndHold->position()))); + if (handleLongTap(tapAndHold->state(), + mapFromScene(event->mapToGraphicsScene(tapAndHold->position())))) { + } } else if (QGesture *gesture = event->gesture(Qt::TapGesture)) { // Tap and hold is not working yet in HW, tap gesture is delivered instead QTapGesture *tap = static_cast(gesture); - handleTap(tap->state(), + eventHandled = handleTap(tap->state(), mapFromScene(event->mapToGraphicsScene(tap->position()))); } else if (QGesture *pan = event->gesture(Qt::PanGesture)) { - handlePanning(static_cast(pan)); + eventHandled = handlePanning(static_cast(pan)); + } + + if (eventHandled) { + event->accept(); + event->accept(Qt::TapAndHoldGesture); + event->accept(Qt::TapGesture); + event->accept(Qt::PanGesture); + } + else { + event->ignore(); + event->ignore(Qt::TapAndHoldGesture); + event->ignore(Qt::TapGesture); + event->ignore(Qt::PanGesture); } } @@ -437,12 +465,9 @@ { FUNC_LOG; - mRenderer = createRenderer(); - if (mRenderer->coverflowModeEnabled()) - mRenderer->setOrientation(Qt::Horizontal, false); - else - mRenderer->setOrientation(scrollDirection, false); - + mRenderer = createRenderer(scrollDirection); + mOrientation = scrollDirection; + mQuadRenderer = mRenderer->getRenderer(); QImage markImage(":/images/mark.svg"); @@ -454,9 +479,8 @@ if (mMarkImage) { mMarkImage->setImage(markImage); } - + connect(&mSpring, SIGNAL(updated()), SLOT(updateBySpringPosition())); - connect(&mSpring, SIGNAL(ended()), SLOT(onScrollingEnded())); connect(&mSpring, SIGNAL(ended()), SIGNAL(scrollingEnded())); connect(&mSpring, SIGNAL(started()), SIGNAL(scrollingStarted())); connect(mRenderer, SIGNAL(renderingNeeded()), SLOT(redraw())); @@ -500,7 +524,7 @@ } -void HgContainer::handlePanning(QPanGesture *gesture) +bool HgContainer::handlePanning(QPanGesture *gesture) { mAnimateUsingScrollBar = false; initSpringForScrolling(); @@ -509,7 +533,7 @@ qreal delta(0); qreal itemSide(0); - if (mRenderer->getOrientation() == mainWindow()->orientation()) { + if (mOrientation == mRenderer->getOrientation()) { delta = gesture->delta().y(); } else { @@ -544,6 +568,7 @@ if (qAbs(newPosition - mSpring.pos().x()) > 0.01f) { mSpring.gotoPos(QPointF(newPosition, 0)); + emit scrollPositionChanged(newPosition,true); update(); } } @@ -566,40 +591,54 @@ else if (gesture->state() == Qt::GestureCanceled) { boundSpring(); } + + return true; } - - -void HgContainer::handleTap(Qt::GestureState state, const QPointF &pos) +bool HgContainer::handleTap(Qt::GestureState state, const QPointF &pos) { FUNC_LOG; if (state == Qt::GestureStarted) { - mTapDuration.start(); - - startLongPressWatcher(pos); + if (hasItemAt(pos)) { + mTapDuration.start(); + startLongPressWatcher(pos); + return true; + } + return false; } else if (state == Qt::GestureCanceled) { stopLongPressWatcher(); + + if (hasItemAt(pos)) { + return true; + } + return false; } else if (state == Qt::GestureFinished) { + stopLongPressWatcher(); + return handleItemAction(pos, mTapDuration.elapsed() > KLongTapDuration ? LongTap : NormalTap); + } - stopLongPressWatcher(); - handleItemAction(pos, mTapDuration.elapsed() > KLongTapDuration ? LongTap : NormalTap); - } + return false; } -void HgContainer::handleLongTap(Qt::GestureState state, const QPointF &pos) +bool HgContainer::handleLongTap(Qt::GestureState state, const QPointF &pos) { FUNC_LOG; - mAnimateUsingScrollBar = false; - initSpringForScrolling(); + if (hasItemAt(pos)) { + mAnimateUsingScrollBar = false; + initSpringForScrolling(); - if (state == Qt::GestureFinished) { - handleItemAction(pos, LongTap); + if (state == Qt::GestureFinished) { + handleItemAction(pos, LongTap); + } + return true; } + + return false; } /*! @@ -608,25 +647,23 @@ Sets the item as the current item and in multiselection mode toggles the item selection status. */ -void HgContainer::handleItemAction(const QPointF &pos, ItemActionType action) +bool HgContainer::handleItemAction(const QPointF &pos, ItemActionType action) { FUNC_LOG; // If there is content, mSelectionModel must always exist - either default or client-provided - if (!mSelectionModel) return; + if (!mSelectionModel) return false; mHitItem = getItemAt(pos, mHitItemIndex); if (mHitItem) { int index = mHitItemIndex; - HgWidgetItem* item = itemByIndex(index); if (item && action != DoubleTap) { - mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); - if (action == LongTap) { INFO("Long tap:" << item->modelIndex().row()); + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); if (!mRenderer->coverflowModeEnabled()) selectItem(); @@ -634,16 +671,19 @@ emit longPressed(item->modelIndex(), pos); } else if (mSelectionMode == HgWidget::MultiSelection) { + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); INFO("Select:" << item->modelIndex().row()); mSelectionModel->select(item->modelIndex(), QItemSelectionModel::Toggle); update(); // It would be enough to update the item } else if (mSelectionMode == HgWidget::SingleSelection) { + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); INFO("Select:" << item->modelIndex().row()); mSelectionModel->select(item->modelIndex(), QItemSelectionModel::ClearAndSelect); update(); // It would be enough to update the item } else if (mSelectionMode == HgWidget::ContiguousSelection) { + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); QModelIndex newSelected = item->modelIndex(); QModelIndexList oldSelection = mSelectionModel->selectedIndexes(); INFO("Select:" << newSelected.row()); @@ -669,6 +709,7 @@ { if (qAbs(qreal(index) - mSpring.pos().x()) < 0.01f) { + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); emit activated(item->modelIndex()); } else @@ -678,17 +719,20 @@ } else { + mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); selectItem(); emit activated(item->modelIndex()); } - } } + + return true; } else { INFO("No quad at pos:" << pos); unselectItem(); + return false; } } @@ -722,67 +766,58 @@ { FUNC_LOG; + // if screen is frequently updated no need to update now. + if (mSpring.isActive() || mDragged ) return; + // TODO FIX THIS FUNCTION!!!!!!!!!!!!!!!!!!!!!! int firstItemOnScreen = 0, lastItemOnScreen = 0; firstItemOnScreen = mSpring.pos().x(); firstItemOnScreen *= rowCount(); - // This code doesnt take into count if there is some empty space at the - // beginning or at the end of the widget - - int itemsOnScreen = 0; - if (mRenderer->getOrientation() == Qt::Vertical) { - itemsOnScreen = this->rect().height()/mRenderer->getImageSize().height(); - itemsOnScreen += rowCount(); - } - else { - // Doesnt work here. Use some magic for now. - itemsOnScreen = this->rect().width()/mRenderer->getImageSize().width(); - itemsOnScreen += 4; - } - itemsOnScreen *= rowCount(); + int itemsOnScreen = mRenderer->getVisibleQuads().count(); lastItemOnScreen = firstItemOnScreen+itemsOnScreen; - if ((firstIndex >= firstItemOnScreen && firstIndex <= lastItemOnScreen) || - (lastIndex >= firstItemOnScreen && lastIndex <= lastItemOnScreen)) { - update( this->rect() ); + if ((firstIndex >= firstItemOnScreen && firstIndex < lastItemOnScreen) || + (lastIndex >= firstItemOnScreen && lastIndex < lastItemOnScreen)) { + update(); } } void HgContainer::selectItem() { // TODO: replace this with own selection implementation - + if (mHitItemIndex < 0 && mHitItemIndex >= mItems.count()) + return; + if (mHitItemView) { delete mHitItemView; mHitItemView = NULL; } - + mHitItemView = new HbGridViewItem(this); mHitItemView->setVisible(false); + mHitItemView->setPos(QPointF(0,0)); + mHitItemView->setPressed(true, false); - QModelIndex modelIndex = mItems[mHitItemIndex]->modelIndex(); - const QAbstractItemModel* model = modelIndex.model(); - mHitItemView->resize(mRenderer->getImageSize().width() + 10, - mRenderer->getImageSize().height() + 10); - - QVariant iconVariant = model->data(modelIndex, Qt::DecorationRole); - mHitItemPixmap = iconVariant.value(); - HbIcon icon(mHitItemPixmap); - + const QImage& image = mItems[mHitItemIndex]->image()->getQImage(); + if (image.isNull()) + { + mHitItemView->setVisible(false); + return; + } + + QPixmap pixmap = QPixmap::fromImage(image); + HbIcon icon(pixmap.scaled(mRenderer->getImageSize().toSize(), Qt::IgnoreAspectRatio)); QGraphicsItem* item = mHitItemView->style()->createPrimitive(HbStyle::P_GridViewItem_icon, mHitItemView); HbIconItem *iconItem = static_cast(item); + iconItem->setAlignment(Qt::AlignCenter); + iconItem->setAspectRatioMode(Qt::IgnoreAspectRatio); iconItem->setIcon(icon); - iconItem->setAlignment(Qt::AlignCenter); - iconItem->setAspectRatioMode(Qt::KeepAspectRatio); - mHitItemView->setModelIndex(modelIndex); - mHitItemView->setPos(QPointF(-10,-10)); - mHitItemView->setPressed(true, false); - mHitItemView->updatePrimitives(); - + mHitItemView->resize(mRenderer->getImageSize().width(), + mRenderer->getImageSize().height()); } void HgContainer::updateSelectedItem() @@ -798,17 +833,11 @@ mHitItemView->setVisible(false); } - if (mHitItemPixmap.isNull()) - { - mHitItemView->setVisible(false); - return; - } - QPolygonF img; - img.append(QPointF(0,mHitItemPixmap.height())); - img.append(QPointF(mHitItemPixmap.width(),mHitItemPixmap.height())); - img.append(QPointF(mHitItemPixmap.width(),0)); - img.append(QPointF(0,0)); + img.append(QPointF(3,mHitItemView->boundingRect().height()-3)); + img.append(QPointF(mHitItemView->boundingRect().width()-3,mHitItemView->boundingRect().height()-3)); + img.append(QPointF(mHitItemView->boundingRect().width()-3,3)); + img.append(QPointF(3,3)); QTransform t; QTransform::quadToQuad(img, points, t); @@ -822,7 +851,6 @@ mHitItemIndex = -1; if (mHitItemView) { - mHitItemView->setPressed(false, false); mHitItemView->setVisible(false); } } @@ -830,9 +858,9 @@ void HgContainer::updateLongPressVisualizer() { int elapsed = mLongTapDuration.elapsed(); - + if (elapsed > 80) - { + { int frame = 100.0f * qreal(elapsed - 80) / qreal(KLongTapDuration - 80); mLongPressVisualizer->setFrame(frame); } @@ -843,6 +871,16 @@ handleCurrentChanged(current); } +bool HgContainer::hasItemAt(const QPointF& pos) +{ + int dummy; + HgWidgetItem *item = getItemAt(pos, dummy); + if (item) { + return item->modelIndex().isValid(); + } + return false; +} + HgWidgetItem* HgContainer::getItemAt(const QPointF& pos, int& index) { QPointF p = mapQtToVg(pos); @@ -891,16 +929,16 @@ QTransform HgContainer::qtToVgTransform() const { QTransform t; - if (mainWindow()->orientation() == Qt::Vertical) + if (mOrientation == Qt::Vertical) { - t.translate(0, rect().height()); + t.translate(0, drawableRect().bottom()); t.scale(1, -1); } else // horizontal { - t.translate(rect().height(), 0); + t.translate(drawableRect().bottom(), 0); t.scale(-1, 1); - t.translate(0, rect().width()); + t.translate(0, drawableRect().right()); t.rotate(-90, Qt::ZAxis); } return t; @@ -949,12 +987,83 @@ // By default do nothing } -void HgContainer::onScrollingEnded() +QRectF HgContainer::drawableRect() const +{ + return rect(); +} + +void HgContainer::setDefaultImage(QImage defaultImage) +{ + HgQuadRenderer *renderer = mRenderer->getRenderer(); + if (renderer) { + QImage scaled = defaultImage.scaled(mRenderer->getImageSize().toSize()); + renderer->setDefaultImage(scaled); + } +} + +void HgContainer::setItemSizePolicy(HgWidget::ItemSizePolicy policy) { -/* int index; - HgWidgetItem* item = getItemAt(rect().center(), index); - if (item && item->modelIndex() != mSelectionModel->currentIndex()) { - mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); - }*/ + if (policy != mItemSizePolicy) + { + mItemSizePolicy = policy; + + updateItemSizeAndSpacing(); + } +} + +HgWidget::ItemSizePolicy HgContainer::itemSizePolicy() const +{ + return mItemSizePolicy; +} + +void HgContainer::setItemSize(const QSizeF& size) +{ + mUserItemSize = size; + updateItemSizeAndSpacing(); +} + +QSizeF HgContainer::itemSize() const +{ + return mRenderer->getImageSize(); } +void HgContainer::setItemSpacing(const QSizeF& spacing) +{ + mUserItemSpacing = spacing; + updateItemSizeAndSpacing(); +} + +QSizeF HgContainer::itemSpacing() const +{ + return mRenderer->getSpacing(); +} + +void HgContainer::updateItemSizeAndSpacing() +{ + if (mItemSizePolicy == HgWidget::ItemSizeUserDefined) + { + mRenderer->setImageSize(mUserItemSize); + mRenderer->setSpacing(mUserItemSpacing); + } +} + +QSizeF HgContainer::getAutoItemSize() const +{ + return mUserItemSize; +} + +QSizeF HgContainer::getAutoItemSpacing() const +{ + return mUserItemSpacing; +} + +Qt::Orientation HgContainer::scrollDirection() const +{ + return mRenderer->getOrientation(); +} + +qreal HgContainer::scrollPosition() const +{ + return mSpring.pos().x(); +} +