[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-05 1:05:00
[Download RAW message or body]

Here is the full version (and with a few corrections).

Benoit.


On Tuesday 04 November 2003 22:49, Lu=EDs Pedro Coelho wrote:
> Can you post a full diff, please?
>
> Still, looking through the patch it looks like the things I wanted to do
> when I wrote the earlier 500ms patch, but didn't ; )

["libkonq_preview_full.diff" (text/x-diff)]

Index: kfileivi.cc
===================================================================
RCS file: /home/kde/kdebase/libkonq/kfileivi.cc,v
retrieving revision 1.80
diff -u -3 -p -r1.80 kfileivi.cc
--- kfileivi.cc	30 Aug 2003 16:40:14 -0000	1.80
+++ kfileivi.cc	5 Nov 2003 00:01:48 -0000
@@ -208,7 +208,7 @@ void KFileIVI::setThumbnailPixmap( const
 
     // Recalc when setting this pixmap!
     QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large,
-			      QIconSet::Normal ), true );
+                              QIconSet::Normal ), true );
 }
 
 void KFileIVI::setActive( bool active )
Index: kfileivi.h
===================================================================
RCS file: /home/kde/kdebase/libkonq/kfileivi.h,v
retrieving revision 1.48
diff -u -3 -p -r1.48 kfileivi.h
--- kfileivi.h	2 Jul 2003 13:13:43 -0000	1.48
+++ kfileivi.h	5 Nov 2003 00:01:49 -0000
@@ -192,6 +192,12 @@ public:
     KIVDirectoryOverlay* setShowDirectoryOverlay( bool );
     bool showDirectoryOverlay( );
 
+    /**
+     * Change the rect of the item, used internally by KonqIconView.
+     * Any other use is discouraged.
+     */
+    void changeLayout( const QRect& newRect ) { setItemRect( newRect ); }  
+     
 protected:
     virtual void dropped( QDropEvent *e, const QValueList<QIconDragItem> &  );
 
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	5 Nov 2003 00:01:54 -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,65 @@ 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)
-            {
+            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())
+                return;
+
+            // 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 icon has been rearranged, we don't need to update
+            // the view
+            if (!forceUpdate && rearranged)
+                return;
+
+            bool itemIsVisible =
+                ( current->rect().right() > left ) &&
+                ( current->rect().left() < right ) &&
+                ( current->rect().bottom() > top ) &&
+                ( current->rect().top() < bottom );
+
+            // If the item is visible, we update the view
+            if (itemIsVisible || forceUpdate) {
+                if (!d->rearrangeIconsTimer->isActive())
+                    d->rearrangeIconsTimer->start( 10, true );
+            }
+
+            // If the item is not visible, we update the view later
+            // (when scrolling)
+            else if (!d->rearrangeIconsTimer->isActive()) {
+                connect( this, SIGNAL( contentsMoving(int,int) ),
+                         this, SLOT( slotRearrangeIcons(int,int) ) );
             }
         }
     }
@@ -708,10 +746,6 @@ void KonqIconViewWidget::slotPreview(con
 void KonqIconViewWidget::slotPreviewResult()
 {
     d->pPreviewJob = 0;
-    if ( d->rearrangeIconsTimer->isActive() ) {
-        d->rearrangeIconsTimer->stop();
-        slotRearrangeIcons();
-    }
     emit imagePreviewFinished();
 }
 
@@ -1083,10 +1117,18 @@ 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();
 }
 
+// Called when the view is scrolled and if an update is needed
+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 +2019,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"
Index: konq_iconviewwidget.h
===================================================================
RCS file: /home/kde/kdebase/libkonq/konq_iconviewwidget.h,v
retrieving revision 1.102
diff -u -3 -p -r1.102 konq_iconviewwidget.h
--- konq_iconviewwidget.h	5 Oct 2003 12:10:22 -0000	1.102
+++ konq_iconviewwidget.h	5 Nov 2003 00:01:55 -0000
@@ -256,6 +256,7 @@ protected slots:
 
 private slots:
     void slotRearrangeIcons();
+    void slotRearrangeIcons(int,int);
 
 protected:
     virtual QDragObject *dragObject();
@@ -278,6 +279,7 @@ protected:
     virtual void backgroundPixmapChange( const QPixmap & );
     void readAnimatedIconsConfig();
     void mousePressChangeValue();
+    bool rearrangeIcon( KFileIVI*, const QPixmap& );
 
 private:
     KURL m_url;



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

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