mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-20 00:41:23 +00:00
Alpha blending for Konqi and KDesktop
svn path=/trunk/kdebase/libkonq/; revision=72889
This commit is contained in:
parent
c97053b88d
commit
62192a1510
|
@ -17,6 +17,13 @@
|
|||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// XXX: This ugly hack should go away as soon as the latest release
|
||||
// of Qt include a way to access QIconView::mask() and QIconView::tmpText
|
||||
#define private public
|
||||
#define protected public
|
||||
#include <qiconview.h>
|
||||
#undef private
|
||||
#undef protected
|
||||
#include "kfileivi.h"
|
||||
#include "konq_fileitem.h"
|
||||
#include "konq_drag.h"
|
||||
|
@ -26,8 +33,26 @@
|
|||
#include <kapp.h>
|
||||
#include <kipc.h>
|
||||
#include <kurldrag.h>
|
||||
#include <kalphapainter.h>
|
||||
#include <kimageeffect.h>
|
||||
#include <kstaticdeleter.h>
|
||||
#undef Bool
|
||||
|
||||
static QPixmap *konqiv_buffer_pixmap = 0;
|
||||
static KStaticDeleter <QPixmap> konqiv_buffer_pixmap_deleter;
|
||||
|
||||
static QPixmap *get_konqiv_buffer_pixmap( const QSize &s )
|
||||
{
|
||||
if ( !konqiv_buffer_pixmap ) {
|
||||
konqiv_buffer_pixmap = konqiv_buffer_pixmap_deleter.setObject(
|
||||
new QPixmap( s ));
|
||||
return konqiv_buffer_pixmap;
|
||||
}
|
||||
|
||||
konqiv_buffer_pixmap->resize( s );
|
||||
return konqiv_buffer_pixmap;
|
||||
}
|
||||
|
||||
KFileIVI::KFileIVI( KonqIconViewWidget *iconview, KonqFileItem* fileitem, int size )
|
||||
: QIconViewItem( iconview, fileitem->text(),
|
||||
fileitem->pixmap( size, KIcon::DefaultState ) ),
|
||||
|
@ -119,22 +144,197 @@ void KFileIVI::returnPressed()
|
|||
m_fileitem->run();
|
||||
}
|
||||
|
||||
void KFileIVI::paintItem( QPainter *p, const QColorGroup &cg )
|
||||
void KFileIVI::paintItem( QPainter *p, const QColorGroup &c )
|
||||
{
|
||||
QColorGroup c( cg );
|
||||
c.setColor( QColorGroup::Text, static_cast<KonqIconViewWidget*>(iconView())->itemColor() );
|
||||
QColorGroup cg( c );
|
||||
cg.setColor( QColorGroup::Text, static_cast<KonqIconViewWidget*>(iconView())->itemColor() );
|
||||
if ( m_fileitem->isLink() )
|
||||
{
|
||||
QFont f( p->font() );
|
||||
f.setItalic( TRUE );
|
||||
p->setFont( f );
|
||||
}
|
||||
QIconViewItem::paintItem( p, c );
|
||||
|
||||
if (!KGlobal::iconLoader()->alphaBlending())
|
||||
{
|
||||
// default fallback if we're not using alphablending
|
||||
QIconViewItem::paintItem( p, cg );
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, we're using alpha blending.
|
||||
|
||||
QPixmap unknown_icon=KIconLoader::unknown();
|
||||
|
||||
if ( !iconView() )
|
||||
return;
|
||||
|
||||
|
||||
// First, let's get the background.
|
||||
|
||||
QRect r=pixmapRect(false);
|
||||
QPixmap background(r.width(),r.height());
|
||||
QPainter *pbg=new QPainter(&background);
|
||||
static_cast<KonqIconViewWidget *>(iconView())->drawBackground(pbg,
|
||||
r , QPoint(0,0));
|
||||
delete pbg;
|
||||
|
||||
QImage bgImg(background.convertToImage());
|
||||
|
||||
// This is done to handle overlapped icons. There are no overlapped
|
||||
// icons in 98% of the cases, so I don't think it's a bad solution.
|
||||
// The right solution would be using QIconView's ItemContainer,
|
||||
// or any other way to get icons that overlap with a given rectangle
|
||||
// and blend (paint over bgImg) only the ones which are below the current
|
||||
// one.
|
||||
|
||||
QIconViewItem *it=iconView()->firstItem();
|
||||
while (it!=static_cast<QIconViewItem *>(this) && it )
|
||||
{
|
||||
if ( r.intersects( it->rect() ) &&
|
||||
( r.intersects(it->pixmapRect(false)) || r.intersects(it->textRect(false)) ) )
|
||||
static_cast<KFileIVI *>(it)->paintAlphaItem(p, cg, bgImg,
|
||||
unknown_icon, true, r.x(), r.y());
|
||||
it=it->nextItem();
|
||||
}
|
||||
|
||||
it=nextItem();
|
||||
while (it)
|
||||
{
|
||||
if ( r.intersects( it->rect() ) &&
|
||||
( r.intersects(it->pixmapRect(false)) || r.intersects(it->textRect(false)) ) )
|
||||
static_cast<KFileIVI *>(it)->paintAlphaItem(p, cg, bgImg,
|
||||
unknown_icon, true, r.x(), r.y());
|
||||
it=it->nextItem();
|
||||
}
|
||||
|
||||
// and now, let's paint this item's icon.
|
||||
|
||||
paintAlphaItem(p, cg, bgImg, unknown_icon, false, r.x(), r.y());
|
||||
}
|
||||
|
||||
void KFileIVI::paintAlphaItem( QPainter *p, const QColorGroup &cg,
|
||||
QImage &background, QPixmap & unknown_icon , bool onBg, int bgx, int bgy)
|
||||
{
|
||||
QPixmap *txtPixmap=0L;
|
||||
QRect txtRect=textRect(false);
|
||||
if (onBg)
|
||||
{
|
||||
txtRect.moveTopLeft(QPoint(0,0));
|
||||
txtPixmap=new QPixmap(txtRect.size());
|
||||
p=new QPainter(txtPixmap);
|
||||
} else {
|
||||
if (!p) return;
|
||||
p->save();
|
||||
}
|
||||
|
||||
// antonio: The next lines have been copied from Qt and are
|
||||
// copyrighted by Trolltech AS (1992-2000) . They also include
|
||||
// many changes by me.
|
||||
|
||||
if ( isSelected() ) {
|
||||
p->setPen( cg.highlightedText() );
|
||||
} else {
|
||||
p->setPen( cg.text() );
|
||||
}
|
||||
|
||||
calcTmpText();
|
||||
|
||||
if ( iconView()->itemTextPos() == QIconView::Bottom ) {
|
||||
int w = ( pixmap() ? pixmap() : &unknown_icon )->width();
|
||||
|
||||
if ( isSelected() ) {
|
||||
QPixmap *pix = pixmap() ? pixmap() : &unknown_icon;
|
||||
if ( pix && !pix->isNull() ) {
|
||||
QPixmap *buffer = get_konqiv_buffer_pixmap( pix->size() );
|
||||
QBitmap mask = iconView()->mask( pix );
|
||||
|
||||
QPainter p2( buffer );
|
||||
p2.fillRect( pix->rect(), white );
|
||||
p2.drawPixmap( 0, 0, *pix );
|
||||
p2.end();
|
||||
buffer->setMask( mask );
|
||||
p2.begin( buffer );
|
||||
p2.fillRect( pix->rect(), QBrush( cg.highlight(),
|
||||
QBrush::Dense4Pattern) );
|
||||
p2.end();
|
||||
QRect cr = pix->rect();
|
||||
KAlphaPainter::draw(((onBg)? 0L : p) , *buffer, background,
|
||||
x() + ( width() - w ) / 2, y(), onBg, bgx, bgy);
|
||||
}
|
||||
} else
|
||||
KAlphaPainter::draw( ((onBg)? 0L : p),
|
||||
*( pixmap() ? pixmap() : &unknown_icon), background,
|
||||
x() + ( width() - w ) / 2, y(), onBg, bgx, bgy);
|
||||
|
||||
|
||||
p->save();
|
||||
if ( isSelected() ) {
|
||||
p->fillRect( txtRect, cg.highlight() );
|
||||
p->setPen( QPen( cg.highlightedText() ) );
|
||||
} else if ( iconView()->itemTextBackground() != NoBrush )
|
||||
p->fillRect( txtRect, iconView()->itemTextBackground() );
|
||||
|
||||
int align = AlignHCenter;
|
||||
if ( iconView()->wordWrapIconText() )
|
||||
align |= WordBreak;
|
||||
p->drawText( txtRect, align, iconView()->wordWrapIconText() ? text() : tmpText );
|
||||
|
||||
p->restore();
|
||||
} else {
|
||||
int h = ( pixmap() ? pixmap() : &unknown_icon )->height();
|
||||
|
||||
if ( isSelected() ) {
|
||||
QPixmap *pix = pixmap() ? pixmap() : &unknown_icon;
|
||||
if ( pix && !pix->isNull() ) {
|
||||
QPixmap *buffer = get_konqiv_buffer_pixmap( pix->size() );
|
||||
QBitmap mask = iconView()->mask( pix );
|
||||
|
||||
QPainter p2( buffer );
|
||||
p2.fillRect( pix->rect(), white );
|
||||
p2.drawPixmap( 0, 0, *pix );
|
||||
p2.end();
|
||||
buffer->setMask( mask );
|
||||
p2.begin( buffer );
|
||||
p2.fillRect( pix->rect(), QBrush( cg.highlight(), QBrush::Dense4Pattern) );
|
||||
p2.end();
|
||||
QRect cr = pix->rect();
|
||||
KAlphaPainter::draw(((onBg)? 0L : p), *buffer, background,
|
||||
x(), y() + ( height() - h ) / 2 , onBg, bgx, bgy);
|
||||
}
|
||||
} else {
|
||||
KAlphaPainter::draw(((onBg) ? 0L : p),
|
||||
*( pixmap() ? pixmap() : &unknown_icon ), background,
|
||||
x(), y() + ( height() - h ) / 2 , onBg, bgx, bgy);
|
||||
}
|
||||
|
||||
p->save();
|
||||
if ( isSelected() ) {
|
||||
p->fillRect( txtRect, cg.highlight() );
|
||||
p->setPen( QPen( cg.highlightedText() ) );
|
||||
} else if ( iconView()->itemTextBackground() != NoBrush )
|
||||
p->fillRect( txtRect, iconView()->itemTextBackground() );
|
||||
|
||||
int align = AlignLeft;
|
||||
if ( iconView()->wordWrapIconText() )
|
||||
align |= WordBreak;
|
||||
p->drawText( txtRect, align, iconView()->wordWrapIconText() ? text() : tmpText );
|
||||
|
||||
p->restore();
|
||||
}
|
||||
|
||||
if (onBg) {
|
||||
delete p;
|
||||
KImageEffect::paint(textRect(false).x()-bgx, textRect(false).y()-bgy, background,
|
||||
txtPixmap->convertToImage());
|
||||
delete txtPixmap;
|
||||
} else
|
||||
p->restore();
|
||||
}
|
||||
|
||||
void KFileIVI::move( int x, int y )
|
||||
{
|
||||
if ( ( (KonqIconViewWidget*)iconView() )->isDesktop() ) {
|
||||
if ( static_cast<KonqIconViewWidget*>(iconView())->isDesktop() ) {
|
||||
if ( x < 5 )
|
||||
x = 5;
|
||||
if ( x > iconView()->viewport()->width() - ( width() + 5 ) )
|
||||
|
@ -146,3 +346,4 @@ void KFileIVI::move( int x, int y )
|
|||
}
|
||||
QIconViewItem::move( x, y );
|
||||
}
|
||||
|
||||
|
|
|
@ -103,8 +103,28 @@ public:
|
|||
virtual void refreshIcon( bool redraw );
|
||||
|
||||
virtual void setKey( const QString &key );
|
||||
|
||||
/**
|
||||
* Paints this item. Takes care of using the normal or alpha
|
||||
* blending methods depending on the configuration.
|
||||
*/
|
||||
virtual void paintItem( QPainter *p, const QColorGroup &cg );
|
||||
|
||||
/**
|
||||
* Paints this item using the KAlphaPainter methods.
|
||||
* @p bgx and @p bgy specify the coordinates where the background
|
||||
* starts so that you don't have to use the whole background as
|
||||
* third parameter. copyOnBg specify if you want to get a copy of
|
||||
* the alpha blended item on the background image, or you prefer
|
||||
* not to change it (default).
|
||||
*
|
||||
* Note that when using copyOnBg=true, it won't paint on the
|
||||
* painter object, so you can use p=0L.
|
||||
*/
|
||||
void paintAlphaItem( QPainter *p, const QColorGroup &cg,
|
||||
QImage &background, QPixmap &unknown_icon,
|
||||
bool copyOnBg=false, int bgx=0, int bgy=0);
|
||||
|
||||
void move( int x, int y );
|
||||
|
||||
protected:
|
||||
|
|
|
@ -324,6 +324,11 @@ void KonqIconViewWidget::slotDropped( QDropEvent *ev, const QValueList<QIconDrag
|
|||
}
|
||||
|
||||
void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
|
||||
{
|
||||
drawBackground(p, r, r.topLeft());
|
||||
}
|
||||
|
||||
void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r , const QPoint &pt)
|
||||
{
|
||||
const QPixmap *pm = backgroundPixmap();
|
||||
bool hasPixmap = pm && !pm->isNull();
|
||||
|
@ -331,15 +336,18 @@ void KonqIconViewWidget::drawBackground( QPainter *p, const QRect &r )
|
|||
pm = viewport()->backgroundPixmap();
|
||||
hasPixmap = pm && !pm->isNull();
|
||||
}
|
||||
|
||||
QRect rtgt(r);
|
||||
rtgt.moveTopLeft(pt);
|
||||
if (!hasPixmap && backgroundMode() != NoBackground) {
|
||||
p->fillRect(r, viewport()->backgroundColor());
|
||||
p->fillRect(rtgt, viewport()->backgroundColor());
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasPixmap) {
|
||||
int ax = (r.x() + contentsX() + leftMargin()) % pm->width();
|
||||
int ay = (r.y() + contentsY() + topMargin()) % pm->height();
|
||||
p->drawTiledPixmap(r, *pm, QPoint(ax, ay));
|
||||
p->drawTiledPixmap(rtgt, *pm, QPoint(ax, ay));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ class KonqIconViewWidget : public KIconView
|
|||
Q_PROPERTY( QRect iconArea READ iconArea WRITE setIconArea )
|
||||
Q_PROPERTY( int lineupMode READ lineupMode WRITE setLineupMode )
|
||||
|
||||
friend class KFileIVI;
|
||||
|
||||
public:
|
||||
|
||||
enum LineupMode { LineupHorizontal=1, LineupVertical, LineupBoth };
|
||||
|
@ -202,6 +204,13 @@ protected:
|
|||
KonqIconDrag *konqDragObject( QWidget * dragSource = 0L );
|
||||
|
||||
virtual void drawBackground( QPainter *p, const QRect &r );
|
||||
/**
|
||||
* r is the rectangle which you want to paint from the background.
|
||||
* pt is the upper left point in the painter device where you want to paint
|
||||
* the rectangle r.
|
||||
*/
|
||||
virtual void drawBackground( QPainter *p, const QRect &r,
|
||||
const QPoint &pt );
|
||||
virtual void viewportResizeEvent(QResizeEvent *);
|
||||
virtual void contentsDragEnterEvent( QDragEnterEvent *e );
|
||||
virtual void contentsDropEvent( QDropEvent *e );
|
||||
|
|
Loading…
Reference in a new issue