[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: Icons Layout and Previews
From:       Benoit Walter <b.walter () free ! fr>
Date:       2003-11-03 22:11:57
[Download RAW message or body]

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.

["libkonq_preview.diff" (text/x-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<KFileIVI *>(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<KFileIVI*> ( 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<KFileIVI*> ( thumb->prevItem() );
+       }
+
+       // Look for item of max height on the right of item
+       thumb = static_cast<KFileIVI*> ( 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<KFileIVI*> ( 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"



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic