66 \brief The HbAbstractViewItem class represents a single item in a AbstractItemView. |
66 \brief The HbAbstractViewItem class represents a single item in a AbstractItemView. |
67 |
67 |
68 The HbAbstractViewItem class provides an item that is used by HbAbstractItemView class to |
68 The HbAbstractViewItem class provides an item that is used by HbAbstractItemView class to |
69 visualize content within single model index. By default HbAbstractViewItem supports QString and QStringList |
69 visualize content within single model index. By default HbAbstractViewItem supports QString and QStringList |
70 stored into Qt::DisplayRole role and QIcon, HbIcon or list of them in QVariantList stored into |
70 stored into Qt::DisplayRole role and QIcon, HbIcon or list of them in QVariantList stored into |
71 Qt::DecoratorRole role. |
71 Qt::DecoratorRole role. |
72 |
72 |
73 This class is provided mainly for customization purposes but it also acts as a default |
73 This class is provided mainly for customization purposes but it also acts as a default |
74 item prototype inside HbAbstractItemView. See HbAbstractItemView how to set customized class as a item prototype. |
74 item prototype inside HbAbstractItemView. See HbAbstractItemView how to set customized class as a item prototype. |
75 |
75 |
76 \b Subclassing |
76 \b Subclassing |
426 } |
426 } |
427 |
427 |
428 if (!child->isVisible() || child == mNonCachableItem || child == mFrontPixmapPainter || child == mBackPixmapPainter) { |
428 if (!child->isVisible() || child == mNonCachableItem || child == mFrontPixmapPainter || child == mBackPixmapPainter) { |
429 continue; |
429 continue; |
430 } |
430 } |
431 |
431 |
432 if (!itemPainted && child->zValue() >= 0) { |
432 if (!itemPainted && child->zValue() >= 0) { |
433 painter->save(); |
|
434 option->exposedRect = q->boundingRect(); |
433 option->exposedRect = q->boundingRect(); |
435 q->paint(painter, option, 0); |
434 q->paint(painter, option, 0); |
436 painter->restore(); |
|
437 itemPainted = true; |
435 itemPainted = true; |
438 } |
436 } |
439 |
437 |
440 painter->save(); |
|
441 if (child == mFrame) { |
438 if (child == mFrame) { |
|
439 QPainter::CompositionMode mode = painter->compositionMode(); |
442 painter->setCompositionMode(QPainter::CompositionMode_Source); |
440 painter->setCompositionMode(QPainter::CompositionMode_Source); |
443 } |
441 painter->translate(child->pos()); |
444 |
442 option->exposedRect = child->boundingRect(); |
445 painter->translate(child->pos()); |
443 child->paint(painter, option, 0); |
446 |
444 painter->setCompositionMode(mode); |
447 option->exposedRect = child->boundingRect(); |
445 painter->translate(-child->pos()); |
448 child->paint(painter, option, 0); |
446 continue; |
449 |
447 } |
450 painter->restore(); |
448 paintChildItemsRecursively(child,painter,option); |
451 } |
449 } |
452 |
|
453 mInPaintItems = false; |
450 mInPaintItems = false; |
454 } |
451 } |
455 |
452 |
|
453 void HbAbstractViewItemPrivate::paintChildItemsRecursively(QGraphicsItem *child, QPainter *painter,QStyleOptionGraphicsItem *option) |
|
454 { |
|
455 if (!child->isVisible()) |
|
456 return; |
|
457 int i = 0; |
|
458 QList<QGraphicsItem *> children = child->childItems(); |
|
459 int count(children.size()); |
|
460 painter->translate(child->pos()); |
|
461 // Draw children behind |
|
462 for (i = 0; i < count; ++i) { |
|
463 QGraphicsItem *subChild = children.at(i); |
|
464 if (!(subChild->flags() & QGraphicsItem::ItemStacksBehindParent)) |
|
465 break; |
|
466 paintChildItemsRecursively(subChild, painter,option); |
|
467 } |
|
468 option->exposedRect = child->boundingRect(); |
|
469 child->paint(painter, option, 0); |
|
470 // Draw children in front |
|
471 for (; i < count; ++i) { |
|
472 QGraphicsItem *subChild = children.at(i); |
|
473 paintChildItemsRecursively(subChild, painter,option); |
|
474 } |
|
475 painter->translate(-child->pos()); |
|
476 } |
|
477 |
|
478 |
456 void HbAbstractViewItemPrivate::setChildFlags(QGraphicsItem *child, bool pixmapCacheEnabled) |
479 void HbAbstractViewItemPrivate::setChildFlags(QGraphicsItem *child, bool pixmapCacheEnabled) |
457 { |
480 { |
|
481 QGraphicsItem::GraphicsItemFlags itemFlags = child->flags(); |
|
482 if (pixmapCacheEnabled) { |
|
483 itemFlags |= QGraphicsItem::ItemHasNoContents; |
|
484 itemFlags |= QGraphicsItem::ItemIgnoresParentOpacity; |
|
485 } |
|
486 else { |
|
487 itemFlags &= ~QGraphicsItem::ItemHasNoContents; |
|
488 itemFlags &= ~QGraphicsItem::ItemIgnoresParentOpacity; |
|
489 } |
|
490 child->setFlags(itemFlags); |
|
491 foreach (QGraphicsItem *subChild, child->childItems()) { |
|
492 setChildFlags(subChild,pixmapCacheEnabled); |
|
493 } |
|
494 } |
|
495 |
|
496 void HbAbstractViewItemPrivate::setChildFlagRecursively(bool pixmapCacheEnabled) |
|
497 { |
458 Q_Q(HbAbstractViewItem); |
498 Q_Q(HbAbstractViewItem); |
459 |
499 foreach (QGraphicsItem *subChild, q->childItems()) { |
460 if (child) { |
500 if (subChild == mNonCachableItem || subChild == mFrontPixmapPainter || |
461 QGraphicsItem::GraphicsItemFlags itemFlags = child->flags(); |
501 subChild == mBackPixmapPainter) { |
462 if (pixmapCacheEnabled) { |
502 continue; |
463 itemFlags |= QGraphicsItem::ItemHasNoContents; |
503 } |
464 itemFlags |= QGraphicsItem::ItemIgnoresParentOpacity; |
504 setChildFlags(subChild, pixmapCacheEnabled); |
465 } |
|
466 else { |
|
467 itemFlags &= ~QGraphicsItem::ItemHasNoContents; |
|
468 itemFlags &= ~QGraphicsItem::ItemIgnoresParentOpacity; |
|
469 } |
|
470 child->setFlags(itemFlags); |
|
471 } else { |
|
472 foreach (QGraphicsItem *child, q->childItems()) { |
|
473 if (child == mNonCachableItem || child == mFrontPixmapPainter || child == mBackPixmapPainter) { |
|
474 continue; |
|
475 } |
|
476 |
|
477 QGraphicsItem::GraphicsItemFlags itemFlags = child->flags(); |
|
478 if (pixmapCacheEnabled) { |
|
479 itemFlags |= QGraphicsItem::ItemHasNoContents; |
|
480 itemFlags |= QGraphicsItem::ItemIgnoresParentOpacity; |
|
481 } |
|
482 else { |
|
483 itemFlags &= ~QGraphicsItem::ItemHasNoContents; |
|
484 itemFlags &= ~QGraphicsItem::ItemIgnoresParentOpacity; |
|
485 } |
|
486 child->setFlags(itemFlags); |
|
487 } |
|
488 } |
505 } |
489 } |
506 } |
490 |
507 |
491 void HbAbstractViewItemPrivate::updatePixmap(QPixmap *pixmap, |
508 void HbAbstractViewItemPrivate::updatePixmap(QPixmap *pixmap, |
492 QPainter *painter, |
509 QPainter *painter, |
510 paintItems(&pixmapPainter, &pixmapOption, startItem, endItem); |
527 paintItems(&pixmapPainter, &pixmapOption, startItem, endItem); |
511 } |
528 } |
512 |
529 |
513 void HbAbstractViewItemPrivate::releasePixmaps() |
530 void HbAbstractViewItemPrivate::releasePixmaps() |
514 { |
531 { |
515 if (mFrontCachePixmap) { |
|
516 delete mFrontCachePixmap; |
|
517 mFrontCachePixmap = 0; |
|
518 } |
|
519 |
|
520 if (mFrontPixmapPainter) { |
532 if (mFrontPixmapPainter) { |
521 mFrontPixmapPainter->setPixmap(0); |
533 mFrontPixmapPainter->setPixmap(0); |
522 } |
|
523 |
|
524 if (mBackCachePixmap) { |
|
525 delete mBackCachePixmap; |
|
526 mBackCachePixmap = 0; |
|
527 } |
534 } |
528 |
535 |
529 if (mBackPixmapPainter) { |
536 if (mBackPixmapPainter) { |
530 mBackPixmapPainter->setPixmap(0); |
537 mBackPixmapPainter->setPixmap(0); |
531 } |
538 } |
850 Invalidates parent layout when ItemTransformHasChanged is received. |
851 Invalidates parent layout when ItemTransformHasChanged is received. |
851 */ |
852 */ |
852 QVariant HbAbstractViewItem::itemChange(GraphicsItemChange change, const QVariant &value) |
853 QVariant HbAbstractViewItem::itemChange(GraphicsItemChange change, const QVariant &value) |
853 { |
854 { |
854 switch (change) { |
855 switch (change) { |
855 case ItemTransformHasChanged: { |
856 case ItemTransformHasChanged: { |
856 Q_D(HbAbstractViewItem); |
|
857 |
|
858 QGraphicsLayoutItem *parentLayoutItem = this->parentLayoutItem(); |
857 QGraphicsLayoutItem *parentLayoutItem = this->parentLayoutItem(); |
859 if (parentLayoutItem && parentLayoutItem->isLayout()) { |
858 if (parentLayoutItem && parentLayoutItem->isLayout()) { |
860 QGraphicsLayout *parentLayout = static_cast<QGraphicsLayout *>(parentLayoutItem); |
859 QGraphicsLayout *parentLayout = static_cast<QGraphicsLayout *>(parentLayoutItem); |
861 parentLayout->invalidate(); |
860 parentLayout->invalidate(); |
862 } |
861 } |
863 d->releasePixmaps(); |
|
864 |
|
865 updatePixmapCache(); |
|
866 break; |
862 break; |
867 } |
863 } |
868 case ItemEnabledHasChanged: { |
864 case ItemEnabledHasChanged: { |
869 updateChildItems(); |
865 updateChildItems(); |
870 break; |
866 break; |
871 } |
867 } |
872 case ItemVisibleHasChanged: { |
868 case ItemVisibleHasChanged: { |
873 Q_D(HbAbstractViewItem); |
869 Q_D(HbAbstractViewItem); |
874 if (!value.toBool() && d->usePixmapCache()) { |
870 if (!value.toBool() && d->usePixmapCache()) { |
875 d->setChildFlags(0, false); |
871 d->setChildFlagRecursively(false); |
876 d->releasePixmaps(); |
872 d->releasePixmaps(); |
877 d->mResetPixmapCache = true; |
873 d->mResetPixmapCache = true; |
878 } |
874 } |
879 break; |
875 break; |
880 } |
876 } |
1346 void HbAbstractViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
1338 void HbAbstractViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
1347 { |
1339 { |
1348 Q_UNUSED(widget); |
1340 Q_UNUSED(widget); |
1349 |
1341 |
1350 Q_D(HbAbstractViewItem); |
1342 Q_D(HbAbstractViewItem); |
1351 |
|
1352 if (!d->mInPaintItems) { |
1343 if (!d->mInPaintItems) { |
1353 bool usePixmapCache = d->usePixmapCache(); |
1344 bool usePixmapCache = d->usePixmapCache(); |
1354 |
1345 |
1355 if (usePixmapCache) { |
1346 if (usePixmapCache) { |
1356 QRectF deviceBounds = painter->worldTransform().mapRect(boundingRect()); |
1347 QRectF deviceBounds = painter->worldTransform().mapRect(boundingRect()); |
1357 QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); |
1348 QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1); |
1358 |
1349 |
|
1350 if (deviceRect.size() != d->mFrontPixmapPainter->pixmapSize()) { |
|
1351 d->mResetPixmapCache = true; |
|
1352 d->releasePixmaps(); |
|
1353 } |
|
1354 |
1359 if (d->mResetPixmapCache) { |
1355 if (d->mResetPixmapCache) { |
1360 if (!d->mFrontCachePixmap) { |
1356 if (!d->mFrontPixmapPainter->pixmap()) { |
1361 d->setChildFlags(0, true); |
1357 d->setChildFlagRecursively(true); |
1362 |
1358 QPixmap *pixmap = new QPixmap(deviceRect.size()); |
1363 d->mFrontCachePixmap = new QPixmap(deviceRect.size()); |
1359 d->mFrontPixmapPainter->setPixmap(pixmap); |
1364 d->mFrontPixmapPainter->setPixmap(d->mFrontCachePixmap); |
|
1365 } |
1360 } |
1366 |
1361 |
1367 // Construct an item-to-pixmap transform. |
1362 // Construct an item-to-pixmap transform. |
1368 QPointF p = deviceRect.topLeft(); |
1363 QPointF p = deviceRect.topLeft(); |
1369 QTransform itemToPixmap = painter->worldTransform(); |
1364 QTransform itemToPixmap = painter->worldTransform(); |
1370 if (!p.isNull()) |
1365 if (!p.isNull()) |
1371 itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y()); |
1366 itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y()); |
1372 |
1367 |
1373 d->updatePixmap(d->mFrontCachePixmap, painter, itemToPixmap, option, d->mNonCachableItem, 0); |
1368 d->updatePixmap(d->mFrontPixmapPainter->pixmap(), painter, itemToPixmap, option, d->mNonCachableItem, 0); |
1374 |
1369 |
1375 if (d->mNonCachableItem) { |
1370 if (d->mNonCachableItem) { |
1376 if (!d->mBackCachePixmap) { |
1371 if (!d->mBackPixmapPainter->pixmap()) { |
1377 d->mBackCachePixmap = new QPixmap(deviceRect.size()); |
1372 QPixmap *pixmap = new QPixmap(deviceRect.size()); |
|
1373 d->mBackPixmapPainter->setPixmap(pixmap); |
1378 } |
1374 } |
1379 d->mBackPixmapPainter->setPixmap(d->mBackCachePixmap); |
1375 d->updatePixmap(d->mBackPixmapPainter->pixmap(), painter, itemToPixmap, option, 0, d->mNonCachableItem); |
1380 d->updatePixmap(d->mBackCachePixmap, painter, itemToPixmap, option, 0, d->mNonCachableItem); |
|
1381 } else if (d->mBackPixmapPainter) { |
1376 } else if (d->mBackPixmapPainter) { |
1382 d->mBackPixmapPainter->setPixmap(0); |
1377 d->mBackPixmapPainter->setPixmap(0); |
1383 } |
1378 } |
1384 |
1379 |
1385 d->mResetPixmapCache = false; |
1380 d->mResetPixmapCache = false; |