Warning, file /frameworks/kdelibs4support/src/kdeui/kfadewidgeteffect.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2008 Matthias Kretz <kretz@kde.org> 0003 Copyright (C) 2008 Rafael Fernández López <ereslibre@kde.org> 0004 0005 This program is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) version 3. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 0020 */ 0021 0022 #include "kfadewidgeteffect.h" 0023 #include "kfadewidgeteffect_p.h" 0024 0025 #include <QEvent> 0026 #include <QPaintEngine> 0027 #include <QPainter> 0028 #include <QStyle> 0029 0030 KFadeWidgetEffectPrivate::KFadeWidgetEffectPrivate(QWidget *_destWidget) 0031 : destWidget(_destWidget), disabled(false) 0032 { 0033 } 0034 0035 // Code from KFileItemDelegate (Author: Frederik Höglund) 0036 // Fast transitions. Read: 0037 // http://techbase.kde.org/Development/Tutorials/Graphics/Performance 0038 // for further information on why not use setOpacity. 0039 QPixmap KFadeWidgetEffectPrivate::transition(const QPixmap &from, const QPixmap &to, qreal amount) const 0040 { 0041 const int value = int(0xff * amount); 0042 0043 if (value == 0) { 0044 return from; 0045 } 0046 0047 if (value == 1) { 0048 return to; 0049 } 0050 0051 QColor color; 0052 color.setAlphaF(amount); 0053 0054 // If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus 0055 if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff) && 0056 from.paintEngine()->hasFeature(QPaintEngine::BlendModes)) { 0057 QPixmap under = from; 0058 QPixmap over = to; 0059 0060 QPainter p; 0061 p.begin(&over); 0062 p.setCompositionMode(QPainter::CompositionMode_DestinationIn); 0063 p.fillRect(over.rect(), color); 0064 p.end(); 0065 0066 p.begin(&under); 0067 p.setCompositionMode(QPainter::CompositionMode_DestinationOut); 0068 p.fillRect(under.rect(), color); 0069 p.setCompositionMode(QPainter::CompositionMode_Plus); 0070 p.drawPixmap(0, 0, over); 0071 p.end(); 0072 0073 return under; 0074 } else { 0075 // Fall back to using QRasterPaintEngine to do the transition. 0076 QImage under = from.toImage(); 0077 QImage over = to.toImage(); 0078 0079 QPainter p; 0080 p.begin(&over); 0081 p.setCompositionMode(QPainter::CompositionMode_DestinationIn); 0082 p.fillRect(over.rect(), color); 0083 p.end(); 0084 0085 p.begin(&under); 0086 p.setCompositionMode(QPainter::CompositionMode_DestinationOut); 0087 p.fillRect(under.rect(), color); 0088 p.setCompositionMode(QPainter::CompositionMode_Plus); 0089 p.drawImage(0, 0, over); 0090 p.end(); 0091 0092 return QPixmap::fromImage(under); 0093 } 0094 } 0095 0096 KFadeWidgetEffect::KFadeWidgetEffect(QWidget *destWidget) 0097 : QWidget(destWidget ? destWidget->parentWidget() : nullptr), 0098 d_ptr(new KFadeWidgetEffectPrivate(destWidget)) 0099 { 0100 Q_D(KFadeWidgetEffect); 0101 d->q_ptr = this; 0102 Q_ASSERT(destWidget && destWidget->parentWidget()); 0103 if (!destWidget || !destWidget->parentWidget() || !destWidget->isVisible() || 0104 !style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)) { 0105 d->disabled = true; 0106 hide(); 0107 return; 0108 } 0109 setGeometry(QRect(destWidget->mapTo(parentWidget(), QPoint(0, 0)), destWidget->size())); 0110 d->oldPixmap = destWidget->grab(); 0111 d->timeLine.setFrameRange(0, 255); 0112 d->timeLine.setCurveShape(QTimeLine::EaseOutCurve); 0113 connect(&d->timeLine, SIGNAL(finished()), SLOT(finished())); 0114 connect(&d->timeLine, SIGNAL(frameChanged(int)), SLOT(repaint())); 0115 show(); 0116 } 0117 0118 KFadeWidgetEffect::~KFadeWidgetEffect() 0119 { 0120 delete d_ptr; 0121 } 0122 0123 void KFadeWidgetEffectPrivate::finished() 0124 { 0125 Q_Q(KFadeWidgetEffect); 0126 destWidget->setUpdatesEnabled(false); 0127 q->hide(); 0128 q->deleteLater(); 0129 destWidget->setUpdatesEnabled(true); 0130 } 0131 0132 void KFadeWidgetEffect::start(int duration) 0133 { 0134 Q_D(KFadeWidgetEffect); 0135 if (d->disabled) { 0136 deleteLater(); 0137 return; 0138 } 0139 d->newPixmap = d->destWidget->grab(); 0140 d->timeLine.setDuration(duration); 0141 d->timeLine.start(); 0142 } 0143 0144 void KFadeWidgetEffect::paintEvent(QPaintEvent *) 0145 { 0146 Q_D(KFadeWidgetEffect); 0147 QPainter p(this); 0148 p.drawPixmap(rect(), d->transition(d->oldPixmap, d->newPixmap, d->timeLine.currentValue())); 0149 p.end(); 0150 } 0151 0152 #include "moc_kfadewidgeteffect.cpp"