]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistsmoothscroller.cpp
Remove dead code
[dolphin.git] / src / kitemviews / private / kitemlistsmoothscroller.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 "kitemlistsmoothscroller.h"
8
9 #include <KConfigGroup>
10 #include <KSharedConfig>
11
12 #include <QApplication>
13 #include <QDBusConnection>
14 #include <QPropertyAnimation>
15 #include <QScrollBar>
16 #include <QStyle>
17 #include <QWheelEvent>
18
19 KItemListSmoothScroller::KItemListSmoothScroller(QScrollBar *scrollBar, QObject *parent)
20 : QObject(parent)
21 , m_scrollBarPressed(false)
22 , m_smoothScrolling(true)
23 , m_scrollBar(scrollBar)
24 , m_animation(nullptr)
25 {
26 m_animation = new QPropertyAnimation(this);
27
28 KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::IncludeGlobals);
29 KConfigGroup configGroup(globalConfig, QStringLiteral("KDE"));
30 updateAnimationDuration(configGroup.readEntry("SmoothScroll", true));
31
32 QDBusConnection::sessionBus().connect(QStringLiteral(""),
33 QStringLiteral("/SmoothScroll"),
34 QStringLiteral("org.kde.SmoothScroll"),
35 QStringLiteral("notifyChange"),
36 this,
37 SLOT(updateAnimationDuration(bool)));
38 connect(m_animation, &QPropertyAnimation::stateChanged, this, &KItemListSmoothScroller::slotAnimationStateChanged);
39
40 m_scrollBar->installEventFilter(this);
41 }
42
43 KItemListSmoothScroller::~KItemListSmoothScroller()
44 {
45 }
46
47 void KItemListSmoothScroller::setScrollBar(QScrollBar *scrollBar)
48 {
49 m_scrollBar = scrollBar;
50 }
51
52 QScrollBar *KItemListSmoothScroller::scrollBar() const
53 {
54 return m_scrollBar;
55 }
56
57 void KItemListSmoothScroller::setTargetObject(QObject *target)
58 {
59 m_animation->setTargetObject(target);
60 }
61
62 QObject *KItemListSmoothScroller::targetObject() const
63 {
64 return m_animation->targetObject();
65 }
66
67 void KItemListSmoothScroller::setPropertyName(const QByteArray &propertyName)
68 {
69 m_animation->setPropertyName(propertyName);
70 }
71
72 QByteArray KItemListSmoothScroller::propertyName() const
73 {
74 return m_animation->propertyName();
75 }
76
77 void KItemListSmoothScroller::scrollContentsBy(qreal distance)
78 {
79 QObject *target = targetObject();
80 if (!target) {
81 return;
82 }
83
84 const QByteArray name = propertyName();
85 const qreal currentOffset = target->property(name).toReal();
86 if (static_cast<int>(currentOffset) == m_scrollBar->value()) {
87 // The current offset is already synchronous to the scrollbar
88 return;
89 }
90
91 const bool animRunning = (m_animation->state() == QAbstractAnimation::Running);
92 if (animRunning) {
93 // Stopping a running animation means skipping the range from the current offset
94 // until the target offset. To prevent skipping of the range the difference
95 // is added to the new target offset.
96 const qreal oldEndOffset = m_animation->endValue().toReal();
97 distance += (currentOffset - oldEndOffset);
98 }
99
100 const qreal endOffset = currentOffset - distance;
101 if (m_smoothScrolling || animRunning) {
102 qreal startOffset = currentOffset;
103 if (animRunning) {
104 // If the animation was running and has been interrupted by assigning a new end-offset
105 // one frame must be added to the start-offset to keep the animation smooth. This also
106 // assures that animation proceeds even in cases where new end-offset are triggered
107 // within a very short timeslots.
108 startOffset += (endOffset - currentOffset) * 1000 / (m_animation->duration() * 60);
109 if (currentOffset < endOffset) {
110 startOffset = qMin(startOffset, endOffset);
111 } else {
112 startOffset = qMax(startOffset, endOffset);
113 }
114 }
115
116 m_animation->stop();
117 m_animation->setStartValue(startOffset);
118 m_animation->setEndValue(endOffset);
119 m_animation->setEasingCurve(animRunning ? QEasingCurve::OutQuad : QEasingCurve::InOutQuad);
120 m_animation->start();
121 target->setProperty(name, startOffset);
122 } else {
123 target->setProperty(name, endOffset);
124 }
125 }
126
127 void KItemListSmoothScroller::scrollTo(qreal position)
128 {
129 int newValue = position;
130 newValue = qBound(0, newValue, m_scrollBar->maximum());
131
132 if (newValue != m_scrollBar->value()) {
133 m_smoothScrolling = true;
134 m_scrollBar->setValue(newValue);
135 }
136 }
137
138 bool KItemListSmoothScroller::requestScrollBarUpdate(int newMaximum)
139 {
140 if (m_animation->state() == QAbstractAnimation::Running) {
141 if (newMaximum == m_scrollBar->maximum()) {
142 // The value has been changed by the animation, no update
143 // of the scrollbars is required as their target state will be
144 // reached with the end of the animation.
145 return false;
146 }
147
148 // The maximum has been changed which indicates that the content
149 // of the view has been changed. Stop the animation in any case and
150 // update the scrollbars immediately.
151 m_animation->stop();
152 }
153 return true;
154 }
155
156 bool KItemListSmoothScroller::eventFilter(QObject *obj, QEvent *event)
157 {
158 Q_ASSERT(obj == m_scrollBar);
159
160 switch (event->type()) {
161 case QEvent::MouseButtonPress:
162 m_scrollBarPressed = true;
163 m_smoothScrolling = true;
164 break;
165
166 case QEvent::MouseButtonRelease:
167 m_scrollBarPressed = false;
168 m_smoothScrolling = false;
169 break;
170
171 case QEvent::Wheel:
172 return false; // we're the ones sending them
173
174 default:
175 break;
176 }
177
178 return QObject::eventFilter(obj, event);
179 }
180
181 void KItemListSmoothScroller::slotAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
182 {
183 Q_UNUSED(oldState)
184 if (newState == QAbstractAnimation::Stopped && m_smoothScrolling && !m_scrollBarPressed) {
185 m_smoothScrolling = false;
186 }
187 if (newState == QAbstractAnimation::Stopped) {
188 Q_EMIT scrollingStopped();
189 }
190 }
191
192 void KItemListSmoothScroller::updateAnimationDuration(bool isSmoothScrollingEnabled)
193 {
194 if (isSmoothScrollingEnabled) {
195 // Breeze sets SH_Widget_Animation_Duration from the KDE global animation speed setting
196 const int animationDuration = m_scrollBar->style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, m_scrollBar);
197 const bool animationEnabled = (animationDuration > 0);
198 m_animation->setDuration(animationEnabled ? animationDuration : 1);
199 } else {
200 m_animation->setDuration(1);
201 }
202 }
203
204 void KItemListSmoothScroller::handleWheelEvent(QWheelEvent *event)
205 {
206 const bool previous = m_smoothScrolling;
207
208 m_smoothScrolling = true;
209
210 QWheelEvent *copy = event->clone();
211 QApplication::sendEvent(m_scrollBar, copy);
212 event->setAccepted(copy->isAccepted());
213
214 m_smoothScrolling = previous;
215 }
216
217 #include "moc_kitemlistsmoothscroller.cpp"