src/hbwidgets/itemviews/hbabstractviewitem_p.h
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 23 e6ad4ef83b23
--- a/src/hbwidgets/itemviews/hbabstractviewitem_p.h	Tue Jul 06 14:36:53 2010 +0300
+++ b/src/hbwidgets/itemviews/hbabstractviewitem_p.h	Wed Aug 18 10:05:37 2010 +0300
@@ -31,14 +31,17 @@
 #include <hbeffect.h>
 #include <hbframebackground.h>
 #include <hbnamespace.h>
+#include <hboogmwatcher_p.h>
+#include <hbabstractitemview.h>
+#include <hbstyleoptionabstractviewitem_p.h>
 
 #include <QObject>
 #include <QPersistentModelIndex>
 #include <QPointer>
 #include <QExplicitlySharedDataPointer>
 #include <QSharedData>
+#include <QPainter>
 
-class HbAbstractItemView;
 class QGraphicsItem;
 class QTimer;
 class QGestureEvent;
@@ -46,6 +49,69 @@
 #define HB_SD(Class) Class##Shared * sd = (Class##Shared *)(d->mSharedData.data())
 #define HB_SDD(Class) Q_D(Class); Class##Shared * sd = (Class##Shared *)(d->mSharedData.data())
 
+class HbViewItemPixmapPainter : public QGraphicsItem
+{
+public:
+
+    HbViewItemPixmapPainter(int zValue, QGraphicsItem *parent) :
+        QGraphicsItem(parent),
+        mPixmap(0),
+        mBoundingRect(parent->boundingRect())
+    {
+        setZValue(zValue);
+    }
+
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
+    {
+        Q_UNUSED(option);
+        Q_UNUSED(widget);
+
+        QTransform restoreTransform = painter->worldTransform();
+        painter->setWorldTransform(QTransform());
+
+        if (mPixmap) {
+            painter->drawPixmap(mDeviceRect.topLeft(), *mPixmap);
+        }
+
+        painter->setWorldTransform(restoreTransform);
+    }
+
+    QRectF boundingRect() const
+    {
+        return mBoundingRect;
+    }
+    
+    void setPixmap(QPixmap *pixmap) 
+    {
+        if (pixmap) {
+            if (!mPixmap) {
+                setFlag(QGraphicsItem::ItemHasNoContents, false);
+            }
+        } else {
+            if (mPixmap) {
+                setFlag(QGraphicsItem::ItemHasNoContents, true);
+            }
+        }
+
+        mPixmap = pixmap;
+    }
+
+    void setDeviceRect(const QRect &deviceRect) {
+        mDeviceRect = deviceRect;
+    }
+
+    void setSize(const QSizeF &size) {
+        prepareGeometryChange();
+        mBoundingRect = QRectF(QPointF(), size);
+    }
+
+private:
+
+    QPixmap *mPixmap;
+    QRect mDeviceRect;
+    QRectF mBoundingRect;
+};
+
 class HbAbstractViewItemShared : public QObject, public QSharedData
 {
     Q_OBJECT
@@ -58,13 +124,28 @@
           mDefaultFrame(),
           mItemType("viewitem"),
           mPressStateChangeTimer(0),
-          mPressedItem(0)
+          mPressedItem(0),
+          mLowGraphicsMemory(false),
+          mStyleOption(0)
         {
+            HbOogmWatcher *watcher = HbOogmWatcher::instance();
+            
+            connect(watcher, SIGNAL(graphicsMemoryLow()), this, SLOT(disablePixmapCaches()));
+            connect(watcher, SIGNAL(graphicsMemoryGood()), this, SLOT(enablePixmapCaches()));
+            
+            mStyleOption = new HbStyleOptionAbstractViewItem;
+        }
+        
+        virtual ~HbAbstractViewItemShared()
+        {
+            delete mStyleOption;
         }
 
     public slots:
 
         void pressStateChangeTimerTriggered();
+        void disablePixmapCaches();
+        void enablePixmapCaches();
 
     public:
 
@@ -80,6 +161,10 @@
         QTimer *mPressStateChangeTimer;
         HbAbstractViewItem *mPressedItem;
         bool mAnimatePress;
+
+        bool mLowGraphicsMemory;
+        
+        HbStyleOptionAbstractViewItem *mStyleOption;
 };
 
 class HbAbstractViewItemPrivate : public HbWidgetPrivate
@@ -90,7 +175,6 @@
 
         explicit HbAbstractViewItemPrivate(HbAbstractViewItem *prototype, HbAbstractViewItemShared *shared = 0) :
           HbWidgetPrivate(),
-          mFocused(false),
           mBackgroundItem(0),
           mFrame(0),
           mCheckState(Qt::Unchecked),
@@ -102,7 +186,14 @@
           mPressed(false),
           mFocusItem(0),
           mMultiSelectionTouchArea(0),                    
-          mSharedData(shared)
+          mSharedData(shared),
+          mBackPixmapPainter(0),
+          mFrontPixmapPainter(0),
+          mBackCachePixmap(0),
+          mFrontCachePixmap(0),
+          mInPaintItems(false),
+          mNonCachableItem(0),
+          mResetPixmapCache(true)
         {
             if (!mSharedData) {
                 mSharedData = new HbAbstractViewItemShared;
@@ -113,7 +204,6 @@
         HbAbstractViewItemPrivate(const HbAbstractViewItemPrivate &source) :
             HbWidgetPrivate(),
             mIndex(source.mIndex),
-            mFocused(source.mFocused),
             mBackgroundItem(0),
             mFrame(0),
             mCheckState(source.mCheckState),
@@ -125,14 +215,20 @@
             mPressed(false),
             mFocusItem(0),
             mMultiSelectionTouchArea(0),
-            mSharedData(source.mSharedData)
+            mSharedData(source.mSharedData),
+            mBackPixmapPainter(0),
+            mFrontPixmapPainter(0),
+            mBackCachePixmap(0),
+            mFrontCachePixmap(0),
+            mInPaintItems(false),
+            mNonCachableItem(source.mNonCachableItem),
+            mResetPixmapCache(true)
         {
         }
         
         HbAbstractViewItemPrivate &operator=(const HbAbstractViewItemPrivate &source)
         {
             mIndex = source.mIndex;
-            mFocused = source.mFocused;
             mBackgroundItem = 0;
             mBackground = QVariant();
             mFrame = 0;
@@ -146,6 +242,13 @@
             mFocusItem = 0;
             mSharedData = source.mSharedData;
             mMultiSelectionTouchArea = 0;
+            mBackPixmapPainter = 0;
+            mFrontPixmapPainter = 0;
+            mBackCachePixmap = 0;
+            mFrontCachePixmap = 0;
+            mInPaintItems = false;
+            mNonCachableItem = source.mNonCachableItem;
+            mResetPixmapCache = true;
 
             return *this;
         }
@@ -174,9 +277,23 @@
 
         void setPressed(bool pressed, bool animate);
 
+        void paintItems(QPainter *painter, QStyleOptionGraphicsItem *option, QGraphicsItem *startItem, QGraphicsItem *endItem);
+
+        void setChildFlags(QGraphicsItem *child, bool pixmapCacheEnabled);
+
+        inline bool usePixmapCache() const;
+
+        void updatePixmap(QPixmap *pixmap, 
+            QPainter *painter, 
+            const QTransform &itemToPixmapTransform, 
+            const QStyleOptionGraphicsItem *option, 
+            QGraphicsItem *startItem, 
+            QGraphicsItem *endItem);
+
+        void releasePixmaps();
+
 public:
         QPersistentModelIndex mIndex;
-        bool mFocused;
         
         QGraphicsItem *mBackgroundItem;
         QVariant mBackground;
@@ -200,6 +317,28 @@
         QGraphicsItem *mMultiSelectionTouchArea;
 
         QExplicitlySharedDataPointer<HbAbstractViewItemShared> mSharedData;
+
+        HbViewItemPixmapPainter *mBackPixmapPainter;
+        HbViewItemPixmapPainter *mFrontPixmapPainter;
+
+        QPixmap *mBackCachePixmap;
+        QPixmap *mFrontCachePixmap;
+
+        bool mInPaintItems;
+
+        QGraphicsItem *mNonCachableItem;
+        bool mResetPixmapCache;
+        
+        friend class HbAbstractViewItemShared;
 };
 
+bool HbAbstractViewItemPrivate::usePixmapCache() const
+{
+    if (mSharedData->mItemView && mSharedData->mItemView->itemPixmapCacheEnabled() && !mSharedData->mLowGraphicsMemory) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
 #endif /*HBABSTRACTVIEWITEM_P_H*/