summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-02-18 20:35:59 -0600
committerSlávek Banko <slavek.banko@axis.cz>2013-02-20 21:52:12 +0100
commit897cd5c506666c79771aa761544f593149f37a40 (patch)
treef7165a8ff9fc47d9d6047d71fcd51adca7f5705c
parentb8ca17c69c9150ef6f3d356f8c75860a085d508a (diff)
downloadqt3-897cd5c506666c79771aa761544f593149f37a40.tar.gz
qt3-897cd5c506666c79771aa761544f593149f37a40.zip
Doublebuffer QIconView to reduce flicker
This closes Bug 1408 (cherry picked from commit 82b71e49603bf3a53240076c395864addd869267)
-rw-r--r--src/iconview/qiconview.cpp47
-rw-r--r--src/iconview/qiconview.h1
2 files changed, 47 insertions, 1 deletions
diff --git a/src/iconview/qiconview.cpp b/src/iconview/qiconview.cpp
index c1ea8cc..36b5da2 100644
--- a/src/iconview/qiconview.cpp
+++ b/src/iconview/qiconview.cpp
@@ -214,6 +214,7 @@ public:
QIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem,
*startDragItem, *pressedItem, *selectAnchor, *renamingItem;
QRect *rubber;
+ QPixmap *backBuffer;
QTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer,
*fullRedrawTimer;
int rastX, rastY, spacing;
@@ -2789,6 +2790,7 @@ QIconView::QIconView( QWidget *parent, const char *name, WFlags f )
d->currentItem = 0;
d->highlightedItem = 0;
d->rubber = 0;
+ d->backBuffer = 0;
d->scrollTimer = 0;
d->startDragItem = 0;
d->tmpCurrentItem = 0;
@@ -2942,6 +2944,8 @@ QIconView::~QIconView()
delete item;
item = tmp;
}
+ delete d->backBuffer;
+ d->backBuffer = 0;
delete d->fm;
d->fm = 0;
#ifndef QT_NO_TOOLTIP
@@ -4943,6 +4947,47 @@ void QIconView::contentsDropEvent( QDropEvent *e )
#endif
/*!
+ This function grabs all paintevents that otherwise would have been
+ processed by the QScrollView::viewportPaintEvent(). Here we use a
+ doublebuffer to reduce 'on-paint' flickering on QIconView
+ (and of course its children).
+
+ \sa QScrollView::viewportPaintEvent(), QIconView::drawContents()
+*/
+
+void QIconView::bufferedPaintEvent( QPaintEvent* pe )
+{
+ QWidget* vp = viewport();
+ QRect r = pe->rect() & vp->rect();
+ int ex = r.x() + contentsX();
+ int ey = r.y() + contentsY();
+ int ew = r.width();
+ int eh = r.height();
+
+ if ( !d->backBuffer )
+ d->backBuffer = new QPixmap(vp->size());
+ if ( d->backBuffer->size() != vp->size() ) {
+ // Resize function (with hysteresis). Uses a good compromise between memory
+ // consumption and speed (number) of resizes.
+ float newWidth = (float)vp->width();
+ float newHeight = (float)vp->height();
+ if ( newWidth > d->backBuffer->width() || newHeight > d->backBuffer->height() )
+ {
+ newWidth *= 1.1892;
+ newHeight *= 1.1892;
+ d->backBuffer->resize( (int)newWidth, (int)newHeight );
+ } else if ( 1.5*newWidth < d->backBuffer->width() || 1.5*newHeight < d->backBuffer->height() )
+ d->backBuffer->resize( (int)newWidth, (int)newHeight );
+ }
+
+ QPainter p;
+ p.begin(d->backBuffer, vp);
+ drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh);
+ p.end();
+ bitBlt(vp, r.x(), r.y(), d->backBuffer, r.x(), r.y(), ew, eh);
+}
+
+/*!
\reimp
*/
@@ -5726,7 +5771,7 @@ bool QIconView::eventFilter( QObject * o, QEvent * e )
if ( !d->rubber )
drawDragShapes( d->oldDragPos );
}
- viewportPaintEvent( (QPaintEvent*)e );
+ bufferedPaintEvent( (QPaintEvent*)e );
if ( d->dragging ) {
if ( !d->rubber )
drawDragShapes( d->oldDragPos );
diff --git a/src/iconview/qiconview.h b/src/iconview/qiconview.h
index 97780d8..109779f 100644
--- a/src/iconview/qiconview.h
+++ b/src/iconview/qiconview.h
@@ -452,6 +452,7 @@ protected:
void contentsDropEvent( QDropEvent *e );
#endif
+ void bufferedPaintEvent( QPaintEvent* );
void resizeEvent( QResizeEvent* e );
void keyPressEvent( QKeyEvent *e );
void focusInEvent( QFocusEvent *e );