Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qstyleanimation.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <qcoreapplication.h>
8#include <qwidget.h>
9#include <qevent.h>
10
12
13static const qreal ScrollBarFadeOutDuration = 200.0;
14static const qreal ScrollBarFadeOutDelay = 450.0;
15
16QStyleAnimation::QStyleAnimation(QObject *target) : QAbstractAnimation(target),
17 _delay(0), _duration(-1), _startTime(QTime::currentTime()), _fps(ThirtyFps), _skip(0)
18{
19}
20
21QStyleAnimation::~QStyleAnimation()
22{
23}
24
25QObject *QStyleAnimation::target() const
26{
27 return parent();
28}
29
30int QStyleAnimation::duration() const
31{
32 return _duration;
33}
34
35void QStyleAnimation::setDuration(int duration)
36{
37 _duration = duration;
38}
39
40int QStyleAnimation::delay() const
41{
42 return _delay;
43}
44
45void QStyleAnimation::setDelay(int delay)
46{
47 _delay = delay;
48}
49
50QTime QStyleAnimation::startTime() const
51{
52 return _startTime;
53}
54
55void QStyleAnimation::setStartTime(QTime time)
56{
57 _startTime = time;
58}
59
60QStyleAnimation::FrameRate QStyleAnimation::frameRate() const
61{
62 return _fps;
63}
64
65void QStyleAnimation::setFrameRate(FrameRate fps)
66{
67 _fps = fps;
68}
69
70void QStyleAnimation::updateTarget()
71{
72 QEvent event(QEvent::StyleAnimationUpdate);
73 event.setAccepted(false);
74 QCoreApplication::sendEvent(target(), &event);
75 if (!event.isAccepted())
76 stop();
77}
78
79void QStyleAnimation::start()
80{
81 _skip = 0;
82 QAbstractAnimation::start(DeleteWhenStopped);
83}
84
85bool QStyleAnimation::isUpdateNeeded() const
86{
87 return currentTime() > _delay;
88}
89
90void QStyleAnimation::updateCurrentTime(int time)
91{
92 if (++_skip >= _fps || time >= duration()) {
93 _skip = 0;
94 if (target() && isUpdateNeeded())
95 updateTarget();
96 }
97}
98
99QProgressStyleAnimation::QProgressStyleAnimation(int speed, QObject *target) :
100 QStyleAnimation(target), _speed(speed), _step(-1)
101{
102}
103
104int QProgressStyleAnimation::animationStep() const
105{
106 return currentTime() / (1000.0 / _speed);
107}
108
109int QProgressStyleAnimation::progressStep(int width) const
110{
111 int step = animationStep();
112 int progress = (step * width / _speed) % width;
113 if (((step * width / _speed) % (2 * width)) >= width)
114 progress = width - progress;
115 return progress;
116}
117
118int QProgressStyleAnimation::speed() const
119{
120 return _speed;
121}
122
123void QProgressStyleAnimation::setSpeed(int speed)
124{
125 _speed = speed;
126}
127
128bool QProgressStyleAnimation::isUpdateNeeded() const
129{
130 if (QStyleAnimation::isUpdateNeeded()) {
131 int current = animationStep();
132 if (_step == -1 || _step != current)
133 {
134 _step = current;
135 return true;
136 }
137 }
138 return false;
139}
140
141QNumberStyleAnimation::QNumberStyleAnimation(QObject *target) :
142 QStyleAnimation(target), _start(0.0), _end(1.0), _prev(0.0)
143{
144 setDuration(250);
145}
146
147qreal QNumberStyleAnimation::startValue() const
148{
149 return _start;
150}
151
152void QNumberStyleAnimation::setStartValue(qreal value)
153{
154 _start = value;
155}
156
157qreal QNumberStyleAnimation::endValue() const
158{
159 return _end;
160}
161
162void QNumberStyleAnimation::setEndValue(qreal value)
163{
164 _end = value;
165}
166
167qreal QNumberStyleAnimation::currentValue() const
168{
169 qreal step = qreal(currentTime() - delay()) / (duration() - delay());
170 return _start + qMax(qreal(0), step) * (_end - _start);
171}
172
173bool QNumberStyleAnimation::isUpdateNeeded() const
174{
175 if (QStyleAnimation::isUpdateNeeded()) {
176 qreal current = currentValue();
177 if (!qFuzzyCompare(_prev, current))
178 {
179 _prev = current;
180 return true;
181 }
182 }
183 return false;
184}
185
186QBlendStyleAnimation::QBlendStyleAnimation(Type type, QObject *target) :
187 QStyleAnimation(target), _type(type)
188{
189 setDuration(250);
190}
191
192QImage QBlendStyleAnimation::startImage() const
193{
194 return _start;
195}
196
197void QBlendStyleAnimation::setStartImage(const QImage& image)
198{
199 _start = image;
200}
201
202QImage QBlendStyleAnimation::endImage() const
203{
204 return _end;
205}
206
207void QBlendStyleAnimation::setEndImage(const QImage& image)
208{
209 _end = image;
210}
211
212QImage QBlendStyleAnimation::currentImage() const
213{
214 return _current;
215}
216
217/*! \internal
218
219 A helper function to blend two images.
220
221 The result consists of ((alpha)*startImage) + ((1-alpha)*endImage)
222
223*/
224static QImage blendedImage(const QImage &start, const QImage &end, float alpha)
225{
226 if (start.isNull() || end.isNull())
227 return QImage();
228
229 QImage blended;
230 const int a = qRound(alpha*256);
231 const int ia = 256 - a;
232 const int sw = start.width();
233 const int sh = start.height();
234 const qsizetype bpl = start.bytesPerLine();
235 switch (start.depth()) {
236 case 32:
237 {
238 blended = QImage(sw, sh, start.format());
239 blended.setDevicePixelRatio(start.devicePixelRatio());
240 uchar *mixed_data = blended.bits();
241 const uchar *back_data = start.bits();
242 const uchar *front_data = end.bits();
243 for (int sy = 0; sy < sh; sy++) {
244 quint32* mixed = (quint32*)mixed_data;
245 const quint32* back = (const quint32*)back_data;
246 const quint32* front = (const quint32*)front_data;
247 for (int sx = 0; sx < sw; sx++) {
248 quint32 bp = back[sx];
249 quint32 fp = front[sx];
250 mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
251 (qGreen(bp)*ia + qGreen(fp)*a)>>8,
252 (qBlue(bp)*ia + qBlue(fp)*a)>>8,
253 (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
254 }
255 mixed_data += bpl;
256 back_data += bpl;
257 front_data += bpl;
258 }
259 }
260 break;
261 default:
262 break;
263 }
264 return blended;
265}
266
267void QBlendStyleAnimation::updateCurrentTime(int time)
268{
269 QStyleAnimation::updateCurrentTime(time);
270
271 float alpha = 1.0;
272 if (duration() > 0) {
273 if (_type == Pulse) {
274 time = time % duration() * 2;
275 if (time > duration())
276 time = duration() * 2 - time;
277 }
278
279 alpha = time / static_cast<float>(duration());
280
281 if (_type == Transition && time > duration()) {
282 alpha = 1.0;
283 stop();
284 }
285 } else if (time > 0) {
286 stop();
287 }
288
289 _current = blendedImage(_start, _end, alpha);
290}
291
292QScrollbarStyleAnimation::QScrollbarStyleAnimation(Mode mode, QObject *target) : QNumberStyleAnimation(target), _mode(mode), _active(false)
293{
294 switch (mode) {
295 case Activating:
296 setDuration(ScrollBarFadeOutDuration);
297 setStartValue(0.0);
298 setEndValue(1.0);
299 break;
300 case Deactivating:
301 setDuration(ScrollBarFadeOutDelay + ScrollBarFadeOutDuration);
302 setDelay(ScrollBarFadeOutDelay);
303 setStartValue(1.0);
304 setEndValue(0.0);
305 break;
306 }
307}
308
309QScrollbarStyleAnimation::Mode QScrollbarStyleAnimation::mode() const
310{
311 return _mode;
312}
313
314bool QScrollbarStyleAnimation::wasActive() const
315{
316 return _active;
317}
318
319void QScrollbarStyleAnimation::setActive(bool active)
320{
321 _active = active;
322}
323
324void QScrollbarStyleAnimation::updateCurrentTime(int time)
325{
326 QNumberStyleAnimation::updateCurrentTime(time);
327 if (_mode == Deactivating && qFuzzyIsNull(currentValue()))
328 target()->setProperty("visible", false);
329}
330
331QT_END_NAMESPACE
332
333#include "moc_qstyleanimation_p.cpp"
\inmodule QtGui
Definition qimage.h:37
static QImage blendedImage(const QImage &start, const QImage &end, float alpha)
static const qreal ScrollBarFadeOutDelay
static QT_BEGIN_NAMESPACE const qreal ScrollBarFadeOutDuration