src/hbwidgets/itemviews/hbabstractviewitem.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    26 #include "hbabstractviewitem_p.h"
    26 #include "hbabstractviewitem_p.h"
    27 
    27 
    28 #include <hbabstractviewitem.h>
    28 #include <hbabstractviewitem.h>
    29 #include <hbabstractitemview.h>
    29 #include <hbabstractitemview.h>
    30 #include <hbnamespace.h>
    30 #include <hbnamespace.h>
    31 #include <hbstyleoptionabstractviewitem_p.h>
       
    32 #include <hbstyle.h>
    31 #include <hbstyle.h>
    33 #include <hbiconitem.h>
    32 #include <hbiconitem.h>
       
    33 #include <hbiconitem_p.h>
    34 #include <hbframebackground.h>
    34 #include <hbframebackground.h>
    35 #include <hbabstractitemview_p.h>
    35 #include <hbabstractitemview_p.h>
    36 #include <hbwidgetfeedback.h>
    36 #include <hbwidgetfeedback.h>
    37 #include <hbtapgesture.h>
    37 #include <hbtapgesture.h>
    38 #include <hbnamespace_p.h>
    38 #include <hbnamespace_p.h>
       
    39 #include <hbevent.h>
       
    40 #include <hbtextitem.h>
       
    41 #include <hbiconitem.h>
       
    42 #include <hbstyletextprimitivedata.h>
       
    43 #include <hbstyleframeprimitivedata.h>
       
    44 #include <hbstyleiconprimitivedata.h>
       
    45 #include <hbstyletouchareaprimitivedata.h>
    39 
    46 
    40 #include <QPersistentModelIndex>
    47 #include <QPersistentModelIndex>
    41 #include <QGraphicsLayout>
    48 #include <QGraphicsLayout>
    42 #include <QVariant>
    49 #include <QVariant>
    43 #include <QCoreApplication>
    50 #include <QCoreApplication>
    44 #include <QEvent>
    51 #include <QEvent>
    45 #include <QTimer>
    52 #include <QTimer>
    46 #include <QGraphicsScene>
    53 #include <QGraphicsScene>
    47 #include <QDebug>
    54 
       
    55 #include <QPixmap>
       
    56 #include <QChildEvent>
    48 
    57 
    49 #include <QGesture>
    58 #include <QGesture>
    50 #include <QGestureEvent>
    59 #include <QGestureEvent>
       
    60 #include <QGraphicsSceneEvent>
       
    61 
       
    62 #include <QDebug>
    51 
    63 
    52 const QString KDefaultLayoutOption = "default";
    64 const QString KDefaultLayoutOption = "default";
    53 const int HbAbstractViewItemShared::ViewItemDeferredDeleteEvent = QEvent::registerEventType();
    65 const int HbAbstractViewItemShared::ViewItemDeferredDeleteEvent = QEvent::registerEventType();
    54 const int HbViewItemPressDelay = 50;
    66 const int HbViewItemPressDelay = 100;
    55 
    67 
    56 /*!
    68 /*!
    57     @alpha
    69     @alpha
    58     @hbwidgets
    70     @hbwidgets
    59     \class HbAbstractViewItem
    71     \class HbAbstractViewItem
    60     \brief The HbAbstractViewItem class represents a single item in a AbstractItemView.  
    72     \brief The HbAbstractViewItem class represents a single item in a AbstractItemView.  
    61 
    73 
    62     The HbAbstractViewItem class provides an item that is used by HbAbstractItemView class to
    74     The HbAbstractViewItem class provides an item that is used by HbAbstractItemView class to
    63     visualize content within single model index. By default HbAbstractViewItem supports QString and QStringList 
    75     visualize content within single model index. 
    64     stored into Qt::DisplayRole role and QIcon, HbIcon or list of them in QVariantList stored into
    76     
    65     Qt::DecoratorRole role. 
    77     By default HbAbstractViewItem supports following model item types in Hb::ItemTypeRole role of data model
       
    78     \li Hb::StandardItem. This is normal item. Item is considered as Hb::StandardItem, if Hb::ItemTypeRole is not set.
       
    79     \li Hb::ParentItem. Item has children. This class provides default frame item for parent item, if Qt::BackgroundRole data is not specifically set.
       
    80     \li Hb::SeparatorItem. Separator is used as boundary between separate items. Item does not interact with user. This requires support from the model, too. Qt::ItemIsEnabled flag must be Off for the model item. This class provides default frame for separator item, if Qt::BackgroundRole data is not specifically set.
       
    81 
       
    82     Every subclass view item do not support every model item type. For more information see subclass documentation.
       
    83 
       
    84     Item data roles HbIcon, QBrush or HbFrameBackground are supported in Qt::BackgroundRole data role.
       
    85     Other supported item data roles can be found in subclass documentation.
    66 
    86 
    67     This class is provided mainly for customization purposes but it also acts as a default
    87     This class is provided mainly for customization purposes but it also acts as a default
    68     item prototype inside HbAbstractItemView. See HbAbstractItemView how to set customized class as a item prototype.
    88     item prototype inside HbAbstractItemView. See HbAbstractItemView how to set customized class as a item prototype.
    69 
    89 
    70     \b Subclassing
    90     \b Subclassing
    75 
    95 
    76     If derived abstract view item has transient state information that is not meaningful to store within model index (child item cursor 
    96     If derived abstract view item has transient state information that is not meaningful to store within model index (child item cursor 
    77     position selection areas etc.) this information can be supplied to transient state model. Transient state model is maintained 
    97     position selection areas etc.) this information can be supplied to transient state model. Transient state model is maintained 
    78     internally by abstract item view. 
    98     internally by abstract item view. 
    79 
    99 
       
   100     If item's pixmap cache is enabled derived class should call updatePixmapCache() when ever visual appearance of the item or its children is
       
   101     changed. For more information about enabling the pixmap cache see HbAbstractItemView::setItemPixmapCacheEnabled().
    80 
   102 
    81     \primitives
   103     \primitives
    82     \primitive{background} HbIconItem representing the item background. This primitive exists in cases the model's Qt::BackgroundRole returns HbIcon or QBrush for this item.
   104     \primitive{background} HbIconItem with item name "background" representing the item background. This primitive exists in cases the model's Qt::BackgroundRole returns HbIcon or QBrush for this item.
    83     \primitive{frame} HbFrameItem representing the background frame of the item. This primitive exists if background primitive does not exist and the model's Qt::BackgroundRole returns HbFrameBackground or there is a default frame set with the setDefaultFrame(). An item can have either the frame or the background primitive, but not the both at the same time.
   105     \primitive{frame} HbFrameItem with item name "frame" representing the background frame of the item. This primitive exists if background primitive does not exist and the model's Qt::BackgroundRole returns HbFrameBackground or there is a default frame set with the setDefaultFrame(). An item can have either the frame or the background primitive, but not the both at the same time.
    84     \primitive{selection-icon} HbIconItem representing the checkbox in the multi selection mode.
   106     \primitive{selection-icon} HbIconItem with item name "selection-icon" representing the checkbox in the multi selection mode.
    85     \primitive{multiselection-toucharea} HbTouchArea used in extending the touch area of the selection-icon. 
   107     \primitive{multiselection-toucharea} HbTouchArea with item name "multiselection-toucharea" used in extending the touch area of the selection-icon. 
       
   108     \primitive{focus} HbFrameItem with item name "focus" for showing focus. 
       
   109 
       
   110     \sa HbListViewItem
       
   111     \sa HbGridViewItem
       
   112     \sa HbTreeViewItem
    86 */
   113 */
    87 
   114 
    88 /*!
   115 /*!
    89     \enum HbAbstractViewItem::SelectionAreaType
   116     \enum HbAbstractViewItem::SelectionAreaType
    90 
   117 
   175     In most subclasses, createItem should be implemented like this:
   202     In most subclasses, createItem should be implemented like this:
   176 
   203 
   177     \snippet{ultimatecodesnippet/customlistviewitem.cpp,1}
   204     \snippet{ultimatecodesnippet/customlistviewitem.cpp,1}
   178 */
   205 */
   179 
   206 
       
   207 void HbAbstractViewItemShared::updateIconItemsAsyncMode()
       
   208 {
       
   209     foreach (HbAbstractViewItem *item, mCloneItems) {
       
   210         QList<QGraphicsItem *> childItems = item->childItems();
       
   211         foreach (QGraphicsItem *child, childItems) {
       
   212             item->d_func()->updateIconItemsAsyncMode(child);
       
   213         }
       
   214     }
       
   215 }
       
   216 
       
   217 void HbAbstractViewItemShared::setItemView(HbAbstractItemView *view)
       
   218 {
       
   219     if (view != mItemView) {
       
   220         if (mItemView) {
       
   221             disconnect(mItemView, SIGNAL(scrollingStarted()), this, SLOT(scrollingStarted()));
       
   222         }
       
   223         mItemView = view;
       
   224         if (mItemView) {
       
   225             connect(mItemView, SIGNAL(scrollingStarted()), this, SLOT(scrollingStarted()));
       
   226         }
       
   227     }
       
   228 }
       
   229 
   180 void HbAbstractViewItemShared::pressStateChangeTimerTriggered()
   230 void HbAbstractViewItemShared::pressStateChangeTimerTriggered()
   181 {
   231 {
   182     HbWidgetFeedback::triggered(mPressedItem, Hb::InstantPressed, 0);
   232     if (mPressedItem) {
   183     mPressedItem->pressStateChanged(true, mAnimatePress);
   233         HbWidgetFeedback::triggered(mPressedItem, Hb::InstantPressed, 0);
       
   234         mPressedItem->pressStateChanged(true, mAnimatePress);
       
   235     }
       
   236 }
       
   237 
       
   238 void HbAbstractViewItemShared::disablePixmapCaches()
       
   239 {
       
   240     mLowGraphicsMemory = true;
       
   241     foreach (HbAbstractViewItem *item, mCloneItems) {
       
   242         item->update();
       
   243     }
       
   244 }
       
   245 
       
   246 void HbAbstractViewItemShared::enablePixmapCaches()
       
   247 {
       
   248     mLowGraphicsMemory = false;
       
   249     foreach (HbAbstractViewItem *item, mCloneItems) {
       
   250         item->update();
       
   251     }
       
   252 }
       
   253 
       
   254 void HbAbstractViewItemShared::scrollingStarted()
       
   255 {
       
   256     if (mItemView && mItemView->iconLoadPolicy() == HbAbstractItemView::LoadAsynchronouslyWhenScrolling) {
       
   257         updateIconItemsAsyncMode();
       
   258     }
   184 }
   259 }
   185 
   260 
   186 void HbAbstractViewItemPrivate::init()
   261 void HbAbstractViewItemPrivate::init()
   187 {
   262 {
   188     Q_Q(HbAbstractViewItem);
   263     Q_Q(HbAbstractViewItem);
   189 
   264 
   190     q->setProperty("state", "normal");
   265     q->setProperty("state", "normal");
       
   266     q->setFlag(QGraphicsItem::ItemHasNoContents, false);
   191 
   267 
   192     if (isPrototype()) {
   268     if (isPrototype()) {
   193         q->setFocusPolicy(Qt::ClickFocus);
   269         q->setFocusPolicy(Qt::ClickFocus);
   194     } else {
   270     } else {
   195         q->grabGesture(Qt::TapGesture);
   271         q->grabGesture(Qt::TapGesture);
   198         q->setFlags(itemFlags);
   274         q->setFlags(itemFlags);
   199 
   275 
   200         q->setFocusPolicy(mSharedData->mPrototype->focusPolicy());
   276         q->setFocusPolicy(mSharedData->mPrototype->focusPolicy());
   201 
   277 
   202         mSharedData->mCloneItems.append(q);
   278         mSharedData->mCloneItems.append(q);
       
   279 
       
   280         mFrontPixmapPainter = new HbViewItemPixmapPainter(1000, q);
       
   281         // setChildFlags gets called in the construction phase, but the values are wrong.
       
   282         // Here we set the flags to force FrontPixmap to obey parent opacity, this is needed in animations
       
   283         setChildFlags(mFrontPixmapPainter, false);
       
   284 
       
   285         mBackPixmapPainter = new HbViewItemPixmapPainter(-1000, q);
       
   286         // setChildFlags gets called in the construction phase, but the values are wrong.
       
   287         // Here we set the flags to force BackPixmap to obey parent opacity, this is needed in animations
       
   288         setChildFlags(mBackPixmapPainter, false);
       
   289 
       
   290         mChildren = q->childItems();
       
   291         q->connect(q, SIGNAL(childrenChanged()), q, SLOT(_q_childrenChanged()));
   203     }
   292     }
   204 }
   293 }
   205 
   294 
   206 /*!
   295 /*!
   207     Returns Hb::ModelItemType of this view item.
   296     Returns Hb::ModelItemType of this view item.
   220 
   309 
   221     if (mFocusItem) {
   310     if (mFocusItem) {
   222         QCoreApplication::postEvent(q, new QEvent((QEvent::Type)HbAbstractViewItemShared::ViewItemDeferredDeleteEvent));
   311         QCoreApplication::postEvent(q, new QEvent((QEvent::Type)HbAbstractViewItemShared::ViewItemDeferredDeleteEvent));
   223     }
   312     }
   224 }
   313 }
       
   314 
       
   315 void HbAbstractViewItemPrivate::_q_childrenChanged()
       
   316 {
       
   317     Q_Q(HbAbstractViewItem);
       
   318 
       
   319     QList<QGraphicsItem *> childList = q->childItems();
       
   320     int currentCount = childList.count();
       
   321     int previousCount = mChildren.count();
       
   322 
       
   323     if (currentCount > previousCount) {
       
   324         QGraphicsItem *addedItem = 0;
       
   325         for (int i = 0; i < currentCount; ++i) {
       
   326             QGraphicsItem *item = childList.at(i);
       
   327             if (item != mChildren.value(i)) {
       
   328                 addedItem = item;
       
   329                 break;
       
   330             }
       
   331         }
       
   332 
       
   333         if (usePixmapCache()) {
       
   334             setChildFlags(addedItem, true);
       
   335         }
       
   336 
       
   337         updateIconItemsAsyncMode(addedItem);
       
   338     } else {
       
   339         if (mUpdateItems.count()) {
       
   340             int itemCount = mUpdateItems.count();
       
   341             for (int i = 0; i < itemCount; ++i) {
       
   342                 QGraphicsItem *item = mUpdateItems.at(i);
       
   343                 int index = childList.indexOf(item);
       
   344                 if (index == -1) {
       
   345                     mUpdateItems.remove(i);
       
   346                     mUpdateItems.squeeze();
       
   347                 }
       
   348             }
       
   349         }
       
   350     }
       
   351 
       
   352     mChildren = childList;
       
   353 }
       
   354 
   225 
   355 
   226 void HbAbstractViewItemPrivate::repolishCloneItems()
   356 void HbAbstractViewItemPrivate::repolishCloneItems()
   227 {
   357 {
   228     int count(mSharedData->mCloneItems.count());
   358     int count(mSharedData->mCloneItems.count());
   229     for (int i = 0; i < count; ++i) {
   359     for (int i = 0; i < count; ++i) {
   276         }
   406         }
   277         case Qt::GestureUpdated: {
   407         case Qt::GestureUpdated: {
   278             if (gesture->tapStyleHint() == HbTapGesture::TapAndHold 
   408             if (gesture->tapStyleHint() == HbTapGesture::TapAndHold 
   279                 && mSharedData->mItemView
   409                 && mSharedData->mItemView
   280                 && mSharedData->mItemView->longPressEnabled()) {
   410                 && mSharedData->mItemView->longPressEnabled()) {
       
   411                 q->scene()->setProperty(HbPrivate::OverridingGesture.latin1(),QVariant());
   281                 setPressed(false, true);
   412                 setPressed(false, true);
   282                 QPointer<HbAbstractViewItem> item = q;
   413                 QPointer<HbAbstractViewItem> item = q;
   283                 emit item->longPressed(position);
   414                 emit item->longPressed(position);
   284                 if (item) {
   415                 if (item) {
   285                     revealItem();
   416                     revealItem();
   372             q->setProperty("state", "normal");
   503             q->setProperty("state", "normal");
   373         }
   504         }
   374     }
   505     }
   375 }
   506 }
   376 
   507 
       
   508 void HbAbstractViewItemPrivate::drawSubPixmap(QPixmap *pixmap,
       
   509                                               QPainter *painter,
       
   510                                               const QStyleOptionGraphicsItem *option)
       
   511 {
       
   512     Q_Q(HbAbstractViewItem);
       
   513 
       
   514     QPixmap subPix;
       
   515     QPainter pixmapPainter;
       
   516     QStyleOptionGraphicsItem pixmapOption(*option);
       
   517 
       
   518     QList<QGraphicsItem *> childList = q->childItems();
       
   519 
       
   520     foreach (QGraphicsItem *subChild, mUpdateItems) {
       
   521         pixmapOption.exposedRect = subChild->boundingRect();
       
   522 
       
   523         subPix = QPixmap(pixmapOption.exposedRect.toRect().size());
       
   524         subPix.fill(Qt::transparent);
       
   525 
       
   526         pixmapPainter.begin(&subPix);
       
   527         pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
       
   528         pixmapPainter.setRenderHints(painter->renderHints(), true);
       
   529         
       
   530         // Draw items on the pixmap
       
   531         paintChildItemsRecursively(subChild, &pixmapPainter, &pixmapOption, QPointF());
       
   532 
       
   533         // Search & paint overlapping child items.
       
   534         QRectF subChildRectRelativeToParent(subChild->pos(), subChild->boundingRect().size());
       
   535 
       
   536         int currentIndex = childList.indexOf(subChild) + 1;
       
   537         int childCount = childList.count();
       
   538         while (currentIndex < childCount) {
       
   539             QGraphicsItem *item = childList.at(currentIndex);
       
   540             if (item != mNonCachableItem 
       
   541                 && item != mFrontPixmapPainter 
       
   542                 && item != mBackPixmapPainter) {
       
   543                 QRectF itemRectRelativeToParent(item->pos(), item->boundingRect().size());
       
   544 
       
   545                 QRectF intersectionRect(itemRectRelativeToParent.intersected(subChildRectRelativeToParent));
       
   546                 if (!intersectionRect.isNull()) {
       
   547                     QStyleOptionGraphicsItem itemPixmapOption(*option);
       
   548                     itemPixmapOption.exposedRect = intersectionRect.translated(-item->pos());
       
   549 
       
   550                     paintChildItemsRecursively(item, &pixmapPainter, &itemPixmapOption, subChild->mapFromParent(itemRectRelativeToParent.topLeft()));
       
   551                 }
       
   552             }
       
   553             ++currentIndex;
       
   554         }
       
   555 
       
   556         pixmapPainter.end();
       
   557 
       
   558         if (!subPix.isNull()) {
       
   559             // Blit the subpixmap into the main pixmap.
       
   560             pixmapPainter.begin(pixmap);
       
   561             pixmapPainter.translate(subChild->pos());
       
   562             pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
       
   563             pixmapPainter.setClipRect(pixmapOption.exposedRect);
       
   564             pixmapPainter.drawPixmap(pixmapOption.exposedRect.topLeft(), subPix);
       
   565             pixmapPainter.end();
       
   566         }
       
   567     }
       
   568     mUpdateItems.clear();
       
   569 }
       
   570 
       
   571 void HbAbstractViewItemPrivate::updatePixmap(QPixmap *pixmap, 
       
   572                                              QPainter *painter, 
       
   573                                              const QStyleOptionGraphicsItem *option, 
       
   574                                              QGraphicsItem *startItem, 
       
   575                                              QGraphicsItem *endItem)
       
   576 {
       
   577     //Q_Q(HbAbstractViewItem);
       
   578     pixmap->fill(Qt::transparent);
       
   579 
       
   580     QPainter pixmapPainter;
       
   581     pixmapPainter.begin(pixmap);
       
   582 
       
   583     pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
       
   584     pixmapPainter.setRenderHints(painter->renderHints());
       
   585 
       
   586     // Draw items on the pixmap
       
   587     QStyleOptionGraphicsItem pixmapOption(*option);
       
   588     paintItems(&pixmapPainter, &pixmapOption, startItem, endItem);
       
   589 }
       
   590 
       
   591 void HbAbstractViewItemPrivate::paintItems(QPainter *painter, QStyleOptionGraphicsItem *option, QGraphicsItem *startItem, QGraphicsItem *endItem)
       
   592 {
       
   593     Q_Q(HbAbstractViewItem);
       
   594 
       
   595     mInPaintItems = true;
       
   596 
       
   597     bool itemPainted = false;
       
   598 
       
   599     bool startItemFound = false;
       
   600     if (!startItem) {
       
   601         startItemFound = true;
       
   602     }
       
   603 
       
   604     foreach (QGraphicsItem *child, q->childItems()) {
       
   605         if (!startItemFound) {
       
   606             if (child == startItem) {
       
   607                 startItemFound = true;
       
   608             }
       
   609             continue;
       
   610         } else if (child == endItem) {
       
   611             break;
       
   612         }
       
   613 
       
   614         if (!child->isVisible() || child == mNonCachableItem || child == mFrontPixmapPainter || child == mBackPixmapPainter) {
       
   615             continue;
       
   616         }
       
   617 
       
   618         if (!itemPainted && child->zValue() >= 0) {
       
   619             option->exposedRect = q->boundingRect();
       
   620             q->paint(painter, option, 0);
       
   621             itemPainted = true;
       
   622         }
       
   623 
       
   624         if (child == mFrame) {
       
   625             QPainter::CompositionMode mode = painter->compositionMode();
       
   626             painter->setCompositionMode(QPainter::CompositionMode_Source);
       
   627             painter->translate(child->pos());
       
   628             option->exposedRect = child->boundingRect();
       
   629             child->paint(painter, option, 0);
       
   630             painter->setCompositionMode(mode);
       
   631             painter->translate(-child->pos());
       
   632             continue;
       
   633         }
       
   634         paintChildItemsRecursively(child,painter,option, child->pos());
       
   635     }
       
   636     mInPaintItems = false;
       
   637 }
       
   638 
       
   639 void HbAbstractViewItemPrivate::paintChildItemsRecursively(QGraphicsItem *child,
       
   640                                                            QPainter *painter,
       
   641                                                            QStyleOptionGraphicsItem *option,
       
   642                                                            const QPointF &translatePosition)
       
   643 {
       
   644     if (!child->isVisible())
       
   645         return;
       
   646     int i = 0;
       
   647     QList<QGraphicsItem *> children =  child->childItems();
       
   648     int count(children.size());
       
   649     if (!translatePosition.isNull()) {
       
   650         painter->translate(translatePosition);
       
   651     }
       
   652     // Draw children behind
       
   653     for (i = 0; i < count; ++i) {
       
   654         QGraphicsItem *subChild = children.at(i);
       
   655         if (!(subChild->flags() & QGraphicsItem::ItemStacksBehindParent))
       
   656             break;
       
   657         paintChildItemsRecursively(subChild, painter,option, subChild->pos());
       
   658     }
       
   659     option->exposedRect = child->boundingRect();
       
   660 
       
   661     bool restorePainter = false;
       
   662     if (child->flags() & QGraphicsItem::ItemClipsToShape) {
       
   663         painter->save();
       
   664         restorePainter = true;
       
   665 
       
   666         painter->setClipRect(child->boundingRect());
       
   667     }
       
   668     child->paint(painter, option, 0);
       
   669 
       
   670     if (restorePainter) {
       
   671         painter->restore();
       
   672     }
       
   673 
       
   674     // Draw children in front
       
   675     for (; i < count; ++i) {
       
   676         QGraphicsItem *subChild = children.at(i);
       
   677         paintChildItemsRecursively(subChild, painter,option, subChild->pos());
       
   678     }
       
   679 
       
   680     if (!translatePosition.isNull()) {
       
   681         painter->translate(-translatePosition);
       
   682     }
       
   683 }
       
   684 
       
   685 
       
   686 void HbAbstractViewItemPrivate::setChildFlags(QGraphicsItem *child, bool pixmapCacheEnabled)
       
   687 {
       
   688     QGraphicsItem::GraphicsItemFlags itemFlags = child->flags();
       
   689     if (pixmapCacheEnabled) {
       
   690         itemFlags |= QGraphicsItem::ItemHasNoContents;
       
   691         itemFlags |= QGraphicsItem::ItemIgnoresParentOpacity;
       
   692     }
       
   693     else {
       
   694         itemFlags &= ~QGraphicsItem::ItemHasNoContents;
       
   695         itemFlags &= ~QGraphicsItem::ItemIgnoresParentOpacity;
       
   696     }
       
   697     child->setFlags(itemFlags);
       
   698     foreach (QGraphicsItem *subChild, child->childItems()) {
       
   699         setChildFlags(subChild,pixmapCacheEnabled);
       
   700     }
       
   701 }
       
   702 
       
   703 void HbAbstractViewItemPrivate::setChildFlagRecursively(bool pixmapCacheEnabled)
       
   704 {
       
   705     Q_Q(HbAbstractViewItem);
       
   706     foreach (QGraphicsItem *subChild, q->childItems()) {
       
   707         if (subChild == mNonCachableItem || subChild == mFrontPixmapPainter ||
       
   708             subChild == mBackPixmapPainter) {
       
   709             continue;
       
   710         }
       
   711         setChildFlags(subChild, pixmapCacheEnabled);
       
   712     }
       
   713 }
       
   714 
       
   715 
       
   716 void HbAbstractViewItemPrivate::releasePixmaps()
       
   717 {
       
   718     if (mFrontPixmapPainter) {
       
   719         mFrontPixmapPainter->setPixmap(0);
       
   720     }
       
   721 
       
   722     if (mBackPixmapPainter) {
       
   723         mBackPixmapPainter->setPixmap(0);
       
   724     }
       
   725 }
       
   726 
       
   727 bool HbAbstractViewItemPrivate::iconLoadedCallback(HbIconItem *target, void *param)
       
   728 {
       
   729     HbAbstractViewItemPrivate* d_ptr = (HbAbstractViewItemPrivate*)param;
       
   730     return d_ptr->iconLoaded(target);
       
   731 }
       
   732 
       
   733 bool HbAbstractViewItemPrivate::iconLoaded(HbIconItem *target)
       
   734 {
       
   735     Q_Q(HbAbstractViewItem);
       
   736     
       
   737     bool result = false;
       
   738 
       
   739     if (usePixmapCache()) {
       
   740         mUpdateItems.append(target);
       
   741         if (mSharedData->mItemView && !mSharedData->mItemView->isScrolling()) {
       
   742             q->update();
       
   743         }
       
   744 
       
   745         result = true;
       
   746     }
       
   747 
       
   748     return result;
       
   749 }
       
   750 
       
   751 void HbAbstractViewItemPrivate::updateIconItemsAsyncMode(QGraphicsItem *item)
       
   752 {
       
   753     if (mSharedData->mItemView) {
       
   754         HbIconItem *iconItem = qgraphicsitem_cast<HbIconItem *>(item);
       
   755         if (iconItem) { 
       
   756             HbAbstractItemView::IconLoadPolicy loadPolicy = mSharedData->mItemView->iconLoadPolicy();
       
   757             if (loadPolicy == HbAbstractItemView::LoadAsynchronouslyAlways 
       
   758                 || (loadPolicy == HbAbstractItemView::LoadAsynchronouslyWhenScrolling
       
   759                 && mSharedData->mItemView->isScrolling())) {
       
   760                 HbIconItemPrivate::d_ptr(iconItem)->setAsyncCallbackFilter(&HbAbstractViewItemPrivate::iconLoadedCallback, this);
       
   761                 iconItem->setAsync(true);
       
   762             } else {
       
   763                 iconItem->setAsync(false);
       
   764             }
       
   765         }
       
   766     }
       
   767 }
   377 
   768 
   378 /*!
   769 /*!
   379     Constructs an abstract view item with the given parent.
   770     Constructs an abstract view item with the given parent.
   380 */
   771 */
   381 HbAbstractViewItem::HbAbstractViewItem(QGraphicsItem *parent) : 
   772 HbAbstractViewItem::HbAbstractViewItem(QGraphicsItem *parent) : 
   418 {
   809 {
   419     Q_D( HbAbstractViewItem );
   810     Q_D( HbAbstractViewItem );
   420     *d = *source.d_func();
   811     *d = *source.d_func();
   421     return *this;
   812     return *this;
   422 }
   813 }
   423 
   814     
   424 
       
   425 /*!
   815 /*!
   426     Destructor.
   816     Destructor.
   427 */
   817 */
   428 HbAbstractViewItem::~HbAbstractViewItem()
   818 HbAbstractViewItem::~HbAbstractViewItem()
   429 {
   819 {
   430     HB_SDD(HbAbstractViewItem);
   820     HbAbstractViewItemPrivate *d = d_func();
   431     if (d && !d->isPrototype()) {
   821     if (d && !d->isPrototype()) {
   432         sd->mCloneItems.removeOne(this);
   822         d->mSharedData->mCloneItems.removeOne(this);
   433     }
   823     }
   434 }
   824 }
   435 
   825 
   436 /*!
   826 /*!
   437     Returns true if \a model index is supported by Abstract view item, otherwise returns false.
   827     Returns true if \a model index is supported by Abstract view item, otherwise returns false.
   488 */
   878 */
   489 QHash<QString, QVariant> HbAbstractViewItem::transientState() const
   879 QHash<QString, QVariant> HbAbstractViewItem::transientState() const
   490 {
   880 {
   491     Q_D( const HbAbstractViewItem );
   881     Q_D( const HbAbstractViewItem );
   492     QHash<QString,QVariant> state;
   882     QHash<QString,QVariant> state;
   493     
   883 
   494     if (d->mFocused) {
       
   495         state.insert("focused", d->mFocused);
       
   496     }
       
   497     if (d->mCheckState != Qt::Unchecked) {
   884     if (d->mCheckState != Qt::Unchecked) {
   498         state.insert("checkState", d->mCheckState);
   885         state.insert("checkState", d->mCheckState);
   499     }
   886     }
   500 
   887 
   501     return state;
   888     return state;
   505     Sets the item's transient state using given \a state data.
   892     Sets the item's transient state using given \a state data.
   506 */
   893 */
   507 void HbAbstractViewItem::setTransientState(const QHash<QString, QVariant> &state)
   894 void HbAbstractViewItem::setTransientState(const QHash<QString, QVariant> &state)
   508 {
   895 {
   509     Q_D( HbAbstractViewItem );
   896     Q_D( HbAbstractViewItem );
   510     d->mFocused = state.value("focused").toBool();
   897     if (state.count()) {
   511     d->mCheckState = (Qt::CheckState)state.value("checkState").toInt();
   898         d->mCheckState = (Qt::CheckState)state.value("checkState").toInt();
       
   899     } else
       
   900         d->mCheckState = Qt::Unchecked;
   512 }
   901 }
   513 
   902 
   514 /*!
   903 /*!
   515     Returns a pointer to HbAbstractViewItem prototype that was used to create this
   904     Returns a pointer to HbAbstractViewItem prototype that was used to create this
   516     view item.
   905     view item.
   525     Sets \a AbstractItemView that contains the Abstract view item.
   914     Sets \a AbstractItemView that contains the Abstract view item.
   526 */
   915 */
   527 void HbAbstractViewItem::setItemView( HbAbstractItemView *itemView )
   916 void HbAbstractViewItem::setItemView( HbAbstractItemView *itemView )
   528 {
   917 {
   529     HB_SDD( HbAbstractViewItem );
   918     HB_SDD( HbAbstractViewItem );
   530     sd->mItemView = itemView;
   919     sd->setItemView(itemView);
   531 }
   920 }
   532 
   921 
   533 /*!
   922 /*!
   534     Returns item view that contains the item view item.
   923     Returns item view that contains the item view item.
   535 */
   924 */
   537 {
   926 {
   538     HB_SDD( const HbAbstractViewItem );
   927     HB_SDD( const HbAbstractViewItem );
   539     return sd->mItemView;
   928     return sd->mItemView;
   540 }
   929 }
   541 
   930 
   542 /*!
       
   543     Populates a style option object for this widget based on its current state, and stores the output in \a option.
       
   544 */
       
   545 void HbAbstractViewItem::initStyleOption(HbStyleOptionAbstractViewItem *option) const
       
   546 {
       
   547     HB_SDD( const HbAbstractViewItem );
       
   548 
       
   549     HbWidget::initStyleOption(option);
       
   550 
       
   551     option->modelItemType = d->mModelItemType;
       
   552     option->index = d->mIndex;
       
   553 
       
   554     option->viewItemType = type();
       
   555     option->checkState = d->mCheckState;
       
   556     option->background = d->mBackground;
       
   557     if (!option->background.isValid()) {
       
   558         if (option->modelItemType == Hb::StandardItem 
       
   559             && !sd->mDefaultFrame.isNull()) {
       
   560             option->background = sd->mDefaultFrame;
       
   561         }
       
   562     }
       
   563 
       
   564     if (d->mPressed) {
       
   565         option->state |= QStyle::State_Sunken;
       
   566     }
       
   567     if (    sd->mItemView
       
   568         &&  sd->mItemView->selectionMode() == HbAbstractItemView::SingleSelection){
       
   569         option->singleSelectionMode = true;
       
   570     }
       
   571 
       
   572     option->insidePopup = testAttribute(Hb::InsidePopup);
       
   573 }
       
   574 
   931 
   575 /*!
   932 /*!
   576     Check whether \a position is inside the selection area of the given selectionAreaType in the view item.
   933     Check whether \a position is inside the selection area of the given selectionAreaType in the view item.
   577 
   934 
   578     Default selection areas are for
   935     Default selection areas are for
   579     \li HbAbstractViewItem::SingleSelection mode: whole item
   936     \li HbAbstractViewItem::SingleSelection mode: whole item
   580     \li HbAbstractViewItem::MultiSelection mode: whole item.
   937     \li HbAbstractViewItem::MultiSelection mode: whole item.
   581     \li HbAbstractViewItem::ContiguousSelection mode: area of HbStyle::P_ItemViewItem_touchmultiselection icon.
   938     \li HbAbstractViewItem::ContiguousSelection mode: area of icon of primitive with item name "multiselection-toucharea".
   582 
   939 
   583     The \a selectionAreaType tells what kind of selection area is requested.  The parameter value ContiguousSelection returns 
   940     The \a selectionAreaType tells what kind of selection area is requested.  The parameter value ContiguousSelection returns 
   584     the area where mouse movement will extend the selection to new items. By default this contiguous selection area is 
   941     the area where mouse movement will extend the selection to new items. By default this contiguous selection is area of
   585     the HbStyle::P_ItemViewItem_touchmultiselection.
   942     "multiselection-toucharea" primitive.
   586     
   943     
   587 */
   944 */
   588 bool HbAbstractViewItem::selectionAreaContains(const QPointF &position, SelectionAreaType selectionAreaType) const
   945 bool HbAbstractViewItem::selectionAreaContains(const QPointF &position, SelectionAreaType selectionAreaType) const
   589 {
   946 {
   590     Q_D(const HbAbstractViewItem);
   947     Q_D(const HbAbstractViewItem);
   614 /*!
   971 /*!
   615     \reimp
   972     \reimp
   616 */
   973 */
   617 bool HbAbstractViewItem::event(QEvent *e)
   974 bool HbAbstractViewItem::event(QEvent *e)
   618 {
   975 {
   619     if (e) {
   976     switch (e->type()) {
   620         switch (e->type()) {
   977         case QEvent::GraphicsSceneResize: {
   621             case QEvent::GraphicsSceneResize: {
   978             Q_D(HbAbstractViewItem );            
   622                 Q_D(HbAbstractViewItem );
   979             QGraphicsSceneResizeEvent *resizeEvent = static_cast<QGraphicsSceneResizeEvent *>(e);
   623                 if (d->mBackgroundItem || d->mFrame || d->mFocusItem) {
   980 
   624                     HbStyleOptionAbstractViewItem styleOption;
   981             if (d->mFrontPixmapPainter) {
   625                     initStyleOption(&styleOption);
   982                 d->mFrontPixmapPainter->setSize(resizeEvent->newSize());
   626                     if (d->mFocusItem) {
   983             }
   627                         style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
   984 
   628                     }
   985             if (d->mBackPixmapPainter) {
   629 
   986                 d->mBackPixmapPainter->setSize(resizeEvent->newSize());
   630                     if (d->mFrame) {
   987             }
   631                         style()->updatePrimitive(d->mFrame, HbStyle::P_ItemViewItem_frame, &styleOption);
   988 
   632                     }
   989             if (d->mBackgroundItem || d->mFrame || d->mFocusItem) {
   633 
   990                 if (d->mFocusItem) {
   634                     if (d->mBackgroundItem) {
   991                     // HbFrameItem
   635                         style()->updatePrimitive(d->mBackgroundItem, HbStyle::P_ItemViewItem_background, &styleOption);
   992                     HbStyleFramePrimitiveData primitiveData;
   636                     }
   993                     initPrimitiveData(&primitiveData, d->mFocusItem);
       
   994                     style()->updatePrimitive(d->mFocusItem, &primitiveData, this);
   637                 }
   995                 }
   638                 break;
   996 
   639             }
   997                 if (d->mFrame) {
   640             case QEvent::LayoutDirectionChange: {
   998                     // HbFrameItem
   641                 repolish();
   999                     HbStyleFramePrimitiveData primitiveData;
   642                 break;
  1000                     initPrimitiveData(&primitiveData, d->mFrame);
   643             }
  1001                     style()->updatePrimitive(d->mFrame, &primitiveData, this);
   644             default: {
  1002                 }
   645                 if (e->type() == HbAbstractViewItemShared::ViewItemDeferredDeleteEvent) {
  1003 
   646                     // cannot handle ViewItemDeferredDeleteEvent in the case statement!
  1004                 if (d->mBackgroundItem) {
   647                     Q_D(HbAbstractViewItem);
  1005                     // HbIconItem
   648                     delete d->mFocusItem;
  1006                     HbStyleIconPrimitiveData primitiveData;
   649                     d->mFocusItem = 0;
  1007                     initPrimitiveData(&primitiveData, d->mBackgroundItem);
   650                }
  1008                     style()->updatePrimitive(d->mBackgroundItem, &primitiveData, this);
   651                 break;
  1009                 }
   652             }
  1010             }
   653         }
  1011             break;
   654 
  1012         }
   655         return HbWidget::event(e);
  1013         case QEvent::LayoutDirectionChange: {
   656     }
  1014             repolish();
   657 
  1015             updatePixmapCache();
   658     return false;
  1016             break;  
   659 }
  1017         }
       
  1018         case QEvent::LayoutRequest: {
       
  1019             updatePixmapCache();
       
  1020             break;
       
  1021         }
       
  1022         default: {
       
  1023             if (e->type() == HbAbstractViewItemShared::ViewItemDeferredDeleteEvent) {
       
  1024                 // cannot handle ViewItemDeferredDeleteEvent in the case statement!
       
  1025                 Q_D(HbAbstractViewItem);
       
  1026 
       
  1027                 d->mNonCachableItem = 0;
       
  1028 
       
  1029                 delete d->mFocusItem;
       
  1030                 d->mFocusItem = 0;
       
  1031 
       
  1032                 updatePixmapCache();
       
  1033             }
       
  1034             break;
       
  1035         }
       
  1036     }
       
  1037     return HbWidget::event(e);
       
  1038 }
       
  1039 
       
  1040 /*!
       
  1041     \reimp
       
  1042 */
       
  1043 void HbAbstractViewItem::changeEvent(QEvent *event)
       
  1044 {
       
  1045     if (event->type() == HbEvent::ThemeChanged) {
       
  1046         updatePixmapCache();
       
  1047     }
       
  1048     HbWidget::changeEvent(event);
       
  1049 }
       
  1050 
   660 
  1051 
   661 /*!
  1052 /*!
   662     \reimp
  1053     \reimp
   663 
  1054 
   664     Invalidates parent layout when ItemTransformHasChanged is received.
  1055     Invalidates parent layout when ItemTransformHasChanged is received.
   676         }
  1067         }
   677         case ItemEnabledHasChanged: {
  1068         case ItemEnabledHasChanged: {
   678             updateChildItems();
  1069             updateChildItems();
   679             break;
  1070             break;
   680         }
  1071         }
       
  1072         case ItemVisibleHasChanged: {
       
  1073             Q_D(HbAbstractViewItem);
       
  1074             if (!value.toBool() && d->usePixmapCache()) {
       
  1075                 d->setChildFlagRecursively(false);
       
  1076                 d->releasePixmaps();
       
  1077                 d->mResetPixmapCache = true;
       
  1078             }
       
  1079             break;
       
  1080         }
   681         default:
  1081         default:
   682             break;
  1082             break;
   683     }
  1083     }
   684 
  1084 
   685     return HbWidget::itemChange(change, value);
  1085     return HbWidget::itemChange(change, value);
   686 }
  1086 }
       
  1087 
       
  1088 /*!
       
  1089   Initializes the HbAbstractViewItem primitive data. 
       
  1090   
       
  1091   This function calls HbWidgetBase::initPrimitiveData().
       
  1092   \a primitiveData is data object, which is populated with data. \a primitive is the primitive.
       
  1093 */
       
  1094 void HbAbstractViewItem::initPrimitiveData( HbStylePrimitiveData     *primitiveData, 
       
  1095                                             const QGraphicsObject    *primitive)
       
  1096 {
       
  1097     Q_ASSERT_X(primitive && primitiveData, "HbAbstractViewItem::initPrimitiveData" , "NULL data not permitted");
       
  1098     HB_SDD(HbAbstractViewItem);
       
  1099 
       
  1100     HbWidgetBase::initPrimitiveData(primitiveData, primitive);
       
  1101     if (primitiveData->type == HbStylePrimitiveData::SPD_Icon) {
       
  1102         HbStyleIconPrimitiveData *iconPrimitiveData = hbstyleprimitivedata_cast<HbStyleIconPrimitiveData*>(primitiveData);
       
  1103 
       
  1104         if (primitive ==d-> mBackgroundItem) {
       
  1105             iconPrimitiveData->geometry = boundingRect();
       
  1106 
       
  1107             QVariant background = d->mBackground;
       
  1108             if (!background.isValid()) {
       
  1109                 if (    d->mModelItemType == Hb::StandardItem 
       
  1110                     && !sd->mDefaultFrame.isNull()) {
       
  1111                     background = sd->mDefaultFrame;
       
  1112                 }
       
  1113             }
       
  1114 
       
  1115             if (background.canConvert<HbIcon>()){
       
  1116                 iconPrimitiveData->icon = background.value<HbIcon>();
       
  1117                 iconPrimitiveData->brush = QBrush();
       
  1118             } else if (background.canConvert<QBrush>()){
       
  1119                 iconPrimitiveData->icon = HbIcon();
       
  1120                 iconPrimitiveData->brush = background.value<QBrush>();
       
  1121             } else {
       
  1122                 iconPrimitiveData->icon = HbIcon();
       
  1123                 iconPrimitiveData->brush = QBrush();
       
  1124             }
       
  1125         } else if (primitive == d->mSelectionItem) {
       
  1126             int viewItemType = type();
       
  1127             bool singleSelectionMode = false;
       
  1128             if (sd->mItemView
       
  1129                 &&  sd->mItemView->selectionMode() == HbAbstractItemView::SingleSelection){
       
  1130                 singleSelectionMode = true;
       
  1131             }
       
  1132 
       
  1133             if (viewItemType == Hb::ItemType_RadioButtonListViewItem) {
       
  1134                 if (d->mCheckState == Qt::Checked) {
       
  1135                     iconPrimitiveData->iconState = QIcon::On;
       
  1136                     if (isEnabled()) {
       
  1137                         iconPrimitiveData->iconName = QLatin1String("qtg_small_radio_selected");
       
  1138                     } else {
       
  1139                         iconPrimitiveData->iconName = QLatin1String("qtg_small_radio_selected_disabled");
       
  1140                     }
       
  1141                 } else {
       
  1142                     iconPrimitiveData->iconState = QIcon::Off;
       
  1143                     if (isEnabled()) {
       
  1144                         iconPrimitiveData->iconName = QLatin1String("qtg_small_radio_unselected");
       
  1145                     } else {
       
  1146                         iconPrimitiveData->iconName = QLatin1String("qtg_small_radio_unselected_disabled");
       
  1147                     }
       
  1148                 }
       
  1149             } else {
       
  1150                 if (d->mCheckState == Qt::Checked) {
       
  1151                     iconPrimitiveData->iconState = QIcon::On;
       
  1152                     if (singleSelectionMode) {
       
  1153                         iconPrimitiveData->iconName = QLatin1String("qtg_small_tick");
       
  1154                     } else {
       
  1155                         iconPrimitiveData->iconName = QLatin1String("qtg_small_selected");
       
  1156                     }
       
  1157                 } else if (d->mCheckState == Qt::PartiallyChecked) {
       
  1158                     iconPrimitiveData->iconState = QIcon::On;
       
  1159                     iconPrimitiveData->iconName = QLatin1String("qtg_small_selected_partial");
       
  1160                 } else {
       
  1161                     iconPrimitiveData->iconState = QIcon::Off;
       
  1162                     if (singleSelectionMode) {
       
  1163                         iconPrimitiveData->iconName = QLatin1String("");
       
  1164                     } else {
       
  1165                         iconPrimitiveData->iconName = QLatin1String("qtg_small_unselected");
       
  1166                     }
       
  1167                 }
       
  1168             }
       
  1169         }
       
  1170     } else if (primitiveData->type == HbStylePrimitiveData::SPD_Frame) {
       
  1171         HbStyleFramePrimitiveData *framePrimitiveData = hbstyleprimitivedata_cast<HbStyleFramePrimitiveData*>(primitiveData);
       
  1172 
       
  1173         if (primitive == d->mFrame ) {
       
  1174             framePrimitiveData->geometry = boundingRect();
       
  1175 
       
  1176             QVariant background = d->mBackground;
       
  1177             if (!background.isValid()) {
       
  1178                 if (    d->mModelItemType == Hb::StandardItem 
       
  1179                     && !sd->mDefaultFrame.isNull()) {
       
  1180                     background = sd->mDefaultFrame;
       
  1181                 }
       
  1182             }
       
  1183 
       
  1184             if (background.canConvert<HbFrameBackground>()) {
       
  1185                 HbFrameBackground frame = background.value<HbFrameBackground>();
       
  1186                 framePrimitiveData->frameType = frame.frameType();
       
  1187                 framePrimitiveData->frameGraphicsName = frame.frameGraphicsName();
       
  1188             } else {
       
  1189                 int viewItemType = type();
       
  1190                 bool insidePopup = testAttribute(Hb::InsidePopup);
       
  1191                 if (viewItemType == Hb::ItemType_TreeViewItem) {
       
  1192                     if (d->mModelItemType == Hb::ParentItem) {
       
  1193                         framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1194                         framePrimitiveData->frameGraphicsName = insidePopup ?
       
  1195                             QLatin1String("qtg_fr_popup_list_parent_normal") : QLatin1String("qtg_fr_list_parent_normal");
       
  1196                     } else if (d->mModelItemType == Hb::SeparatorItem) {
       
  1197                         framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1198                         framePrimitiveData->frameGraphicsName = QLatin1String("qtg_fr_list_separator");
       
  1199                     } else {
       
  1200                         framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1201                         framePrimitiveData->frameGraphicsName =  insidePopup ?
       
  1202                             QLatin1String("qtg_fr_popup_list_normal") : QLatin1String("qtg_fr_list_normal");
       
  1203                     }
       
  1204                 } else if (viewItemType == Hb::ItemType_ListViewItem
       
  1205                             ||  viewItemType == Hb::ItemType_RadioButtonListViewItem) {
       
  1206                     if (d->mModelItemType == Hb::SeparatorItem) {
       
  1207                         framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1208                         framePrimitiveData->frameGraphicsName = QLatin1String("qtg_fr_list_separator");
       
  1209                     } else {
       
  1210                         framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1211                         framePrimitiveData->frameGraphicsName = insidePopup ?
       
  1212                             QLatin1String("qtg_fr_popup_list_normal") : QLatin1String("qtg_fr_list_normal");
       
  1213                     }
       
  1214                 } else if (viewItemType == Hb::ItemType_GridViewItem
       
  1215                             || viewItemType == HbPrivate::ItemType_ColorGridViewItem) {
       
  1216                     framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1217                     framePrimitiveData->frameGraphicsName = insidePopup ?
       
  1218                         QLatin1String("qtg_fr_popup_grid_normal") : QLatin1String("qtg_fr_grid_normal");
       
  1219                 } else{
       
  1220                     framePrimitiveData->frameGraphicsName = QString();
       
  1221                 }
       
  1222             }
       
  1223         } else if (primitive == d->mFocusItem) {
       
  1224             framePrimitiveData->geometry = boundingRect();
       
  1225 
       
  1226             int viewItemType = type();
       
  1227             bool insidePopup = testAttribute(Hb::InsidePopup);
       
  1228             if (viewItemType == Hb::ItemType_TreeViewItem
       
  1229                 || viewItemType == Hb::ItemType_ListViewItem
       
  1230                 || viewItemType == Hb::ItemType_RadioButtonListViewItem) {
       
  1231                 framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1232                 framePrimitiveData->frameGraphicsName = insidePopup ?
       
  1233                     QLatin1String("qtg_fr_popup_list_pressed") : QLatin1String("qtg_fr_list_pressed");
       
  1234             } else if (     viewItemType == Hb::ItemType_GridViewItem
       
  1235                         ||  viewItemType == HbPrivate::ItemType_ColorGridViewItem) {
       
  1236                 framePrimitiveData->frameType = HbFrameDrawer::NinePieces;
       
  1237                 framePrimitiveData->frameGraphicsName = insidePopup ?
       
  1238                     QLatin1String("qtg_fr_popup_grid_pressed") : QLatin1String("qtg_fr_grid_pressed");
       
  1239             } else{
       
  1240                 framePrimitiveData->frameGraphicsName = QString();
       
  1241             }
       
  1242         }
       
  1243 
       
  1244     } // else if (primitiveData->type == HbStylePrimitiveData::SPD_TouchArea) {
       
  1245         // mMultiSelectionTouchArea: no data provided
       
  1246 }
       
  1247 
       
  1248 
   687 
  1249 
   688 /*!
  1250 /*!
   689     \reimp
  1251     \reimp
   690 
  1252 
   691     To optimize loading css/xml definitions to take place only once, this function should be
  1253     To optimize loading css/xml definitions to take place only once, this function should be
   725             }
  1287             }
   726         }
  1288         }
   727     }
  1289     }
   728 #endif
  1290 #endif
   729 
  1291 
   730 
       
   731     HbStyleOptionAbstractViewItem styleOption;
       
   732     initStyleOption(&styleOption);
       
   733 
       
   734     if (d->mBackgroundItem) {
  1292     if (d->mBackgroundItem) {
   735         style()->updatePrimitive(d->mBackgroundItem, HbStyle::P_ItemViewItem_background, &styleOption);
  1293         // HbIconItem
       
  1294         HbStyleIconPrimitiveData primitiveData;
       
  1295         initPrimitiveData(&primitiveData, d->mBackgroundItem);
       
  1296         style()->updatePrimitive(d->mBackgroundItem, &primitiveData, this);
   736     }
  1297     }
   737 
  1298 
   738     if (d->mFrame) {
  1299     if (d->mFrame) {
   739         style()->updatePrimitive(d->mFrame, HbStyle::P_ItemViewItem_frame, &styleOption);
  1300         // HbFrameItem
       
  1301         HbStyleFramePrimitiveData primitiveData;
       
  1302         initPrimitiveData(&primitiveData, d->mFrame);
       
  1303         style()->updatePrimitive(d->mFrame, &primitiveData, this);
   740     }
  1304     }
   741 
  1305 
   742     if (d->mSelectionItem) {
  1306     if (d->mSelectionItem) {
   743         style()->updatePrimitive(d->mSelectionItem, HbStyle::P_ItemViewItem_selection, &styleOption);
  1307         // HbIconItem
       
  1308         HbStyleIconPrimitiveData primitiveData;
       
  1309         initPrimitiveData(&primitiveData, d->mSelectionItem);
       
  1310         style()->updatePrimitive(d->mSelectionItem, &primitiveData, this);
   744     }
  1311     }
   745 
  1312 
   746     if (d->mMultiSelectionTouchArea) {
  1313     if (d->mMultiSelectionTouchArea) {
   747         style()->updatePrimitive(d->mMultiSelectionTouchArea, HbStyle::P_ItemViewItem_touchmultiselection, &styleOption);
  1314         // HbTouchArea
       
  1315         HbStyleTouchAreaPrimitiveData primitiveData;
       
  1316         initPrimitiveData(&primitiveData, d->mMultiSelectionTouchArea);
       
  1317         style()->updatePrimitive(d->mMultiSelectionTouchArea, &primitiveData, this);
   748     }
  1318     }
   749 
  1319 
   750     if (d->mFocusItem) {
  1320     if (d->mFocusItem) {
   751         style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
  1321         // HbFrameItem
   752     }
  1322         HbStyleFramePrimitiveData primitiveData;
       
  1323         initPrimitiveData(&primitiveData, d->mFocusItem);
       
  1324         style()->updatePrimitive(d->mFocusItem, &primitiveData, this);
       
  1325     }
       
  1326         
       
  1327     updatePixmapCache();
   753 }
  1328 }
   754 
  1329 
   755 
  1330 
   756 /*!
  1331 /*!
   757     Updates child graphics items to represent current state and content. 
  1332     Updates child graphics items to represent current state and content. 
   787     /* Summary of background and frame handling:
  1362     /* Summary of background and frame handling:
   788          d->mBackground is read from Qt::BackgroundRole of model
  1363          d->mBackground is read from Qt::BackgroundRole of model
   789          d->mBackgroundItem is created from d-mBackground (Qt::BackgroundRole), if this is HbIcon or QBrush.
  1364          d->mBackgroundItem is created from d-mBackground (Qt::BackgroundRole), if this is HbIcon or QBrush.
   790 
  1365 
   791          If d->mBackgroundItem does not exist, d->mFrame is created from d-mBackground (Qt::BackgroundRole), 
  1366          If d->mBackgroundItem does not exist, d->mFrame is created from d-mBackground (Qt::BackgroundRole), 
   792          if this is HbFrameBackground otherwise it either is created from sd->mDefaultFrame, 
  1367          if this is HbFrameBackground, otherwise it is either created from sd->mDefaultFrame, 
   793          not created at all or from system default.
  1368          not created at all or from system default.
   794     */
  1369     */
   795  
  1370  
   796     // background
  1371     // background
   797     QVariant currentBackground = d->mIndex.data(Qt::BackgroundRole);
  1372     QVariant currentBackground = d->mIndex.data(Qt::BackgroundRole);
   799         d->mBackground = currentBackground;
  1374         d->mBackground = currentBackground;
   800         if (currentBackground.canConvert<HbIcon>() 
  1375         if (currentBackground.canConvert<HbIcon>() 
   801             || currentBackground.canConvert<QBrush>()) {
  1376             || currentBackground.canConvert<QBrush>()) {
   802             if (!d->mBackgroundItem) {  
  1377             if (!d->mBackgroundItem) {  
   803                 d->mItemsChanged = true;
  1378                 d->mItemsChanged = true;
   804                 d->mBackgroundItem = style()->createPrimitive(HbStyle::P_ItemViewItem_background, this);
  1379                 d->mBackgroundItem = style()->createPrimitive(HbStyle::PT_IconItem, QLatin1String("background"), 0);
       
  1380                 d->mBackgroundItem->setParentItem(this); // To enable asynchronous icon loading.
       
  1381                 d->mBackgroundItem->setZValue(-3.0);
       
  1382                 HbIconItem *iconItem = qobject_cast<HbIconItem*>(d->mBackgroundItem);
       
  1383                 if (iconItem) {
       
  1384                     iconItem->setAspectRatioMode(Qt::IgnoreAspectRatio);
       
  1385                 }
   805                 delete d->mFrame;
  1386                 delete d->mFrame;
   806                 d->mFrame = 0;
  1387                 d->mFrame = 0;
   807             }
  1388             }
   808         } else if (currentBackground.canConvert<HbFrameBackground>()) {
  1389         } else if (currentBackground.canConvert<HbFrameBackground>()) {
   809             if (!d->mFrame) {
  1390             if (!d->mFrame) {
   810                 d->mItemsChanged = true;
  1391                 d->mItemsChanged = true;
   811                 d->mFrame = style()->createPrimitive(HbStyle::P_ItemViewItem_frame, this);
  1392                 d->mFrame = style()->createPrimitive(HbStyle::PT_FrameItem, QLatin1String("frame"), this);
       
  1393                 d->mFrame->setZValue(-4.0);
       
  1394 
   812                 delete d->mBackgroundItem;
  1395                 delete d->mBackgroundItem;
   813                 d->mBackgroundItem = 0;
  1396                 d->mBackgroundItem = 0;
   814             }
  1397             }
   815         } else if (d->mBackgroundItem) {
  1398         } else if (d->mBackgroundItem) {
   816             d->mItemsChanged = true;
  1399             d->mItemsChanged = true;
   827                 &&  (   d->mBackground.canConvert<HbFrameBackground>()
  1410                 &&  (   d->mBackground.canConvert<HbFrameBackground>()
   828                     ||  sd->mDefaultFrame.frameGraphicsName().length() > 0    
  1411                     ||  sd->mDefaultFrame.frameGraphicsName().length() > 0    
   829                     ||  sd->mDefaultFrame.isNull()))) { 
  1412                     ||  sd->mDefaultFrame.isNull()))) { 
   830             if (!d->mFrame) {
  1413             if (!d->mFrame) {
   831                 d->mItemsChanged = true;
  1414                 d->mItemsChanged = true;
   832                 d->mFrame = style()->createPrimitive(HbStyle::P_ItemViewItem_frame, this);
  1415                 d->mFrame = style()->createPrimitive(HbStyle::PT_FrameItem, QLatin1String("frame"), this);
       
  1416                 d->mFrame->setZValue(-4.0);
   833             }
  1417             }
   834         } else if (d->mFrame) {
  1418         } else if (d->mFrame) {
   835             d->mItemsChanged = true;
  1419             d->mItemsChanged = true;
   836             delete d->mFrame;
  1420             delete d->mFrame;
   837             d->mFrame = 0;
  1421             d->mFrame = 0;
   877 
  1461 
   878     if (previousSelectable != itemSelectable) {
  1462     if (previousSelectable != itemSelectable) {
   879         if (itemSelectable) {
  1463         if (itemSelectable) {
   880             if (!d->mSelectionItem) {
  1464             if (!d->mSelectionItem) {
   881                 d->mItemsChanged = true;
  1465                 d->mItemsChanged = true;
   882                 d->mSelectionItem = style()->createPrimitive(HbStyle::P_ItemViewItem_selection, this);
  1466                 d->mSelectionItem = style()->createPrimitive(HbStyle::PT_IconItem, QLatin1String("selection-icon"), 0);
       
  1467                 d->mSelectionItem ->setParentItem(this); // To enable asynchronous icon loading.
       
  1468                 HbIconItem *iconItem = qobject_cast<HbIconItem*>(d->mSelectionItem);
       
  1469                 if (iconItem) {
       
  1470                     iconItem->setAlignment(Qt::AlignCenter);
       
  1471                 }
   883             }
  1472             }
   884         } else {
  1473         } else {
   885             d->mItemsChanged = true;
  1474             d->mItemsChanged = true;
   886             delete d->mSelectionItem;
  1475             delete d->mSelectionItem;
   887             d->mSelectionItem = 0;
  1476             d->mSelectionItem = 0;
   893     // multiselection area
  1482     // multiselection area
   894     if (    itemSelectable 
  1483     if (    itemSelectable 
   895         &&  selectionMode == HbAbstractItemView::MultiSelection) {
  1484         &&  selectionMode == HbAbstractItemView::MultiSelection) {
   896         if (!d->mMultiSelectionTouchArea) {
  1485         if (!d->mMultiSelectionTouchArea) {
   897             d->mItemsChanged = true;
  1486             d->mItemsChanged = true;
   898             d->mMultiSelectionTouchArea = style()->createPrimitive(HbStyle::P_ItemViewItem_touchmultiselection, this);
  1487             d->mMultiSelectionTouchArea = style()->createPrimitive(HbStyle::PT_TouchArea, QLatin1String("multiselection-toucharea"), this);
   899         }
  1488         }
   900     } else if (d->mMultiSelectionTouchArea) {
  1489     } else if (d->mMultiSelectionTouchArea) {
   901         d->mItemsChanged = true;
  1490         d->mItemsChanged = true;
   902         delete d->mMultiSelectionTouchArea;
  1491         delete d->mMultiSelectionTouchArea;
   903         d->mMultiSelectionTouchArea = 0;
  1492         d->mMultiSelectionTouchArea = 0;
   906     // items visibility or items content has really changed
  1495     // items visibility or items content has really changed
   907     updatePrimitives();
  1496     updatePrimitives();
   908     if (!d->mContentChangedSupported
  1497     if (!d->mContentChangedSupported
   909         || d->mItemsChanged) {
  1498         || d->mItemsChanged) {
   910         updateGeometry();   // ensures that sizehint is calculated again in case items have been created or deleted
  1499         updateGeometry();   // ensures that sizehint is calculated again in case items have been created or deleted
   911         d->mRepolishRequested = true;
  1500         
   912         // handle QEvent::Polish & QEvent::LayoutRequest event itself in ::sizeHint() as our performance is slightly better
  1501         if (d->viewAnimating()) {
   913         // (saving a layoutrequest and going event loop through twice)
  1502             // Force QEvent::Polish & QEvent::LayoutRequest event handling to be synchronous (handled when sizeHint() is called) 
   914         if (sd->mItemView && sd->mItemView->isScrolling()) {
  1503             // when view is animating (=scrollling) because of better performance.
   915             d->mHandlingRepolishSynchronously = true;
  1504             d->mHandlingRepolishSynchronously = true;
   916         }
  1505         }
   917         repolish();
  1506         repolish();
       
  1507 
   918         d->mHandlingRepolishSynchronously = false;
  1508         d->mHandlingRepolishSynchronously = false;
   919     }
  1509     }
   920     d->mItemsChanged = false;
  1510     d->mItemsChanged = false;
   921 }
  1511 }
   922 
  1512 
   963 
  1553 
   964     bool doAnimate = animate;
  1554     bool doAnimate = animate;
   965     if (sd->mItemView && !(sd->mItemView->enabledAnimations() & HbAbstractItemView::TouchDown)) {
  1555     if (sd->mItemView && !(sd->mItemView->enabledAnimations() & HbAbstractItemView::TouchDown)) {
   966         doAnimate = false;
  1556         doAnimate = false;
   967     }
  1557     }
       
  1558 
   968     if (pressed) {
  1559     if (pressed) {
   969         if (!d->mFocusItem) {
  1560         if (!d->mFocusItem) {
   970             d->mFocusItem = style()->createPrimitive(HbStyle::P_ItemViewItem_focus, this);
  1561             d->mFocusItem = style()->createPrimitive(HbStyle::PT_FrameItem, QLatin1String("focus") , this);
   971         }
  1562             d->mFocusItem->setZValue(-1.0);
   972 
  1563             // setChildFlags gets called in the construction phase, but the values are wrong.
   973         HbStyleOptionAbstractViewItem styleOption;
  1564             // Here we set the flags to force focusItem to be painted even when itemPixmapCache is on
   974         initStyleOption(&styleOption);
  1565             d->setChildFlags(d->mFocusItem, false);
       
  1566         }
   975 
  1567 
   976         if (d->mFocusItem) {
  1568         if (d->mFocusItem) {
   977             style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
  1569             HbStyleFramePrimitiveData primitiveData;
       
  1570             initPrimitiveData(&primitiveData, d->mFocusItem);
       
  1571             style()->updatePrimitive(d->mFocusItem, &primitiveData, this);
   978         }
  1572         }
   979 
  1573 
   980         if (doAnimate) {
  1574         if (doAnimate) {
   981             HbEffect::cancel(this, "released");
  1575             HbEffect::cancel(this, "released");
   982             HbEffect::cancel(d->mFocusItem, "released");
  1576             HbEffect::cancel(d->mFocusItem, "released");
       
  1577 
       
  1578             d->mNonCachableItem = d->mFocusItem;
       
  1579             updatePixmapCache();
   983 
  1580 
   984             HbEffect::start(this, sd->mItemType, "pressed");
  1581             HbEffect::start(this, sd->mItemType, "pressed");
   985             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "pressed");
  1582             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "pressed");
   986         }
  1583         }
   987     } else {
  1584     } else {
   988         if (doAnimate) {
  1585         if (doAnimate) {
   989             HbEffect::cancel(this, "pressed");
  1586             HbEffect::cancel(this, "pressed");
   990             HbEffect::cancel(d->mFocusItem, "pressed");
  1587             HbEffect::cancel(d->mFocusItem, "pressed");
       
  1588 
       
  1589             d->mNonCachableItem = d->mFocusItem;
       
  1590             updatePixmapCache();
   991 
  1591 
   992             HbEffect::start(this, sd->mItemType, "released");
  1592             HbEffect::start(this, sd->mItemType, "released");
   993             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "released", this, "_q_animationFinished");
  1593             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "released", this, "_q_animationFinished");
   994         } else {
  1594         } else {
   995             HbEffect::cancel(this, "pressed");
  1595             HbEffect::cancel(this, "pressed");
  1018 void HbAbstractViewItem::polish(HbStyleParameters& params)
  1618 void HbAbstractViewItem::polish(HbStyleParameters& params)
  1019 {
  1619 {
  1020     HB_SDD(HbAbstractViewItem);
  1620     HB_SDD(HbAbstractViewItem);
  1021 
  1621 
  1022     if (!d->polished && layout()) {
  1622     if (!d->polished && layout()) {
  1023     return;
  1623         return;
  1024     }
  1624     }
  1025 
  1625 
  1026     if (sd->mItemView) {
  1626     if (sd->mItemView) {
  1027         setProperty("layoutName", sd->mItemView->layoutName());
  1627         setProperty("layoutName", sd->mItemView->layoutName());
  1028     }
  1628     }
  1029 
  1629 
  1030     d->mRepolishRequested = false;
       
  1031     HbWidget::polish(params);
  1630     HbWidget::polish(params);
  1032 
  1631 
  1033     // TODO Brush background is overridden by css system even if bursh would not be set
  1632     // TODO Brush background is overridden by css system even if bursh would not be set
  1034     // explicitly by css/xml. This is feature, which will change
  1633     // explicitly by css/xml. This is feature, which will change
  1035     // later in css system. Workaround for it. This overrides the background brush set by css. 
  1634     // later in css system. Workaround for it. This overrides the background brush set by css. 
  1047     \reimp
  1646     \reimp
  1048 */
  1647 */
  1049 QSizeF HbAbstractViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
  1648 QSizeF HbAbstractViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
  1050 {
  1649 {
  1051     Q_D(const HbAbstractViewItem);
  1650     Q_D(const HbAbstractViewItem);
  1052     if (d->mRepolishRequested) {
  1651     if (d->repolishOutstanding) {
  1053         if (d->repolishOutstanding) {
  1652         // force the polish event in order to get the real size
  1054             // force the polish event in order to get the real size
  1653         // updateGeometry() in ::updateChildItems() causes this function to be called
  1055             // updateGeometry() in ::updateChildItems() causes this function to be called
  1654         // before QEvent::Polish of repolish() is handled from the event loop.
  1056             // before QEvent::Polish of repolish() is handled from the event loop
  1655         QCoreApplication::sendPostedEvents(const_cast<HbAbstractViewItem*>(this), QEvent::Polish);
  1057             QCoreApplication::sendPostedEvents(const_cast<HbAbstractViewItem*>(this), QEvent::Polish);
       
  1058         } else {
       
  1059             // needed for pure widget or at startup phase, if first polish has not yet been done
       
  1060             QEvent polishEvent(QEvent::Polish);
       
  1061             QCoreApplication::sendEvent(const_cast<HbAbstractViewItem *>(this), &polishEvent);
       
  1062         }
       
  1063         QCoreApplication::sendPostedEvents(const_cast<HbAbstractViewItem *>(this), QEvent::LayoutRequest);
  1656         QCoreApplication::sendPostedEvents(const_cast<HbAbstractViewItem *>(this), QEvent::LayoutRequest);
  1064     }
  1657     }
  1065     return HbWidget::sizeHint(which, constraint);
  1658     return HbWidget::sizeHint(which, constraint);
  1066 }
  1659 }
  1067 
  1660 
  1115     } else {
  1708     } else {
  1116         HbWidget::gestureEvent(event);
  1709         HbWidget::gestureEvent(event);
  1117     }
  1710     }
  1118 }
  1711 }
  1119 
  1712 
       
  1713 /*!
       
  1714     \reimp
       
  1715 */
       
  1716 void HbAbstractViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  1717 {
       
  1718     Q_UNUSED(widget);
       
  1719 
       
  1720     Q_D(HbAbstractViewItem);
       
  1721     
       
  1722     if (!d->mFrontPixmapPainter) {
       
  1723         return;
       
  1724     }
       
  1725     
       
  1726     if (!d->mInPaintItems) {
       
  1727         bool usePixmapCache = d->usePixmapCache();
       
  1728 
       
  1729         if (usePixmapCache) {
       
  1730             QRect rect = boundingRect().toAlignedRect();
       
  1731             if (    d->mFrontPixmapPainter->pixmap()
       
  1732                 &&  rect.size() != d->mFrontPixmapPainter->pixmap()->size()) {
       
  1733                 d->mResetPixmapCache = true;
       
  1734                 d->releasePixmaps();
       
  1735             }
       
  1736 
       
  1737             if (!d->mResetPixmapCache && d->mUpdateItems.count() && d->mFrontPixmapPainter->pixmap()) {
       
  1738                  d->drawSubPixmap(d->mFrontPixmapPainter->pixmap(), painter, option);
       
  1739             }
       
  1740 
       
  1741             if (d->mResetPixmapCache) {
       
  1742                 if (!d->mFrontPixmapPainter->pixmap()) {
       
  1743                     d->setChildFlagRecursively(true);
       
  1744                     QPixmap *pixmap = new QPixmap(rect.size());
       
  1745                     d->mFrontPixmapPainter->setPixmap(pixmap);
       
  1746                 }
       
  1747                 
       
  1748                 d->mUpdateItems.clear();
       
  1749 
       
  1750                 d->updatePixmap(d->mFrontPixmapPainter->pixmap(), painter, option, d->mNonCachableItem, 0);
       
  1751 
       
  1752                 if (d->mNonCachableItem) {
       
  1753                     if (!d->mBackPixmapPainter->pixmap()) {
       
  1754                         QPixmap *pixmap = new QPixmap(rect.size());
       
  1755                         d->mBackPixmapPainter->setPixmap(pixmap);
       
  1756                     } 
       
  1757                     d->updatePixmap(d->mBackPixmapPainter->pixmap(), painter, option, 0, d->mNonCachableItem);
       
  1758                 } else if (d->mBackPixmapPainter) {
       
  1759                     d->mBackPixmapPainter->setPixmap(0);
       
  1760                 }
       
  1761 
       
  1762                 d->mResetPixmapCache = false;
       
  1763             }
       
  1764         } else {
       
  1765             if (d->mFrontPixmapPainter->pixmap()) {
       
  1766                 d->setChildFlagRecursively(false);
       
  1767                 d->releasePixmaps();
       
  1768             }
       
  1769         }
       
  1770     }
       
  1771 }
       
  1772 
       
  1773 /*!
       
  1774     Updates the pixmap cache.
       
  1775 
       
  1776     Call this function when cache pixmap requires updating due to item or child state change
       
  1777     that affects its visual appearance.
       
  1778 */
       
  1779 void HbAbstractViewItem::updatePixmapCache()
       
  1780 {
       
  1781     Q_D(HbAbstractViewItem);
       
  1782 
       
  1783     if (!d->mResetPixmapCache && d->usePixmapCache()) {
       
  1784         d->mResetPixmapCache = true;
       
  1785         update();
       
  1786     }
       
  1787 }
  1120 
  1788 
  1121 #include "moc_hbabstractviewitem.cpp"
  1789 #include "moc_hbabstractviewitem.cpp"
  1122 
  1790