From kfm-devel Mon Nov 03 22:11:57 2003 From: Benoit Walter Date: Mon, 03 Nov 2003 22:11:57 +0000 To: kfm-devel Subject: Re: Icons Layout and Previews X-MARC-Message: https://marc.info/?l=kfm-devel&m=106789751718444 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_0Aup/xxG8mpqXQD" --Boundary-00=_0Aup/xxG8mpqXQD Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline I have improved this patch and this should work better now. The iconview is now updated only for visible icons, otherwise the update is delayed. It fixes a bug and does not change any i18n string. Can someone review it? Benoit. On Monday 03 November 2003 00:01, Benoit Walter wrote: > Hi, > > I have tried to improve the painting of thumbnails during preview > generation. The problem of overlapped icons has been partially adressed by > updating the iconview every 500ms (kfileivi.cc revision 1.250). This does > not really solve the problem because the display remains ugly while > generating preview during 500ms. > With the following patch, the icon view is updated when a new thumbnail has > been generated, but only if the update is needed (in most cases once for > each row). Otherwise, the icon is moved. This avoids having a messy icon > layout during generation of thumbnails. > > Possible improvement: > Update the view less frequently when the generated thumbnail is not > visible. > > This solution is not yet perfect and it would be great if someone could try > the patch and give some comments. > > Cheers, > Benoit. --Boundary-00=_0Aup/xxG8mpqXQD Content-Type: text/x-diff; charset="iso-8859-1"; name="libkonq_preview.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="libkonq_preview.diff" Index: konq_iconviewwidget.cc =================================================================== RCS file: /home/kde/kdebase/libkonq/konq_iconviewwidget.cc,v retrieving revision 1.266 diff -u -3 -p -r1.266 konq_iconviewwidget.cc --- konq_iconviewwidget.cc 24 Oct 2003 20:46:48 -0000 1.266 +++ konq_iconviewwidget.cc 3 Nov 2003 22:04:14 -0000 @@ -337,7 +337,7 @@ struct KonqIconViewWidgetPrivate pSoundTimer = 0; pPreviewJob = 0; bAllowSetWallpaper = false; - gridXspacing = 50; + gridXspacing = 50; doAnimations = true; m_movie = 0L; @@ -362,7 +362,6 @@ struct KonqIconViewWidgetPrivate bool bSoundItemClicked; bool bAllowSetWallpaper; int gridXspacing; - QTimer* rearrangeIconsTimer; // Animated icons support @@ -680,26 +679,62 @@ void KonqIconViewWidget::slotStartSoundP void KonqIconViewWidget::slotPreview(const KFileItem *item, const QPixmap &pix) { + int left = contentsX(); + int right = left + viewport()->width(); + int top = contentsY(); + int bottom = top + viewport()->height(); + // ### slow. Idea: move KonqKfmIconView's m_itemDict into this class for (QIconViewItem *it = firstItem(); it; it = it->nextItem()) { KFileIVI* current = static_cast(it); if (current->item() == item) { - bool needsUpdate = ( !current->pixmap() || current->pixmap()->width() < pix.width() || current->pixmap()->height() < pix.height() ); - if(item->overlays() & KIcon::HiddenOverlay) - { - QPixmap p(pix); + bool itemIsVisible = + ( current->x() > left ) && + ( current->x() < right ) && + ( current->y() > top ) && + ( current->y() < bottom ); + bool rearranged = false; + if (item->overlays() & KIcon::HiddenOverlay) { + QPixmap p(pix); KIconEffect::semiTransparent(p); + if ( autoArrange() ) + rearranged = rearrangeIcon(current, p); current->setThumbnailPixmap(p); - } else { + } + else { + if (autoArrange()) + rearranged = rearrangeIcon(current, pix); current->setThumbnailPixmap(pix); } - if ( needsUpdate - && autoArrange() - && !d->rearrangeIconsTimer->isActive() ) { - d->rearrangeIconsTimer->start( 500, true ); + + if (!autoArrange()) + continue; + + // Force immediate if the icon is too far on the right + bool forceUpdate = + ( itemTextPos() == QIconView::Bottom && + contentsWidth() > viewport()->width() && + viewport()->width() > 200 ) || + ( itemTextPos() == QIconView::Right && + contentsHeight() > viewport()->height() && + viewport()->height() > 170 ); + + // If the item is visible and has not been rearranged, we + // update the view immediately + if ( ((itemIsVisible && !rearranged) || forceUpdate) && + !d->rearrangeIconsTimer->isActive() ) + d->rearrangeIconsTimer->start( 20, true ); + + // If the item is not visible and has not been rearranged, we + // will update the view later (after all previews have been + // generated or after scrolling) + else if (!itemIsVisible && !rearranged && + !d->rearrangeIconsTimer->isActive() ) { + connect( this, SIGNAL( contentsMoving(int,int) ), + this, SLOT( slotRearrangeIcons(int,int) ) ); } } } @@ -708,10 +743,6 @@ void KonqIconViewWidget::slotPreview(con void KonqIconViewWidget::slotPreviewResult() { d->pPreviewJob = 0; - if ( d->rearrangeIconsTimer->isActive() ) { - d->rearrangeIconsTimer->stop(); - slotRearrangeIcons(); - } emit imagePreviewFinished(); } @@ -1083,10 +1114,16 @@ void KonqIconViewWidget::slotAboutToCrea void KonqIconViewWidget::slotRearrangeIcons() { - // We cannot actually call arrangeItemsInGrid directly as a slot because it has a default parameter. - arrangeItemsInGrid(); + // We cannot actually call arrangeItemsInGrid directly as a slot because it has a default parameter. + arrangeItemsInGrid(); } +void KonqIconViewWidget::slotRearrangeIcons( int, int ) +{ + disconnect( this, SIGNAL( contentsMoving(int,int) ), + this, SLOT( slotRearrangeIcons(int,int) ) ); + arrangeItemsInGrid(); +} void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r ) { @@ -1977,6 +2014,62 @@ void KonqIconViewWidget::setNewURL( cons else u = url; setURL( u ); +} + +bool KonqIconViewWidget::rearrangeIcon( KFileIVI* item, const QPixmap& pixmap ) +{ + int maxHeight = 0; + int maxTop = 0; + + // Text at bottom of icons + if ( itemTextPos() == QIconView::Bottom ) { + + // Look for item of max height on the left of item + KFileIVI* thumb = static_cast ( item->prevItem() ); + while ( thumb && thumb->x() < item->x() ) { + int currentHeight = thumb->pixmap()->height(); + if ( currentHeight > maxHeight ) { + maxHeight = currentHeight; + maxTop = thumb->rect().top(); + } + thumb = static_cast ( thumb->prevItem() ); + } + + // Look for item of max height on the right of item + thumb = static_cast ( item->nextItem() ); + while ( thumb && thumb->x() > item->x() ) { + int currentHeight = thumb->pixmap()->height(); + if ( currentHeight > maxHeight ) { + maxHeight = currentHeight; + maxTop = thumb->rect().top(); + } + thumb = static_cast ( thumb->nextItem() ); + } + } + + // Text alongside icons + else { + // Height of the current icon (not yet thumbnail) + maxHeight = item->pixmap()->height(); + maxTop = item->rect().top(); + } + + // If maxHeight > currentHeight, move and resize current icon + int currentHeight = pixmap.height(); + if ( maxHeight >= currentHeight ) { + QRect tmpRect = item->rect(); + // Center icon horizontally if needed + if ( itemTextPos() == QIconView::Bottom && + item->textRect().width() < pixmap.width() ) { + tmpRect.setLeft( + tmpRect.left() - ( pixmap.width() - tmpRect.width() ) / 2 ); + } + // Top of icon + tmpRect.setTop( maxTop + maxHeight - currentHeight ); + item->changeLayout( tmpRect ); // cannot use setItemLayout directly + return true; // Icon has been rearranged + } + return false; // Icon could not be rearranged, we need to update the view } #include "konq_iconviewwidget.moc" --Boundary-00=_0Aup/xxG8mpqXQD--