pieslice.cpp
140 lines
| 3.3 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" | ||
Jani Honkonen
|
r203 | #include "qpieslice.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
|
r203 | PieSlice::PieSlice(QGraphicsItem* parent) | ||
Jani Honkonen
|
r174 | :QGraphicsObject(parent), | ||
m_slicelabel(new PieSliceLabel(this)), | ||||
Jani Honkonen
|
r203 | m_angle(0), | ||
m_span(0), | ||||
m_isExploded(false) | ||||
Tero Ahola
|
r51 | { | ||
setAcceptHoverEvents(true); | ||||
Jani Honkonen
|
r142 | setAcceptedMouseButtons(Qt::LeftButton); | ||
Tero Ahola
|
r51 | } | ||
PieSlice::~PieSlice() | ||||
{ | ||||
Jani Honkonen
|
r203 | |||
Tero Ahola
|
r51 | } | ||
QRectF PieSlice::boundingRect() const | ||||
{ | ||||
Jani Honkonen
|
r203 | return m_path.boundingRect(); | ||
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
|
r203 | painter->setPen(m_pen); | ||
painter->setBrush(m_brush); | ||||
Jani Honkonen
|
r157 | painter->drawPath(m_path); | ||
Tero Ahola
|
r51 | } | ||
Jani Honkonen
|
r174 | void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) | ||
Tero Ahola
|
r51 | { | ||
Jani Honkonen
|
r203 | emit hoverEnter(); | ||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r163 | void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) | ||
Jani Honkonen
|
r157 | { | ||
Jani Honkonen
|
r203 | emit hoverLeave(); | ||
Tero Ahola
|
r51 | } | ||
Jani Honkonen
|
r163 | void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) | ||
Jani Honkonen
|
r142 | { | ||
Jani Honkonen
|
r203 | emit clicked(); | ||
} | ||||
void PieSlice::setPieRect(QRectF rect) | ||||
{ | ||||
m_pieRect = rect; | ||||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r203 | void PieSlice::updateGeometry() | ||
Jani Honkonen
|
r157 | { | ||
prepareGeometryChange(); | ||||
Jani Honkonen
|
r174 | // calculate center angle | ||
Jani Honkonen
|
r203 | qreal centerAngle = m_angle + (m_span/2); | ||
Jani Honkonen
|
r157 | |||
Jani Honkonen
|
r174 | // adjust rect for exploding | ||
Jani Honkonen
|
r203 | QRectF rect = m_pieRect; | ||
Jani Honkonen
|
r174 | rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET); | ||
Jani Honkonen
|
r203 | if (m_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
|
r203 | path.arcTo(rect, -m_angle + 90, -m_span); | ||
path.closeSubpath(); | ||||
Jani Honkonen
|
r157 | m_path = path; | ||
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->updateGeometry(); | ||||
Jani Honkonen
|
r174 | |||
Jani Honkonen
|
r203 | //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span; | ||
} | ||||
void PieSlice::handleSliceDataChanged() | ||||
{ | ||||
QPieSlice *slice = qobject_cast<QPieSlice*>(sender()); | ||||
Q_ASSERT(slice); | ||||
updateData(slice); | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r157 | |||
Jani Honkonen
|
r203 | void PieSlice::updateData(const QPieSlice* sliceData) | ||
Jani Honkonen
|
r157 | { | ||
Jani Honkonen
|
r203 | // TODO: compare what has changes to avoid unneccesary geometry updates | ||
Jani Honkonen
|
r174 | |||
Jani Honkonen
|
r203 | m_angle = sliceData->angle(); | ||
m_span = sliceData->span(); | ||||
m_isExploded = sliceData->isExploded(); | ||||
m_pen = sliceData->pen(); | ||||
m_brush = sliceData->brush(); | ||||
Jani Honkonen
|
r174 | |||
Jani Honkonen
|
r203 | m_slicelabel->setVisible(sliceData->isLabelVisible()); | ||
m_slicelabel->setText(sliceData->label()); | ||||
m_slicelabel->setPen(sliceData->labelPen()); | ||||
m_slicelabel->setFont(sliceData->labelFont()); | ||||
m_slicelabel->setArmLength(sliceData->labelArmLenght()); | ||||
Jani Honkonen
|
r209 | |||
updateGeometry(); | ||||
update(); | ||||
Jani Honkonen
|
r174 | m_slicelabel->update(); | ||
Jani Honkonen
|
r157 | } | ||
Jani Honkonen
|
r174 | #include "moc_pieslice.cpp" | ||
Tero Ahola
|
r51 | QTCOMMERCIALCHART_END_NAMESPACE | ||