##// END OF EJS Templates
Refactor piechart to avoid using invalid QPieSlice pointers....
Jani Honkonen -
r1053:615ed2b99418
parent child
Show More
@@ -251,18 +251,18 void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints,
251 QTimer::singleShot(0, animation, SLOT(start()));
251 QTimer::singleShot(0, animation, SLOT(start()));
252 }
252 }
253
253
254 void ChartAnimator::addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
254 void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty)
255 {
255 {
256 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
256 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
257 Q_ASSERT(animation);
257 Q_ASSERT(animation);
258 animation->addSlice(slice, sliceData, isEmpty);
258 animation->addSlice(sliceItem, sliceData, isEmpty);
259 }
259 }
260
260
261 void ChartAnimator::removeAnimation(PieChartItem *item, QPieSlice *slice)
261 void ChartAnimator::removeAnimation(PieChartItem *item, PieSliceItem *sliceItem)
262 {
262 {
263 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
263 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
264 Q_ASSERT(animation);
264 Q_ASSERT(animation);
265 animation->removeSlice(slice);
265 animation->removeSlice(sliceItem);
266 }
266 }
267
267
268 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
268 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
@@ -272,11 +272,11 void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout)
272 animation->updateValues(layout);
272 animation->updateValues(layout);
273 }
273 }
274
274
275 void ChartAnimator::updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData)
275 void ChartAnimator::updateLayout(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData)
276 {
276 {
277 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
277 PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
278 Q_ASSERT(animation);
278 Q_ASSERT(animation);
279 animation->updateValue(slice, sliceData);
279 animation->updateValue(sliceItem, sliceData);
280 }
280 }
281
281
282 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
282 void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout)
@@ -59,10 +59,10 public:
59 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
59 void updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newContorlPoints, int index);
60 void updateLayout(ChartAxis *item, QVector<qreal> &layout);
60 void updateLayout(ChartAxis *item, QVector<qreal> &layout);
61
61
62 void addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty);
62 void addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty);
63 void removeAnimation(PieChartItem *item, QPieSlice *slice);
63 void removeAnimation(PieChartItem *item, PieSliceItem *sliceItem);
64 void updateLayout(PieChartItem *item, const PieLayout &layout);
64 void updateLayout(PieChartItem *item, const PieLayout &layout);
65 void updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData);
65 void updateLayout(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData);
66
66
67 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
67 void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
68
68
@@ -38,13 +38,13 PieAnimation::~PieAnimation()
38
38
39 void PieAnimation::updateValues(const PieLayout &newValues)
39 void PieAnimation::updateValues(const PieLayout &newValues)
40 {
40 {
41 foreach (QPieSlice *s, newValues.keys())
41 foreach (PieSliceItem *s, newValues.keys())
42 updateValue(s, newValues.value(s));
42 updateValue(s, newValues.value(s));
43 }
43 }
44
44
45 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceData &sliceData)
45 void PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
46 {
46 {
47 PieSliceAnimation *animation = m_animations.value(slice);
47 PieSliceAnimation *animation = m_animations.value(sliceItem);
48 Q_ASSERT(animation);
48 Q_ASSERT(animation);
49 animation->stop();
49 animation->stop();
50
50
@@ -55,10 +55,10 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceData &sliceData)
55 QTimer::singleShot(0, animation, SLOT(start()));
55 QTimer::singleShot(0, animation, SLOT(start()));
56 }
56 }
57
57
58 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
58 void PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty)
59 {
59 {
60 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
60 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
61 m_animations.insert(slice, animation);
61 m_animations.insert(sliceItem, animation);
62
62
63 PieSliceData startValue = sliceData;
63 PieSliceData startValue = sliceData;
64 startValue.m_radius = 0;
64 startValue.m_radius = 0;
@@ -74,15 +74,14 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceData &sliceData, boo
74 QTimer::singleShot(0, animation, SLOT(start()));
74 QTimer::singleShot(0, animation, SLOT(start()));
75 }
75 }
76
76
77 void PieAnimation::removeSlice(QPieSlice *slice)
77 void PieAnimation::removeSlice(PieSliceItem *sliceItem)
78 {
78 {
79 PieSliceAnimation *animation = m_animations.value(slice);
79 PieSliceAnimation *animation = m_animations.value(sliceItem);
80 Q_ASSERT(animation);
80 Q_ASSERT(animation);
81 animation->stop();
81 animation->stop();
82
82
83 PieSliceData endValue = animation->currentSliceValue();
83 PieSliceData endValue = animation->currentSliceValue();
84 endValue.m_radius = 0;
84 endValue.m_radius = 0;
85 // TODO: find the actual angle where this slice disappears
86 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
85 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
87 endValue.m_angleSpan = 0;
86 endValue.m_angleSpan = 0;
88
87
@@ -90,7 +89,10 void PieAnimation::removeSlice(QPieSlice *slice)
90 animation->setDuration(1000);
89 animation->setDuration(1000);
91 animation->setEasingCurve(QEasingCurve::OutQuart);
90 animation->setEasingCurve(QEasingCurve::OutQuart);
92
91
93 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
92 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
93 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
94 m_animations.remove(sliceItem);
95
94 QTimer::singleShot(0, animation, SLOT(start()));
96 QTimer::singleShot(0, animation, SLOT(start()));
95 }
97 }
96
98
@@ -99,14 +101,6 void PieAnimation::updateCurrentValue(const QVariant &)
99 // nothing to do...
101 // nothing to do...
100 }
102 }
101
103
102 void PieAnimation::destroySliceAnimationComplete()
103 {
104 PieSliceAnimation *animation = static_cast<PieSliceAnimation *>(sender());
105 QPieSlice *slice = m_animations.key(animation);
106 m_item->destroySlice(slice);
107 delete m_animations.take(slice);
108 }
109
110 #include "moc_pieanimation_p.cpp"
104 #include "moc_pieanimation_p.cpp"
111
105
112 QTCOMMERCIALCHART_END_NAMESPACE
106 QTCOMMERCIALCHART_END_NAMESPACE
@@ -37,19 +37,16 public:
37 PieAnimation(PieChartItem *item);
37 PieAnimation(PieChartItem *item);
38 ~PieAnimation();
38 ~PieAnimation();
39 void updateValues(const PieLayout &newValues);
39 void updateValues(const PieLayout &newValues);
40 void updateValue(QPieSlice *slice, const PieSliceData &newValue);
40 void updateValue(PieSliceItem *sliceItem, const PieSliceData &newValue);
41 void addSlice(QPieSlice *slice, const PieSliceData &endValue, bool isEmpty);
41 void addSlice(PieSliceItem *sliceItem, const PieSliceData &endValue, bool isEmpty);
42 void removeSlice(QPieSlice *slice);
42 void removeSlice(PieSliceItem *sliceItem);
43
43
44 public: // from QVariantAnimation
44 public: // from QVariantAnimation
45 void updateCurrentValue(const QVariant &value);
45 void updateCurrentValue(const QVariant &value);
46
46
47 public Q_SLOTS:
48 void destroySliceAnimationComplete();
49
50 private:
47 private:
51 PieChartItem *m_item;
48 PieChartItem *m_item;
52 QHash<QPieSlice *, PieSliceAnimation *> m_animations;
49 QHash<PieSliceItem *, PieSliceAnimation *> m_animations;
53 };
50 };
54
51
55 QTCOMMERCIALCHART_END_NAMESPACE
52 QTCOMMERCIALCHART_END_NAMESPACE
@@ -20,7 +20,6
20
20
21 #include "piesliceanimation_p.h"
21 #include "piesliceanimation_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23 #include "qpieslice.h"
24
23
25 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
26
25
@@ -58,10 +57,9 QBrush linearPos(QBrush start, QBrush end, qreal pos)
58 return end;
57 return end;
59 }
58 }
60
59
61 PieSliceAnimation::PieSliceAnimation(PieChartItem *item, QPieSlice *slice)
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
62 :QVariantAnimation(item),
61 :QVariantAnimation(sliceItem),
63 m_item(item),
62 m_sliceItem(sliceItem)
64 m_slice(slice)
65 {
63 {
66 }
64 }
67
65
@@ -120,7 +118,9 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
120 {
118 {
121 if (state() != QAbstractAnimation::Stopped) { //workaround
119 if (state() != QAbstractAnimation::Stopped) { //workaround
122 m_currentValue = qVariantValue<PieSliceData>(value);
120 m_currentValue = qVariantValue<PieSliceData>(value);
123 m_item->setLayout(m_slice, m_currentValue);
121 m_sliceItem->setSliceData(m_currentValue);
122 m_sliceItem->updateGeometry();
123 m_sliceItem->update();
124 }
124 }
125 }
125 }
126
126
@@ -21,18 +21,17
21 #ifndef PIESLICEANIMATION_P_H
21 #ifndef PIESLICEANIMATION_P_H
22 #define PIESLICEANIMATION_P_H
22 #define PIESLICEANIMATION_P_H
23
23
24 #include "piechartitem_p.h"
25 #include <QVariantAnimation>
24 #include <QVariantAnimation>
25 #include "piesliceitem_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 class PieChartItem;
29 class PieChartItem;
30 class QPieSlice;
31
30
32 class PieSliceAnimation : public QVariantAnimation
31 class PieSliceAnimation : public QVariantAnimation
33 {
32 {
34 public:
33 public:
35 PieSliceAnimation(PieChartItem *item, QPieSlice *slice);
34 PieSliceAnimation(PieSliceItem *sliceItem);
36 ~PieSliceAnimation();
35 ~PieSliceAnimation();
37 void setValue(const PieSliceData &startValue, const PieSliceData &endValue);
36 void setValue(const PieSliceData &startValue, const PieSliceData &endValue);
38 void updateValue(const PieSliceData &endValue);
37 void updateValue(const PieSliceData &endValue);
@@ -43,8 +42,7 protected:
43 void updateCurrentValue(const QVariant &value);
42 void updateCurrentValue(const QVariant &value);
44
43
45 private:
44 private:
46 PieChartItem *m_item;
45 PieSliceItem *m_sliceItem;
47 QPieSlice *m_slice;
48 PieSliceData m_currentValue;
46 PieSliceData m_currentValue;
49 };
47 };
50
48
@@ -84,9 +84,9 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
84 PieSliceData data = sliceData(s);
84 PieSliceData data = sliceData(s);
85
85
86 if (animator())
86 if (animator())
87 animator()->addAnimation(this, s, data, isEmpty);
87 animator()->addAnimation(this, item, data, isEmpty);
88 else
88 else
89 setLayout(s, data);
89 setLayout(item, data);
90 }
90 }
91 }
91 }
92
92
@@ -94,11 +94,16 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
94 {
94 {
95 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
95 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
96
96
97 foreach (QPieSlice *s, slices) {
97 foreach (QPieSlice *slice, slices) {
98
99 PieSliceItem *item = m_slices.value(slice);
100 Q_ASSERT(item);
101 m_slices.remove(slice);
102
98 if (animator())
103 if (animator())
99 animator()->removeAnimation(this, s);
104 animator()->removeAnimation(this, item); // animator deletes the PieSliceItem
100 else
105 else
101 destroySlice(s);
106 delete item;
102 }
107 }
103 }
108 }
104
109
@@ -114,7 +119,7 void PieChartItem::handleSliceChanged()
114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
119 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
115 Q_ASSERT(m_slices.contains(slice));
120 Q_ASSERT(m_slices.contains(slice));
116 PieSliceData data = sliceData(slice);
121 PieSliceData data = sliceData(slice);
117 updateLayout(slice, data);
122 updateLayout(m_slices.value(slice), data);
118 update();
123 update();
119 }
124 }
120
125
@@ -160,7 +165,7 PieLayout PieChartItem::calculateLayout()
160 PieLayout layout;
165 PieLayout layout;
161 foreach (QPieSlice* s, m_series->slices()) {
166 foreach (QPieSlice* s, m_series->slices()) {
162 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
167 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
163 layout.insert(s, sliceData(s));
168 layout.insert(m_slices.value(s), sliceData(s));
164 }
169 }
165 return layout;
170 return layout;
166 }
171 }
@@ -173,38 +178,29 void PieChartItem::applyLayout(const PieLayout &layout)
173 setLayout(layout);
178 setLayout(layout);
174 }
179 }
175
180
176 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
181 void PieChartItem::updateLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData)
177 {
182 {
178 if (animator())
183 if (animator())
179 animator()->updateLayout(this, slice, sliceData);
184 animator()->updateLayout(this, sliceItem, sliceData);
180 else
185 else
181 setLayout(slice, sliceData);
186 setLayout(sliceItem, sliceData);
182 }
187 }
183
188
184 void PieChartItem::setLayout(const PieLayout &layout)
189 void PieChartItem::setLayout(const PieLayout &layout)
185 {
190 {
186 foreach (QPieSlice *slice, layout.keys()) {
191 foreach (PieSliceItem *item, layout.keys()) {
187 PieSliceItem *item = m_slices.value(slice);
192 item->setSliceData(layout.value(item));
188 Q_ASSERT(item);
189 item->setSliceData(layout.value(slice));
190 item->updateGeometry();
193 item->updateGeometry();
191 item->update();
194 item->update();
192 }
195 }
193 }
196 }
194
197
195 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
198 void PieChartItem::setLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData)
196 {
197 // find slice
198 PieSliceItem *item = m_slices.value(slice);
199 Q_ASSERT(item);
200 item->setSliceData(sliceData);
201 item->updateGeometry();
202 item->update();
203 }
204
205 void PieChartItem::destroySlice(QPieSlice *slice)
206 {
199 {
207 delete m_slices.take(slice);
200 Q_ASSERT(sliceItem);
201 sliceItem->setSliceData(sliceData);
202 sliceItem->updateGeometry();
203 sliceItem->update();
208 }
204 }
209
205
210 #include "moc_piechartitem_p.cpp"
206 #include "moc_piechartitem_p.cpp"
@@ -30,7 +30,7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 class QPieSlice;
30 class QPieSlice;
31 class ChartPresenter;
31 class ChartPresenter;
32
32
33 typedef QHash<QPieSlice*, PieSliceData> PieLayout;
33 typedef QHash<PieSliceItem*, PieSliceData> PieLayout;
34
34
35 class PieChartItem : public ChartItem
35 class PieChartItem : public ChartItem
36 {
36 {
@@ -59,10 +59,9 public:
59 PieSliceData sliceData(QPieSlice *slice);
59 PieSliceData sliceData(QPieSlice *slice);
60 PieLayout calculateLayout();
60 PieLayout calculateLayout();
61 void applyLayout(const PieLayout &layout);
61 void applyLayout(const PieLayout &layout);
62 void updateLayout(QPieSlice *slice, const PieSliceData &sliceData);
62 void updateLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData);
63 void setLayout(const PieLayout &layout);
63 void setLayout(const PieLayout &layout);
64 void setLayout(QPieSlice *slice, const PieSliceData &sliceData);
64 void setLayout(PieSliceItem *sliceItem, const PieSliceData &sliceData);
65 void destroySlice(QPieSlice *slice);
66
65
67 private:
66 private:
68 friend class PieSliceItem;
67 friend class PieSliceItem;
General Comments 0
You need to be logged in to leave comments. Login now