diff options
Diffstat (limited to 'src/piechart/piesliceitem.cpp')
-rw-r--r-- | src/piechart/piesliceitem.cpp | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/src/piechart/piesliceitem.cpp b/src/piechart/piesliceitem.cpp deleted file mode 100644 index 2f3728a8..00000000 --- a/src/piechart/piesliceitem.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 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 Enterprise Charts Add-on. -** -** $QT_BEGIN_LICENSE$ -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise 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$ -** -****************************************************************************/ - -#include "piesliceitem_p.h" -#include "piechartitem_p.h" -#include "qpieseries.h" -#include "qpieslice.h" -#include "chartpresenter_p.h" -#include <QPainter> -#include <qmath.h> -#include <QGraphicsSceneEvent> -#include <QTime> -#include <QTextDocument> -#include <QDebug> - -QTCOMMERCIALCHART_BEGIN_NAMESPACE - -QPointF offset(qreal angle, qreal length) -{ - qreal dx = qSin(angle * (M_PI / 180)) * length; - qreal dy = qCos(angle * (M_PI / 180)) * length; - return QPointF(dx, -dy); -} - -PieSliceItem::PieSliceItem(QGraphicsItem *parent) - : QGraphicsObject(parent), - m_hovered(false) -{ - setAcceptHoverEvents(true); - setAcceptedMouseButtons(Qt::MouseButtonMask); - setZValue(ChartPresenter::PieSeriesZValue); - m_labelItem = new QGraphicsTextItem(this); - m_labelItem->document()->setDocumentMargin(1.0); -} - -PieSliceItem::~PieSliceItem() -{ - // 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); -} - -QRectF PieSliceItem::boundingRect() const -{ - return m_boundingRect; -} - -QPainterPath PieSliceItem::shape() const -{ - // Don't include the label and label arm. - // This is used to detect a mouse clicks. We do not want clicks from label. - return m_slicePath; -} - -void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) -{ - painter->save(); - painter->setClipRect(parentItem()->boundingRect()); - painter->setPen(m_data.m_slicePen); - painter->setBrush(m_data.m_sliceBrush); - painter->drawPath(m_slicePath); - painter->restore(); - - if (m_data.m_isLabelVisible) { - painter->save(); - - // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead - painter->setBrush(m_data.m_labelBrush); - - if (m_data.m_labelPosition == QPieSlice::LabelOutside) { - painter->setClipRect(parentItem()->boundingRect()); - painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color()); - } - - painter->restore(); - } -} - -void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/) -{ - m_hovered = true; - emit hovered(true); -} - -void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/) -{ - m_hovered = false; - emit hovered(false); -} - -void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - emit clicked(event->buttons()); -} - -void PieSliceItem::setLayout(const PieSliceData &sliceData) -{ - m_data = sliceData; - updateGeometry(); - update(); -} - -void PieSliceItem::updateGeometry() -{ - if (m_data.m_radius <= 0) - return; - - prepareGeometryChange(); - - // slice path - qreal centerAngle; - QPointF armStart; - m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, ¢erAngle, &armStart); - - m_labelItem->setVisible(m_data.m_isLabelVisible); - - if (m_data.m_isLabelVisible) { - // text rect - m_labelTextRect = ChartPresenter::textBoundingRect(m_data.m_labelFont, - m_data.m_labelText, - 0); - - QString label(m_data.m_labelText); - m_labelItem->setDefaultTextColor(m_data.m_labelBrush.color()); - m_labelItem->setFont(m_data.m_labelFont); - - // text position - if (m_data.m_labelPosition == QPieSlice::LabelOutside) { - setFlag(QGraphicsItem::ItemClipsChildrenToShape, false); - - // label arm path - QPointF labelTextStart; - m_labelArmPath = labelArmPath(armStart, centerAngle, - m_data.m_radius * m_data.m_labelArmLengthFactor, - m_labelTextRect.width(), &labelTextStart); - - m_labelTextRect.moveBottomLeft(labelTextStart); - if (m_labelTextRect.left() < 0) - m_labelTextRect.setLeft(0); - else if (m_labelTextRect.left() < parentItem()->boundingRect().left()) - m_labelTextRect.setLeft(parentItem()->boundingRect().left()); - if (m_labelTextRect.right() > parentItem()->boundingRect().right()) - m_labelTextRect.setRight(parentItem()->boundingRect().right()); - - label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText, - qreal(0.0), m_labelTextRect.width(), - m_labelTextRect.height(), m_labelTextRect); - m_labelArmPath = labelArmPath(armStart, centerAngle, - m_data.m_radius * m_data.m_labelArmLengthFactor, - m_labelTextRect.width(), &labelTextStart); - m_labelTextRect.moveBottomLeft(labelTextStart); - - m_labelItem->setTextWidth(m_labelTextRect.width() - + m_labelItem->document()->documentMargin()); - m_labelItem->setHtml(label); - m_labelItem->setRotation(0); - m_labelItem->setPos(m_labelTextRect.x(), m_labelTextRect.y() + 1.0); - } else { - // label inside - setFlag(QGraphicsItem::ItemClipsChildrenToShape); - m_labelItem->setTextWidth(m_labelTextRect.width() - + m_labelItem->document()->documentMargin()); - m_labelItem->setHtml(label); - - 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_labelItem->setPos(textCenter.x() - m_labelItem->boundingRect().width() / 2, - textCenter.y() - m_labelTextRect.height() / 2); - - QPointF labelCenter = m_labelItem->boundingRect().center(); - m_labelItem->setTransformOriginPoint(labelCenter); - - if (m_data.m_labelPosition == QPieSlice::LabelInsideTangential) { - m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2); - } else if (m_data.m_labelPosition == QPieSlice::LabelInsideNormal) { - if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180) - m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90); - else - m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90); - } else { - m_labelItem->setRotation(0); - } - } - // Hide label if it's outside the bounding rect of parent item - QRectF labelRect(m_labelItem->boundingRect()); - labelRect.moveTopLeft(m_labelItem->pos()); - if ((parentItem()->boundingRect().left() - < (labelRect.left() + m_labelItem->document()->documentMargin() + 1.0)) - && (parentItem()->boundingRect().right() - > (labelRect.right() - m_labelItem->document()->documentMargin() - 1.0)) - && (parentItem()->boundingRect().top() - < (labelRect.top() + m_labelItem->document()->documentMargin() + 1.0)) - && (parentItem()->boundingRect().bottom() - > (labelRect.bottom() - m_labelItem->document()->documentMargin() - 1.0))) - m_labelItem->show(); - else - m_labelItem->hide(); - } - - // bounding rect - if (m_data.m_isLabelVisible) - m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect); - else - m_boundingRect = m_slicePath.boundingRect(); - - // 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); -} - -QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice) -{ - if (slice->isExploded()) { - qreal centerAngle = slice->startAngle() + (slice->angleSpan() / 2); - qreal len = radius * slice->explodeDistanceFactor(); - point += offset(centerAngle, len); - } - return point; -} - -QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart) -{ - // calculate center angle - *centerAngle = startAngle + (angleSpan / 2); - - // calculate slice rectangle - QRectF rect(center.x() - radius, center.y() - radius, radius * 2, radius * 2); - - // slice path - QPainterPath path; - if (m_data.m_holeRadius > 0) { - QRectF insideRect(center.x() - m_data.m_holeRadius, center.y() - m_data.m_holeRadius, m_data.m_holeRadius * 2, m_data.m_holeRadius * 2); - 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(); - } - - // calculate label arm start point - *armStart = center; - *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP); - - return path; -} - -QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart) -{ - // 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; - - // 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 - QPointF parm1 = start + offset(angle, length); - - // line to underline the label - QPointF parm2 = parm1; - if (angle < 180) { // arm swings the other way on the left side - parm2 += QPointF(textWidth, 0); - *textStart = parm1; - } else { - parm2 += QPointF(-textWidth, 0); - *textStart = parm2; - } - - QPainterPath path; - path.moveTo(start); - path.lineTo(parm1); - path.lineTo(parm2); - - return path; -} - -#include "moc_piesliceitem_p.cpp" - -QTCOMMERCIALCHART_END_NAMESPACE - |