##// END OF EJS Templates
Fix wrong intialization of QPointF with QPoint
Michal Klocek -
r1773:5d5f1f8b87bd
parent child
Show More
@@ -1,212 +1,212
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "splineanimation_p.h"
21 #include "splineanimation_p.h"
22 #include "splinechartitem_p.h"
22 #include "splinechartitem_p.h"
23 #include <QDebug>
23 #include <QDebug>
24
24
25 Q_DECLARE_METATYPE(QVector<QPointF>)
25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 Q_DECLARE_METATYPE(SplineVector)
26 Q_DECLARE_METATYPE(SplineVector)
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
30 SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
31 m_item(item),
31 m_item(item),
32 m_valid(false)
32 m_valid(false)
33 {
33 {
34 }
34 }
35
35
36 SplineAnimation::~SplineAnimation()
36 SplineAnimation::~SplineAnimation()
37 {
37 {
38 }
38 }
39
39
40 void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
40 void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
41 {
41 {
42 if(newPoints.count() * 2 - 2 != newControlPoints.count() || newControlPoints.count() < 2){
42 if(newPoints.count() * 2 - 2 != newControlPoints.count() || newControlPoints.count() < 2){
43 m_valid=false;
43 m_valid=false;
44 m_dirty=false;
44 m_dirty=false;
45 m_item->setGeometryPoints(newPoints);
45 m_item->setGeometryPoints(newPoints);
46 m_item->setControlGeometryPoints(newControlPoints);
46 m_item->setControlGeometryPoints(newControlPoints);
47 m_item->setDirty(false);
47 m_item->setDirty(false);
48 m_item->updateGeometry();
48 m_item->updateGeometry();
49 return;
49 return;
50 }
50 }
51
51
52 m_type = NewAnimation;
52 m_type = NewAnimation;
53
53
54 if (state() != QAbstractAnimation::Stopped) {
54 if (state() != QAbstractAnimation::Stopped) {
55 stop();
55 stop();
56 m_dirty=false;
56 m_dirty=false;
57 }
57 }
58
58
59 if(!m_dirty) {
59 if(!m_dirty) {
60 m_dirty = true;
60 m_dirty = true;
61 m_oldSpline.first = oldPoints;
61 m_oldSpline.first = oldPoints;
62 m_oldSpline.second = oldControlPoints;
62 m_oldSpline.second = oldControlPoints;
63 }
63 }
64
64
65 m_newSpline.first=newPoints;
65 m_newSpline.first=newPoints;
66 m_newSpline.second=newControlPoints;
66 m_newSpline.second=newControlPoints;
67
67
68
68
69 int x = m_oldSpline.first.count();
69 int x = m_oldSpline.first.count();
70 int y = m_newSpline.first.count();
70 int y = m_newSpline.first.count();
71
71
72 if(x - y == 1 && index >= 0 && y>0) {
72 if(x - y == 1 && index >= 0 && y>0) {
73 //remove point
73 //remove point
74 if(index>0){
74 if(index>0){
75 m_newSpline.first.insert(index, newPoints[index-1]);
75 m_newSpline.first.insert(index, newPoints[index-1]);
76 m_newSpline.second.insert((index -1) * 2, newPoints[index-1] );
76 m_newSpline.second.insert((index -1) * 2, newPoints[index-1] );
77 m_newSpline.second.insert((index -1) * 2 + 1, newPoints[index-1]);
77 m_newSpline.second.insert((index -1) * 2 + 1, newPoints[index-1]);
78 }else{
78 }else{
79 m_newSpline.first.insert(index, newPoints[index]);
79 m_newSpline.first.insert(index, newPoints[index]);
80 m_newSpline.second.insert(index * 2, newPoints[index] );
80 m_newSpline.second.insert(index * 2, newPoints[index] );
81 m_newSpline.second.insert(index * 2 + 1, newPoints[index]);
81 m_newSpline.second.insert(index * 2 + 1, newPoints[index]);
82 }
82 }
83 m_index=index;
83 m_index=index;
84 m_type = RemovePointAnimation;
84 m_type = RemovePointAnimation;
85 }
85 }
86
86
87 if(x - y == -1 && index >= 0) {
87 if(x - y == -1 && index >= 0) {
88 //add point
88 //add point
89 if(index>0){
89 if(index>0){
90 m_oldSpline.first.insert(index, newPoints[index-1]);
90 m_oldSpline.first.insert(index, newPoints[index-1]);
91 m_oldSpline.second.insert((index - 1) * 2, newPoints[index-1]);
91 m_oldSpline.second.insert((index - 1) * 2, newPoints[index-1]);
92 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index-1]);
92 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index-1]);
93 }else{
93 }else{
94 m_oldSpline.first.insert(index, newPoints[index]);
94 m_oldSpline.first.insert(index, newPoints[index]);
95 m_oldSpline.second.insert((index - 1) * 2, newPoints[index]);
95 m_oldSpline.second.insert((index - 1) * 2, newPoints[index]);
96 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index]);
96 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index]);
97 }
97 }
98 m_index=index;
98 m_index=index;
99 m_type = AddPointAnimation;
99 m_type = AddPointAnimation;
100 }
100 }
101
101
102 x = m_oldSpline.first.count();
102 x = m_oldSpline.first.count();
103 y = m_newSpline.first.count();
103 y = m_newSpline.first.count();
104
104
105 if(x != y)
105 if(x != y)
106 {
106 {
107 m_type = NewAnimation;
107 m_type = NewAnimation;
108 }
108 }
109 else if(m_type == NewAnimation)
109 else if(m_type == NewAnimation)
110 {
110 {
111 m_type = ReplacePointAnimation;
111 m_type = ReplacePointAnimation;
112 }
112 }
113
113
114
114
115 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
115 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
116 setKeyValueAt(1.0, qVariantFromValue(m_newSpline));
116 setKeyValueAt(1.0, qVariantFromValue(m_newSpline));
117
117
118 m_valid=true;
118 m_valid=true;
119
119
120 }
120 }
121
121
122 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
122 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
123 {
123 {
124
124
125 SplineVector startPair = qVariantValue< SplineVector >(start);
125 SplineVector startPair = qVariantValue< SplineVector >(start);
126 SplineVector endPair = qVariantValue< SplineVector >(end);
126 SplineVector endPair = qVariantValue< SplineVector >(end);
127 SplineVector result;
127 SplineVector result;
128
128
129 switch (animationType()) {
129 switch (animationType()) {
130
130
131 case RemovePointAnimation:
131 case RemovePointAnimation:
132 case AddPointAnimation:
132 case AddPointAnimation:
133 case ReplacePointAnimation:
133 case ReplacePointAnimation:
134 {
134 {
135 if (startPair.first.count() != endPair.first.count())
135 if (startPair.first.count() != endPair.first.count())
136 break;
136 break;
137 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
137 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
138 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
138 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
139 for(int i = 0; i < endPair.first.count(); i++) {
139 for(int i = 0; i < endPair.first.count(); i++) {
140 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
140 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
141 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
141 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
142 result.first << QPointF(x,y);
142 result.first << QPointF(x,y);
143 if (i + 1 >= endPair.first.count())
143 if (i + 1 >= endPair.first.count())
144 continue;
144 continue;
145 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
145 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
146 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
146 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
147 result.second << QPoint(x,y);
147 result.second << QPointF(x,y);
148 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
148 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
149 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
149 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
150 result.second << QPoint(x,y);
150 result.second << QPointF(x,y);
151 }
151 }
152
152
153 }
153 }
154 break;
154 break;
155 case NewAnimation: {
155 case NewAnimation: {
156 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
156 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
157 int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
157 int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
158 for(int i = 0; i < count; i++) {
158 for(int i = 0; i < count; i++) {
159 result.first << endPair.first[i];
159 result.first << endPair.first[i];
160 if(i + 1 == count)
160 if(i + 1 == count)
161 break;
161 break;
162 result.second << endPair.second[2 * i];
162 result.second << endPair.second[2 * i];
163 result.second << endPair.second[2 * i + 1];
163 result.second << endPair.second[2 * i + 1];
164 }
164 }
165 }
165 }
166 break;
166 break;
167 default:
167 default:
168 qWarning() << "Unknown type of animation";
168 qWarning() << "Unknown type of animation";
169 break;
169 break;
170 }
170 }
171
171
172 return qVariantFromValue(result);
172 return qVariantFromValue(result);
173 }
173 }
174
174
175 void SplineAnimation::updateCurrentValue (const QVariant &value )
175 void SplineAnimation::updateCurrentValue (const QVariant &value )
176 {
176 {
177 if (state() != QAbstractAnimation::Stopped && m_valid) { //workaround
177 if (state() != QAbstractAnimation::Stopped && m_valid) { //workaround
178 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
178 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
179 m_item->setGeometryPoints(pair.first);
179 m_item->setGeometryPoints(pair.first);
180 m_item->setControlGeometryPoints(pair.second);
180 m_item->setControlGeometryPoints(pair.second);
181 m_item->updateGeometry();
181 m_item->updateGeometry();
182 m_item->setDirty(true);
182 m_item->setDirty(true);
183 m_dirty = false;
183 m_dirty = false;
184 }
184 }
185 }
185 }
186
186
187 void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
187 void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
188 {
188 {
189 XYAnimation::updateState(newState, oldState);
189 XYAnimation::updateState(newState, oldState);
190
190
191 if(oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped)
191 if(oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped)
192 {
192 {
193 if(m_item->isDirty() && m_type==RemovePointAnimation) {
193 if(m_item->isDirty() && m_type==RemovePointAnimation) {
194 if(!m_newSpline.first.isEmpty()) {
194 if(!m_newSpline.first.isEmpty()) {
195 m_newSpline.first.remove(m_index);
195 m_newSpline.first.remove(m_index);
196 m_newSpline.second.remove((m_index-1) * 2);
196 m_newSpline.second.remove((m_index-1) * 2);
197 m_newSpline.second.remove((m_index-1) * 2);
197 m_newSpline.second.remove((m_index-1) * 2);
198 }
198 }
199 m_item->setGeometryPoints(m_newSpline.first);
199 m_item->setGeometryPoints(m_newSpline.first);
200 m_item->setControlGeometryPoints(m_newSpline.second);
200 m_item->setControlGeometryPoints(m_newSpline.second);
201 }
201 }
202 }
202 }
203
203
204 if(oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running)
204 if(oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running)
205 {
205 {
206 if(!m_valid) {
206 if(!m_valid) {
207 stop();
207 stop();
208 }
208 }
209 }
209 }
210 }
210 }
211
211
212 QTCOMMERCIALCHART_END_NAMESPACE
212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,380 +1,380
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "legendlayout_p.h"
21 #include "legendlayout_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "legendmarker_p.h"
23 #include "legendmarker_p.h"
24 #include "qlegend_p.h"
24 #include "qlegend_p.h"
25 #include <QDebug>
25 #include <QDebug>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 LegendLayout::LegendLayout(QLegend* legend):
29 LegendLayout::LegendLayout(QLegend* legend):
30 m_legend(legend)
30 m_legend(legend)
31 {
31 {
32
32
33 }
33 }
34
34
35 LegendLayout::~LegendLayout()
35 LegendLayout::~LegendLayout()
36 {
36 {
37
37
38 }
38 }
39
39
40 void LegendLayout::setOffset(qreal x, qreal y)
40 void LegendLayout::setOffset(qreal x, qreal y)
41 {
41 {
42 bool scrollHorizontal = true;
42 bool scrollHorizontal = true;
43 switch(m_legend->alignment()) {
43 switch(m_legend->alignment()) {
44 case Qt::AlignTop:
44 case Qt::AlignTop:
45 case Qt::AlignBottom: {
45 case Qt::AlignBottom: {
46 scrollHorizontal = true;
46 scrollHorizontal = true;
47 break;
47 break;
48 }
48 }
49 case Qt::AlignLeft:
49 case Qt::AlignLeft:
50 case Qt::AlignRight: {
50 case Qt::AlignRight: {
51 scrollHorizontal = false;
51 scrollHorizontal = false;
52 break;
52 break;
53 }
53 }
54 }
54 }
55
55
56 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
56 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
57 if (!m_legend->isAttachedToChart()) {
57 if (!m_legend->isAttachedToChart()) {
58 scrollHorizontal = !scrollHorizontal;
58 scrollHorizontal = !scrollHorizontal;
59 }
59 }
60
60
61 QRectF boundingRect = geometry();
61 QRectF boundingRect = geometry();
62
62
63 // Limit offset between m_minOffset and m_maxOffset
63 // Limit offset between m_minOffset and m_maxOffset
64 if (scrollHorizontal) {
64 if (scrollHorizontal) {
65 if(m_width<=boundingRect.width()) return;
65 if(m_width<=boundingRect.width()) return;
66
66
67 if (x != m_offsetX) {
67 if (x != m_offsetX) {
68 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
68 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
69 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
69 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
70 }
70 }
71 }
71 }
72 else {
72 else {
73 if(m_height<=boundingRect.height()) return;
73 if(m_height<=boundingRect.height()) return;
74
74
75 if (y != m_offsetY) {
75 if (y != m_offsetY) {
76 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
76 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
77 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
77 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
78 }
78 }
79 }
79 }
80 }
80 }
81
81
82 QPointF LegendLayout::offset() const
82 QPointF LegendLayout::offset() const
83 {
83 {
84 return QPointF(m_offsetX,m_offsetY);
84 return QPointF(m_offsetX,m_offsetY);
85 }
85 }
86
86
87 void LegendLayout::setGeometry(const QRectF& rect)
87 void LegendLayout::setGeometry(const QRectF& rect)
88 {
88 {
89
89
90 QGraphicsLayout::setGeometry(rect);
90 QGraphicsLayout::setGeometry(rect);
91
91
92 if(m_legend->isAttachedToChart()) {
92 if(m_legend->isAttachedToChart()) {
93 setAttachedGeometry(rect);
93 setAttachedGeometry(rect);
94 }
94 }
95 else {
95 else {
96 setDettachedGeometry(rect);
96 setDettachedGeometry(rect);
97 }
97 }
98 }
98 }
99
99
100 void LegendLayout::setAttachedGeometry(const QRectF& rect)
100 void LegendLayout::setAttachedGeometry(const QRectF& rect)
101 {
101 {
102 if (!rect.isValid()) return;
102 if (!rect.isValid()) return;
103
103
104 m_offsetX=0;
104 m_offsetX=0;
105 m_offsetY=0;
105 m_offsetY=0;
106
106
107 QSizeF size(0,0);
107 QSizeF size(0,0);
108
108
109 if( m_legend->d_ptr->markers().isEmpty()) return;
109 if( m_legend->d_ptr->markers().isEmpty()) return;
110
110
111 m_width=0;
111 m_width=0;
112 m_height=0;
112 m_height=0;
113
113
114 switch(m_legend->alignment()) {
114 switch(m_legend->alignment()) {
115
115
116 case Qt::AlignTop:
116 case Qt::AlignTop:
117
117
118 case Qt::AlignBottom: {
118 case Qt::AlignBottom: {
119 QPointF point(0,0);
119 QPointF point(0,0);
120 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
120 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
121 if (marker->isVisible()) {
121 if (marker->isVisible()) {
122 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
122 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
123 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
123 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
124 const QRectF& rect = marker->boundingRect();
124 const QRectF& rect = marker->boundingRect();
125 size = size.expandedTo(rect.size());
125 size = size.expandedTo(rect.size());
126 qreal w = rect.width();
126 qreal w = rect.width();
127 m_width+=w;
127 m_width+=w;
128 point.setX(point.x() + w);
128 point.setX(point.x() + w);
129 }
129 }
130 }
130 }
131 if(m_width<rect.width()) {
131 if(m_width<rect.width()) {
132 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
132 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
133
133
134 }
134 }
135 else {
135 else {
136 m_legend->d_ptr->items()->setPos(rect.topLeft());
136 m_legend->d_ptr->items()->setPos(rect.topLeft());
137 }
137 }
138 m_height=size.height();
138 m_height=size.height();
139 }
139 }
140 break;
140 break;
141 case Qt::AlignLeft:
141 case Qt::AlignLeft:
142 case Qt::AlignRight: {
142 case Qt::AlignRight: {
143 QPointF point(0,0);
143 QPointF point(0,0);
144 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
144 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
145 if (marker->isVisible()) {
145 if (marker->isVisible()) {
146 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
146 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
147 marker->setPos(point);
147 marker->setPos(point);
148 const QRectF& rect = marker->boundingRect();
148 const QRectF& rect = marker->boundingRect();
149 qreal h = rect.height();
149 qreal h = rect.height();
150 size = size.expandedTo(rect.size());
150 size = size.expandedTo(rect.size());
151 m_height+=h;
151 m_height+=h;
152 point.setY(point.y() + h);
152 point.setY(point.y() + h);
153 }
153 }
154 }
154 }
155 if(m_height<rect.height()) {
155 if(m_height<rect.height()) {
156 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
156 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
157 }
157 }
158 else {
158 else {
159 m_legend->d_ptr->items()->setPos(rect.topLeft());
159 m_legend->d_ptr->items()->setPos(rect.topLeft());
160 }
160 }
161 m_width=size.width();
161 m_width=size.width();
162 }
162 }
163 break;
163 break;
164 }
164 }
165
165
166 m_minOffsetX = 0;
166 m_minOffsetX = 0;
167 m_minOffsetY = 0;
167 m_minOffsetY = 0;
168 m_maxOffsetX = m_width - rect.width();
168 m_maxOffsetX = m_width - rect.width();
169 m_maxOffsetY = m_height - rect.height();
169 m_maxOffsetY = m_height - rect.height();
170 }
170 }
171
171
172 void LegendLayout::setDettachedGeometry(const QRectF& rect)
172 void LegendLayout::setDettachedGeometry(const QRectF& rect)
173 {
173 {
174 if (!rect.isValid()) return;
174 if (!rect.isValid()) return;
175
175
176 // Detached layout is different.
176 // Detached layout is different.
177 // In detached mode legend may have multiple rows and columns, so layout calculations
177 // In detached mode legend may have multiple rows and columns, so layout calculations
178 // differ a log from attached mode.
178 // differ a log from attached mode.
179 // Also the scrolling logic is bit different.
179 // Also the scrolling logic is bit different.
180
180
181 m_offsetX=0;
181 m_offsetX=0;
182 m_offsetY=0;
182 m_offsetY=0;
183
183
184 QSizeF size(0,0);
184 QSizeF size(0,0);
185
185
186 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
186 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
187
187
188 if(markers.isEmpty()) return;
188 if(markers.isEmpty()) return;
189
189
190 switch (m_legend->alignment()) {
190 switch (m_legend->alignment()) {
191 case Qt::AlignTop: {
191 case Qt::AlignTop: {
192 QPointF point = rect.topLeft();
192 QPointF point = rect.topLeft();
193 m_width = 0;
193 m_width = 0;
194 m_height = 0;
194 m_height = 0;
195 for (int i=0; i<markers.count(); i++) {
195 for (int i=0; i<markers.count(); i++) {
196 LegendMarker *marker = markers.at(i);
196 LegendMarker *marker = markers.at(i);
197 if (marker->isVisible()) {
197 if (marker->isVisible()) {
198 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
198 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
199 marker->setPos(point.x(),point.y());
199 marker->setPos(point.x(),point.y());
200 const QRectF& boundingRect = marker->boundingRect();
200 const QRectF& boundingRect = marker->boundingRect();
201 qreal w = boundingRect.width();
201 qreal w = boundingRect.width();
202 qreal h = boundingRect.height();
202 qreal h = boundingRect.height();
203 m_width = qMax(m_width,w);
203 m_width = qMax(m_width,w);
204 m_height = qMax(m_height,h);
204 m_height = qMax(m_height,h);
205 point.setX(point.x() + w);
205 point.setX(point.x() + w);
206 if (point.x() + w > rect.topLeft().x() + rect.width()) {
206 if (point.x() + w > rect.topLeft().x() + rect.width()) {
207 // Next item would go off rect.
207 // Next item would go off rect.
208 point.setX(rect.topLeft().x());
208 point.setX(rect.topLeft().x());
209 point.setY(point.y() + h);
209 point.setY(point.y() + h);
210 if (i+1 < markers.count()) {
210 if (i+1 < markers.count()) {
211 m_height += h;
211 m_height += h;
212 }
212 }
213 }
213 }
214 }
214 }
215 }
215 }
216 m_legend->d_ptr->items()->setPos(rect.topLeft());
216 m_legend->d_ptr->items()->setPos(rect.topLeft());
217
217
218 m_minOffsetX = 0;
218 m_minOffsetX = 0;
219 m_minOffsetY = 0;
219 m_minOffsetY = 0;
220 m_maxOffsetX = m_width - rect.width();
220 m_maxOffsetX = m_width - rect.width();
221 m_maxOffsetY = m_height - rect.height();
221 m_maxOffsetY = m_height - rect.height();
222 }
222 }
223 break;
223 break;
224 case Qt::AlignBottom: {
224 case Qt::AlignBottom: {
225 QPointF point = rect.bottomLeft();
225 QPointF point = rect.bottomLeft();
226 m_width = 0;
226 m_width = 0;
227 m_height = 0;
227 m_height = 0;
228 for (int i=0; i<markers.count(); i++) {
228 for (int i=0; i<markers.count(); i++) {
229 LegendMarker *marker = markers.at(i);
229 LegendMarker *marker = markers.at(i);
230 if (marker->isVisible()) {
230 if (marker->isVisible()) {
231 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
231 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
232 const QRectF& boundingRect = marker->boundingRect();
232 const QRectF& boundingRect = marker->boundingRect();
233 qreal w = boundingRect.width();
233 qreal w = boundingRect.width();
234 qreal h = boundingRect.height();
234 qreal h = boundingRect.height();
235 m_width = qMax(m_width,w);
235 m_width = qMax(m_width,w);
236 m_height = qMax(m_height,h);
236 m_height = qMax(m_height,h);
237 marker->setPos(point.x(),point.y() - h);
237 marker->setPos(point.x(),point.y() - h);
238 point.setX(point.x() + w);
238 point.setX(point.x() + w);
239 if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
239 if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
240 // Next item would go off rect.
240 // Next item would go off rect.
241 point.setX(rect.bottomLeft().x());
241 point.setX(rect.bottomLeft().x());
242 point.setY(point.y() - h);
242 point.setY(point.y() - h);
243 if (i+1 < markers.count()) {
243 if (i+1 < markers.count()) {
244 m_height += h;
244 m_height += h;
245 }
245 }
246 }
246 }
247 }
247 }
248 }
248 }
249 m_legend->d_ptr->items()->setPos(rect.topLeft());
249 m_legend->d_ptr->items()->setPos(rect.topLeft());
250
250
251 m_minOffsetX = 0;
251 m_minOffsetX = 0;
252 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
252 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
253 m_maxOffsetX = m_width - rect.width();
253 m_maxOffsetX = m_width - rect.width();
254 m_maxOffsetY = 0;
254 m_maxOffsetY = 0;
255 }
255 }
256 break;
256 break;
257 case Qt::AlignLeft: {
257 case Qt::AlignLeft: {
258 QPointF point = rect.topLeft();
258 QPointF point = rect.topLeft();
259 m_width = 0;
259 m_width = 0;
260 m_height = 0;
260 m_height = 0;
261 qreal maxWidth = 0;
261 qreal maxWidth = 0;
262 for (int i=0; i<markers.count(); i++) {
262 for (int i=0; i<markers.count(); i++) {
263 LegendMarker *marker = markers.at(i);
263 LegendMarker *marker = markers.at(i);
264 if (marker->isVisible()) {
264 if (marker->isVisible()) {
265 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
265 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
266 const QRectF& boundingRect = marker->boundingRect();
266 const QRectF& boundingRect = marker->boundingRect();
267 qreal w = boundingRect.width();
267 qreal w = boundingRect.width();
268 qreal h = boundingRect.height();
268 qreal h = boundingRect.height();
269 m_height = qMax(m_height,h);
269 m_height = qMax(m_height,h);
270 maxWidth = qMax(maxWidth,w);
270 maxWidth = qMax(maxWidth,w);
271 marker->setPos(point.x(),point.y());
271 marker->setPos(point.x(),point.y());
272 point.setY(point.y() + h);
272 point.setY(point.y() + h);
273 if (point.y() + h > rect.topLeft().y() + rect.height()) {
273 if (point.y() + h > rect.topLeft().y() + rect.height()) {
274 // Next item would go off rect.
274 // Next item would go off rect.
275 point.setX(point.x() + maxWidth);
275 point.setX(point.x() + maxWidth);
276 point.setY(rect.topLeft().y());
276 point.setY(rect.topLeft().y());
277 if (i+1 < markers.count()) {
277 if (i+1 < markers.count()) {
278 m_width += maxWidth;
278 m_width += maxWidth;
279 maxWidth = 0;
279 maxWidth = 0;
280 }
280 }
281 }
281 }
282 }
282 }
283 }
283 }
284 m_width += maxWidth;
284 m_width += maxWidth;
285 m_legend->d_ptr->items()->setPos(rect.topLeft());
285 m_legend->d_ptr->items()->setPos(rect.topLeft());
286
286
287 m_minOffsetX = 0;
287 m_minOffsetX = 0;
288 m_minOffsetY = 0;
288 m_minOffsetY = 0;
289 m_maxOffsetX = m_width - rect.width();
289 m_maxOffsetX = m_width - rect.width();
290 m_maxOffsetY = m_height - rect.height();
290 m_maxOffsetY = m_height - rect.height();
291 }
291 }
292 break;
292 break;
293 case Qt::AlignRight: {
293 case Qt::AlignRight: {
294 QPointF point = rect.topRight();
294 QPointF point = rect.topRight();
295 m_width = 0;
295 m_width = 0;
296 m_height = 0;
296 m_height = 0;
297 qreal maxWidth = 0;
297 qreal maxWidth = 0;
298 for (int i=0; i<markers.count(); i++) {
298 for (int i=0; i<markers.count(); i++) {
299 LegendMarker *marker = markers.at(i);
299 LegendMarker *marker = markers.at(i);
300 if (marker->isVisible()) {
300 if (marker->isVisible()) {
301 marker->setGeometry(QRectF(QPoint(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
301 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
302 const QRectF& boundingRect = marker->boundingRect();
302 const QRectF& boundingRect = marker->boundingRect();
303 qreal w = boundingRect.width();
303 qreal w = boundingRect.width();
304 qreal h = boundingRect.height();
304 qreal h = boundingRect.height();
305 m_height = qMax(m_height,h);
305 m_height = qMax(m_height,h);
306 maxWidth = qMax(maxWidth,w);
306 maxWidth = qMax(maxWidth,w);
307 marker->setPos(point.x() - w,point.y());
307 marker->setPos(point.x() - w,point.y());
308 point.setY(point.y() + h);
308 point.setY(point.y() + h);
309 if (point.y() + h > rect.topLeft().y() + rect.height()) {
309 if (point.y() + h > rect.topLeft().y() + rect.height()) {
310 // Next item would go off rect.
310 // Next item would go off rect.
311 point.setX(point.x() - maxWidth);
311 point.setX(point.x() - maxWidth);
312 point.setY(rect.topLeft().y());
312 point.setY(rect.topLeft().y());
313 if (i+1 < markers.count()) {
313 if (i+1 < markers.count()) {
314 m_width += maxWidth;
314 m_width += maxWidth;
315 maxWidth = 0;
315 maxWidth = 0;
316 }
316 }
317 }
317 }
318 }
318 }
319 }
319 }
320 m_width += maxWidth;
320 m_width += maxWidth;
321 m_legend->d_ptr->items()->setPos(rect.topLeft());
321 m_legend->d_ptr->items()->setPos(rect.topLeft());
322
322
323 m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
323 m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
324 m_minOffsetY = 0;
324 m_minOffsetY = 0;
325 m_maxOffsetX = 0;
325 m_maxOffsetX = 0;
326 m_maxOffsetY = m_height - rect.height();
326 m_maxOffsetY = m_height - rect.height();
327 }
327 }
328 break;
328 break;
329 default:
329 default:
330 break;
330 break;
331 }
331 }
332
332
333 }
333 }
334
334
335 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
335 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
336 {
336 {
337 QSizeF size(0, 0);
337 QSizeF size(0, 0);
338 qreal left, top, right, bottom;
338 qreal left, top, right, bottom;
339 getContentsMargins(&left, &top, &right, &bottom);
339 getContentsMargins(&left, &top, &right, &bottom);
340
340
341 if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
341 if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
342
342
343 if(constraint.isValid()) {
343 if(constraint.isValid()) {
344 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
344 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
345 size = size.expandedTo(marker->effectiveSizeHint(which));
345 size = size.expandedTo(marker->effectiveSizeHint(which));
346 }
346 }
347 size = size.boundedTo(constraint);
347 size = size.boundedTo(constraint);
348 }
348 }
349 else if (constraint.width() >= 0) {
349 else if (constraint.width() >= 0) {
350 qreal width = 0;
350 qreal width = 0;
351 qreal height = 0;
351 qreal height = 0;
352 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
352 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
353 width+=marker->effectiveSizeHint(which).width();
353 width+=marker->effectiveSizeHint(which).width();
354 height=qMax(height,marker->effectiveSizeHint(which).height());
354 height=qMax(height,marker->effectiveSizeHint(which).height());
355 }
355 }
356
356
357 size = QSizeF(qMin(constraint.width(),width), height);
357 size = QSizeF(qMin(constraint.width(),width), height);
358 }
358 }
359 else if (constraint.height() >= 0) {
359 else if (constraint.height() >= 0) {
360 qreal width = 0;
360 qreal width = 0;
361 qreal height = 0;
361 qreal height = 0;
362 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
362 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
363 width=qMax(width,marker->effectiveSizeHint(which).width());
363 width=qMax(width,marker->effectiveSizeHint(which).width());
364 height+=height,marker->effectiveSizeHint(which).height();
364 height+=height,marker->effectiveSizeHint(which).height();
365 }
365 }
366 size = QSizeF(width,qMin(constraint.height(),height));
366 size = QSizeF(width,qMin(constraint.height(),height));
367 }
367 }
368 else {
368 else {
369 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
369 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
370 size = size.expandedTo(marker->effectiveSizeHint(which));
370 size = size.expandedTo(marker->effectiveSizeHint(which));
371 }
371 }
372 }
372 }
373 size += QSize(left + right, top + bottom);
373 size += QSize(left + right, top + bottom);
374
374
375 return size;
375 return size;
376
376
377
377
378 }
378 }
379
379
380 QTCOMMERCIALCHART_END_NAMESPACE
380 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,251 +1,251
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scroller_p.h"
21 #include "scroller_p.h"
22 #include "qlegend.h"
22 #include "qlegend.h"
23 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsSceneMouseEvent>
24 #include <QDebug>
24 #include <QDebug>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 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_state(Idle),
31 m_moveThreshold(10),
31 m_moveThreshold(10),
32 m_timeTreshold(50)
32 m_timeTreshold(50)
33 {
33 {
34
34
35 }
35 }
36
36
37 Scroller::~Scroller()
37 Scroller::~Scroller()
38 {
38 {
39 }
39 }
40
40
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
42 {
42 {
43 if (event->button() == Qt::LeftButton) {
43 if (event->button() == Qt::LeftButton) {
44
44
45 switch (m_state) {
45 switch (m_state) {
46 case Idle:
46 case Idle:
47 {
47 {
48 m_state = Pressed;
48 m_state = Pressed;
49 m_offset = offset();
49 m_offset = offset();
50 m_press = event->pos();
50 m_press = event->pos();
51 m_timeStamp = QTime::currentTime();
51 m_timeStamp = QTime::currentTime();
52 event->accept();
52 event->accept();
53 break;
53 break;
54 }
54 }
55 case Scroll:
55 case Scroll:
56 {
56 {
57 m_state = Stop;
57 m_state = Stop;
58 m_speed = QPoint(0, 0);
58 m_speed = QPointF(0, 0);
59 m_offset = offset();
59 m_offset = offset();
60 m_press = event->pos();
60 m_press = event->pos();
61 event->accept();
61 event->accept();
62 break;
62 break;
63 }
63 }
64 case Pressed:
64 case Pressed:
65 case Move:
65 case Move:
66 case Stop:
66 case Stop:
67 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
67 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
68 event->ignore();
68 event->ignore();
69 break;
69 break;
70 }
70 }
71 }
71 }
72 }
72 }
73
73
74 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
74 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
75 {
75 {
76 QPointF delta = event->pos() - m_press;
76 QPointF delta = event->pos() - m_press;
77
77
78 switch (m_state) {
78 switch (m_state) {
79 case Pressed:
79 case Pressed:
80 case Stop:
80 case Stop:
81 {
81 {
82 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
82 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
83 m_state = Move;
83 m_state = Move;
84 m_timeStamp = QTime::currentTime();
84 m_timeStamp = QTime::currentTime();
85 m_distance = QPointF(0, 0);
85 m_distance = QPointF(0, 0);
86 m_press = event->pos();
86 m_press = event->pos();
87 event->accept();
87 event->accept();
88 break;
88 break;
89 }
89 }
90 else {
90 else {
91 event->ignore();
91 event->ignore();
92 break;
92 break;
93 }
93 }
94 }
94 }
95 case Move:
95 case Move:
96 {
96 {
97 setOffset(m_offset - delta);
97 setOffset(m_offset - delta);
98 calculateSpeed(event->pos());
98 calculateSpeed(event->pos());
99 event->accept();
99 event->accept();
100 break;
100 break;
101 }
101 }
102 case Idle:
102 case Idle:
103 case Scroll:
103 case Scroll:
104 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
104 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
105 event->ignore();
105 event->ignore();
106 break;
106 break;
107 }
107 }
108
108
109 }
109 }
110
110
111 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
111 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
112 {
112 {
113 if (event->button() == Qt::LeftButton) {
113 if (event->button() == Qt::LeftButton) {
114
114
115 switch (m_state) {
115 switch (m_state) {
116
116
117 case Scroll:
117 case Scroll:
118 m_state = Stop;
118 m_state = Stop;
119 m_speed = QPointF(0, 0);
119 m_speed = QPointF(0, 0);
120 m_offset = offset();
120 m_offset = offset();
121 event->accept();
121 event->accept();
122 break;
122 break;
123 case Pressed:
123 case Pressed:
124 {
124 {
125 m_state = Idle;
125 m_state = Idle;
126 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
126 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
127
127
128 //emit clicked(m_offset.toPoint());
128 //emit clicked(m_offset.toPoint());
129 //}
129 //}
130 event->accept();
130 event->accept();
131 break;
131 break;
132 }
132 }
133 case Move:
133 case Move:
134 {
134 {
135 calculateSpeed(event->pos());
135 calculateSpeed(event->pos());
136 m_offset = offset();
136 m_offset = offset();
137 m_press = event->pos();
137 m_press = event->pos();
138 if (m_speed == QPointF(0, 0)) {
138 if (m_speed == QPointF(0, 0)) {
139 m_state = Idle;
139 m_state = Idle;
140 }
140 }
141 else {
141 else {
142 m_speed /= 3.75;
142 m_speed /= 3.75;
143 m_state = Scroll;
143 m_state = Scroll;
144 m_ticker.start(25);
144 m_ticker.start(25);
145 }
145 }
146 event->accept();
146 event->accept();
147 break;
147 break;
148 }
148 }
149
149
150 case Stop:
150 case Stop:
151 case Idle:
151 case Idle:
152 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
152 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
153 event->ignore();
153 event->ignore();
154 break;
154 break;
155
155
156 }
156 }
157 }
157 }
158 }
158 }
159
159
160 void Scroller::scrollTick()
160 void Scroller::scrollTick()
161 {
161 {
162 switch (m_state) {
162 switch (m_state) {
163 case Scroll:
163 case Scroll:
164 {
164 {
165 lowerSpeed(m_speed);
165 lowerSpeed(m_speed);
166 setOffset(m_offset - m_speed);
166 setOffset(m_offset - m_speed);
167 m_offset = offset();
167 m_offset = offset();
168 if (m_speed == QPointF(0, 0)) {
168 if (m_speed == QPointF(0, 0)) {
169 m_state = Idle;
169 m_state = Idle;
170 m_ticker.stop();
170 m_ticker.stop();
171 }
171 }
172 break;
172 break;
173 }
173 }
174 case Stop:
174 case Stop:
175 m_ticker.stop();
175 m_ticker.stop();
176 break;
176 break;
177 case Idle:
177 case Idle:
178 case Move:
178 case Move:
179 case Pressed:
179 case Pressed:
180 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
180 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
181 m_ticker.stop();
181 m_ticker.stop();
182 break;
182 break;
183
183
184 }
184 }
185 }
185 }
186
186
187 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
187 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
188 {
188 {
189 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
189 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
190 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
190 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
191
191
192 x = (x == 0) ? x :
192 x = (x == 0) ? x :
193 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
193 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
194 y = (y == 0) ? y :
194 y = (y == 0) ? y :
195 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
195 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
196 speed.setX(x);
196 speed.setX(x);
197 speed.setY(y);
197 speed.setY(y);
198 }
198 }
199
199
200 void Scroller::calculateSpeed(const QPointF& position)
200 void Scroller::calculateSpeed(const QPointF& position)
201 {
201 {
202 if (m_timeStamp.elapsed() > m_timeTreshold) {
202 if (m_timeStamp.elapsed() > m_timeTreshold) {
203
203
204 QPointF distance = position - m_press;
204 QPointF distance = position - m_press;
205
205
206 m_timeStamp = QTime::currentTime();
206 m_timeStamp = QTime::currentTime();
207 m_speed = distance - m_distance;
207 m_speed = distance - m_distance;
208 m_distance = distance;
208 m_distance = distance;
209
209
210 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
210 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
211
211
212 if (fraction != 0) {
212 if (fraction != 0) {
213 m_fraction.setX(qAbs(m_speed.x() / fraction));
213 m_fraction.setX(qAbs(m_speed.x() / fraction));
214 m_fraction.setY(qAbs(m_speed.y() / fraction));
214 m_fraction.setY(qAbs(m_speed.y() / fraction));
215 }
215 }
216 else {
216 else {
217 m_fraction.setX(1);
217 m_fraction.setX(1);
218 m_fraction.setY(1);
218 m_fraction.setY(1);
219 }
219 }
220 }
220 }
221 }
221 }
222
222
223 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224
224
225 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
225 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
226 m_scroller(scroller)
226 m_scroller(scroller)
227 {
227 {
228
228
229 }
229 }
230
230
231 void ScrollTicker::start(int interval)
231 void ScrollTicker::start(int interval)
232 {
232 {
233 if (!m_timer.isActive()){
233 if (!m_timer.isActive()){
234 m_timer.start(interval, this);
234 m_timer.start(interval, this);
235 }
235 }
236 }
236 }
237
237
238 void ScrollTicker::stop()
238 void ScrollTicker::stop()
239 {
239 {
240 m_timer.stop();
240 m_timer.stop();
241 }
241 }
242
242
243 void ScrollTicker::timerEvent(QTimerEvent *event)
243 void ScrollTicker::timerEvent(QTimerEvent *event)
244 {
244 {
245 Q_UNUSED(event);
245 Q_UNUSED(event);
246 m_scroller->scrollTick();
246 m_scroller->scrollTick();
247 }
247 }
248
248
249 #include "moc_scroller_p.cpp"
249 #include "moc_scroller_p.cpp"
250
250
251 QTCOMMERCIALCHART_END_NAMESPACE
251 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now