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 );