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