KDELibs4Support

kfadewidgeteffect.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2008 Matthias Kretz <[email protected]>
3  Copyright (C) 2008 Rafael Fernández López <[email protected]>
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) version 3.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 
20 */
21 
22 #include "kfadewidgeteffect.h"
23 #include "kfadewidgeteffect_p.h"
24 
25 #include <QEvent>
26 #include <QPaintEngine>
27 #include <QPainter>
28 #include <QStyle>
29 
30 KFadeWidgetEffectPrivate::KFadeWidgetEffectPrivate(QWidget *_destWidget)
31  : destWidget(_destWidget), disabled(false)
32 {
33 }
34 
35 // Code from KFileItemDelegate (Author: Frederik Höglund)
36 // Fast transitions. Read:
37 // http://techbase.kde.org/Development/Tutorials/Graphics/Performance
38 // for further information on why not use setOpacity.
39 QPixmap KFadeWidgetEffectPrivate::transition(const QPixmap &from, const QPixmap &to, qreal amount) const
40 {
41  const int value = int(0xff * amount);
42 
43  if (value == 0) {
44  return from;
45  }
46 
47  if (value == 1) {
48  return to;
49  }
50 
51  QColor color;
52  color.setAlphaF(amount);
53 
54  // If the native paint engine supports Porter/Duff compositing and CompositionMode_Plus
57  QPixmap under = from;
58  QPixmap over = to;
59 
60  QPainter p;
61  p.begin(&over);
63  p.fillRect(over.rect(), color);
64  p.end();
65 
66  p.begin(&under);
68  p.fillRect(under.rect(), color);
70  p.drawPixmap(0, 0, over);
71  p.end();
72 
73  return under;
74  } else {
75  // Fall back to using QRasterPaintEngine to do the transition.
76  QImage under = from.toImage();
77  QImage over = to.toImage();
78 
79  QPainter p;
80  p.begin(&over);
82  p.fillRect(over.rect(), color);
83  p.end();
84 
85  p.begin(&under);
87  p.fillRect(under.rect(), color);
89  p.drawImage(0, 0, over);
90  p.end();
91 
92  return QPixmap::fromImage(under);
93  }
94 }
95 
97  : QWidget(destWidget ? destWidget->parentWidget() : nullptr),
98  d_ptr(new KFadeWidgetEffectPrivate(destWidget))
99 {
100  Q_D(KFadeWidgetEffect);
101  d->q_ptr = this;
102  Q_ASSERT(destWidget && destWidget->parentWidget());
103  if (!destWidget || !destWidget->parentWidget() || !destWidget->isVisible() ||
104  !style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)) {
105  d->disabled = true;
106  hide();
107  return;
108  }
109  setGeometry(QRect(destWidget->mapTo(parentWidget(), QPoint(0, 0)), destWidget->size()));
110  d->oldPixmap = QPixmap::grabWidget(destWidget);
111  d->timeLine.setFrameRange(0, 255);
112  d->timeLine.setCurveShape(QTimeLine::EaseOutCurve);
113  connect(&d->timeLine, SIGNAL(finished()), SLOT(finished()));
114  connect(&d->timeLine, SIGNAL(frameChanged(int)), SLOT(repaint()));
115  show();
116 }
117 
119 {
120  delete d_ptr;
121 }
122 
123 void KFadeWidgetEffectPrivate::finished()
124 {
125  Q_Q(KFadeWidgetEffect);
126  destWidget->setUpdatesEnabled(false);
127  q->hide();
128  q->deleteLater();
129  destWidget->setUpdatesEnabled(true);
130 }
131 
132 void KFadeWidgetEffect::start(int duration)
133 {
134  Q_D(KFadeWidgetEffect);
135  if (d->disabled) {
136  deleteLater();
137  return;
138  }
139  d->newPixmap = QPixmap::grabWidget(d->destWidget);
140  d->timeLine.setDuration(duration);
141  d->timeLine.start();
142 }
143 
145 {
146  Q_D(KFadeWidgetEffect);
147  QPainter p(this);
148  p.drawPixmap(rect(), d->transition(d->oldPixmap, d->newPixmap, d->timeLine.currentValue()));
149  p.end();
150 }
151 
152 #include "moc_kfadewidgeteffect.cpp"
void paintEvent(QPaintEvent *) override
KFadeWidgetEffect(QWidget *destWidget)
Create the animation widget.
bool end()
void fillRect(const QRectF &rectangle, const QBrush &brush)
void setCompositionMode(QPainter::CompositionMode mode)
QPixmap grabWidget(QObject *widget, const QRect &rectangle)
QStyle * style() const const
bool isVisible() const const
SH_Widget_Animate
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
virtual QPaintEngine * paintEngine() const const =0
Animates changes fading the new UI over the old look.
void start(int duration=250)
Starts the animation.
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
QRect rect() const const
virtual int styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const const =0
void deleteLater()
void hide()
QRect rect() const const
CompositionMode_DestinationIn
void repaint()
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
QPoint mapTo(const QWidget *parent, const QPoint &pos) const const
QWidget * parentWidget() const const
KFadeWidgetEffectPrivate *const d_ptr
void setAlphaF(qreal alpha)
~KFadeWidgetEffect()
Destructor.
bool hasFeature(QPaintEngine::PaintEngineFeatures feature) const const
void show()
QImage toImage() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool begin(QPaintDevice *device)
QRect rect() const const
void setGeometry(int x, int y, int w, int h)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Thu Jul 9 2020 22:57:48 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.