src/hbwidgets/itemviews/hbabstractviewitem.cpp
changeset 23 e6ad4ef83b23
parent 21 4633027730f5
child 28 b7da29130b0e
equal deleted inserted replaced
21:4633027730f5 23:e6ad4ef83b23
    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     }
   585 {
   592 {
   586     HB_SDD(HbAbstractViewItem);
   593     HB_SDD(HbAbstractViewItem);
   587     if (d && !d->isPrototype()) {
   594     if (d && !d->isPrototype()) {
   588         sd->mCloneItems.removeOne(this);
   595         sd->mCloneItems.removeOne(this);
   589     }
   596     }
   590     delete d->mFrontCachePixmap;     
       
   591     delete d->mBackCachePixmap;     
       
   592 }
   597 }
   593 
   598 
   594 /*!
   599 /*!
   595     Returns true if \a model index is supported by Abstract view item, otherwise returns false.
   600     Returns true if \a model index is supported by Abstract view item, otherwise returns false.
   596     This function is called for every item on the prototype list (, if several prototypes exist)
   601     This function is called for every item on the prototype list (, if several prototypes exist)
   772 */
   777 */
   773 bool HbAbstractViewItem::event(QEvent *e)
   778 bool HbAbstractViewItem::event(QEvent *e)
   774 {
   779 {
   775     switch (e->type()) {
   780     switch (e->type()) {
   776         case QEvent::GraphicsSceneResize: {
   781         case QEvent::GraphicsSceneResize: {
   777             Q_D(HbAbstractViewItem );
   782             Q_D(HbAbstractViewItem );            
   778             d->releasePixmaps();
       
   779 
       
   780             updatePixmapCache();            
       
   781             
       
   782             QGraphicsSceneResizeEvent *resizeEvent = static_cast<QGraphicsSceneResizeEvent *>(e);
   783             QGraphicsSceneResizeEvent *resizeEvent = static_cast<QGraphicsSceneResizeEvent *>(e);
   783 
   784 
   784             if (d->mFrontPixmapPainter) {
   785             if (d->mFrontPixmapPainter) {
   785                 d->mFrontPixmapPainter->setSize(resizeEvent->newSize());
   786                 d->mFrontPixmapPainter->setSize(resizeEvent->newSize());
   786             }
   787             }
   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         }
   883             if (d->usePixmapCache()) {
   879             if (d->usePixmapCache()) {
   884                 d->setChildFlags(qvariant_cast<QGraphicsItem *>(value), true);
   880                 d->setChildFlags(qvariant_cast<QGraphicsItem *>(value), true);
   885             }
   881             }
   886             break;
   882             break;
   887         }
   883         }
   888     default:
   884         default:
   889         break;
   885             break;
   890     }
   886     }
   891 
   887 
   892     return HbWidget::itemChange(change, value);
   888     return HbWidget::itemChange(change, value);
   893 }
   889 }
   894 
   890 
   954     }
   950     }
   955 
   951 
   956     if (d->mFocusItem) {
   952     if (d->mFocusItem) {
   957         HbStylePrivate::updatePrimitive(d->mFocusItem, HbStylePrivate::P_ItemViewItem_focus, d->mSharedData->mStyleOption);
   953         HbStylePrivate::updatePrimitive(d->mFocusItem, HbStylePrivate::P_ItemViewItem_focus, d->mSharedData->mStyleOption);
   958     }
   954     }
   959 	    
   955         
   960     updatePixmapCache();
   956     updatePixmapCache();
   961 }
   957 }
   962 
   958 
   963 
   959 
   964 /*!
   960 /*!
  1240 
  1236 
  1241     if (!d->polished && layout()) {
  1237     if (!d->polished && layout()) {
  1242         return;
  1238         return;
  1243     }
  1239     }
  1244 
  1240 
  1245     if (d->polished && !d->repolishOutstanding && !d->mRepolishRequested) {
       
  1246        return;
       
  1247     }
       
  1248      
       
  1249     if (sd->mItemView) {
  1241     if (sd->mItemView) {
  1250         setProperty("layoutName", sd->mItemView->layoutName());
  1242         setProperty("layoutName", sd->mItemView->layoutName());
  1251     }
  1243     }
  1252 
  1244 
  1253     d->mRepolishRequested = false;
  1245     d->mRepolishRequested = false;
  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;
  1391             
  1386             
  1392             if (d->mFrontPixmapPainter) {
  1387             if (d->mFrontPixmapPainter) {
  1393                 d->mFrontPixmapPainter->setDeviceRect(deviceRect);
  1388                 d->mFrontPixmapPainter->setDeviceRect(deviceRect);
  1394             }
  1389             }
  1395         } else {
  1390         } else {
  1396             if (d->mFrontCachePixmap) {
  1391             if (d->mFrontPixmapPainter->pixmap()) {
  1397                 d->setChildFlags(0, false);
  1392                 d->setChildFlagRecursively(false);
  1398 
       
  1399                 d->releasePixmaps();
  1393                 d->releasePixmaps();
  1400             }
  1394             }
  1401         }
  1395         }
  1402     }
  1396     }
  1403 }
  1397 }
  1410 */
  1404 */
  1411 void HbAbstractViewItem::updatePixmapCache()
  1405 void HbAbstractViewItem::updatePixmapCache()
  1412 {
  1406 {
  1413     Q_D(HbAbstractViewItem);
  1407     Q_D(HbAbstractViewItem);
  1414 
  1408 
  1415     if (d->usePixmapCache()) {
  1409     if (!d->mResetPixmapCache && d->usePixmapCache()) {
  1416         d->mResetPixmapCache = true;
  1410         d->mResetPixmapCache = true;
  1417         update();
  1411         update();
  1418     }
  1412     }
  1419 }
  1413 }
  1420 
  1414