• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kfadewidgeteffect.cpp

Go to the documentation of this file.
00001 /*  This file is part of the KDE project
00002     Copyright (C) 2008 Matthias Kretz <kretz@kde.org>
00003     Copyright (C) 2008 Rafael Fernández López <ereslibre@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) version 3.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 
00020 */
00021 
00022 #include "kfadewidgeteffect.h"
00023 #include "kfadewidgeteffect_p.h"
00024 
00025 #include <config.h> // for HAVE_XRENDER
00026 
00027 #include <QtCore/QEvent>
00028 #include <QtGui/QPaintEngine>
00029 #include <QtGui/QPainter>
00030 
00031 #include <kglobalsettings.h>
00032 
00033 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
00034 #  include <X11/Xlib.h>
00035 #  include <X11/extensions/Xrender.h>
00036 #  include <QX11Info>
00037 #  undef KeyPress
00038 #  undef FocusOut
00039 #endif
00040 
00041 KFadeWidgetEffectPrivate::KFadeWidgetEffectPrivate(QWidget *_destWidget)
00042     : destWidget(_destWidget), disabled(false)
00043 {
00044 }
00045 
00046 // Code from KFileItemDelegate (Author: Frederik Höglund)
00047 // Fast transitions. Read:
00048 // http://techbase.kde.org/Development/Tutorials/Graphics/Performance
00049 // for further information on why not use setOpacity.
00050 QPixmap KFadeWidgetEffectPrivate::transition(const QPixmap &from, const QPixmap &to, qreal amount) const
00051 {
00052     const int value = int(0xff * amount);
00053 
00054     if (value == 0)
00055         return from;
00056 
00057     if (value == 1)
00058         return to;
00059 
00060     QColor color;
00061     color.setAlphaF(amount);
00062 
00063     // If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
00064     if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff) &&
00065         from.paintEngine()->hasFeature(QPaintEngine::BlendModes))
00066     {
00067         QPixmap under = from;
00068         QPixmap over  = to;
00069 
00070         QPainter p;
00071         p.begin(&over);
00072         p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00073         p.fillRect(over.rect(), color);
00074         p.end();
00075 
00076         p.begin(&under);
00077         p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00078         p.fillRect(under.rect(), color);
00079         p.setCompositionMode(QPainter::CompositionMode_Plus);
00080         p.drawPixmap(0, 0, over);
00081         p.end();
00082 
00083         return under;
00084     }
00085 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
00086     else if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) // We have Xrender support
00087     {
00088         // QX11PaintEngine doesn't implement CompositionMode_Plus in Qt 4.3,
00089         // which we need to be able to do a transition from one pixmap to
00090         // another.
00091         //
00092         // In order to avoid the overhead of converting the pixmaps to images
00093         // and doing the operation entirely in software, this function has a
00094         // specialized path for X11 that uses Xrender directly to do the
00095         // transition. This operation can be fully accelerated in HW.
00096         //
00097         // This specialization can be removed when QX11PaintEngine supports
00098         // CompositionMode_Plus.
00099         QPixmap source(to), destination(from);
00100 
00101         source.detach();
00102         destination.detach();
00103 
00104         Display *dpy = QX11Info::display();
00105 
00106         XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
00107         XRenderPictureAttributes pa;
00108         pa.repeat = 1; // RepeatNormal
00109 
00110         // Create a 1x1 8 bit repeating alpha picture
00111         Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
00112         Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
00113         XFreePixmap(dpy, pixmap);
00114 
00115         // Fill the alpha picture with the opacity value
00116         XRenderColor xcolor;
00117         xcolor.alpha = quint16(0xffff * amount);
00118         XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
00119 
00120         // Reduce the alpha of the destination with 1 - opacity
00121         XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
00122                          0, 0, 0, 0, 0, 0, destination.width(), destination.height());
00123 
00124         // Add source * opacity to the destination
00125         XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
00126                          destination.x11PictureHandle(),
00127                          0, 0, 0, 0, 0, 0, destination.width(), destination.height());
00128 
00129         XRenderFreePicture(dpy, alpha);
00130         return destination;
00131     }
00132 #endif
00133     else
00134     {
00135         // Fall back to using QRasterPaintEngine to do the transition.
00136         QImage under = from.toImage();
00137         QImage over  = to.toImage();
00138 
00139         QPainter p;
00140         p.begin(&over);
00141         p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00142         p.fillRect(over.rect(), color);
00143         p.end();
00144 
00145         p.begin(&under);
00146         p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00147         p.fillRect(under.rect(), color);
00148         p.setCompositionMode(QPainter::CompositionMode_Plus);
00149         p.drawImage(0, 0, over);
00150         p.end();
00151 
00152         return QPixmap::fromImage(under);
00153     }
00154 }
00155 
00156 KFadeWidgetEffect::KFadeWidgetEffect(QWidget *destWidget)
00157     : QWidget(destWidget ? destWidget->parentWidget() : 0),
00158     d_ptr(new KFadeWidgetEffectPrivate(destWidget))
00159 {
00160     Q_D(KFadeWidgetEffect);
00161     d->q_ptr = this;
00162     Q_ASSERT(destWidget && destWidget->parentWidget());
00163     if (!destWidget || !destWidget->parentWidget() || !destWidget->isVisible() ||
00164         !(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00165         d->disabled = true;
00166         hide();
00167         return;
00168     }
00169     setGeometry(QRect(destWidget->mapTo(parentWidget(), QPoint(0, 0)), destWidget->size()));
00170     d->oldPixmap = QPixmap::grabWidget(destWidget);
00171     d->timeLine.setFrameRange(0, 255);
00172     d->timeLine.setCurveShape(QTimeLine::EaseOutCurve);
00173     connect(&d->timeLine, SIGNAL(finished()), SLOT(finished()));
00174     connect(&d->timeLine, SIGNAL(frameChanged(int)), SLOT(repaint()));
00175     show();
00176 }
00177 
00178 KFadeWidgetEffect::~KFadeWidgetEffect()
00179 {
00180     delete d_ptr;
00181 }
00182 
00183 void KFadeWidgetEffectPrivate::finished()
00184 {
00185     Q_Q(KFadeWidgetEffect);
00186     destWidget->setUpdatesEnabled(false);
00187     q->hide();
00188     q->deleteLater();
00189     destWidget->setUpdatesEnabled(true);
00190 }
00191 
00192 void KFadeWidgetEffect::start(int duration)
00193 {
00194     Q_D(KFadeWidgetEffect);
00195     if (d->disabled) {
00196         deleteLater();
00197         return;
00198     }
00199     d->newPixmap = QPixmap::grabWidget(d->destWidget);
00200     d->timeLine.setDuration(duration);
00201     d->timeLine.start();
00202 }
00203 
00204 void KFadeWidgetEffect::paintEvent(QPaintEvent *)
00205 {
00206     Q_D(KFadeWidgetEffect);
00207     QPainter p(this);
00208     p.drawPixmap(rect(), d->transition(d->oldPixmap, d->newPixmap, d->timeLine.currentValue()));
00209     p.end();
00210 }
00211 
00212 #include "moc_kfadewidgeteffect.cpp"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal