piechartitem.cpp
211 lines
| 6.1 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
** | ||||
** Copyright (C) 2012 Digia Plc | ||||
** All rights reserved. | ||||
** For any questions to Digia, please use contact form at http://qt.digia.com | ||||
** | ||||
** This file is part of the Qt Commercial Charts Add-on. | ||||
** | ||||
** $QT_BEGIN_LICENSE$ | ||||
** Licensees holding valid Qt Commercial licenses may use this file in | ||||
** accordance with the Qt Commercial License Agreement provided with the | ||||
** Software or, alternatively, in accordance with the terms contained in | ||||
** a written agreement between you and Digia. | ||||
** | ||||
** If you have questions regarding the use of this file, please use | ||||
** contact form at http://qt.digia.com | ||||
** $QT_END_LICENSE$ | ||||
** | ||||
****************************************************************************/ | ||||
Jani Honkonen
|
r568 | #include "piechartitem_p.h" | ||
Jani Honkonen
|
r673 | #include "piesliceitem_p.h" | ||
Jani Honkonen
|
r203 | #include "qpieslice.h" | ||
Jani Honkonen
|
r289 | #include "qpieseries.h" | ||
Tero Ahola
|
r490 | #include "chartpresenter_p.h" | ||
Jani Honkonen
|
r659 | #include "chartdataset_p.h" | ||
Jani Honkonen
|
r618 | #include "chartanimator_p.h" | ||
Jani Honkonen
|
r142 | #include <QDebug> | ||
Jani Honkonen
|
r437 | #include <QPainter> | ||
Jani Honkonen
|
r621 | #include <QTimer> | ||
Jani Honkonen
|
r142 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
Michal Klocek
|
r677 | PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter) | ||
:ChartItem(presenter), | ||||
m_series(series) | ||||
Jani Honkonen
|
r142 | { | ||
Q_ASSERT(series); | ||||
Jani Honkonen
|
r621 | connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>))); | ||
connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>))); | ||||
connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged())); | ||||
connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged())); | ||||
Jani Honkonen
|
r905 | QTimer::singleShot(0, this, SLOT(initialize())); // TODO: get rid of this | ||
Tero Ahola
|
r490 | |||
// Note: the following does not affect as long as the item does not have anything to paint | ||||
setZValue(ChartPresenter::PieSeriesZValue); | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | PieChartItem::~PieChartItem() | ||
Jani Honkonen
|
r142 | { | ||
Jani Honkonen
|
r174 | // slices deleted automatically through QGraphicsItem | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) | ||
Jani Honkonen
|
r142 | { | ||
Tero Ahola
|
r611 | Q_UNUSED(painter) | ||
Jani Honkonen
|
r174 | // TODO: paint shadows for all components | ||
// - get paths from items & merge & offset and draw with shadow color? | ||||
Jani Honkonen
|
r437 | //painter->setBrush(QBrush(Qt::red)); | ||
//painter->drawRect(m_debugRect); | ||||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r621 | void PieChartItem::initialize() | ||
{ | ||||
Jani Honkonen
|
r669 | handleSlicesAdded(m_series->slices()); | ||
Jani Honkonen
|
r621 | } | ||
void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices) | ||||
{ | ||||
Jani Honkonen
|
r634 | bool isEmpty = m_slices.isEmpty(); | ||
Michal Klocek
|
r943 | presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series)); | ||
Jani Honkonen
|
r659 | |||
Jani Honkonen
|
r621 | foreach (QPieSlice *s, slices) { | ||
Jani Honkonen
|
r673 | PieSliceItem* item = new PieSliceItem(this); | ||
m_slices.insert(s, item); | ||||
Jani Honkonen
|
r621 | connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged())); | ||
Jani Honkonen
|
r707 | connect(item, SIGNAL(clicked(Qt::MouseButtons)), s, SIGNAL(clicked(Qt::MouseButtons))); | ||
Jani Honkonen
|
r673 | connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter())); | ||
connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave())); | ||||
Jani Honkonen
|
r621 | |||
Jani Honkonen
|
r668 | PieSliceData data = sliceData(s); | ||
Jani Honkonen
|
r621 | |||
Michal Klocek
|
r679 | if (animator()) | ||
animator()->addAnimation(this, s, data, isEmpty); | ||||
Jani Honkonen
|
r621 | else | ||
Jani Honkonen
|
r668 | setLayout(s, data); | ||
Jani Honkonen
|
r621 | } | ||
} | ||||
void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices) | ||||
{ | ||||
Michal Klocek
|
r943 | presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series)); | ||
Jani Honkonen
|
r659 | |||
Jani Honkonen
|
r621 | foreach (QPieSlice *s, slices) { | ||
Michal Klocek
|
r677 | if (animator()) | ||
animator()->removeAnimation(this, s); | ||||
Jani Honkonen
|
r621 | else | ||
destroySlice(s); | ||||
} | ||||
} | ||||
void PieChartItem::handlePieLayoutChanged() | ||||
Jani Honkonen
|
r174 | { | ||
Jani Honkonen
|
r629 | PieLayout layout = calculateLayout(); | ||
Jani Honkonen
|
r618 | applyLayout(layout); | ||
Jani Honkonen
|
r566 | update(); | ||
} | ||||
Jani Honkonen
|
r142 | |||
Jani Honkonen
|
r568 | void PieChartItem::handleSliceChanged() | ||
Jani Honkonen
|
r566 | { | ||
Jani Honkonen
|
r618 | QPieSlice* slice = qobject_cast<QPieSlice *>(sender()); | ||
Q_ASSERT(m_slices.contains(slice)); | ||||
Jani Honkonen
|
r668 | PieSliceData data = sliceData(slice); | ||
updateLayout(slice, data); | ||||
Jani Honkonen
|
r566 | update(); | ||
Jani Honkonen
|
r203 | } | ||
Jani Honkonen
|
r174 | |||
Jani Honkonen
|
r568 | void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal) | ||
Jani Honkonen
|
r203 | { | ||
// TODO | ||||
} | ||||
Jani Honkonen
|
r568 | void PieChartItem::handleGeometryChanged(const QRectF& rect) | ||
Jani Honkonen
|
r203 | { | ||
Jani Honkonen
|
r289 | prepareGeometryChange(); | ||
Jani Honkonen
|
r566 | m_rect = rect; | ||
Jani Honkonen
|
r621 | handlePieLayoutChanged(); | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r621 | void PieChartItem::calculatePieLayout() | ||
Jani Honkonen
|
r566 | { | ||
Jani Honkonen
|
r454 | // find pie center coordinates | ||
Tero Ahola
|
r884 | m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->horizontalPosition())); | ||
m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->verticalPosition())); | ||||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r454 | // find maximum radius for pie | ||
Jani Honkonen
|
r621 | m_pieRadius = m_rect.height() / 2; | ||
Jani Honkonen
|
r454 | if (m_rect.width() < m_rect.height()) | ||
Jani Honkonen
|
r621 | m_pieRadius = m_rect.width() / 2; | ||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r454 | // apply size factor | ||
Jani Honkonen
|
r621 | m_pieRadius *= m_series->pieSize(); | ||
} | ||||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r668 | PieSliceData PieChartItem::sliceData(QPieSlice *slice) | ||
Jani Honkonen
|
r621 | { | ||
Jani Honkonen
|
r818 | // TODO: This function is kid of useless now. Refactor. | ||
Jani Honkonen
|
r822 | PieSliceData sliceData = PieSliceData::data(slice); | ||
Jani Honkonen
|
r673 | sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice); | ||
Jani Honkonen
|
r668 | sliceData.m_radius = m_pieRadius; | ||
return sliceData; | ||||
Jani Honkonen
|
r621 | } | ||
Jani Honkonen
|
r629 | PieLayout PieChartItem::calculateLayout() | ||
Jani Honkonen
|
r621 | { | ||
calculatePieLayout(); | ||||
Jani Honkonen
|
r668 | PieLayout layout; | ||
Jani Honkonen
|
r566 | foreach (QPieSlice* s, m_series->slices()) { | ||
Jani Honkonen
|
r621 | if (m_slices.contains(s)) // calculate layout only for those slices that are already visible | ||
Jani Honkonen
|
r668 | layout.insert(s, sliceData(s)); | ||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r566 | return layout; | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r629 | void PieChartItem::applyLayout(const PieLayout &layout) | ||
Jani Honkonen
|
r142 | { | ||
Michal Klocek
|
r677 | if (animator()) | ||
animator()->updateLayout(this, layout); | ||||
Jani Honkonen
|
r618 | else | ||
setLayout(layout); | ||||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r668 | void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData) | ||
Jani Honkonen
|
r618 | { | ||
Michal Klocek
|
r679 | if (animator()) | ||
animator()->updateLayout(this, slice, sliceData); | ||||
Jani Honkonen
|
r618 | else | ||
Jani Honkonen
|
r668 | setLayout(slice, sliceData); | ||
Jani Honkonen
|
r618 | } | ||
Jani Honkonen
|
r629 | void PieChartItem::setLayout(const PieLayout &layout) | ||
Jani Honkonen
|
r289 | { | ||
Jani Honkonen
|
r629 | foreach (QPieSlice *slice, layout.keys()) { | ||
Jani Honkonen
|
r673 | PieSliceItem *item = m_slices.value(slice); | ||
Q_ASSERT(item); | ||||
item->setSliceData(layout.value(slice)); | ||||
item->updateGeometry(); | ||||
item->update(); | ||||
Jani Honkonen
|
r289 | } | ||
Jani Honkonen
|
r618 | } | ||
Jani Honkonen
|
r668 | void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData) | ||
Jani Honkonen
|
r618 | { | ||
// find slice | ||||
Jani Honkonen
|
r673 | PieSliceItem *item = m_slices.value(slice); | ||
Q_ASSERT(item); | ||||
item->setSliceData(sliceData); | ||||
item->updateGeometry(); | ||||
item->update(); | ||||
Jani Honkonen
|
r618 | } | ||
void PieChartItem::destroySlice(QPieSlice *slice) | ||||
{ | ||||
delete m_slices.take(slice); | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | #include "moc_piechartitem_p.cpp" | ||
Jani Honkonen
|
r142 | |||
QTCOMMERCIALCHART_END_NAMESPACE | ||||