##// END OF EJS Templates
accurate speed calculation to kinetic scrolling
sauimone -
r2190:2e3db467e0a5
parent child
Show More
@@ -1,159 +1,163
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "scroller_p.h"
22 22 #include "qlegend.h"
23 23 #include <QGraphicsSceneMouseEvent>
24 24 #include <QDebug>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 Scroller::Scroller()
29 29 : m_ticker(this),
30 30 m_timeTresholdMin(50),
31 31 m_timeTresholdMax(300),
32 32 m_state(Idle)
33 33 {
34 34
35 35 }
36 36
37 37 Scroller::~Scroller()
38 38 {
39 39 }
40 40
41 41 void Scroller::move(const QPointF &delta)
42 42 {
43 43 switch (m_state) {
44 44 case Idle:
45 45 m_timeStamp = QTime::currentTime();
46 46 m_state = Move;
47 47 break;
48 48 case Scroll:
49 49 stopTicker();
50 50 m_timeStamp = QTime::currentTime();
51 51 m_state = Move;
52 52 break;
53 53 default:
54 54 break;
55 55 }
56 56 setOffset(offset() - delta);
57 57 }
58 58
59 59 void Scroller::release(const QPointF &delta)
60 60 {
61 61 // Starts scrolling, if at least m_timeTresholdMin msecs has gone since timestamp
62 62 // current time is no more than m_timeTresholdMax from timestamp
63 63
64 64 if ((m_timeStamp.elapsed() > m_timeTresholdMin) && (m_timeStamp.msecsTo(QTime::currentTime()) < m_timeTresholdMax)) {
65 65 // Release was quick enough. Start scrolling.
66 // Magic number is to make scroll bit slower (the resolution of screen may affect this)
67 m_speed = delta / 5;
66 qreal interval = 25;
67 qreal time = m_timeStamp.msecsTo(QTime::currentTime());
68 if (qFuzzyIsNull(time))
69 m_speed = delta / 5;
70 else
71 m_speed = delta * interval / time;
68 72
69 73 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
70 74
71 75 if (!qFuzzyIsNull(fraction)) {
72 76 m_fraction.setX(qAbs(m_speed.x() / fraction));
73 77 m_fraction.setY(qAbs(m_speed.y() / fraction));
74 78 } else {
75 79 m_fraction.setX(1);
76 80 m_fraction.setY(1);
77 81 }
78 startTicker(25);
82 startTicker(interval);
79 83 m_state = Scroll;
80 84 } else {
81 85 stopTicker(); // Stop ticker, if one is running.
82 86 m_state = Idle;
83 87 }
84 88 }
85 89
86 90 void Scroller::startTicker(int interval)
87 91 {
88 92 m_state = Scroll;
89 93 m_ticker.start(interval);
90 94 }
91 95
92 96 void Scroller::stopTicker()
93 97 {
94 98 m_state = Idle;
95 99 m_ticker.stop();
96 100 }
97 101
98 102 void Scroller::scrollTick()
99 103 {
100 104 switch (m_state) {
101 105 case Scroll:
102 106 lowerSpeed(m_speed);
103 107 setOffset(offset() - m_speed);
104 108 if (m_speed == QPointF(0, 0)) {
105 109 m_state = Idle;
106 110 m_ticker.stop();
107 111 }
108 112 break;
109 113 case Idle:
110 114 case Move:
111 115 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
112 116 m_ticker.stop();
113 117 m_state = Idle;
114 118 break;
115 119 }
116 120 }
117 121
118 122 void Scroller::lowerSpeed(QPointF &speed, qreal maxSpeed)
119 123 {
120 124 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
121 125 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
122 126
123 127 x = (x == 0) ? x :
124 128 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
125 129 y = (y == 0) ? y :
126 130 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
127 131 speed.setX(x);
128 132 speed.setY(y);
129 133 }
130 134
131 135 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
132 136
133 137 ScrollTicker::ScrollTicker(Scroller *scroller, QObject *parent)
134 138 : QObject(parent),
135 139 m_scroller(scroller)
136 140 {
137 141
138 142 }
139 143
140 144 void ScrollTicker::start(int interval)
141 145 {
142 146 if (!m_timer.isActive())
143 147 m_timer.start(interval, this);
144 148 }
145 149
146 150 void ScrollTicker::stop()
147 151 {
148 152 m_timer.stop();
149 153 }
150 154
151 155 void ScrollTicker::timerEvent(QTimerEvent *event)
152 156 {
153 157 Q_UNUSED(event);
154 158 m_scroller->scrollTick();
155 159 }
156 160
157 161 #include "moc_scroller_p.cpp"
158 162
159 163 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now