]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistviewanimation.cpp
ccc387529b994e29bd85d0163cf042c09c216753
[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 #include "kitemviews/kitemlistview.h"
22
23 #include <QPropertyAnimation>
24
25 KItemListViewAnimation::KItemListViewAnimation(QObject* parent) :
26 QObject(parent),
27 m_scrollOrientation(Qt::Vertical),
28 m_scrollOffset(0),
29 m_animation()
30 {
31 }
32
33 KItemListViewAnimation::~KItemListViewAnimation()
34 {
35 for (int type = 0; type < AnimationTypeCount; ++type) {
36 qDeleteAll(m_animation[type]);
37 }
38 }
39
40 void KItemListViewAnimation::setScrollOrientation(Qt::Orientation orientation)
41 {
42 m_scrollOrientation = orientation;
43 }
44
45 Qt::Orientation KItemListViewAnimation::scrollOrientation() const
46 {
47 return m_scrollOrientation;
48 }
49
50 void KItemListViewAnimation::setScrollOffset(qreal offset)
51 {
52 const qreal diff = m_scrollOffset - offset;
53 m_scrollOffset = offset;
54
55 // The change of the offset requires that the position of all
56 // animated QGraphicsWidgets get adjusted. An exception is made
57 // for the delete animation that should just fade away on the
58 // existing position.
59 for (int type = 0; type < AnimationTypeCount; ++type) {
60 if (type == DeleteAnimation) {
61 continue;
62 }
63
64 QHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]);
65 while (it.hasNext()) {
66 it.next();
67
68 QGraphicsWidget* widget = it.key();
69 QPropertyAnimation* propertyAnim = it.value();
70
71 QPointF currentPos = widget->pos();
72 if (m_scrollOrientation == Qt::Vertical) {
73 currentPos.ry() += diff;
74 } else {
75 currentPos.rx() += diff;
76 }
77
78 if (type == MovingAnimation) {
79 // Stop the animation, calculate the moved start- and end-value
80 // and restart the animation for the remaining duration.
81 const int remainingDuration = propertyAnim->duration()
82 - propertyAnim->currentTime();
83
84 const bool block = propertyAnim->signalsBlocked();
85 propertyAnim->blockSignals(true);
86 propertyAnim->stop();
87
88 QPointF endPos = propertyAnim->endValue().toPointF();
89 if (m_scrollOrientation == Qt::Vertical) {
90 endPos.ry() += diff;
91 } else {
92 endPos.rx() += diff;
93 }
94
95 propertyAnim->setDuration(remainingDuration);
96 propertyAnim->setStartValue(currentPos);
97 propertyAnim->setEndValue(endPos);
98 propertyAnim->start();
99 propertyAnim->blockSignals(block);
100 } else {
101 widget->setPos(currentPos);
102 }
103 }
104 }
105 }
106
107 qreal KItemListViewAnimation::scrollOffset() const
108 {
109 return m_scrollOffset;
110 }
111
112 void KItemListViewAnimation::start(QGraphicsWidget* widget, AnimationType type, const QVariant& endValue)
113 {
114 stop(widget, type);
115
116 QPropertyAnimation* propertyAnim = nullptr;
117 const int animationDuration = widget->style()->styleHint(QStyle::SH_Widget_Animate) ? 200 : 1;
118
119 switch (type) {
120 case MovingAnimation: {
121 const QPointF newPos = endValue.toPointF();
122 if (newPos == widget->pos()) {
123 return;
124 }
125
126 propertyAnim = new QPropertyAnimation(widget, "pos");
127 propertyAnim->setDuration(animationDuration);
128 propertyAnim->setEndValue(newPos);
129 break;
130 }
131
132 case CreateAnimation: {
133 propertyAnim = new QPropertyAnimation(widget, "opacity");
134 propertyAnim->setEasingCurve(QEasingCurve::InQuart);
135 propertyAnim->setDuration(animationDuration);
136 propertyAnim->setStartValue(0.0);
137 propertyAnim->setEndValue(1.0);
138 break;
139 }
140
141 case DeleteAnimation: {
142 propertyAnim = new QPropertyAnimation(widget, "opacity");
143 propertyAnim->setEasingCurve(QEasingCurve::OutQuart);
144 propertyAnim->setDuration(animationDuration);
145 propertyAnim->setStartValue(1.0);
146 propertyAnim->setEndValue(0.0);
147 break;
148 }
149
150 case ResizeAnimation: {
151 const QSizeF newSize = endValue.toSizeF();
152 if (newSize == widget->size()) {
153 return;
154 }
155
156 propertyAnim = new QPropertyAnimation(widget, "size");
157 propertyAnim->setDuration(animationDuration);
158 propertyAnim->setEndValue(newSize);
159 break;
160 }
161
162 default:
163 break;
164 }
165
166 Q_ASSERT(propertyAnim);
167 connect(propertyAnim, &QPropertyAnimation::finished, this, &KItemListViewAnimation::slotFinished);
168 m_animation[type].insert(widget, propertyAnim);
169
170 propertyAnim->start();
171 }
172
173 void KItemListViewAnimation::stop(QGraphicsWidget* widget, AnimationType type)
174 {
175 QPropertyAnimation* propertyAnim = m_animation[type].value(widget);
176 if (propertyAnim) {
177 propertyAnim->stop();
178
179 switch (type) {
180 case MovingAnimation: break;
181 case CreateAnimation: widget->setOpacity(1.0); break;
182 case DeleteAnimation: widget->setOpacity(0.0); break;
183 case ResizeAnimation: break;
184 default: break;
185 }
186
187 m_animation[type].remove(widget);
188 delete propertyAnim;
189
190 emit finished(widget, type);
191 }
192 }
193
194 void KItemListViewAnimation::stop(QGraphicsWidget* widget)
195 {
196 for (int type = 0; type < AnimationTypeCount; ++type) {
197 stop(widget, static_cast<AnimationType>(type));
198 }
199 }
200
201 bool KItemListViewAnimation::isStarted(QGraphicsWidget *widget, AnimationType type) const
202 {
203 return m_animation[type].value(widget);
204 }
205
206 bool KItemListViewAnimation::isStarted(QGraphicsWidget* widget) const
207 {
208 for (int type = 0; type < AnimationTypeCount; ++type) {
209 if (isStarted(widget, static_cast<AnimationType>(type))) {
210 return true;
211 }
212 }
213 return false;
214 }
215
216 void KItemListViewAnimation::slotFinished()
217 {
218 QPropertyAnimation* finishedAnim = qobject_cast<QPropertyAnimation*>(sender());
219 for (int type = 0; type < AnimationTypeCount; ++type) {
220 QMutableHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]);
221 while (it.hasNext()) {
222 it.next();
223 QPropertyAnimation* propertyAnim = it.value();
224 if (propertyAnim == finishedAnim) {
225 QGraphicsWidget* widget = it.key();
226 it.remove();
227 finishedAnim->deleteLater();
228
229 emit finished(widget, static_cast<AnimationType>(type));
230 return;
231 }
232 }
233 }
234 Q_ASSERT(false);
235 }
236