diff --git a/src/charttheme.cpp b/src/charttheme.cpp index 4a9c33f..ba4224b 100644 --- a/src/charttheme.cpp +++ b/src/charttheme.cpp @@ -206,20 +206,30 @@ void ChartTheme::decorate(QScatterSeries* series, int index,bool force) void ChartTheme::decorate(QPieSeries* series, int index, bool force) { - QPen pen; - QBrush brush; - for (int i(0); i < series->slices().count(); i++) { - if (pen == series->slices().at(i)->slicePen() || force) { - QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0); - series->slices().at(i)->setSlicePen(penColor); - } + + QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0); // Get color for a slice from a gradient linearly, beginning from the start of the gradient qreal pos = (qreal) (i + 1) / (qreal) series->count(); - if (brush == series->slices().at(i)->sliceBrush() || force) { - QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos); - series->slices().at(i)->setSliceBrush(brushColor); + QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos); + + QPieSlice::DataPtr s = series->slices().at(i)->data_ptr(); + PieSliceData data = s->m_data; + + if (data.m_slicePen.isThemed() || force) { + data.m_slicePen = penColor; + data.m_slicePen.setThemed(true); + } + + if (data.m_sliceBrush.isThemed() || force) { + data.m_sliceBrush = brushColor; + data.m_sliceBrush.setThemed(true); + } + + if (s->m_data != data) { + s->m_data = data; + emit s->changed(); } } } diff --git a/src/piechart/piechartitem.cpp b/src/piechart/piechartitem.cpp index 0f41e4a..281a1b5 100644 --- a/src/piechart/piechartitem.cpp +++ b/src/piechart/piechartitem.cpp @@ -51,7 +51,7 @@ void PieChartItem::handleSlicesAdded(QList slices) { bool isEmpty = m_slices.isEmpty(); - presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series)); + presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false); foreach (QPieSlice *s, slices) { PieSliceItem* item = new PieSliceItem(this); @@ -72,7 +72,7 @@ void PieChartItem::handleSlicesAdded(QList slices) void PieChartItem::handleSlicesRemoved(QList slices) { - presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series)); + presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series), false); foreach (QPieSlice *s, slices) { if (animator()) @@ -130,7 +130,6 @@ PieSliceData PieChartItem::sliceData(QPieSlice *slice) PieSliceData sliceData = slice->data_ptr()->m_data; sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice); sliceData.m_radius = m_pieRadius; - sliceData.m_angleSpan = slice->endAngle() - slice->startAngle(); return sliceData; } diff --git a/src/piechart/pieslicedata_p.h b/src/piechart/pieslicedata_p.h index f8427c8..ab60b41 100644 --- a/src/piechart/pieslicedata_p.h +++ b/src/piechart/pieslicedata_p.h @@ -4,37 +4,99 @@ #include #include #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE +template +class Themed : public T +{ +public: + Themed():m_isThemed(true) {} + + inline T &operator=(const T &other) { return T::operator =(other); } + + inline bool operator!=(const T &other) { return T::operator !=(other); } + inline bool operator!=(const Themed &other) + { + if (T::operator !=(other)) + return true; + + if (m_isThemed != other.m_isThemed) + return true; + + return false; + } + + inline void setThemed(bool state) { m_isThemed = state; } + inline bool isThemed() const { return m_isThemed; } + +private: + bool m_isThemed; +}; + class PieSliceData { public: PieSliceData() { m_value = 0; - m_percentage = 0; - m_startAngle = 0; - m_angleSpan = 0; + m_isExploded = false; m_explodeDistanceFactor = 0.15; - m_labelVisible = false; + + m_isLabelVisible = false; m_labelArmLengthFactor = 0.15; + + m_percentage = 0; + m_radius = 0; + m_startAngle = 0; + m_angleSpan = 0; + } + + bool operator!=(const PieSliceData &other) + { + if (m_value != other.m_value) + return true; + + if (m_slicePen != other.m_slicePen || + m_sliceBrush != other.m_sliceBrush) + return true; + + if (m_isExploded != other.m_isExploded || + m_explodeDistanceFactor != other.m_explodeDistanceFactor) + return true; + + if (m_isLabelVisible != other.m_isLabelVisible || + m_labelText != other.m_labelText || + m_labelFont != other.m_labelFont || + m_labelArmLengthFactor != other.m_labelArmLengthFactor || + m_labelArmPen != other.m_labelArmPen) + return true; + + if (m_percentage != other.m_percentage || + m_center != other.m_center || + m_radius != other.m_radius || + m_startAngle != other.m_startAngle || + m_angleSpan != other.m_angleSpan) + return true; + + return false; } qreal m_value; - QPen m_slicePen; - QBrush m_sliceBrush; + Themed m_slicePen; + Themed m_sliceBrush; bool m_isExploded; qreal m_explodeDistanceFactor; - bool m_labelVisible; + bool m_isLabelVisible; QString m_labelText; - QFont m_labelFont; + Themed m_labelFont; qreal m_labelArmLengthFactor; - QPen m_labelArmPen; + Themed m_labelArmPen; qreal m_percentage; QPointF m_center; diff --git a/src/piechart/piesliceitem.cpp b/src/piechart/piesliceitem.cpp index 09ae0d5..ec9aa27 100644 --- a/src/piechart/piesliceitem.cpp +++ b/src/piechart/piesliceitem.cpp @@ -55,7 +55,7 @@ void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*op painter->drawPath(m_slicePath); painter->restore(); - if (m_data.m_labelVisible) { + if (m_data.m_isLabelVisible) { painter->save(); painter->setPen(m_data.m_labelArmPen); painter->drawPath(m_labelArmPath); diff --git a/src/piechart/qpieslice.cpp b/src/piechart/qpieslice.cpp index 0e83363..331f1bd 100644 --- a/src/piechart/qpieslice.cpp +++ b/src/piechart/qpieslice.cpp @@ -93,7 +93,7 @@ QString QPieSlice::label() const bool QPieSlice::isLabelVisible() const { Q_D(const QPieSlice); - return d->m_data.m_labelVisible; + return d->m_data.m_isLabelVisible; } /*! @@ -202,7 +202,7 @@ QFont QPieSlice::labelFont() const } /*! - Gets the label arm lenght factor. + Gets the label arm length factor. The factor is relative to pie radius. For example: 1.0 means the length is the same as the radius. @@ -288,8 +288,8 @@ void QPieSlice::setLabel(QString label) void QPieSlice::setLabelVisible(bool visible) { Q_D(QPieSlice); - if (d->m_data.m_labelVisible != visible) { - d->m_data.m_labelVisible = visible; + if (d->m_data.m_isLabelVisible != visible) { + d->m_data.m_isLabelVisible = visible; emit changed(); } } @@ -337,6 +337,7 @@ void QPieSlice::setSlicePen(const QPen &pen) Q_D(QPieSlice); if (d->m_data.m_slicePen != pen) { d->m_data.m_slicePen = pen; + d->m_data.m_slicePen.setThemed(false); emit changed(); } } @@ -351,6 +352,7 @@ void QPieSlice::setSliceBrush(const QBrush &brush) Q_D(QPieSlice); if (d->m_data.m_sliceBrush != brush) { d->m_data.m_sliceBrush = brush; + d->m_data.m_sliceBrush.setThemed(false); emit changed(); } } @@ -365,6 +367,7 @@ void QPieSlice::setLabelArmPen(const QPen &pen) Q_D(QPieSlice); if (d->m_data.m_labelArmPen != pen) { d->m_data.m_labelArmPen = pen; + d->m_data.m_labelArmPen.setThemed(false); emit changed(); } } @@ -379,12 +382,13 @@ void QPieSlice::setLabelFont(const QFont &font) Q_D(QPieSlice); if (d->m_data.m_labelFont != font) { d->m_data.m_labelFont = font; + d->m_data.m_labelFont.setThemed(false); emit changed(); } } /*! - Sets the label arm lenght \a factor. + Sets the label arm length \a factor. The factor is relative to pie radius. For example: 1.0 means the length is the same as the radius. diff --git a/src/piechart/qpiesliceprivate_p.h b/src/piechart/qpiesliceprivate_p.h index 30f7050..6056780 100644 --- a/src/piechart/qpiesliceprivate_p.h +++ b/src/piechart/qpiesliceprivate_p.h @@ -26,6 +26,7 @@ Q_SIGNALS: public: friend class QPieSeriesPrivate; + friend class ChartTheme; QPieSlice * const q_ptr; PieSliceData m_data; };