##// END OF EJS Templates
Fix zooming in crash...
Fix zooming in crash The bounding rect has to fit inside int limits when zooming in, meaning that the height and width both have to be within the int limits (INT_MAX). QWidget::update() uses a region (based on bounding rect) that has to be compatible with QRect. The geometry change is only done if the bounding rect fulfills this requirement. Task-number: QTRD-1907 Change-Id: I4e874de355390c5fc983ac1e0976bf0d21e2d10c Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>

File last commit:

r2596:1427ecd2e391
r2603:1e4c29e111d4
Show More
piesliceitem.cpp
298 lines | 10.4 KiB | text/x-c | CppLexer
Jani Honkonen
Add license headers
r794 /****************************************************************************
**
Miikka Heikkinen
Fixed the copyright year 2012 -> 2013
r2432 ** Copyright (C) 2013 Digia Plc
Jani Honkonen
Add license headers
r794 ** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
Miikka Heikkinen
Qt Commercial -> Qt Enterprise...
r2574 ** This file is part of the Qt Enterprise Charts Add-on.
Jani Honkonen
Add license headers
r794 **
** $QT_BEGIN_LICENSE$
Miikka Heikkinen
Qt Commercial -> Qt Enterprise...
r2574 ** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
Jani Honkonen
Add license headers
r794 ** 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
rename PieSlice -> PieSliceItem
r673 #include "piesliceitem_p.h"
Jani Honkonen
Rename piepresenter -> piechartitem
r568 #include "piechartitem_p.h"
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 #include "qpieseries.h"
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 #include "qpieslice.h"
Tero Ahola
Z order for pie
r490 #include "chartpresenter_p.h"
Tero Ahola
Integrated draft version of pie series
r51 #include <QPainter>
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 #include <qmath.h>
Jani Honkonen
Make pie work better with chartwidgettest
r163 #include <QGraphicsSceneEvent>
Jani Honkonen
Refactoring piechart API (and internals)
r174 #include <QTime>
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 #include <QDebug>
Tero Ahola
Integrated draft version of pie series
r51
QTCOMMERCIALCHART_BEGIN_NAMESPACE
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 QPointF offset(qreal angle, qreal length)
{
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 qreal dx = qSin(angle * (M_PI / 180)) * length;
qreal dy = qCos(angle * (M_PI / 180)) * length;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 return QPointF(dx, -dy);
}
Jani Honkonen
more coding style fixes for src-folder...
r2104 PieSliceItem::PieSliceItem(QGraphicsItem *parent)
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 : QGraphicsObject(parent),
Marek Rosa
Added initial donut chart support to Pie series
r1670 m_hovered(false)
Tero Ahola
Integrated draft version of pie series
r51 {
setAcceptHoverEvents(true);
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 setAcceptedMouseButtons(Qt::MouseButtonMask);
Tero Ahola
Z order for pie
r490 setZValue(ChartPresenter::PieSeriesZValue);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 PieSliceItem::~PieSliceItem()
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 // If user is hovering over the slice and it gets destroyed we do
// not get a hover leave event. So we must emit the signal here.
if (m_hovered)
emit hovered(false);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QRectF PieSliceItem::boundingRect() const
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Refactoring pie series and animations.
r621 return m_boundingRect;
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QPainterPath PieSliceItem::shape() const
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Introducing vertical and horizontal factors to control the position of the pie.
r454 // Don't include the label and label arm.
// This is used to detect a mouse clicks. We do not want clicks from label.
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 return m_slicePath;
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 painter->save();
Tero Ahola
Declarative series classed now derived from QSeries childs
r789 painter->setClipRect(parentItem()->boundingRect());
Jani Honkonen
Adding PIMPL to pie
r669 painter->setPen(m_data.m_slicePen);
painter->setBrush(m_data.m_sliceBrush);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 painter->drawPath(m_slicePath);
painter->restore();
Jani Honkonen
Fix setting custom color to pie. Now the pie knows if the color is set by the user.
r691 if (m_data.m_isLabelVisible) {
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 painter->save();
Jani Honkonen
pie: add label position to slice
r1450
Tero Ahola
Use labelBrush instead of labelPen for text labels
r1307 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
// Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
painter->setPen(m_data.m_labelBrush.color());
Jani Honkonen
pie: add label position to slice
r1450 painter->setBrush(m_data.m_labelBrush);
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 painter->setFont(m_data.m_labelFont);
Marek Rosa
Added one more type of label placing on Pie chart
r1712
Titta Heikkala
Fix pie chart label clipping...
r2596 QFontMetricsF fm(m_data.m_labelFont);
QString label = m_data.m_labelText;
QRectF labelBoundingRect;
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 switch (m_data.m_labelPosition) {
Marek Rosa
Added one more type of label placing on Pie chart
r1712 case QPieSlice::LabelOutside:
Jani Honkonen
pie: add label position to slice
r1450 painter->setClipRect(parentItem()->boundingRect());
painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
Titta Heikkala
Fix pie chart label clipping...
r2596 if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) {
label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
qreal(0.0), m_labelTextRect.width(),
Qt::Horizontal, labelBoundingRect);
}
painter->drawText(m_labelTextRect, Qt::AlignCenter, label);
Marek Rosa
Added one more type of label placing on Pie chart
r1712 break;
Jani Honkonen
QPieSlice::LabelInside -> LabelInsideHorizontal
r1759 case QPieSlice::LabelInsideHorizontal:
Jani Honkonen
pie: add label position to slice
r1450 painter->setClipPath(m_slicePath);
Marek Rosa
Added insert, remove and other common methodds to QDonutGroup. Donut example added
r1693 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
Marek Rosa
Added one more type of label placing on Pie chart
r1712 break;
case QPieSlice::LabelInsideTangential:
painter->setClipPath(m_slicePath);
painter->translate(m_labelTextRect.center());
painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
break;
case QPieSlice::LabelInsideNormal:
painter->setClipPath(m_slicePath);
painter->translate(m_labelTextRect.center());
if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
else
painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
break;
Jani Honkonen
pie: add label position to slice
r1450 }
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 painter->restore();
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 }
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 m_hovered = true;
Jani Honkonen
API review changes for pie
r1009 emit hovered(true);
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 m_hovered = false;
Jani Honkonen
API review changes for pie
r1009 emit hovered(false);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
Jani Honkonen
Pie chart refactoring
r142 {
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 emit clicked(event->buttons());
Michal Klocek
Fixes mouse handling in base class of chartseries
r1747 QGraphicsItem::mousePressEvent(event);
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 }
Jani Honkonen
Refactor graphical side of pie to simplify the implementation.
r1074 void PieSliceItem::setLayout(const PieSliceData &sliceData)
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 {
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 m_data = sliceData;
Jani Honkonen
Refactor graphical side of pie to simplify the implementation.
r1074 updateGeometry();
update();
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 void PieSliceItem::updateGeometry()
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 {
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 if (m_data.m_radius <= 0)
Jani Honkonen
Make pie fit better inside its given rectangle. Label texts still go outside. Needs a bit more work...
r289 return;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 prepareGeometryChange();
Jani Honkonen
pie: add label position to slice
r1450 // slice path
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 qreal centerAngle;
QPointF armStart;
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157
Jani Honkonen
pie: add label position to slice
r1450 // text rect
QFontMetricsF fm(m_data.m_labelFont);
m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157
Jani Honkonen
pie: add label position to slice
r1450 // label arm path
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 QPointF labelTextStart;
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157
Jani Honkonen
pie: add label position to slice
r1450 // text position
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 switch (m_data.m_labelPosition) {
Marek Rosa
Added one more type of label placing on Pie chart
r1712 case QPieSlice::LabelOutside:
Jani Honkonen
pie: add label position to slice
r1450 m_labelTextRect.moveBottomLeft(labelTextStart);
Titta Heikkala
Fix pie chart label clipping...
r2596 if (m_labelTextRect.left() < 0)
m_labelTextRect.setLeft(0);
if (m_labelTextRect.right() > parentItem()->boundingRect().right())
m_labelTextRect.setRight(parentItem()->boundingRect().right());
Marek Rosa
Added one more type of label placing on Pie chart
r1712 break;
Jani Honkonen
QPieSlice::LabelInside -> LabelInsideHorizontal
r1759 case QPieSlice::LabelInsideHorizontal:
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 case QPieSlice::LabelInsideTangential: {
Marek Rosa
Added basic donut chart example. Still better data needed
r1841 QPointF textCenter;
if (m_data.m_holeRadius > 0)
textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
else
textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
m_labelTextRect.moveCenter(textCenter);
break;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 }
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 case QPieSlice::LabelInsideNormal: {
Marek Rosa
Added one more type of label placing on Pie chart
r1712 QPointF textCenter;
Marek Rosa
Donut support simplified. Examples updated
r1838 if (m_data.m_holeRadius > 0)
textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
Marek Rosa
Added one more type of label placing on Pie chart
r1712 else
textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
m_labelTextRect.moveCenter(textCenter);
break;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 }
Jani Honkonen
pie: add label position to slice
r1450 }
Jani Honkonen
Refactoring piechart API (and internals)
r174
Jani Honkonen
pie: add label position to slice
r1450 // bounding rect
Jani Honkonen
PieSliceItem bounding rect fix
r718 if (m_data.m_isLabelVisible)
m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
else
m_boundingRect = m_slicePath.boundingRect();
Miikka Heikkinen
Adjust pie slice bounding rectangle to account for thick pens...
r2454
// Inflate bounding rect by 2/3 pen width to make sure it encompasses whole slice also for thick pens
// and miter joins.
int penWidth = (m_data.m_slicePen.width() * 2) / 3;
m_boundingRect = m_boundingRect.adjusted(-penWidth, -penWidth, penWidth, penWidth);
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 {
if (slice->isExploded()) {
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 qreal centerAngle = slice->startAngle() + (slice->angleSpan() / 2);
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 qreal len = radius * slice->explodeDistanceFactor();
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 point += offset(centerAngle, len);
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 }
return point;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart)
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 {
// calculate center angle
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 *centerAngle = startAngle + (angleSpan / 2);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// calculate slice rectangle
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 QRectF rect(center.x() - radius, center.y() - radius, radius * 2, radius * 2);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// slice path
QPainterPath path;
Marek Rosa
Donut support simplified. Examples updated
r1838 if (m_data.m_holeRadius > 0) {
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 QRectF insideRect(center.x() - m_data.m_holeRadius, center.y() - m_data.m_holeRadius, m_data.m_holeRadius * 2, m_data.m_holeRadius * 2);
Marek Rosa
Added initial donut chart support to Pie series
r1670 path.arcMoveTo(rect, -startAngle + 90);
path.arcTo(rect, -startAngle + 90, -angleSpan);
path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
path.closeSubpath();
} else {
path.moveTo(rect.center());
path.arcTo(rect, -startAngle + 90, -angleSpan);
path.closeSubpath();
}
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// calculate label arm start point
*armStart = center;
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
return path;
}
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 {
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 // Normalize the angle to 0-360 range
// NOTE: We are using int here on purpose. Depenging on platform and hardware
// qreal can be a double, float or something the user gives to the Qt configure
// (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
// but there are fmod() and fmodf() functions for that. So instead of some #ifdef
// that might break we just use int. Precision for this is just fine for our needs.
int normalized = angle * 10.0;
normalized = normalized % 3600;
if (normalized < 0)
normalized += 3600;
angle = (qreal) normalized / 10.0;
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 // prevent label arm pointing straight down because it will look bad
if (angle < 180 && angle > 170)
angle = 170;
if (angle > 180 && angle < 190)
angle = 190;
// line from slice to label
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 QPointF parm1 = start + offset(angle, length);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 // line to underline the label
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 QPointF parm2 = parm1;
if (angle < 180) { // arm swings the other way on the left side
Marek Rosa
Added initial donut chart support to Pie series
r1670 parm2 += QPointF(textWidth, 0);
*textStart = parm1;
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 } else {
parm2 += QPointF(-textWidth, 0);
Marek Rosa
Added initial donut chart support to Pie series
r1670 *textStart = parm2;
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 }
QPainterPath path;
path.moveTo(start);
path.lineTo(parm1);
path.lineTo(parm2);
return path;
}
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 #include "moc_piesliceitem_p.cpp"
Jani Honkonen
Refactoring piechart API (and internals)
r174
Tero Ahola
Integrated draft version of pie series
r51 QTCOMMERCIALCHART_END_NAMESPACE
Marek Rosa
Added insert, remove and other common methodds to QDonutGroup. Donut example added
r1693