pieslice.cpp
142 lines
| 3.6 KiB
| text/x-c
|
CppLexer
Tero Ahola
|
r51 | #include "pieslice.h" | ||
Jani Honkonen
|
r174 | #include "pieslicelabel.h" | ||
Jani Honkonen
|
r146 | #include "piepresenter.h" | ||
Jani Honkonen
|
r157 | #include "qpieseries.h" | ||
Tero Ahola
|
r51 | #include <QPainter> | ||
#include <QDebug> | ||||
Jani Honkonen
|
r157 | #include <qmath.h> | ||
Jani Honkonen
|
r163 | #include <QGraphicsSceneEvent> | ||
Jani Honkonen
|
r174 | #include <QTime> | ||
Tero Ahola
|
r51 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
Jani Honkonen
|
r157 | #define PI 3.14159265 | ||
#define EXPLODE_OFFSET 20 | ||||
QPointF offset(qreal angle, qreal length) | ||||
{ | ||||
qreal dx = qSin(angle*(PI/180)) * length; | ||||
qreal dy = qCos(angle*(PI/180)) * length; | ||||
return QPointF(dx, -dy); | ||||
} | ||||
Jani Honkonen
|
r174 | PieSlice::PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent) | ||
:QGraphicsObject(parent), | ||||
m_id(id), | ||||
m_series(series), | ||||
m_slicelabel(new PieSliceLabel(this)), | ||||
m_isHovering(false) | ||||
Tero Ahola
|
r51 | { | ||
Jani Honkonen
|
r174 | Q_ASSERT(series); | ||
Tero Ahola
|
r51 | setAcceptHoverEvents(true); | ||
Jani Honkonen
|
r142 | setAcceptedMouseButtons(Qt::LeftButton); | ||
Jani Honkonen
|
r174 | updateData(); | ||
Tero Ahola
|
r51 | } | ||
PieSlice::~PieSlice() | ||||
{ | ||||
Jani Honkonen
|
r174 | qDebug() << "~PieSlice()" << m_id; | ||
Tero Ahola
|
r51 | } | ||
QRectF PieSlice::boundingRect() const | ||||
{ | ||||
Jani Honkonen
|
r157 | return m_rect; | ||
Tero Ahola
|
r51 | } | ||
QPainterPath PieSlice::shape() const | ||||
{ | ||||
Jani Honkonen
|
r157 | return m_path; | ||
Tero Ahola
|
r51 | } | ||
Jani Honkonen
|
r142 | void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) | ||
Tero Ahola
|
r51 | { | ||
Jani Honkonen
|
r174 | // set hover brush | ||
// TODO: what if we are using gradients... | ||||
QBrush brush = m_data.brush(); | ||||
if (m_isHovering) | ||||
brush.setColor(brush.color().lighter()); | ||||
Jani Honkonen
|
r142 | |||
Jani Honkonen
|
r174 | painter->setRenderHint(QPainter::Antialiasing); | ||
painter->setPen(m_data.pen()); | ||||
painter->setBrush(brush); | ||||
Jani Honkonen
|
r157 | painter->drawPath(m_path); | ||
Tero Ahola
|
r51 | } | ||
Jani Honkonen
|
r174 | void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) | ||
Tero Ahola
|
r51 | { | ||
Jani Honkonen
|
r174 | m_isHovering = true; | ||
Jani Honkonen
|
r157 | update(); | ||
Jani Honkonen
|
r174 | // TODO: emit hoverEnter() | ||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r163 | void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) | ||
Jani Honkonen
|
r157 | { | ||
Jani Honkonen
|
r174 | m_isHovering = false; | ||
Jani Honkonen
|
r157 | update(); | ||
Jani Honkonen
|
r174 | // TODO: emit hoverLeave() | ||
Tero Ahola
|
r51 | } | ||
Jani Honkonen
|
r163 | void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) | ||
Jani Honkonen
|
r142 | { | ||
Jani Honkonen
|
r174 | // TODO: emit clicked | ||
// TODO: should we let the user decide if this can be exploded? | ||||
m_data.setExploded(!m_data.isExploded()); | ||||
m_series->update(m_data); | ||||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r174 | void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span) | ||
Jani Honkonen
|
r157 | { | ||
prepareGeometryChange(); | ||||
Jani Honkonen
|
r174 | // calculate center angle | ||
qreal centerAngle = startAngle + (span/2); | ||||
Jani Honkonen
|
r157 | |||
Jani Honkonen
|
r174 | // adjust rect for exploding | ||
rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET); | ||||
if (m_data.isExploded()) { | ||||
Jani Honkonen
|
r157 | QPointF d = offset((centerAngle), EXPLODE_OFFSET); | ||
rect.translate(d.x(), d.y()); | ||||
} | ||||
Jani Honkonen
|
r174 | // update slice path | ||
// TODO: draw the shape so that it might have a hole in the center | ||||
Jani Honkonen
|
r157 | QPainterPath path; | ||
path.moveTo(rect.center()); | ||||
Jani Honkonen
|
r174 | path.arcTo(rect, -startAngle + 90, -span); | ||
Jani Honkonen
|
r157 | m_path = path; | ||
m_rect = path.boundingRect(); | ||||
Jani Honkonen
|
r174 | // update label position | ||
Jani Honkonen
|
r157 | qreal radius = rect.height() / 2; | ||
Jani Honkonen
|
r174 | QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5); | ||
Jani Honkonen
|
r181 | |||
m_slicelabel->setArmStartPoint(edgeCenter); | ||||
m_slicelabel->setArmAngle(centerAngle); | ||||
m_slicelabel->setArmLength(50); | ||||
m_slicelabel->updateGeometry(); | ||||
Jani Honkonen
|
r174 | |||
//qDebug() << "PieSlice::updateGeometry" << m_rect; | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r157 | |||
Jani Honkonen
|
r174 | void PieSlice::updateData() | ||
Jani Honkonen
|
r157 | { | ||
Jani Honkonen
|
r174 | if (!m_series->m_slices.contains(m_id)) | ||
qWarning() << "PieSlice::updateData(): cannot find slice data!" << m_id; | ||||
QPieSlice data = m_series->slice(m_id); | ||||
// TODO: find out what has changed and trigger some animation | ||||
m_data = data; | ||||
update(); | ||||
m_slicelabel->setVisible(m_data.isLabelVisible()); | ||||
Jani Honkonen
|
r181 | m_slicelabel->setText(m_data.label()); | ||
//m_slicelabel->setPen(m_data.labelPen()); | ||||
//m_slicelabel->setFont(m_data.labelFont()); | ||||
m_slicelabel->updateGeometry(); // text size & font modifies the geometry | ||||
Jani Honkonen
|
r174 | m_slicelabel->update(); | ||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r174 | #include "moc_pieslice.cpp" | ||
Tero Ahola
|
r51 | QTCOMMERCIALCHART_END_NAMESPACE | ||