1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Charts module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include <private/piesliceanimation_p.h> |
31 | #include <private/piechartitem_p.h> |
32 | |
33 | Q_DECLARE_METATYPE(QT_CHARTS_NAMESPACE::PieSliceData) |
34 | |
35 | QT_CHARTS_BEGIN_NAMESPACE |
36 | |
37 | qreal linearPos(qreal start, qreal end, qreal pos) |
38 | { |
39 | return start + ((end - start) * pos); |
40 | } |
41 | |
42 | QPointF linearPos(QPointF start, QPointF end, qreal pos) |
43 | { |
44 | qreal x = linearPos(start: start.x(), end: end.x(), pos); |
45 | qreal y = linearPos(start: start.y(), end: end.y(), pos); |
46 | return QPointF(x, y); |
47 | } |
48 | |
49 | QPen linearPos(QPen start, QPen end, qreal pos) |
50 | { |
51 | QColor c; |
52 | c.setRedF(linearPos(start: start.color().redF(), end: end.color().redF(), pos)); |
53 | c.setGreenF(linearPos(start: start.color().greenF(), end: end.color().greenF(), pos)); |
54 | c.setBlueF(linearPos(start: start.color().blueF(), end: end.color().blueF(), pos)); |
55 | end.setColor(c); |
56 | return end; |
57 | } |
58 | |
59 | QBrush linearPos(QBrush start, QBrush end, qreal pos) |
60 | { |
61 | QColor c; |
62 | c.setRedF(linearPos(start: start.color().redF(), end: end.color().redF(), pos)); |
63 | c.setGreenF(linearPos(start: start.color().greenF(), end: end.color().greenF(), pos)); |
64 | c.setBlueF(linearPos(start: start.color().blueF(), end: end.color().blueF(), pos)); |
65 | end.setColor(c); |
66 | return end; |
67 | } |
68 | |
69 | PieSliceAnimation::PieSliceAnimation(PieSliceItem *sliceItem) |
70 | : ChartAnimation(sliceItem), |
71 | m_sliceItem(sliceItem), |
72 | m_currentValue(m_sliceItem->m_data) |
73 | { |
74 | |
75 | } |
76 | |
77 | PieSliceAnimation::~PieSliceAnimation() |
78 | { |
79 | } |
80 | |
81 | void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue) |
82 | { |
83 | if (state() != QAbstractAnimation::Stopped) |
84 | stop(); |
85 | |
86 | m_currentValue = startValue; |
87 | |
88 | setKeyValueAt(step: 0.0, value: QVariant::fromValue(value: startValue)); |
89 | setKeyValueAt(step: 1.0, value: QVariant::fromValue(value: endValue)); |
90 | } |
91 | |
92 | void PieSliceAnimation::updateValue(const PieSliceData &endValue) |
93 | { |
94 | if (state() != QAbstractAnimation::Stopped) |
95 | stop(); |
96 | |
97 | setKeyValueAt(step: 0.0, value: QVariant::fromValue(value: m_currentValue)); |
98 | setKeyValueAt(step: 1.0, value: QVariant::fromValue(value: endValue)); |
99 | } |
100 | |
101 | PieSliceData PieSliceAnimation::currentSliceValue() |
102 | { |
103 | // NOTE: |
104 | // We must use an internal current value because QVariantAnimation::currentValue() is updated |
105 | // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue() |
106 | // will have the end value set from the first call and the second call will interpolate that instead of |
107 | // the original current value as it was before the first call. |
108 | return m_currentValue; |
109 | } |
110 | |
111 | QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const |
112 | { |
113 | PieSliceData startValue = qvariant_cast<PieSliceData>(v: start); |
114 | PieSliceData endValue = qvariant_cast<PieSliceData>(v: end); |
115 | |
116 | PieSliceData result; |
117 | result = endValue; |
118 | result.m_center = linearPos(start: startValue.m_center, end: endValue.m_center, pos: progress); |
119 | result.m_radius = linearPos(start: startValue.m_radius, end: endValue.m_radius, pos: progress); |
120 | result.m_startAngle = linearPos(start: startValue.m_startAngle, end: endValue.m_startAngle, pos: progress); |
121 | result.m_angleSpan = linearPos(start: startValue.m_angleSpan, end: endValue.m_angleSpan, pos: progress); |
122 | result.m_slicePen = linearPos(start: startValue.m_slicePen, end: endValue.m_slicePen, pos: progress); |
123 | result.m_sliceBrush = linearPos(start: startValue.m_sliceBrush, end: endValue.m_sliceBrush, pos: progress); |
124 | result.m_holeRadius = linearPos(start: startValue.m_holeRadius, end: endValue.m_holeRadius, pos: progress); |
125 | |
126 | return QVariant::fromValue(value: result); |
127 | } |
128 | |
129 | void PieSliceAnimation::updateCurrentValue(const QVariant &value) |
130 | { |
131 | if (state() != QAbstractAnimation::Stopped) { //workaround |
132 | m_currentValue = qvariant_cast<PieSliceData>(v: value); |
133 | m_sliceItem->setLayout(m_currentValue); |
134 | } |
135 | } |
136 | |
137 | QT_CHARTS_END_NAMESPACE |
138 | |