[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: Re: [PATH] Improve icons layout
From: Benoit Walter <b.walter () free ! fr>
Date: 2004-01-20 19:45:29
Message-ID: 200401202045.29731.b.walter () free ! fr
[Download RAW message or body]
Thanks for the comment, updated patch removes the added members in KFileIVI.
The previewIconSize function is fast enough, so it shouldn't have any effect
on performance. I also removed m_canPreview which was actually not needed.
On Tuesday 20 January 2004 19:57, David Faure wrote:
> I can't really comment on the rest of the patch, but the above seems to eat
> quite some memory unnecessarily. This is for each item - and in some
> directories there can be many many items, so better not enlarge KFileIVI if
> not needed.
>
> m_iconView is already stored in QIconViewItem, just cast iconView()
> to a KonqIconViewWidget * like we already do in kfileivi.cc
>
> m_canPreview is ok (it fits with the other bool, no size increase)
>
> m_thumbSize can apparently be removed and always recalculated on the fly
> as iconview->previewIconSize( size ), unless that's too slow.
>
> Thanks for taking into account the memory consumption issue.
["libkonq2.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 20 Jan 2004 19:42:02 -0000
@@ -47,13 +47,17 @@ struct KFileIVI::Private
};
KFileIVI::KFileIVI( KonqIconViewWidget *iconview, KFileItem* fileitem, int size )
- : KIconViewItem( iconview, fileitem->text(),
- fileitem->pixmap( size, KIcon::DefaultState ) ),
- m_size( size ), m_state( KIcon::DefaultState ),
- m_bDisabled( false ), m_bThumbnail( false ), m_fileitem( fileitem )
+ : KIconViewItem( iconview, fileitem->text() ), m_size( size ),
+ m_state( KIcon::DefaultState ), m_bDisabled( false ),
+ m_bThumbnail( false ), m_fileitem( fileitem )
{
- setDropEnabled( S_ISDIR( m_fileitem->mode() ) );
d = new KFileIVI::Private;
+ if ( needEnlarge() )
+ QIconViewItem::setPixmap( enlargedFileItemPixmap() );
+ else
+ QIconViewItem::setPixmap( m_fileitem->pixmap( m_size, m_state ) );
+
+ setDropEnabled( S_ISDIR( m_fileitem->mode() ) );
// Cache entry for the icon effects
d->icons.reset( *pixmap(), QIconSet::Large );
@@ -100,13 +104,14 @@ void KFileIVI::invalidateThumb( int stat
m_state = state;
QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ),
- false, redraw );
+ false, redraw );
}
void KFileIVI::setIcon( int size, int state, bool recalc, bool redraw )
{
m_size = size;
m_bThumbnail = false;
+
if ( m_bDisabled )
m_state = KIcon::DisabledState;
else
@@ -124,7 +129,10 @@ void KFileIVI::setIcon( int size, int st
d->m_overlay = DesktopIcon(d->m_overlayName, halfSize);
}
- setPixmapDirect(m_fileitem->pixmap( m_size, m_state ) , recalc, redraw );
+ if ( needEnlarge() )
+ setPixmapDirect( enlargedFileItemPixmap(), recalc, redraw );
+ else
+ setPixmapDirect( m_fileitem->pixmap( m_size, m_state ), recalc, redraw );
}
void KFileIVI::setOverlay( const QString& iconName )
@@ -179,7 +187,7 @@ void KFileIVI::setPixmapDirect( const QP
d->icons = QIconSet();
d->icons.setPixmap( pixmap, QIconSet::Large, mode );
QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ),
- recalc, redraw );
+ recalc, redraw );
}
void KFileIVI::setDisabled( bool disabled )
@@ -189,7 +197,12 @@ void KFileIVI::setDisabled( bool disable
m_bDisabled = disabled;
bool active = ( m_state == KIcon::ActiveState );
m_state = m_bDisabled ? KIcon::DisabledState : ( active ? KIcon::ActiveState \
: KIcon::DefaultState );
- QIconViewItem::setPixmap( m_fileitem->pixmap( m_size, m_state ), false, true \
); +
+ if ( needEnlarge() )
+ QIconViewItem::setPixmap( enlargedFileItemPixmap(), false, true );
+ else
+ QIconViewItem::setPixmap( m_fileitem->pixmap( m_size, m_state ),
+ false, true );
}
}
@@ -208,7 +221,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 )
@@ -240,7 +253,9 @@ void KFileIVI::setEffect( int state )
KIconEffect *effect = KGlobal::iconLoader()->iconEffect();
bool haveEffect = effect->hasEffect( KIcon::Desktop, m_state ) !=
- effect->hasEffect( KIcon::Desktop, state );
+ effect->hasEffect( KIcon::Desktop, state ) &&
+ effect->fingerprint( KIcon::Desktop, m_state ) !=
+ effect->fingerprint( KIcon::Desktop, state );
//kdDebug(1203) << "desktop;defaultstate=" <<
// effect->fingerprint(KIcon::Desktop, KIcon::DefaultState) <<
@@ -249,27 +264,31 @@ void KFileIVI::setEffect( int state )
// effect->fingerprint(KIcon::Desktop, KIcon::ActiveState) <<
// endl;
- if( haveEffect &&
- effect->fingerprint( KIcon::Desktop, m_state ) !=
- effect->fingerprint( KIcon::Desktop, state ) )
+ m_state = state;
+
+ if( haveEffect )
{
- // Effects on are not applied until they are first accessed to
- // save memory. Do this now when needed
- if( m_bThumbnail )
- {
- if( d->icons.isGenerated( QIconSet::Large, mode ) )
- d->icons.setPixmap( effect->apply( d->thumb, KIcon::Desktop, state ),
- QIconSet::Large, mode );
- }
- else
- {
- if( d->icons.isGenerated( QIconSet::Large, mode ) )
- d->icons.setPixmap( m_fileitem->pixmap( m_size, state ),
- QIconSet::Large, mode );
- }
- QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ) );
+ // Effects on are not applied until they are first accessed to
+ // save memory. Do this now when needed
+ if( m_bThumbnail )
+ {
+ if( d->icons.isGenerated( QIconSet::Large, mode ) )
+ d->icons.setPixmap( effect->apply( d->thumb, KIcon::Desktop, m_state ),
+ QIconSet::Large, mode );
+ }
+ else
+ {
+ if( d->icons.isGenerated( QIconSet::Large, mode ) ) {
+ if ( needEnlarge() )
+ d->icons.setPixmap( enlargedFileItemPixmap(),
+ QIconSet::Large, mode );
+ else
+ d->icons.setPixmap( m_fileitem->pixmap( m_size, m_state ),
+ QIconSet::Large, mode );
+ }
+ }
+ QIconViewItem::setPixmap( d->icons.pixmap( QIconSet::Large, mode ) );
}
- m_state = state;
}
void KFileIVI::refreshIcon( bool redraw )
@@ -423,4 +442,46 @@ void KFileIVI::setAnimated( bool a )
d->m_animated = a;
}
-/* vim: set noet sw=4 ts=8 softtabstop=4: */
+QPixmap KFileIVI::enlargedFileItemPixmap() const
+{
+ // Enlarge the icon for items that can be previewed to match
+ // the size of a thumbnail
+ int size = m_size ? m_size :
+ KGlobal::iconLoader()->currentSize( KIcon::Desktop );
+
+ QPixmap pix( m_fileitem->pixmap( size, m_state ) );
+ int w, h, dx, dy;
+ int thumbSize =
+ static_cast<KonqIconViewWidget*>(iconView())->previewIconSize( size );
+
+ // Text under Icons
+ if ( static_cast<KonqIconViewWidget*>
+ (iconView())->itemTextPos() == QIconView::Bottom ) {
+ w = h = thumbSize;
+ dx = ( w - size ) / 2;
+ dy = h - size;
+ }
+ // Text alongside Icons
+ else {
+ w = size;
+ h = thumbSize;
+ dx = 0;
+ dy = ( h - size ) / 2;
+ }
+
+ // Copy the file item pixmap into a larger, transparent pixmap
+ QPixmap p( w, h );
+ QBitmap mask( w, h );
+ mask.fill( color0 );
+ bitBlt( &mask, dx, dy, pix.mask() );
+ bitBlt( &p, dx, dy, &pix );
+ p.setMask( mask );
+ return p;
+}
+
+bool KFileIVI::needEnlarge() const
+{
+ KonqIconViewWidget* view = static_cast<KonqIconViewWidget*>(iconView());
+ return ( view->previewIconSize( m_size ) != m_size &&
+ view->canPreview( item() ) );
+}
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 20 Jan 2004 19:42:03 -0000
@@ -216,6 +216,10 @@ private:
virtual void setPixmap ( const QPixmap & icon ) { KIconViewItem::setPixmap( icon \
); }
virtual void setPixmap ( const QPixmap & icon, bool recalc, bool redraw = TRUE )
{ KIconViewItem::setPixmap( icon, recalc, redraw ); }
+
+ bool KFileIVI::needEnlarge() const;
+ QPixmap enlargedFileItemPixmap() const;
+
int m_size, m_state;
bool m_bDisabled;
bool m_bThumbnail;
Index: konq_iconviewwidget.cc
===================================================================
RCS file: /home/kde/kdebase/libkonq/konq_iconviewwidget.cc,v
retrieving revision 1.269
diff -u -3 -p -r1.269 konq_iconviewwidget.cc
--- konq_iconviewwidget.cc 9 Jan 2004 17:55:59 -0000 1.269
+++ konq_iconviewwidget.cc 20 Jan 2004 19:42:20 -0000
@@ -45,6 +45,7 @@
#include <kurldrag.h>
#include <kstandarddirs.h>
#include <kprotocolinfo.h>
+#include <ktrader.h>
#include <assert.h>
#include <unistd.h>
@@ -344,6 +345,10 @@ struct KonqIconViewWidgetPrivate
m_movieBlocked = 0;
pFileTip = 0;
pActivateDoubleClick = 0L;
+ pPreviewMimeTypes = 0L;
+
+ KConfigGroup group( KGlobal::config(), "PreviewSettings" );
+ bBoostPreview = group.readBoolEntry("BoostSize", false);
}
~KonqIconViewWidgetPrivate() {
delete pSoundPlayer;
@@ -351,6 +356,7 @@ struct KonqIconViewWidgetPrivate
delete m_movie;
delete pFileTip;
delete pActivateDoubleClick;
+ delete pPreviewMimeTypes;
//delete pPreviewJob; done by stopImagePreview
}
KFileIVI *pActiveItem;
@@ -363,8 +369,6 @@ struct KonqIconViewWidgetPrivate
bool bAllowSetWallpaper;
int gridXspacing;
- QTimer* rearrangeIconsTimer;
-
// Animated icons support
bool doAnimations;
QMovie* m_movie;
@@ -374,6 +378,8 @@ struct KonqIconViewWidgetPrivate
KIO::PreviewJob *pPreviewJob;
KFileTip* pFileTip;
QStringList previewSettings;
+ QStringList* pPreviewMimeTypes;
+ bool bBoostPreview;
bool renameItem;
bool firstClick;
bool releaseMouseEvent;
@@ -389,7 +395,6 @@ KonqIconViewWidget::KonqIconViewWidget(
m_bSetGridX( !kdesktop ) /* No line breaking on the desktop */
{
d = new KonqIconViewWidgetPrivate;
- d->rearrangeIconsTimer = new QTimer( this );
connect( this, SIGNAL( dropped( QDropEvent *, const QValueList<QIconDragItem> & \
) ),
this, SLOT( slotDropped( QDropEvent*, const QValueList<QIconDragItem> & \
) ) );
@@ -402,8 +407,6 @@ KonqIconViewWidget::KonqIconViewWidget(
connect( this, SIGNAL(onViewport()), SLOT(slotOnViewport()) );
connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), \
SLOT(slotItemRenamed(QIconViewItem *, const QString &)) );
- connect( d->rearrangeIconsTimer, SIGNAL( timeout() ), SLOT( slotRearrangeIcons() \
) );
-
// hardcoded settings
setSelectionMode( QIconView::Extended );
setItemTextPos( QIconView::Bottom );
@@ -686,21 +689,58 @@ void KonqIconViewWidget::slotPreview(con
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);
-
- KIconEffect::semiTransparent(p);
- current->setThumbnailPixmap(p);
- } else {
- current->setThumbnailPixmap(pix);
+ if ( !d->bBoostPreview ) {
+ if (item->overlays() & KIcon::HiddenOverlay) {
+ QPixmap p(pix);
+ KIconEffect::semiTransparent(p);
+ current->setThumbnailPixmap(p);
+ }
+ else
+ current->setThumbnailPixmap(pix);
+ break;
+ }
+
+ // Create a pixmap as large as the current icon and copy the
+ // thumbnail pixmap
+ int w, h, dx, dy;
+
+ // Text under Icons
+ if ( itemTextPos() == QIconView::Bottom ) {
+ QSize s = current->pixmap()->size();
+ w = s.width();
+ h = s.height();
+ dx = ( w - pix.width() ) / 2;
+ dy = h - pix.height();
+ }
+
+ // Text alongside Icons
+ else {
+ w = pix.width();
+ h = current->pixmap()->height();
+ dx = 0;
+ dy = ( h - pix.height() ) / 2;
}
- if ( needsUpdate
- && autoArrange()
- && !d->rearrangeIconsTimer->isActive() ) {
- d->rearrangeIconsTimer->start( 500, true );
+
+ QPixmap p( w, h );
+ QBitmap mask( w, h );
+ mask.fill( color0 );
+ QBitmap* imask;
+ if ( pix.mask() )
+ imask = new QBitmap( *( pix.mask() ) );
+ else {
+ imask = new QBitmap( pix.size() );
+ imask->fill( color1 );
}
+ bitBlt( &mask, dx, dy, imask );
+ bitBlt( &p, dx, dy, &pix );
+ p.setMask( mask );
+ delete imask;
+
+ if(item->overlays() & KIcon::HiddenOverlay)
+ KIconEffect::semiTransparent(p);
+
+ current->setThumbnailPixmap( p );
+ break;
}
}
}
@@ -708,10 +748,6 @@ void KonqIconViewWidget::slotPreview(con
void KonqIconViewWidget::slotPreviewResult()
{
d->pPreviewJob = 0;
- if ( d->rearrangeIconsTimer->isActive() ) {
- d->rearrangeIconsTimer->stop();
- slotRearrangeIcons();
- }
emit imagePreviewFinished();
}
@@ -900,11 +936,16 @@ void KonqIconViewWidget::setIcons( int s
{
ivi->setIcon( size, ivi->state(), true, false );
}
- else
+ else {
ivi->invalidateThumb( ivi->state(), false );
+ if ( sizeChanged )
+ ivi->setIcon( size, ivi->state(), true, false );
+ }
}
- if ( autoArrange() && (oldGridX != gridX() || !stopImagePreviewFor.isEmpty()) )
+ if ( autoArrange() &&
+ ( oldGridX != gridX() || !stopImagePreviewFor.isEmpty() ||
+ d->bBoostPreview ) )
arrangeItemsInGrid( true ); // take new grid into account and repaint
else
viewport()->update(); //Repaint later..
@@ -939,6 +980,10 @@ void KonqIconViewWidget::setItemTextPos(
}
KIconView::setItemTextPos( pos );
+
+ // Update the icons if preview size is boosted
+ if ( d->bBoostPreview )
+ setIcons( m_size );
}
void KonqIconViewWidget::calculateGridX()
@@ -957,6 +1002,7 @@ int KonqIconViewWidget::gridXValue() con
void KonqIconViewWidget::refreshMimeTypes()
{
+ updatePreviewMimeTypes();
for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
(static_cast<KFileIVI *>( it ))->item()->refreshMimeType();
setIcons( m_size );
@@ -1018,19 +1064,11 @@ void KonqIconViewWidget::startImagePrevi
int size;
KConfigGroup group( KGlobal::config(), "PreviewSettings" );
- if ( group.readBoolEntry("BoostSize", false) ) {
- if (iconSize < 28)
- size = 48;
- else if (iconSize < 40)
- size = 64;
- else if (iconSize < 60)
- size = 96;
- else
- size = 128;
- } else {
- size = iconSize;
+ d->bBoostPreview = group.readBoolEntry("BoostSize", false);
+ size = previewIconSize( iconSize );
+
+ if ( !d->bBoostPreview )
iconSize /= 2;
- }
d->pPreviewJob = KIO::filePreview( items, size, size, iconSize,
m_pSettings->textPreviewIconTransparency(), true /* scale */,
@@ -1081,13 +1119,6 @@ void KonqIconViewWidget::slotAboutToCrea
// Do nothing :-)
}
-void KonqIconViewWidget::slotRearrangeIcons()
-{
- // We cannot actually call arrangeItemsInGrid directly as a slot because it has \
a default parameter.
- arrangeItemsInGrid();
-}
-
-
void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
{
drawBackground(p, r, r.topLeft());
@@ -1969,6 +2000,53 @@ void KonqIconViewWidget::lineupIcons()
return;
}
+bool KonqIconViewWidget::canPreview( KFileItem* item )
+{
+ if ( d->pPreviewMimeTypes == 0L )
+ updatePreviewMimeTypes();
+
+ return mimeTypeMatch( item->mimetype(), *( d->pPreviewMimeTypes ) );
+}
+
+void KonqIconViewWidget::updatePreviewMimeTypes()
+{
+ if ( d->pPreviewMimeTypes == 0L )
+ d->pPreviewMimeTypes = new QStringList;
+ else
+ d->pPreviewMimeTypes->clear();
+
+ // Load the list of plugins to determine which mimetypes are supported
+ KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator");
+ KTrader::OfferList::ConstIterator it;
+
+ for ( it = plugins.begin(); it != plugins.end(); ++it ) {
+ if ( d->previewSettings.contains((*it)->desktopEntryName()) ) {
+ QStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
+ for (QStringList::ConstIterator mt = mimeTypes.begin(); mt != \
mimeTypes.end(); ++mt) + d->pPreviewMimeTypes->append(*mt);
+ }
+ }
+}
+
+int KonqIconViewWidget::previewIconSize( int size ) const
+{
+ int iconSize = size ? size : KGlobal::iconLoader()->currentSize( KIcon::Desktop \
); + int previewIconSize;
+
+ if (!d->bBoostPreview)
+ previewIconSize = iconSize;
+ else if (iconSize < 28)
+ previewIconSize = 48;
+ else if (iconSize < 40)
+ previewIconSize = 64;
+ else if (iconSize < 60)
+ previewIconSize = 96;
+ else
+ previewIconSize = 128;
+
+ return previewIconSize;
+}
+
void KonqIconViewWidget::visualActivate(QIconViewItem * item)
{
// Rect of the QIconViewItem.
@@ -1995,6 +2073,11 @@ void KonqIconViewWidget::backgroundPixma
void KonqIconViewWidget::setPreviewSettings( const QStringList& settings )
{
d->previewSettings = settings;
+ updatePreviewMimeTypes();
+
+ // Update the icons if preview size is boosted
+ if ( d->bBoostPreview )
+ setIcons( m_size );
}
const QStringList& KonqIconViewWidget::previewSettings()
Index: konq_iconviewwidget.h
===================================================================
RCS file: /home/kde/kdebase/libkonq/konq_iconviewwidget.h,v
retrieving revision 1.103
diff -u -3 -p -r1.103 konq_iconviewwidget.h
--- konq_iconviewwidget.h 12 Dec 2003 00:03:58 -0000 1.103
+++ konq_iconviewwidget.h 20 Jan 2004 19:42:21 -0000
@@ -257,9 +257,6 @@ protected slots:
void slotAboutToCreate(const QPoint &pos, const QValueList<KIO::CopyInfo> \
&files); void doubleClickTimeout();
-private slots:
- void slotRearrangeIcons();
-
protected:
virtual QDragObject *dragObject();
KonqIconDrag *konqDragObject( QWidget * dragSource = 0L );
@@ -282,8 +279,13 @@ protected:
virtual void wheelEvent( QWheelEvent* );
void readAnimatedIconsConfig();
void mousePressChangeValue();
+
+ bool canPreview( KFileItem* item );
+ int previewIconSize( int size ) const;
private:
+ void updatePreviewMimeTypes();
+
KURL m_url;
const KFileItem * m_rootItem;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic