##// END OF EJS Templates
Kinetic scrolling is back for legend
sauimone -
r2189:4cb139890ac2
parent child
Show More
@@ -39,7 +39,8 LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject
39 m_textItem(new QGraphicsSimpleTextItem(this)),
39 m_textItem(new QGraphicsSimpleTextItem(this)),
40 m_rectItem(new QGraphicsRectItem(this)),
40 m_rectItem(new QGraphicsRectItem(this)),
41 m_margin(4),
41 m_margin(4),
42 m_space(4)
42 m_space(4),
43 m_pressPos(0, 0)
43 {
44 {
44 m_rectItem->setRect(m_markerRect);
45 m_rectItem->setRect(m_markerRect);
45 }
46 }
@@ -163,6 +164,7 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint)
163 void LegendMarkerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
164 void LegendMarkerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
164 {
165 {
165 MouseEventHandler::handleMousePressEvent(event);
166 MouseEventHandler::handleMousePressEvent(event);
167 m_pressPos = event->screenPos();
166 }
168 }
167
169
168 void LegendMarkerItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
170 void LegendMarkerItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
@@ -180,18 +182,14 void LegendMarkerItem::mouseClicked()
180 emit m_marker->q_func()->clicked();
182 emit m_marker->q_func()->clicked();
181 }
183 }
182
184
183 void LegendMarkerItem::mouseMoved(QPointF delta)
185 void LegendMarkerItem::mouseMoved(const QPointF &delta)
184 {
186 {
185 qreal dx = m_marker->m_legend->d_ptr->offset().x() - delta.x();
187 m_marker->m_legend->d_ptr->move(delta);
186 qreal dy = m_marker->m_legend->d_ptr->offset().y() - delta.y();
187 m_marker->m_legend->d_ptr->setOffset(dx, dy);
188 }
188 }
189
189
190 void LegendMarkerItem::mouseReleased(QPointF delta)
190 void LegendMarkerItem::mouseReleased(const QPointF &pos)
191 {
191 {
192 qreal dx = m_marker->m_legend->d_ptr->offset().x() - delta.x();
192 m_marker->m_legend->d_ptr->release(pos - m_pressPos);
193 qreal dy = m_marker->m_legend->d_ptr->offset().y() - delta.y();
194 m_marker->m_legend->d_ptr->setOffset(dx, dy);
195 }
193 }
196
194
197 #include "moc_legendmarkeritem_p.cpp"
195 #include "moc_legendmarkeritem_p.cpp"
@@ -80,8 +80,8 public:
80
80
81 // Filtered callbacks from MouseEventHandler
81 // Filtered callbacks from MouseEventHandler
82 void mouseClicked();
82 void mouseClicked();
83 void mouseMoved(QPointF delta);
83 void mouseMoved(const QPointF &delta);
84 void mouseReleased(QPointF delta);
84 void mouseReleased(const QPointF &pos);
85
85
86 protected:
86 protected:
87 QLegendMarkerPrivate *m_marker; // Knows
87 QLegendMarkerPrivate *m_marker; // Knows
@@ -99,6 +99,8 protected:
99 QBrush m_brush;
99 QBrush m_brush;
100 bool m_visible;
100 bool m_visible;
101
101
102 QPointF m_pressPos;
103
102 friend class QLegendMarker;
104 friend class QLegendMarker;
103 friend class QLegendMarkerPrivate;
105 friend class QLegendMarkerPrivate;
104 friend class LegendMarkerItem;
106 friend class LegendMarkerItem;
@@ -33,25 +33,18
33
33
34 #include "qlegend.h"
34 #include "qlegend.h"
35 #include "qlegend_p.h"
35 #include "qlegend_p.h"
36 #include "scroller_p.h"
37
36
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
38
40 class LegendScroller: public QLegend, public Scroller
39 class LegendScroller: public QLegend
41 {
40 {
42
41
43 public:
42 public:
44 LegendScroller(QChart *chart): QLegend(chart) { }
43 LegendScroller(QChart *chart): QLegend(chart) { }
45
44
46 void setOffset(const QPointF &point) { d_ptr->setOffset(point.x(), point.y()); }
45 void setOffset(const QPointF &point) { d_ptr->setOffset(point); }
47
46
48 QPointF offset() const { return d_ptr->offset(); }
47 QPointF offset() const { return d_ptr->offset(); }
49
50 void mousePressEvent(QGraphicsSceneMouseEvent *event) { Scroller::mousePressEvent(event); }
51
52 void mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Scroller::mouseMoveEvent(event); }
53
54 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Scroller::mouseReleaseEvent(event); }
55 };
48 };
56
49
57 QTCOMMERCIALCHART_END_NAMESPACE
50 QTCOMMERCIALCHART_END_NAMESPACE
@@ -77,7 +77,6 void MouseEventHandler::handleMouseMoveEvent(QGraphicsSceneMouseEvent* event)
77
77
78 void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
78 void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
79 {
79 {
80 QPointF delta = event->screenPos() - m_lastPos;
81 m_lastPos = event->screenPos();
80 m_lastPos = event->screenPos();
82
81
83 switch (m_state) {
82 switch (m_state) {
@@ -91,7 +90,7 void MouseEventHandler::handleMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
91 case Moved:
90 case Moved:
92 {
91 {
93 m_state = Idle;
92 m_state = Idle;
94 mouseReleased(delta);
93 mouseReleased(m_lastPos);
95 event->accept();
94 event->accept();
96 break;
95 break;
97 }
96 }
@@ -71,8 +71,8 public:
71 void setMoveTreshold(qreal treshold);
71 void setMoveTreshold(qreal treshold);
72
72
73 virtual void mouseClicked() = 0;
73 virtual void mouseClicked() = 0;
74 virtual void mouseMoved(QPointF delta) = 0;
74 virtual void mouseMoved(const QPointF &delta) = 0;
75 virtual void mouseReleased(QPointF delta) = 0;
75 virtual void mouseReleased(const QPointF &pos) = 0;
76
76
77 void handleMousePressEvent(QGraphicsSceneMouseEvent* event);
77 void handleMousePressEvent(QGraphicsSceneMouseEvent* event);
78 void handleMouseMoveEvent(QGraphicsSceneMouseEvent* event);
78 void handleMouseMoveEvent(QGraphicsSceneMouseEvent* event);
@@ -458,9 +458,9 QLegendPrivate::~QLegendPrivate()
458
458
459 }
459 }
460
460
461 void QLegendPrivate::setOffset(qreal x, qreal y)
461 void QLegendPrivate::setOffset(const QPointF &offset)
462 {
462 {
463 m_layout->setOffset(x, y);
463 m_layout->setOffset(offset.x(), offset.y());
464 }
464 }
465
465
466 QPointF QLegendPrivate::offset() const
466 QPointF QLegendPrivate::offset() const
@@ -31,6 +31,7
31 #define QLEGEND_P_H
31 #define QLEGEND_P_H
32
32
33 #include "qlegend.h"
33 #include "qlegend.h"
34 #include "scroller_p.h"
34
35
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
37
@@ -41,14 +42,14 class LegendLayout;
41 class Domain;
42 class Domain;
42 class QLegendMarker;
43 class QLegendMarker;
43
44
44 class QLegendPrivate : public QObject
45 class QLegendPrivate : public QObject, public Scroller
45 {
46 {
46 Q_OBJECT
47 Q_OBJECT
47 public:
48 public:
48 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
49 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
49 ~QLegendPrivate();
50 ~QLegendPrivate();
50
51
51 void setOffset(qreal x, qreal y);
52 void setOffset(const QPointF &offset);
52 QPointF offset() const;
53 QPointF offset() const;
53 int roundness(qreal size);
54 int roundness(qreal size);
54
55
@@ -27,9 +27,9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 Scroller::Scroller()
28 Scroller::Scroller()
29 : m_ticker(this),
29 : m_ticker(this),
30 m_state(Idle),
30 m_timeTresholdMin(50),
31 m_moveThreshold(10),
31 m_timeTresholdMax(300),
32 m_timeTreshold(50)
32 m_state(Idle)
33 {
33 {
34
34
35 }
35 }
@@ -38,146 +38,80 Scroller::~Scroller()
38 {
38 {
39 }
39 }
40
40
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent *event)
41 void Scroller::move(const QPointF &delta)
42 {
42 {
43 if (event->button() == Qt::LeftButton) {
44 switch (m_state) {
43 switch (m_state) {
45 case Idle:
44 case Idle:
46 m_state = Pressed;
47 m_offset = offset();
48 m_press = event->pos();
49 m_timeStamp = QTime::currentTime();
45 m_timeStamp = QTime::currentTime();
50 event->accept();
46 m_state = Move;
51 break;
47 break;
52 case Scroll:
48 case Scroll:
53 m_state = Stop;
49 stopTicker();
54 m_speed = QPointF(0, 0);
50 m_timeStamp = QTime::currentTime();
55 m_offset = offset();
51 m_state = Move;
56 m_press = event->pos();
57 event->accept();
58 break;
52 break;
59 case Pressed:
53 default:
60 case Move:
61 case Stop:
62 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
63 event->ignore();
64 break;
54 break;
65 }
55 }
66 }
56 setOffset(offset() - delta);
67 }
57 }
68
58
69 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
59 void Scroller::release(const QPointF &delta)
70 {
60 {
71 QPointF delta = event->pos() - m_press;
61 // Starts scrolling, if at least m_timeTresholdMin msecs has gone since timestamp
62 // current time is no more than m_timeTresholdMax from timestamp
72
63
73 switch (m_state) {
64 if ((m_timeStamp.elapsed() > m_timeTresholdMin) && (m_timeStamp.msecsTo(QTime::currentTime()) < m_timeTresholdMax)) {
74 case Pressed:
65 // Release was quick enough. Start scrolling.
75 case Stop:
66 // Magic number is to make scroll bit slower (the resolution of screen may affect this)
76 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
67 m_speed = delta / 5;
77 m_state = Move;
68
78 m_timeStamp = QTime::currentTime();
69 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
79 m_distance = QPointF(0, 0);
70
80 m_press = event->pos();
71 if (!qFuzzyIsNull(fraction)) {
81 event->accept();
72 m_fraction.setX(qAbs(m_speed.x() / fraction));
73 m_fraction.setY(qAbs(m_speed.y() / fraction));
82 } else {
74 } else {
83 event->ignore();
75 m_fraction.setX(1);
76 m_fraction.setY(1);
84 }
77 }
85 break;
78 startTicker(25);
86 case Move:
79 m_state = Scroll;
87 setOffset(m_offset - delta);
80 } else {
88 calculateSpeed(event->pos());
81 stopTicker(); // Stop ticker, if one is running.
89 event->accept();
82 m_state = Idle;
90 break;
91 case Idle:
92 case Scroll:
93 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
94 event->ignore();
95 break;
96 }
83 }
97 }
84 }
98
85
99 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
86 void Scroller::startTicker(int interval)
100 {
87 {
101 if (event->button() == Qt::LeftButton) {
102
103 switch (m_state) {
104
105 case Scroll:
106 m_state = Stop;
107 m_speed = QPointF(0, 0);
108 m_offset = offset();
109 event->accept();
110 break;
111 case Pressed:
112 m_state = Idle;
113 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
114 //emit clicked(m_offset.toPoint());
115 //}
116 event->accept();
117 break;
118 case Move:
119 calculateSpeed(event->pos());
120 m_offset = offset();
121 m_press = event->pos();
122 if (m_speed == QPointF(0, 0)) {
123 m_state = Idle;
124 } else {
125 m_speed /= 3.75;
126 m_state = Scroll;
88 m_state = Scroll;
127 m_ticker.start(25);
89 m_ticker.start(interval);
128 }
129 event->accept();
130 break;
131 case Stop:
132 case Idle:
133 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
134 event->ignore();
135 break;
136 }
137 }
138 }
90 }
139
91
140 void Scroller::scroll(const QPointF &velocity)
92 void Scroller::stopTicker()
141 {
93 {
142 Q_UNUSED(velocity);
143 // TODO:
144 /*
145 m_offset = offset();
146 m_speed = velocity;
147 if (m_speed == QPointF(0, 0)) {
148 m_state = Idle;
94 m_state = Idle;
149 }
95 m_ticker.stop();
150 else {
151 m_speed /= 3.75;
152 m_state = Scroll;
153 m_ticker.start(25);
154 }
155 */
156 }
96 }
157
97
158
159 void Scroller::scrollTick()
98 void Scroller::scrollTick()
160 {
99 {
161 switch (m_state) {
100 switch (m_state) {
162 case Scroll:
101 case Scroll:
163 lowerSpeed(m_speed);
102 lowerSpeed(m_speed);
164 setOffset(m_offset - m_speed);
103 setOffset(offset() - m_speed);
165 m_offset = offset();
166 if (m_speed == QPointF(0, 0)) {
104 if (m_speed == QPointF(0, 0)) {
167 m_state = Idle;
105 m_state = Idle;
168 m_ticker.stop();
106 m_ticker.stop();
169 }
107 }
170 break;
108 break;
171 case Stop:
172 m_ticker.stop();
173 break;
174 case Idle:
109 case Idle:
175 case Move:
110 case Move:
176 case Pressed:
177 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
111 qWarning() << __FUNCTION__ << "Scroller unexpected state" << m_state;
178 m_ticker.stop();
112 m_ticker.stop();
113 m_state = Idle;
179 break;
114 break;
180
181 }
115 }
182 }
116 }
183
117
@@ -194,28 +128,6 void Scroller::lowerSpeed(QPointF &speed, qreal maxSpeed)
194 speed.setY(y);
128 speed.setY(y);
195 }
129 }
196
130
197 void Scroller::calculateSpeed(const QPointF &position)
198 {
199 if (m_timeStamp.elapsed() > m_timeTreshold) {
200
201 QPointF distance = position - m_press;
202
203 m_timeStamp = QTime::currentTime();
204 m_speed = distance - m_distance;
205 m_distance = distance;
206
207 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
208
209 if (fraction != 0) {
210 m_fraction.setX(qAbs(m_speed.x() / fraction));
211 m_fraction.setY(qAbs(m_speed.y() / fraction));
212 } else {
213 m_fraction.setX(1);
214 m_fraction.setY(1);
215 }
216 }
217 }
218
219 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
220
132
221 ScrollTicker::ScrollTicker(Scroller *scroller, QObject *parent)
133 ScrollTicker::ScrollTicker(Scroller *scroller, QObject *parent)
@@ -62,10 +62,8 class Scroller
62 public:
62 public:
63 enum State {
63 enum State {
64 Idle,
64 Idle,
65 Pressed,
66 Move,
65 Move,
67 Scroll,
66 Scroll
68 Stop
69 };
67 };
70
68
71 Scroller();
69 Scroller();
@@ -74,15 +72,15 public:
74 virtual void setOffset(const QPointF &point) = 0;
72 virtual void setOffset(const QPointF &point) = 0;
75 virtual QPointF offset() const = 0;
73 virtual QPointF offset() const = 0;
76
74
77 void scroll(const QPointF& velocity);
75 void move(const QPointF &delta);
76 void release(const QPointF &delta);
78
77
79 public:
80 void scrollTick();
78 void scrollTick();
81
79
82 public:
80 private:
83 void mousePressEvent(QGraphicsSceneMouseEvent *event);
81 void startTicker(int interval);
84 void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
82 void stopTicker();
85 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
83
86
84
87 private:
85 private:
88 void calculateSpeed(const QPointF &position);
86 void calculateSpeed(const QPointF &position);
@@ -90,15 +88,13 private:
90
88
91 private:
89 private:
92 ScrollTicker m_ticker;
90 ScrollTicker m_ticker;
93 State m_state;
94 QTime m_timeStamp;
91 QTime m_timeStamp;
95 QPointF m_press;
96 QPointF m_offset;
97 QPointF m_speed;
92 QPointF m_speed;
98 QPointF m_distance;
99 QPointF m_fraction;
93 QPointF m_fraction;
100 int m_moveThreshold;
94 int m_timeTresholdMin;
101 int m_timeTreshold;
95 int m_timeTresholdMax;
96
97 State m_state;
102 };
98 };
103
99
104 QTCOMMERCIALCHART_END_NAMESPACE
100 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now