--- 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<HgWidgetItem*>::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; i<itemCount; i++) {
HgWidgetItem* item = new HgWidgetItem(mQuadRenderer);
@@ -207,14 +208,15 @@
{
FUNC_LOG;
- return mRenderer->getOrientation();
+ 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<QTapAndHoldGesture *>(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<QTapGesture *>(gesture);
- handleTap(tap->state(),
+ eventHandled = handleTap(tap->state(),
mapFromScene(event->mapToGraphicsScene(tap->position())));
}
else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
- handlePanning(static_cast<QPanGesture*>(pan));
+ eventHandled = handlePanning(static_cast<QPanGesture*>(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<QPixmap>();
- 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<HbIconItem*>(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();
+}
+