##// END OF EJS Templates
moving mouse event handling logic to scroller
sauimone -
r2199:07ffd59c3233
parent child
Show More
@@ -1,127 +1,74
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 <QDebug>
22 22 #include <QGraphicsSceneMouseEvent>
23 23 #include <QGraphicsScene>
24 24 #include <QLegendMarker>
25 25 #include "qlegendmarker_p.h"
26 26 #include "legendmarkeritem_p.h"
27 27 #include "legendscroller_p.h"
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 LegendScroller::LegendScroller(QChart *chart) : QLegend(chart),
32 m_lastPos(0, 0),
33 m_state(Idle),
34 m_treshold(10)
31 LegendScroller::LegendScroller(QChart *chart) : QLegend(chart)
35 32 {
36 33 }
37 34
38 35 void LegendScroller::setOffset(const QPointF &point)
39 36 {
40 37 d_ptr->setOffset(point);
41 38 }
42 39
43 40 QPointF LegendScroller::offset() const
44 41 {
45 42 return d_ptr->offset();
46 43 }
47 44
48 void LegendScroller::setMoveTreshold(qreal treshold)
49 {
50 m_treshold = treshold;
51 }
52
53 45 void LegendScroller::mousePressEvent(QGraphicsSceneMouseEvent *event)
54 46 {
55 m_pressPos = event->screenPos();
56 m_lastPos = m_pressPos;
57 m_state = Pressed;
58 event->accept();
47 Scroller::handleMousePressEvent(event);
59 48 }
60 49
61 50 void LegendScroller::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
62 51 {
63 QPointF delta = event->screenPos() - m_lastPos;
64
65 switch (m_state) {
66 case Pressed: {
67 // calculate treshold. If enough, change to move state and send out move deltas.
68 if (qAbs(delta.x()) > m_treshold || qAbs(delta.y()) > m_treshold) {
69 m_state = Moved;
70 m_lastPos = event->screenPos();
71 move(delta);
72 }
73 event->accept();
74 break;
75 }
76 case Moved: {
77 m_lastPos = event->screenPos();
78 move(delta);
79 event->accept();
80 break;
81 }
82 case Idle:
83 default: {
84 event->ignore();
85 break;
86 }
87 }
52 Scroller::handleMouseMoveEvent(event);
88 53 }
89 54
90 55 void LegendScroller::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
91 56 {
92 m_lastPos = event->screenPos();
57 Scroller::handleMouseReleaseEvent(event);
93 58
94 switch (m_state) {
95 case Pressed:
96 {
97 m_state = Idle;
59 if (!event->isAccepted()) {
98 60 QList<QGraphicsItem *> items = scene()->items(event->scenePos());
99 61
100 62 foreach (QGraphicsItem *i, items) {
101 63 if (d_ptr->m_markerHash.contains(i)) {
102 64 QLegendMarker *marker = d_ptr->m_markerHash.value(i);
103 65 emit marker->clicked();
104 66 }
105 67 }
106
107 event->accept();
108 break;
109 }
110 case Moved:
111 {
112 scrollTo(m_lastPos - m_pressPos);
113 event->accept();
114 break;
115 }
116 default:
117 {
118 m_state = Idle;
119 event->ignore();
120 break;
121 }
68 event->accept();
122 69 }
123 70 }
124 71
125 72
126 73 #include "moc_legendscroller_p.cpp"
127 74 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,73 +1,57
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30
31 31 #ifndef LEGENDSCROLLER_P_H
32 32 #define LEGENDSCROLLER_P_H
33 33
34 34 #include "qlegend.h"
35 35 #include "qlegend_p.h"
36 36 #include "scroller_p.h"
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class LegendScroller: public QLegend, public Scroller
41 41 {
42 42 Q_OBJECT
43 43
44 44 public:
45 45 LegendScroller(QChart *chart);
46 46
47 47 void setOffset(const QPointF &point);
48 48 QPointF offset() const;
49 49
50 void setMoveTreshold(qreal treshold);
51
52 50 void mousePressEvent(QGraphicsSceneMouseEvent *event);
53 51 void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
54 52 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
55
56 private:
57
58 enum State {
59 Idle,
60 Pressed,
61 Moved,
62 Released
63 };
64
65 QPointF m_pressPos;
66 QPointF m_lastPos;
67 State m_state;
68 qreal m_treshold;
69 53 };
70 54
71 55 QTCOMMERCIALCHART_END_NAMESPACE
72 56
73 57 #endif
@@ -1,162 +1,216
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 m_state(Idle)
32 m_state(Idle),
33 m_treshold(10)
33 34 {
34 35
35 36 }
36 37
37 38 Scroller::~Scroller()
38 39 {
39 40 }
40 41
41 42 void Scroller::move(const QPointF &delta)
42 43 {
43 44 switch (m_state) {
44 case Idle:
45 case Pressed:
45 46 m_timeStamp = QTime::currentTime();
46 m_state = Move;
47 47 break;
48 48 case Scroll:
49 49 stopTicker();
50 50 m_timeStamp = QTime::currentTime();
51 m_state = Move;
52 51 break;
53 52 default:
54 53 break;
55 54 }
56 55 setOffset(offset() - delta);
57 56 }
58 57
59 58 void Scroller::scrollTo(const QPointF &delta)
60 59 {
61 60 // Starts scrolling, if at least m_timeTresholdMin msecs has gone since timestamp
62 61 // current time is no more than m_timeTresholdMax from timestamp
63 62
64 63 if ((m_timeStamp.elapsed() > m_timeTresholdMin) && (m_timeStamp.msecsTo(QTime::currentTime()) < m_timeTresholdMax)) {
65 64 // Release was quick enough. Start scrolling.
66 65 qreal interval = 25;
67 66 qreal time = m_timeStamp.msecsTo(QTime::currentTime());
68 67 if (qFuzzyIsNull(time)) {
69 68 m_speed = delta / 5;
70 69 } else {
71 70 m_speed = delta * interval / time;
72 71 }
73 72
74 73 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
75 74
76 75 if (!qFuzzyIsNull(fraction)) {
77 76 m_fraction.setX(qAbs(m_speed.x() / fraction));
78 77 m_fraction.setY(qAbs(m_speed.y() / fraction));
79 78 } else {
80 79 m_fraction.setX(1);
81 80 m_fraction.setY(1);
82 81 }
83 82 startTicker(interval);
84 83 } else {
85 84 stopTicker(); // Stop ticker, if one is running.
86 85 }
87 86 }
88 87
88 void Scroller::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
89 {
90 stopTicker();
91 m_pressPos = event->screenPos();
92 m_lastPos = m_pressPos;
93 m_state = Pressed;
94 event->accept();
95 }
96
97 void Scroller::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
98 {
99 QPointF delta = event->screenPos() - m_lastPos;
100
101 switch (m_state) {
102 case Pressed: {
103 // calculate treshold. If enough, change to move state and send out move deltas.
104 if (qAbs(delta.x()) > m_treshold || qAbs(delta.y()) > m_treshold) {
105 m_lastPos = event->screenPos();
106 move(delta);
107 m_state = Move;
108 }
109 event->accept();
110 break;
111 }
112 case Move: {
113 m_lastPos = event->screenPos();
114 move(delta);
115 event->accept();
116 break;
117 }
118 case Idle:
119 default: {
120 event->ignore();
121 break;
122 }
123 }
124 }
125
126 void Scroller::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
127 {
128 switch (m_state) {
129 case Move:
130 {
131 scrollTo(m_lastPos - m_pressPos);
132 event->accept();
133 break;
134 }
135 default:
136 {
137 m_state = Idle;
138 event->ignore();
139 break;
140 }
141 }
142 }
143
89 144 void Scroller::startTicker(int interval)
90 145 {
91 146 m_state = Scroll;
92 147 m_ticker.start(interval);
93 148 }
94 149
95 150 void Scroller::stopTicker()
96 151 {
97 152 m_state = Idle;
98 153 m_ticker.stop();
99 154 }
100 155
101 156 void Scroller::scrollTick()
102 157 {
103 158 switch (m_state) {
104 159 case Scroll:
105 160 lowerSpeed(m_speed);
106 161 setOffset(offset() - m_speed);
107 162 if (m_speed == QPointF(0, 0)) {
108 163 m_state = Idle;
109 164 m_ticker.stop();
110 165 }
111 166 break;
112 case Idle:
113 case Move:
167 default:
114 168 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
115 169 m_ticker.stop();
116 170 m_state = Idle;
117 171 break;
118 172 }
119 173 }
120 174
121 175 void Scroller::lowerSpeed(QPointF &speed, qreal maxSpeed)
122 176 {
123 177 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
124 178 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
125 179
126 180 x = (x == 0) ? x :
127 181 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
128 182 y = (y == 0) ? y :
129 183 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
130 184 speed.setX(x);
131 185 speed.setY(y);
132 186 }
133 187
134 188 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
135 189
136 190 ScrollTicker::ScrollTicker(Scroller *scroller, QObject *parent)
137 191 : QObject(parent),
138 192 m_scroller(scroller)
139 193 {
140 194
141 195 }
142 196
143 197 void ScrollTicker::start(int interval)
144 198 {
145 199 if (!m_timer.isActive())
146 200 m_timer.start(interval, this);
147 201 }
148 202
149 203 void ScrollTicker::stop()
150 204 {
151 205 m_timer.stop();
152 206 }
153 207
154 208 void ScrollTicker::timerEvent(QTimerEvent *event)
155 209 {
156 210 Q_UNUSED(event);
157 211 m_scroller->scrollTick();
158 212 }
159 213
160 214 #include "moc_scroller_p.cpp"
161 215
162 216 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,101 +1,109
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef SCROLLER_P_H
31 31 #define SCROLLER_P_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QBasicTimer>
35 35 #include <QTime>
36 36 #include <QPointF>
37 37
38 38 class QGraphicsSceneMouseEvent;
39 39
40 40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 41
42 42 class Scroller;
43 43 class QLegend;
44 44
45 45 class ScrollTicker : public QObject
46 46 {
47 47 Q_OBJECT
48 48 public:
49 49 explicit ScrollTicker(Scroller *scroller, QObject *parent = 0);
50 50 void start(int interval);
51 51 void stop();
52 52 protected:
53 53 void timerEvent(QTimerEvent *event);
54 54
55 55 private:
56 56 QBasicTimer m_timer;
57 57 Scroller *m_scroller;
58 58 };
59 59
60 60 class Scroller
61 61 {
62 62 public:
63 63 enum State {
64 64 Idle,
65 Pressed,
65 66 Move,
66 67 Scroll
67 68 };
68 69
69 70 Scroller();
70 71 virtual ~Scroller();
71 72
72 73 virtual void setOffset(const QPointF &point) = 0;
73 74 virtual QPointF offset() const = 0;
74 75
75 76 void move(const QPointF &delta);
76 77 void scrollTo(const QPointF &delta);
77 78
79 void handleMousePressEvent(QGraphicsSceneMouseEvent *event);
80 void handleMouseMoveEvent(QGraphicsSceneMouseEvent *event);
81 void handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event);
82
78 83 void scrollTick();
79 84
80 85 private:
81 86 void startTicker(int interval);
82 87 void stopTicker();
83 88
84 89 private:
85 90 void calculateSpeed(const QPointF &position);
86 91 void lowerSpeed(QPointF &speed, qreal maxSpeed = 100);
87 92
88 93 private:
89 94 ScrollTicker m_ticker;
90 95 QTime m_timeStamp;
91 96 QPointF m_speed;
92 97 QPointF m_fraction;
93 98 int m_timeTresholdMin;
94 99 int m_timeTresholdMax;
95 100
96 101 State m_state;
102 QPointF m_pressPos;
103 QPointF m_lastPos;
104 qreal m_treshold;
97 105 };
98 106
99 107 QTCOMMERCIALCHART_END_NAMESPACE
100 108
101 109 #endif /* SCROLLER_P_H */
General Comments 0
You need to be logged in to leave comments. Login now