##// END OF EJS Templates
Add HTML support for pie slice labels...
Titta Heikkala -
r2626:ec2eee97ed6a
parent child
Show More
@@ -1,300 +1,305
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 "piesliceitem_p.h"
21 #include "piesliceitem_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23 #include "qpieseries.h"
23 #include "qpieseries.h"
24 #include "qpieslice.h"
24 #include "qpieslice.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QGraphicsSceneEvent>
28 #include <QGraphicsSceneEvent>
29 #include <QTime>
29 #include <QTime>
30 #include <QTextDocument>
30 #include <QDebug>
31 #include <QDebug>
31
32
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
34
34 QPointF offset(qreal angle, qreal length)
35 QPointF offset(qreal angle, qreal length)
35 {
36 {
36 qreal dx = qSin(angle * (M_PI / 180)) * length;
37 qreal dx = qSin(angle * (M_PI / 180)) * length;
37 qreal dy = qCos(angle * (M_PI / 180)) * length;
38 qreal dy = qCos(angle * (M_PI / 180)) * length;
38 return QPointF(dx, -dy);
39 return QPointF(dx, -dy);
39 }
40 }
40
41
41 PieSliceItem::PieSliceItem(QGraphicsItem *parent)
42 PieSliceItem::PieSliceItem(QGraphicsItem *parent)
42 : QGraphicsObject(parent),
43 : QGraphicsObject(parent),
43 m_hovered(false)
44 m_hovered(false)
44 {
45 {
45 setAcceptHoverEvents(true);
46 setAcceptHoverEvents(true);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setZValue(ChartPresenter::PieSeriesZValue);
48 setZValue(ChartPresenter::PieSeriesZValue);
49 m_labelItem = new QGraphicsTextItem(this);
50 m_labelItem->document()->setDocumentMargin(1.0);
48 }
51 }
49
52
50 PieSliceItem::~PieSliceItem()
53 PieSliceItem::~PieSliceItem()
51 {
54 {
52 // If user is hovering over the slice and it gets destroyed we do
55 // If user is hovering over the slice and it gets destroyed we do
53 // not get a hover leave event. So we must emit the signal here.
56 // not get a hover leave event. So we must emit the signal here.
54 if (m_hovered)
57 if (m_hovered)
55 emit hovered(false);
58 emit hovered(false);
56 }
59 }
57
60
58 QRectF PieSliceItem::boundingRect() const
61 QRectF PieSliceItem::boundingRect() const
59 {
62 {
60 return m_boundingRect;
63 return m_boundingRect;
61 }
64 }
62
65
63 QPainterPath PieSliceItem::shape() const
66 QPainterPath PieSliceItem::shape() const
64 {
67 {
65 // Don't include the label and label arm.
68 // Don't include the label and label arm.
66 // This is used to detect a mouse clicks. We do not want clicks from label.
69 // This is used to detect a mouse clicks. We do not want clicks from label.
67 return m_slicePath;
70 return m_slicePath;
68 }
71 }
69
72
70 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
73 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
71 {
74 {
72 painter->save();
75 painter->save();
73 painter->setClipRect(parentItem()->boundingRect());
76 painter->setClipRect(parentItem()->boundingRect());
74 painter->setPen(m_data.m_slicePen);
77 painter->setPen(m_data.m_slicePen);
75 painter->setBrush(m_data.m_sliceBrush);
78 painter->setBrush(m_data.m_sliceBrush);
76 painter->drawPath(m_slicePath);
79 painter->drawPath(m_slicePath);
77 painter->restore();
80 painter->restore();
78
81
79 if (m_data.m_isLabelVisible) {
82 if (m_data.m_isLabelVisible) {
80 painter->save();
83 painter->save();
81
84
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
85 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
84 painter->setPen(m_data.m_labelBrush.color());
85 painter->setBrush(m_data.m_labelBrush);
86 painter->setBrush(m_data.m_labelBrush);
86 painter->setFont(m_data.m_labelFont);
87
87
88 QFontMetricsF fm(m_data.m_labelFont);
88 if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
89 QString label = m_data.m_labelText;
90 QRectF labelBoundingRect;
91
92 switch (m_data.m_labelPosition) {
93 case QPieSlice::LabelOutside:
94 painter->setClipRect(parentItem()->boundingRect());
89 painter->setClipRect(parentItem()->boundingRect());
95 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
90 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
96 if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) {
97 // Only one line label text is supported currently.
98 // The height for the label is set one pixel over the font metrics.
99 label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
100 qreal(0.0), m_labelTextRect.width(),
101 fm.height() + 1.0, labelBoundingRect);
102 }
103 painter->drawText(m_labelTextRect, Qt::AlignCenter, label);
104 break;
105 case QPieSlice::LabelInsideHorizontal:
106 painter->setClipPath(m_slicePath);
107 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
108 break;
109 case QPieSlice::LabelInsideTangential:
110 painter->setClipPath(m_slicePath);
111 painter->translate(m_labelTextRect.center());
112 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
113 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
114 break;
115 case QPieSlice::LabelInsideNormal:
116 painter->setClipPath(m_slicePath);
117 painter->translate(m_labelTextRect.center());
118 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
119 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
120 else
121 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
122 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
123 break;
124 }
91 }
125
92
126 painter->restore();
93 painter->restore();
127 }
94 }
128 }
95 }
129
96
130 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
97 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
131 {
98 {
132 m_hovered = true;
99 m_hovered = true;
133 emit hovered(true);
100 emit hovered(true);
134 }
101 }
135
102
136 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
103 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
137 {
104 {
138 m_hovered = false;
105 m_hovered = false;
139 emit hovered(false);
106 emit hovered(false);
140 }
107 }
141
108
142 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
109 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
143 {
110 {
144 emit clicked(event->buttons());
111 emit clicked(event->buttons());
145 QGraphicsItem::mousePressEvent(event);
112 QGraphicsItem::mousePressEvent(event);
146 }
113 }
147
114
148 void PieSliceItem::setLayout(const PieSliceData &sliceData)
115 void PieSliceItem::setLayout(const PieSliceData &sliceData)
149 {
116 {
150 m_data = sliceData;
117 m_data = sliceData;
151 updateGeometry();
118 updateGeometry();
152 update();
119 update();
153 }
120 }
154
121
155 void PieSliceItem::updateGeometry()
122 void PieSliceItem::updateGeometry()
156 {
123 {
157 if (m_data.m_radius <= 0)
124 if (m_data.m_radius <= 0)
158 return;
125 return;
159
126
160 prepareGeometryChange();
127 prepareGeometryChange();
161
128
162 // slice path
129 // slice path
163 qreal centerAngle;
130 qreal centerAngle;
164 QPointF armStart;
131 QPointF armStart;
165 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
132 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
166
133
167 // text rect
134 if (m_data.m_isLabelVisible) {
168 QFontMetricsF fm(m_data.m_labelFont);
135 // text rect
169 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
136 QFontMetricsF fm(m_data.m_labelFont);
170
137 m_labelTextRect = ChartPresenter::textBoundingRect(m_data.m_labelFont,
171 // label arm path
138 m_data.m_labelText,
172 QPointF labelTextStart;
139 0);
173 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
140
174
141 QString label(m_data.m_labelText);
175 // text position
142 m_labelItem->setVisible(m_data.m_isLabelVisible);
176 switch (m_data.m_labelPosition) {
143 m_labelItem->setDefaultTextColor(m_data.m_labelBrush.color());
177 case QPieSlice::LabelOutside:
144 m_labelItem->setFont(m_data.m_labelFont);
178 m_labelTextRect.moveBottomLeft(labelTextStart);
145
179 if (m_labelTextRect.left() < 0)
146 // text position
180 m_labelTextRect.setLeft(0);
147 if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
181 if (m_labelTextRect.right() > parentItem()->boundingRect().right())
148 setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
182 m_labelTextRect.setRight(parentItem()->boundingRect().right());
149
183 break;
150 // label arm path
184 case QPieSlice::LabelInsideHorizontal:
151 QPointF labelTextStart;
185 case QPieSlice::LabelInsideTangential: {
152 m_labelArmPath = labelArmPath(armStart, centerAngle,
186 QPointF textCenter;
153 m_data.m_radius * m_data.m_labelArmLengthFactor,
187 if (m_data.m_holeRadius > 0)
154 m_labelTextRect.width(), &labelTextStart);
188 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
155
189 else
156 m_labelTextRect.moveBottomLeft(labelTextStart);
190 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
157 if (m_labelTextRect.left() < 0)
191 m_labelTextRect.moveCenter(textCenter);
158 m_labelTextRect.setLeft(0);
192 break;
159 else if (m_labelTextRect.left() < parentItem()->boundingRect().left())
193 }
160 m_labelTextRect.setLeft(parentItem()->boundingRect().left());
194 case QPieSlice::LabelInsideNormal: {
161 if (m_labelTextRect.right() > parentItem()->boundingRect().right())
195 QPointF textCenter;
162 m_labelTextRect.setRight(parentItem()->boundingRect().right());
196 if (m_data.m_holeRadius > 0)
163
197 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
164 if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) {
198 else
165 label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
199 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
166 qreal(0.0), m_labelTextRect.width(),
200 m_labelTextRect.moveCenter(textCenter);
167 m_labelTextRect.height(), m_labelTextRect);
201 break;
168 m_labelArmPath = labelArmPath(armStart, centerAngle,
202 }
169 m_data.m_radius * m_data.m_labelArmLengthFactor,
170 m_labelTextRect.width(), &labelTextStart);
171
172 m_labelTextRect.moveBottomLeft(labelTextStart);
173 }
174 m_labelItem->setTextWidth(m_labelTextRect.width()
175 + m_labelItem->document()->documentMargin());
176 m_labelItem->setHtml(label);
177 m_labelItem->setPos(m_labelTextRect.x(), m_labelTextRect.y() + 1.0);
178 } else {
179 // label inside
180 setFlag(QGraphicsItem::ItemClipsChildrenToShape);
181 m_labelItem->setTextWidth(m_labelTextRect.width()
182 + m_labelItem->document()->documentMargin());
183 m_labelItem->setHtml(label);
184
185 QPointF textCenter;
186 if (m_data.m_holeRadius > 0) {
187 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius
188 + (m_data.m_radius
189 - m_data.m_holeRadius) / 2);
190 } else {
191 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
192 }
193 m_labelItem->setPos(textCenter.x() - m_labelItem->boundingRect().width() / 2,
194 textCenter.y() - fm.height() / 2);
195
196 QPointF labelCenter = m_labelItem->boundingRect().center();
197 m_labelItem->setTransformOriginPoint(labelCenter);
198
199 if (m_data.m_labelPosition == QPieSlice::LabelInsideTangential) {
200 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2);
201 } else if (m_data.m_labelPosition == QPieSlice::LabelInsideNormal) {
202 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
203 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
204 else
205 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
206 }
207 }
203 }
208 }
204
209
205 // bounding rect
210 // bounding rect
206 if (m_data.m_isLabelVisible)
211 if (m_data.m_isLabelVisible)
207 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
212 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
208 else
213 else
209 m_boundingRect = m_slicePath.boundingRect();
214 m_boundingRect = m_slicePath.boundingRect();
210
215
211 // Inflate bounding rect by 2/3 pen width to make sure it encompasses whole slice also for thick pens
216 // Inflate bounding rect by 2/3 pen width to make sure it encompasses whole slice also for thick pens
212 // and miter joins.
217 // and miter joins.
213 int penWidth = (m_data.m_slicePen.width() * 2) / 3;
218 int penWidth = (m_data.m_slicePen.width() * 2) / 3;
214 m_boundingRect = m_boundingRect.adjusted(-penWidth, -penWidth, penWidth, penWidth);
219 m_boundingRect = m_boundingRect.adjusted(-penWidth, -penWidth, penWidth, penWidth);
215 }
220 }
216
221
217 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
222 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
218 {
223 {
219 if (slice->isExploded()) {
224 if (slice->isExploded()) {
220 qreal centerAngle = slice->startAngle() + (slice->angleSpan() / 2);
225 qreal centerAngle = slice->startAngle() + (slice->angleSpan() / 2);
221 qreal len = radius * slice->explodeDistanceFactor();
226 qreal len = radius * slice->explodeDistanceFactor();
222 point += offset(centerAngle, len);
227 point += offset(centerAngle, len);
223 }
228 }
224 return point;
229 return point;
225 }
230 }
226
231
227 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart)
232 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart)
228 {
233 {
229 // calculate center angle
234 // calculate center angle
230 *centerAngle = startAngle + (angleSpan / 2);
235 *centerAngle = startAngle + (angleSpan / 2);
231
236
232 // calculate slice rectangle
237 // calculate slice rectangle
233 QRectF rect(center.x() - radius, center.y() - radius, radius * 2, radius * 2);
238 QRectF rect(center.x() - radius, center.y() - radius, radius * 2, radius * 2);
234
239
235 // slice path
240 // slice path
236 QPainterPath path;
241 QPainterPath path;
237 if (m_data.m_holeRadius > 0) {
242 if (m_data.m_holeRadius > 0) {
238 QRectF insideRect(center.x() - m_data.m_holeRadius, center.y() - m_data.m_holeRadius, m_data.m_holeRadius * 2, m_data.m_holeRadius * 2);
243 QRectF insideRect(center.x() - m_data.m_holeRadius, center.y() - m_data.m_holeRadius, m_data.m_holeRadius * 2, m_data.m_holeRadius * 2);
239 path.arcMoveTo(rect, -startAngle + 90);
244 path.arcMoveTo(rect, -startAngle + 90);
240 path.arcTo(rect, -startAngle + 90, -angleSpan);
245 path.arcTo(rect, -startAngle + 90, -angleSpan);
241 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
246 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
242 path.closeSubpath();
247 path.closeSubpath();
243 } else {
248 } else {
244 path.moveTo(rect.center());
249 path.moveTo(rect.center());
245 path.arcTo(rect, -startAngle + 90, -angleSpan);
250 path.arcTo(rect, -startAngle + 90, -angleSpan);
246 path.closeSubpath();
251 path.closeSubpath();
247 }
252 }
248
253
249 // calculate label arm start point
254 // calculate label arm start point
250 *armStart = center;
255 *armStart = center;
251 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
256 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
252
257
253 return path;
258 return path;
254 }
259 }
255
260
256 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
261 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
257 {
262 {
258 // Normalize the angle to 0-360 range
263 // Normalize the angle to 0-360 range
259 // NOTE: We are using int here on purpose. Depenging on platform and hardware
264 // NOTE: We are using int here on purpose. Depenging on platform and hardware
260 // qreal can be a double, float or something the user gives to the Qt configure
265 // qreal can be a double, float or something the user gives to the Qt configure
261 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
266 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
262 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
267 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
263 // that might break we just use int. Precision for this is just fine for our needs.
268 // that might break we just use int. Precision for this is just fine for our needs.
264 int normalized = angle * 10.0;
269 int normalized = angle * 10.0;
265 normalized = normalized % 3600;
270 normalized = normalized % 3600;
266 if (normalized < 0)
271 if (normalized < 0)
267 normalized += 3600;
272 normalized += 3600;
268 angle = (qreal) normalized / 10.0;
273 angle = (qreal) normalized / 10.0;
269
274
270 // prevent label arm pointing straight down because it will look bad
275 // prevent label arm pointing straight down because it will look bad
271 if (angle < 180 && angle > 170)
276 if (angle < 180 && angle > 170)
272 angle = 170;
277 angle = 170;
273 if (angle > 180 && angle < 190)
278 if (angle > 180 && angle < 190)
274 angle = 190;
279 angle = 190;
275
280
276 // line from slice to label
281 // line from slice to label
277 QPointF parm1 = start + offset(angle, length);
282 QPointF parm1 = start + offset(angle, length);
278
283
279 // line to underline the label
284 // line to underline the label
280 QPointF parm2 = parm1;
285 QPointF parm2 = parm1;
281 if (angle < 180) { // arm swings the other way on the left side
286 if (angle < 180) { // arm swings the other way on the left side
282 parm2 += QPointF(textWidth, 0);
287 parm2 += QPointF(textWidth, 0);
283 *textStart = parm1;
288 *textStart = parm1;
284 } else {
289 } else {
285 parm2 += QPointF(-textWidth, 0);
290 parm2 += QPointF(-textWidth, 0);
286 *textStart = parm2;
291 *textStart = parm2;
287 }
292 }
288
293
289 QPainterPath path;
294 QPainterPath path;
290 path.moveTo(start);
295 path.moveTo(start);
291 path.lineTo(parm1);
296 path.lineTo(parm1);
292 path.lineTo(parm2);
297 path.lineTo(parm2);
293
298
294 return path;
299 return path;
295 }
300 }
296
301
297 #include "moc_piesliceitem_p.cpp"
302 #include "moc_piesliceitem_p.cpp"
298
303
299 QTCOMMERCIALCHART_END_NAMESPACE
304 QTCOMMERCIALCHART_END_NAMESPACE
300
305
@@ -1,90 +1,91
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise 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 Qt Enterprise Chart API. It exists purely as an
24 // This file is not part of the Qt Enterprise 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 QGraphicsTextItem *m_labelItem;
84
85
85 friend class PieSliceAnimation;
86 friend class PieSliceAnimation;
86 };
87 };
87
88
88 QTCOMMERCIALCHART_END_NAMESPACE
89 QTCOMMERCIALCHART_END_NAMESPACE
89
90
90 #endif // PIESLICEITEM_H
91 #endif // PIESLICEITEM_H
General Comments 0
You need to be logged in to leave comments. Login now