##// END OF EJS Templates
Fix pie animation chrash
Jani Honkonen -
r2321:9b8615dbb840
parent child
Show More
@@ -1,106 +1,110
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 "pieanimation_p.h"
21 #include "pieanimation_p.h"
22 #include "piesliceanimation_p.h"
22 #include "piesliceanimation_p.h"
23 #include "piechartitem_p.h"
23 #include "piechartitem_p.h"
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 PieAnimation::PieAnimation(PieChartItem *item)
27 PieAnimation::PieAnimation(PieChartItem *item)
28 : ChartAnimation(item),
28 : ChartAnimation(item),
29 m_item(item)
29 m_item(item)
30 {
30 {
31 }
31 }
32
32
33 PieAnimation::~PieAnimation()
33 PieAnimation::~PieAnimation()
34 {
34 {
35 }
35 }
36
36
37 ChartAnimation *PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
37 ChartAnimation *PieAnimation::updateValue(PieSliceItem *sliceItem, const PieSliceData &sliceData)
38 {
38 {
39 PieSliceAnimation *animation = m_animations.value(sliceItem);
39 PieSliceAnimation *animation = m_animations.value(sliceItem);
40 Q_ASSERT(animation);
40 if (!animation) {
41 animation->stop();
41 animation = new PieSliceAnimation(sliceItem);
42 m_animations.insert(sliceItem, animation);
43 } else {
44 animation->stop();
45 }
42
46
43 animation->updateValue(sliceData);
47 animation->updateValue(sliceData);
44 animation->setDuration(ChartAnimationDuration);
48 animation->setDuration(ChartAnimationDuration);
45 animation->setEasingCurve(QEasingCurve::OutQuart);
49 animation->setEasingCurve(QEasingCurve::OutQuart);
46
50
47 return animation;
51 return animation;
48 }
52 }
49
53
50 ChartAnimation *PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
54 ChartAnimation *PieAnimation::addSlice(PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
51 {
55 {
52 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
56 PieSliceAnimation *animation = new PieSliceAnimation(sliceItem);
53 m_animations.insert(sliceItem, animation);
57 m_animations.insert(sliceItem, animation);
54
58
55 PieSliceData startValue = sliceData;
59 PieSliceData startValue = sliceData;
56 startValue.m_radius = 0;
60 startValue.m_radius = 0;
57 if (startupAnimation)
61 if (startupAnimation)
58 startValue.m_startAngle = 0;
62 startValue.m_startAngle = 0;
59 else
63 else
60 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan / 2);
64 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan / 2);
61 startValue.m_angleSpan = 0;
65 startValue.m_angleSpan = 0;
62
66
63 if (sliceData.m_holeRadius > 0)
67 if (sliceData.m_holeRadius > 0)
64 startValue.m_radius = sliceData.m_holeRadius;
68 startValue.m_radius = sliceData.m_holeRadius;
65
69
66 animation->setValue(startValue, sliceData);
70 animation->setValue(startValue, sliceData);
67 animation->setDuration(ChartAnimationDuration);
71 animation->setDuration(ChartAnimationDuration);
68 animation->setEasingCurve(QEasingCurve::OutQuart);
72 animation->setEasingCurve(QEasingCurve::OutQuart);
69
73
70 return animation;
74 return animation;
71 }
75 }
72
76
73 ChartAnimation *PieAnimation::removeSlice(PieSliceItem *sliceItem)
77 ChartAnimation *PieAnimation::removeSlice(PieSliceItem *sliceItem)
74 {
78 {
75 PieSliceAnimation *animation = m_animations.value(sliceItem);
79 PieSliceAnimation *animation = m_animations.value(sliceItem);
76 Q_ASSERT(animation);
80 Q_ASSERT(animation);
77 animation->stop();
81 animation->stop();
78
82
79 PieSliceData endValue = animation->currentSliceValue();
83 PieSliceData endValue = animation->currentSliceValue();
80 if (endValue.m_holeRadius > 0)
84 if (endValue.m_holeRadius > 0)
81 endValue.m_radius = endValue.m_holeRadius;
85 endValue.m_radius = endValue.m_holeRadius;
82 else
86 else
83 endValue.m_radius = 0;
87 endValue.m_radius = 0;
84 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
88 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
85 endValue.m_angleSpan = 0;
89 endValue.m_angleSpan = 0;
86 endValue.m_isLabelVisible = false;
90 endValue.m_isLabelVisible = false;
87
91
88 animation->updateValue(endValue);
92 animation->updateValue(endValue);
89 animation->setDuration(ChartAnimationDuration);
93 animation->setDuration(ChartAnimationDuration);
90 animation->setEasingCurve(QEasingCurve::OutQuart);
94 animation->setEasingCurve(QEasingCurve::OutQuart);
91
95
92 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
96 // PieSliceItem is the parent of PieSliceAnimation so the animation will be deleted as well..
93 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
97 connect(animation, SIGNAL(finished()), sliceItem, SLOT(deleteLater()));
94 m_animations.remove(sliceItem);
98 m_animations.remove(sliceItem);
95
99
96 return animation;
100 return animation;
97 }
101 }
98
102
99 void PieAnimation::updateCurrentValue(const QVariant &)
103 void PieAnimation::updateCurrentValue(const QVariant &)
100 {
104 {
101 // nothing to do...
105 // nothing to do...
102 }
106 }
103
107
104 #include "moc_pieanimation_p.cpp"
108 #include "moc_pieanimation_p.cpp"
105
109
106 QTCOMMERCIALCHART_END_NAMESPACE
110 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,126 +1,128
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 "piesliceanimation_p.h"
21 #include "piesliceanimation_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23
23
24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
24 Q_DECLARE_METATYPE(QTCOMMERCIALCHART_NAMESPACE::PieSliceData)
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 qreal linearPos(qreal start, qreal end, qreal pos)
28 qreal linearPos(qreal start, qreal end, qreal pos)
29 {
29 {
30 return start + ((end - start) * pos);
30 return start + ((end - start) * pos);
31 }
31 }
32
32
33 QPointF linearPos(QPointF start, QPointF end, qreal pos)
33 QPointF linearPos(QPointF start, QPointF end, qreal pos)
34 {
34 {
35 qreal x = linearPos(start.x(), end.x(), pos);
35 qreal x = linearPos(start.x(), end.x(), pos);
36 qreal y = linearPos(start.y(), end.y(), pos);
36 qreal y = linearPos(start.y(), end.y(), pos);
37 return QPointF(x, y);
37 return QPointF(x, y);
38 }
38 }
39
39
40 QPen linearPos(QPen start, QPen end, qreal pos)
40 QPen linearPos(QPen start, QPen end, qreal pos)
41 {
41 {
42 QColor c;
42 QColor c;
43 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
43 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
44 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
44 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
45 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
45 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
46 end.setColor(c);
46 end.setColor(c);
47 return end;
47 return end;
48 }
48 }
49
49
50 QBrush linearPos(QBrush start, QBrush end, qreal pos)
50 QBrush linearPos(QBrush start, QBrush end, qreal pos)
51 {
51 {
52 QColor c;
52 QColor c;
53 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
53 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
54 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
54 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
55 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
55 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
56 end.setColor(c);
56 end.setColor(c);
57 return end;
57 return end;
58 }
58 }
59
59
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
60 PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem)
61 : ChartAnimation(sliceItem),
61 : ChartAnimation(sliceItem),
62 m_sliceItem(sliceItem)
62 m_sliceItem(sliceItem),
63 m_currentValue(m_sliceItem->m_data)
63 {
64 {
65
64 }
66 }
65
67
66 PieSliceAnimation::~PieSliceAnimation()
68 PieSliceAnimation::~PieSliceAnimation()
67 {
69 {
68 }
70 }
69
71
70 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
72 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
71 {
73 {
72 if (state() != QAbstractAnimation::Stopped)
74 if (state() != QAbstractAnimation::Stopped)
73 stop();
75 stop();
74
76
75 m_currentValue = startValue;
77 m_currentValue = startValue;
76
78
77 setKeyValueAt(0.0, qVariantFromValue(startValue));
79 setKeyValueAt(0.0, qVariantFromValue(startValue));
78 setKeyValueAt(1.0, qVariantFromValue(endValue));
80 setKeyValueAt(1.0, qVariantFromValue(endValue));
79 }
81 }
80
82
81 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
83 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
82 {
84 {
83 if (state() != QAbstractAnimation::Stopped)
85 if (state() != QAbstractAnimation::Stopped)
84 stop();
86 stop();
85
87
86 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
88 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
87 setKeyValueAt(1.0, qVariantFromValue(endValue));
89 setKeyValueAt(1.0, qVariantFromValue(endValue));
88 }
90 }
89
91
90 PieSliceData PieSliceAnimation::currentSliceValue()
92 PieSliceData PieSliceAnimation::currentSliceValue()
91 {
93 {
92 // NOTE:
94 // NOTE:
93 // We must use an internal current value because QVariantAnimation::currentValue() is updated
95 // We must use an internal current value because QVariantAnimation::currentValue() is updated
94 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
96 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
95 // will have the end value set from the first call and the second call will interpolate that instead of
97 // will have the end value set from the first call and the second call will interpolate that instead of
96 // the original current value as it was before the first call.
98 // the original current value as it was before the first call.
97 return m_currentValue;
99 return m_currentValue;
98 }
100 }
99
101
100 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
102 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
101 {
103 {
102 PieSliceData startValue = qvariant_cast<PieSliceData>(start);
104 PieSliceData startValue = qvariant_cast<PieSliceData>(start);
103 PieSliceData endValue = qvariant_cast<PieSliceData>(end);
105 PieSliceData endValue = qvariant_cast<PieSliceData>(end);
104
106
105 PieSliceData result;
107 PieSliceData result;
106 result = endValue;
108 result = endValue;
107 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
109 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
108 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
110 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
109 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
111 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
110 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
112 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
111 result.m_slicePen = linearPos(startValue.m_slicePen, endValue.m_slicePen, progress);
113 result.m_slicePen = linearPos(startValue.m_slicePen, endValue.m_slicePen, progress);
112 result.m_sliceBrush = linearPos(startValue.m_sliceBrush, endValue.m_sliceBrush, progress);
114 result.m_sliceBrush = linearPos(startValue.m_sliceBrush, endValue.m_sliceBrush, progress);
113 result.m_holeRadius = linearPos(startValue.m_holeRadius, endValue.m_holeRadius, progress);
115 result.m_holeRadius = linearPos(startValue.m_holeRadius, endValue.m_holeRadius, progress);
114
116
115 return qVariantFromValue(result);
117 return qVariantFromValue(result);
116 }
118 }
117
119
118 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
120 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
119 {
121 {
120 if (state() != QAbstractAnimation::Stopped) { //workaround
122 if (state() != QAbstractAnimation::Stopped) { //workaround
121 m_currentValue = qvariant_cast<PieSliceData>(value);
123 m_currentValue = qvariant_cast<PieSliceData>(value);
122 m_sliceItem->setLayout(m_currentValue);
124 m_sliceItem->setLayout(m_currentValue);
123 }
125 }
124 }
126 }
125
127
126 QTCOMMERCIALCHART_END_NAMESPACE
128 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,90
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef PIESLICEITEM_H
30 #ifndef PIESLICEITEM_H
31 #define PIESLICEITEM_H
31 #define PIESLICEITEM_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "charttheme_p.h"
34 #include "charttheme_p.h"
35 #include "qpieseries.h"
35 #include "qpieseries.h"
36 #include "pieslicedata_p.h"
36 #include "pieslicedata_p.h"
37 #include <QGraphicsItem>
37 #include <QGraphicsItem>
38 #include <QRectF>
38 #include <QRectF>
39 #include <QColor>
39 #include <QColor>
40 #include <QPen>
40 #include <QPen>
41
41
42 #define PIESLICE_LABEL_GAP 5
42 #define PIESLICE_LABEL_GAP 5
43
43
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
45 class PieChartItem;
45 class PieChartItem;
46 class PieSliceLabel;
46 class PieSliceLabel;
47 class QPieSlice;
47 class QPieSlice;
48
48
49 class PieSliceItem : public QGraphicsObject
49 class PieSliceItem : public QGraphicsObject
50 {
50 {
51 Q_OBJECT
51 Q_OBJECT
52
52
53 public:
53 public:
54 PieSliceItem(QGraphicsItem *parent = 0);
54 PieSliceItem(QGraphicsItem *parent = 0);
55 ~PieSliceItem();
55 ~PieSliceItem();
56
56
57 // from QGraphicsItem
57 // from QGraphicsItem
58 QRectF boundingRect() const;
58 QRectF boundingRect() const;
59 QPainterPath shape() const;
59 QPainterPath shape() const;
60 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
60 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
61 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
61 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
62 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
62 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
63 void mousePressEvent(QGraphicsSceneMouseEvent *event);
63 void mousePressEvent(QGraphicsSceneMouseEvent *event);
64
64
65 void setLayout(const PieSliceData &sliceData);
65 void setLayout(const PieSliceData &sliceData);
66 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
66 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
67
67
68 Q_SIGNALS:
68 Q_SIGNALS:
69 void clicked(Qt::MouseButtons buttons);
69 void clicked(Qt::MouseButtons buttons);
70 void hovered(bool state);
70 void hovered(bool state);
71
71
72 private:
72 private:
73 void updateGeometry();
73 void updateGeometry();
74 QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart);
74 QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart);
75 QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart);
75 QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart);
76
76
77 private:
77 private:
78 PieSliceData m_data;
78 PieSliceData m_data;
79 QRectF m_boundingRect;
79 QRectF m_boundingRect;
80 QPainterPath m_slicePath;
80 QPainterPath m_slicePath;
81 QPainterPath m_labelArmPath;
81 QPainterPath m_labelArmPath;
82 QRectF m_labelTextRect;
82 QRectF m_labelTextRect;
83 bool m_hovered;
83 bool m_hovered;
84
85 friend class PieSliceAnimation;
84 };
86 };
85
87
86 QTCOMMERCIALCHART_END_NAMESPACE
88 QTCOMMERCIALCHART_END_NAMESPACE
87
89
88 #endif // PIESLICEITEM_H
90 #endif // PIESLICEITEM_H
General Comments 0
You need to be logged in to leave comments. Login now