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