pixmap fading transition effect in paintutils taken from
KFileItemDelegate::Private::transition() now icon widget uses it svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=866344
This commit is contained in:
parent
266765dd9b
commit
c1a7cb7ce7
105
paintutils.cpp
105
paintutils.cpp
@ -22,6 +22,7 @@
|
||||
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QPaintEngine>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "effects/blur.cpp"
|
||||
@ -113,6 +114,110 @@ QPainterPath roundedRectangle(const QRectF& rect, qreal radius)
|
||||
return path;
|
||||
}
|
||||
|
||||
QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
|
||||
{
|
||||
int value = int(0xff * amount);
|
||||
|
||||
if (value == 0) {
|
||||
return from;
|
||||
} else if (value == 1) {
|
||||
return to;
|
||||
}
|
||||
|
||||
QColor color;
|
||||
color.setAlphaF(amount);
|
||||
|
||||
// If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
|
||||
if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff) &&
|
||||
from.paintEngine()->hasFeature(QPaintEngine::BlendModes)) {
|
||||
QPixmap under = from;
|
||||
QPixmap over = to;
|
||||
|
||||
QPainter p;
|
||||
p.begin(&over);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.fillRect(over.rect(), color);
|
||||
p.end();
|
||||
|
||||
p.begin(&under);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
||||
p.fillRect(under.rect(), color);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||
p.drawPixmap(0, 0, over);
|
||||
p.end();
|
||||
|
||||
return under;
|
||||
}
|
||||
#if defined(Q_WS_X11) && defined(HAVE_XRENDER)
|
||||
// We have Xrender support
|
||||
else if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) {
|
||||
// QX11PaintEngine doesn't implement CompositionMode_Plus in Qt 4.3,
|
||||
// which we need to be able to do a transition from one pixmap to
|
||||
// another.
|
||||
//
|
||||
// In order to avoid the overhead of converting the pixmaps to images
|
||||
// and doing the operation entirely in software, this function has a
|
||||
// specialized path for X11 that uses Xrender directly to do the
|
||||
// transition. This operation can be fully accelerated in HW.
|
||||
//
|
||||
// This specialization can be removed when QX11PaintEngine supports
|
||||
// CompositionMode_Plus.
|
||||
QPixmap source(to), destination(from);
|
||||
|
||||
source.detach();
|
||||
destination.detach();
|
||||
|
||||
Display *dpy = QX11Info::display();
|
||||
|
||||
XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
|
||||
XRenderPictureAttributes pa;
|
||||
pa.repeat = 1; // RepeatNormal
|
||||
|
||||
// Create a 1x1 8 bit repeating alpha picture
|
||||
Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
|
||||
Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
|
||||
XFreePixmap(dpy, pixmap);
|
||||
|
||||
// Fill the alpha picture with the opacity value
|
||||
XRenderColor xcolor;
|
||||
xcolor.alpha = quint16(0xffff * amount);
|
||||
XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
|
||||
|
||||
// Reduce the alpha of the destination with 1 - opacity
|
||||
XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
|
||||
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
|
||||
|
||||
// Add source * opacity to the destination
|
||||
XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
|
||||
destination.x11PictureHandle(),
|
||||
0, 0, 0, 0, 0, 0, destination.width(), destination.height());
|
||||
|
||||
XRenderFreePicture(dpy, alpha);
|
||||
return destination;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// Fall back to using QRasterPaintEngine to do the transition.
|
||||
QImage under = from.toImage();
|
||||
QImage over = to.toImage();
|
||||
|
||||
QPainter p;
|
||||
p.begin(&over);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.fillRect(over.rect(), color);
|
||||
p.end();
|
||||
|
||||
p.begin(&under);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
|
||||
p.fillRect(under.rect(), color);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||
p.drawImage(0, 0, over);
|
||||
p.end();
|
||||
|
||||
return QPixmap::fromImage(under);
|
||||
}
|
||||
}
|
||||
|
||||
} // PaintUtils namespace
|
||||
|
||||
} // Plasma namespace
|
||||
|
@ -58,6 +58,11 @@ PLASMA_EXPORT QPixmap shadowText(QString text,
|
||||
*/
|
||||
PLASMA_EXPORT QPainterPath roundedRectangle(const QRectF& rect, qreal radius);
|
||||
|
||||
/**
|
||||
* Blends a pixmap into another
|
||||
*/
|
||||
PLASMA_EXPORT QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount);
|
||||
|
||||
} // PaintUtils namespace
|
||||
|
||||
} // Plasma namespace
|
||||
|
@ -509,16 +509,6 @@ void Icon::hoverEffect(bool show)
|
||||
d->states |= IconPrivate::HoverState;
|
||||
}
|
||||
|
||||
if (d->m_hoverAnimId == -1 && !d->drawBg) {
|
||||
// we do this only when we don't do the anim, because
|
||||
// this gets set at animation end when we are animating
|
||||
if (!show) {
|
||||
d->states &= ~IconPrivate::HoverState;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_fadeIn = show;
|
||||
const int FadeInDuration = 150;
|
||||
|
||||
@ -614,13 +604,17 @@ QPixmap IconPrivate::decoration(const QStyleOptionGraphicsItem *option, bool use
|
||||
|
||||
// We disable the iconeffect here since we cannot get it into sync with
|
||||
// the fade animation. TODO: Enable it when animations are switched off
|
||||
if (!result.isNull() && useHoverEffect && !drawBg) {
|
||||
if (!result.isNull() && useHoverEffect) {
|
||||
KIconEffect *effect = KIconLoader::global()->iconEffect();
|
||||
// Note that in KIconLoader terminology, active = hover.
|
||||
// We're assuming that the icon group is desktop/filemanager, since this
|
||||
// is KFileItemDelegate.
|
||||
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
|
||||
result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
|
||||
if (qFuzzyCompare(qreal(1.0), m_hoverAlpha)) {
|
||||
result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
|
||||
} else {
|
||||
result = PaintUtils::transition(result, effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState), m_hoverAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user