]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistviewanimation.cpp
Port to QDebug*. KVBox--
[dolphin.git] / src / kitemviews / private / kitemlistviewanimation.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include "kitemlistviewanimation.h"
21
22 #include <kitemviews/kitemlistview.h>
23
24 #include <QDebug>
25 #include <KGlobalSettings>
26
27 #include <QGraphicsWidget>
28 #include <QPropertyAnimation>
29
30 KItemListViewAnimation::KItemListViewAnimation(QObject* parent) :
31 QObject(parent),
32 m_animationDuration(200),
33 m_scrollOrientation(Qt::Vertical),
34 m_scrollOffset(0),
35 m_animation()
36 {
37 if (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects) {
38 m_animationDuration = 1;
39 }
40 }
41
42 KItemListViewAnimation::~KItemListViewAnimation()
43 {
44 for (int type = 0; type < AnimationTypeCount; ++type) {
45 qDeleteAll(m_animation[type]);
46 }
47 }
48
49 void KItemListViewAnimation::setScrollOrientation(Qt::Orientation orientation)
50 {
51 m_scrollOrientation = orientation;
52 }
53
54 Qt::Orientation KItemListViewAnimation::scrollOrientation() const
55 {
56 return m_scrollOrientation;
57 }
58
59 void KItemListViewAnimation::setScrollOffset(qreal offset)
60 {
61 const qreal diff = m_scrollOffset - offset;
62 m_scrollOffset = offset;
63
64 // The change of the offset requires that the position of all
65 // animated QGraphicsWidgets get adjusted. An exception is made
66 // for the delete animation that should just fade away on the
67 // existing position.
68 for (int type = 0; type < AnimationTypeCount; ++type) {
69 if (type == DeleteAnimation) {
70 continue;
71 }
72
73 QHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]);
74 while (it.hasNext()) {
75 it.next();
76
77 QGraphicsWidget* widget = it.key();
78 QPropertyAnimation* propertyAnim = it.value();
79
80 QPointF currentPos = widget->pos();
81 if (m_scrollOrientation == Qt::Vertical) {
82 currentPos.ry() += diff;
83 } else {
84 currentPos.rx() += diff;
85 }
86
87 if (type == MovingAnimation) {
88 // Stop the animation, calculate the moved start- and end-value
89 // and restart the animation for the remaining duration.
90 const int remainingDuration = propertyAnim->duration()
91 - propertyAnim->currentTime();
92
93 const bool block = propertyAnim->signalsBlocked();
94 propertyAnim->blockSignals(true);
95 propertyAnim->stop();
96
97 QPointF endPos = propertyAnim->endValue().toPointF();
98 if (m_scrollOrientation == Qt::Vertical) {
99 endPos.ry() += diff;
100 } else {
101 endPos.rx() += diff;
102 }
103
104 propertyAnim->setDuration(remainingDuration);
105 propertyAnim->setStartValue(currentPos);
106 propertyAnim->setEndValue(endPos);
107 propertyAnim->start();
108 propertyAnim->blockSignals(block);
109 } else {
110 widget->setPos(currentPos);
111 }
112 }
113 }
114 }
115
116 qreal KItemListViewAnimation::scrollOffset() const
117 {
118 return m_scrollOffset;
119 }
120
121 void KItemListViewAnimation::start(QGraphicsWidget* widget, AnimationType type, const QVariant& endValue)
122 {
123 stop(widget, type);
124
125 QPropertyAnimation* propertyAnim = 0;
126
127 switch (type) {
128 case MovingAnimation: {
129 const QPointF newPos = endValue.toPointF();
130 if (newPos == widget->pos()) {
131 return;
132 }
133
134 propertyAnim = new QPropertyAnimation(widget, "pos");
135 propertyAnim->setDuration(m_animationDuration);
136 propertyAnim->setEndValue(newPos);
137 break;
138 }
139
140 case CreateAnimation: {
141 propertyAnim = new QPropertyAnimation(widget, "opacity");
142 propertyAnim->setEasingCurve(QEasingCurve::InQuart);
143 propertyAnim->setDuration(m_animationDuration);
144 propertyAnim->setStartValue(0.0);
145 propertyAnim->setEndValue(1.0);
146 break;
147 }
148
149 case DeleteAnimation: {
150 propertyAnim = new QPropertyAnimation(widget, "opacity");
151 propertyAnim->setEasingCurve(QEasingCurve::OutQuart);
152 propertyAnim->setDuration(m_animationDuration);
153 propertyAnim->setStartValue(1.0);
154 propertyAnim->setEndValue(0.0);
155 break;
156 }
157
158 case ResizeAnimation: {
159 const QSizeF newSize = endValue.toSizeF();
160 if (newSize == widget->size()) {
161 return;
162 }
163
164 propertyAnim = new QPropertyAnimation(widget, "size");
165 propertyAnim->setDuration(m_animationDuration);
166 propertyAnim->setEndValue(newSize);
167 break;
168 }
169
170 default:
171 break;
172 }
173
174 Q_ASSERT(propertyAnim);
175 connect(propertyAnim, &QPropertyAnimation::finished, this, &KItemListViewAnimation::slotFinished);
176 m_animation[type].insert(widget, propertyAnim);
177
178 propertyAnim->start();
179 }
180
181 void KItemListViewAnimation::stop(QGraphicsWidget* widget, AnimationType type)
182 {
183 QPropertyAnimation* propertyAnim = m_animation[type].value(widget);
184 if (propertyAnim) {
185 propertyAnim->stop();
186
187 switch (type) {
188 case MovingAnimation: break;
189 case CreateAnimation: widget->setOpacity(1.0); break;
190 case DeleteAnimation: widget->setOpacity(0.0); break;
191 case ResizeAnimation: break;
192 default: break;
193 }
194
195 m_animation[type].remove(widget);
196 delete propertyAnim;
197
198 emit finished(widget, type);
199 }
200 }
201
202 void KItemListViewAnimation::stop(QGraphicsWidget* widget)
203 {
204 for (int type = 0; type < AnimationTypeCount; ++type) {
205 stop(widget, static_cast<AnimationType>(type));
206 }
207 }
208
209 bool KItemListViewAnimation::isStarted(QGraphicsWidget *widget, AnimationType type) const
210 {
211 return m_animation[type].value(widget);
212 }
213
214 bool KItemListViewAnimation::isStarted(QGraphicsWidget* widget) const
215 {
216 for (int type = 0; type < AnimationTypeCount; ++type) {
217 if (isStarted(widget, static_cast<AnimationType>(type))) {
218 return true;
219 }
220 }
221 return false;
222 }
223
224 void KItemListViewAnimation::slotFinished()
225 {
226 QPropertyAnimation* finishedAnim = qobject_cast<QPropertyAnimation*>(sender());
227 for (int type = 0; type < AnimationTypeCount; ++type) {
228 QMutableHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]);
229 while (it.hasNext()) {
230 it.next();
231 QPropertyAnimation* propertyAnim = it.value();
232 if (propertyAnim == finishedAnim) {
233 QGraphicsWidget* widget = it.key();
234 it.remove();
235 finishedAnim->deleteLater();
236
237 emit finished(widget, static_cast<AnimationType>(type));
238 return;
239 }
240 }
241 }
242 Q_ASSERT(false);
243 }
244