diff options
Diffstat (limited to 'src/charts/legend')
28 files changed, 3663 insertions, 0 deletions
diff --git a/src/charts/legend/legend.pri b/src/charts/legend/legend.pri new file mode 100644 index 00000000..c14cf6b0 --- /dev/null +++ b/src/charts/legend/legend.pri @@ -0,0 +1,36 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +SOURCES += \ + $$PWD/qlegend.cpp \ + $$PWD/legendlayout.cpp \ + $$PWD/qlegendmarker.cpp \ + $$PWD/qpielegendmarker.cpp \ + $$PWD/legendmarkeritem.cpp \ + $$PWD/qbarlegendmarker.cpp \ + $$PWD/qxylegendmarker.cpp \ + $$PWD/qarealegendmarker.cpp \ + $$PWD/legendscroller.cpp \ + $$PWD/qboxplotlegendmarker.cpp + +PRIVATE_HEADERS += \ + $$PWD/legendscroller_p.h \ + $$PWD/qlegend_p.h \ + $$PWD/legendlayout_p.h \ + $$PWD/qlegendmarker_p.h \ + $$PWD/legendmarkeritem_p.h \ + $$PWD/qpielegendmarker_p.h \ + $$PWD/qbarlegendmarker_p.h \ + $$PWD/qxylegendmarker_p.h \ + $$PWD/qarealegendmarker_p.h \ + $$PWD/qboxplotlegendmarker_p.h + + +PUBLIC_HEADERS += \ + $$PWD/qlegend.h \ + $$PWD/qlegendmarker.h \ + $$PWD/qpielegendmarker.h \ + $$PWD/qbarlegendmarker.h \ + $$PWD/qxylegendmarker.h \ + $$PWD/qarealegendmarker.h \ + $$PWD/qboxplotlegendmarker.h diff --git a/src/charts/legend/legendlayout.cpp b/src/charts/legend/legendlayout.cpp new file mode 100644 index 00000000..b4e443c0 --- /dev/null +++ b/src/charts/legend/legendlayout.cpp @@ -0,0 +1,506 @@ +/**************************************************************************** +** +** 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 "legendlayout_p.h" +#include "chartpresenter_p.h" +#include "qlegend_p.h" +#include "abstractchartlayout_p.h" + +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "qlegendmarker.h" + +QT_CHARTS_BEGIN_NAMESPACE + +LegendLayout::LegendLayout(QLegend *legend) + : m_legend(legend), + m_offsetX(0), + m_offsetY(0) +{ + +} + +LegendLayout::~LegendLayout() +{ + +} + +void LegendLayout::setOffset(qreal x, qreal y) +{ + bool scrollHorizontal = true; + switch (m_legend->alignment()) { + case Qt::AlignTop: + case Qt::AlignBottom: + scrollHorizontal = true; + break; + case Qt::AlignLeft: + case Qt::AlignRight: + scrollHorizontal = false; + break; + } + + // If detached, the scrolling direction is vertical instead of horizontal and vice versa. + if (!m_legend->isAttachedToChart()) + scrollHorizontal = !scrollHorizontal; + + QRectF boundingRect = geometry(); + qreal left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + boundingRect.adjust(left, top, -right, -bottom); + + // Limit offset between m_minOffset and m_maxOffset + if (scrollHorizontal) { + if (m_width <= boundingRect.width()) + return; + + if (x != m_offsetX) { + m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX); + m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top()); + } + } else { + if (m_height <= boundingRect.height()) + return; + + if (y != m_offsetY) { + m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY); + m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY); + } + } +} + +QPointF LegendLayout::offset() const +{ + return QPointF(m_offsetX, m_offsetY); +} + +void LegendLayout::invalidate() +{ + QGraphicsLayout::invalidate(); + if (m_legend->isAttachedToChart()) + m_legend->d_ptr->m_presenter->layout()->invalidate(); +} + +void LegendLayout::setGeometry(const QRectF &rect) +{ + m_legend->d_ptr->items()->setVisible(m_legend->isVisible()); + + QGraphicsLayout::setGeometry(rect); + + if (m_legend->isAttachedToChart()) + setAttachedGeometry(rect); + else + setDettachedGeometry(rect); +} + +void LegendLayout::setAttachedGeometry(const QRectF &rect) +{ + if (!rect.isValid()) + return; + + qreal oldOffsetX = m_offsetX; + qreal oldOffsetY = m_offsetY; + m_offsetX = 0; + m_offsetY = 0; + + QSizeF size(0, 0); + + if (m_legend->d_ptr->markers().isEmpty()) { + return; + } + + m_width = 0; + m_height = 0; + + qreal left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + + QRectF geometry = rect.adjusted(left, top, -right, -bottom); + + switch(m_legend->alignment()) { + case Qt::AlignTop: + case Qt::AlignBottom: { + // Calculate the space required for items and add them to a sorted list. + qreal markerItemsWidth = 0; + qreal itemMargins = 0; + QList<LegendWidthStruct *> legendWidthList; + foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { + LegendMarkerItem *item = marker->d_ptr->item(); + if (item->isVisible()) { + QSizeF dummySize; + qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width(); + LegendWidthStruct *structItem = new LegendWidthStruct; + structItem->item = item; + structItem->width = itemWidth; + legendWidthList.append(structItem); + markerItemsWidth += itemWidth; + itemMargins += marker->d_ptr->item()->m_margin; + } + } + std::sort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan); + + // If the items would occupy more space than is available, start truncating them + // from the longest one. + qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins; + if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 0) { + bool truncated(false); + int count = legendWidthList.count(); + for (int i = 1; i < count; i++) { + int truncateIndex = i - 1; + + while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width + && !truncated) { + legendWidthList.at(truncateIndex)->width--; + markerItemsWidth--; + if (i > 1) { + // Truncate the items that are before the truncated one in the list. + for (int j = truncateIndex - 1; j >= 0; j--) { + if (legendWidthList.at(truncateIndex)->width + < legendWidthList.at(j)->width) { + legendWidthList.at(j)->width--; + markerItemsWidth--; + } + } + } + if (markerItemsWidth < availableGeometry) + truncated = true; + } + // Truncate the last item if needed. + if (i == count - 1) { + if (legendWidthList.at(count - 1)->width + > legendWidthList.at(truncateIndex)->width) { + legendWidthList.at(count - 1)->width--; + markerItemsWidth--; + } + } + + if (truncated) + break; + } + // Items are of same width and all of them need to be truncated + // or there is just one item that is truncated. + while (markerItemsWidth >= availableGeometry) { + for (int i = 0; i < count; i++) { + legendWidthList.at(i)->width--; + markerItemsWidth--; + } + } + } + + QPointF point(0,0); + + int markerCount = m_legend->d_ptr->markers().count(); + for (int i = 0; i < markerCount; i++) { + QLegendMarker *marker; + if (m_legend->d_ptr->m_reverseMarkers) + marker = m_legend->d_ptr->markers().at(markerCount - 1 - i); + else + marker = m_legend->d_ptr->markers().at(i); + LegendMarkerItem *item = marker->d_ptr->item(); + if (item->isVisible()) { + QRectF itemRect = geometry; + qreal availableWidth = 0; + for (int i = 0; i < legendWidthList.size(); ++i) { + if (legendWidthList.at(i)->item == item) { + availableWidth = legendWidthList.at(i)->width; + break; + } + } + itemRect.setWidth(availableWidth); + item->setGeometry(itemRect); + item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2); + const QRectF &rect = item->boundingRect(); + size = size.expandedTo(rect.size()); + qreal w = rect.width(); + m_width = m_width + w - item->m_margin; + point.setX(point.x() + w); + } + } + // Delete structs from the container + qDeleteAll(legendWidthList); + + if (m_width < geometry.width()) + m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top()); + else + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + m_height = size.height(); + } + break; + case Qt::AlignLeft: + case Qt::AlignRight: { + QPointF point(0,0); + int markerCount = m_legend->d_ptr->markers().count(); + for (int i = 0; i < markerCount; i++) { + QLegendMarker *marker; + if (m_legend->d_ptr->m_reverseMarkers) + marker = m_legend->d_ptr->markers().at(markerCount - 1 - i); + else + marker = m_legend->d_ptr->markers().at(i); + LegendMarkerItem *item = marker->d_ptr->item(); + if (item->isVisible()) { + item->setGeometry(geometry); + item->setPos(point); + const QRectF &rect = item->boundingRect(); + qreal h = rect.height(); + size = size.expandedTo(rect.size()); + m_height+=h; + point.setY(point.y() + h); + } + } + + if (m_height < geometry.height()) + m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2); + else + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + m_width = size.width(); + break; + } + } + + m_minOffsetX = -left; + m_minOffsetY = - top; + m_maxOffsetX = m_width - geometry.width() - right; + m_maxOffsetY = m_height - geometry.height() - bottom; + + setOffset(oldOffsetX, oldOffsetY); +} + +void LegendLayout::setDettachedGeometry(const QRectF &rect) +{ + if (!rect.isValid()) + return; + + // Detached layout is different. + // In detached mode legend may have multiple rows and columns, so layout calculations + // differ a log from attached mode. + // Also the scrolling logic is bit different. + + qreal oldOffsetX = m_offsetX; + qreal oldOffsetY = m_offsetY; + m_offsetX = 0; + m_offsetY = 0; + + qreal left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRectF geometry = rect.adjusted(left, top, -right, -bottom); + + QSizeF size(0, 0); + + QList<QLegendMarker *> markers = m_legend->d_ptr->markers(); + + if (markers.isEmpty()) + return; + + switch (m_legend->alignment()) { + case Qt::AlignTop: { + QPointF point(0, 0); + m_width = 0; + m_height = 0; + for (int i = 0; i < markers.count(); i++) { + LegendMarkerItem *item = markers.at(i)->d_ptr->item(); + if (item->isVisible()) { + item->setGeometry(geometry); + item->setPos(point.x(),point.y()); + const QRectF &boundingRect = item->boundingRect(); + qreal w = boundingRect.width(); + qreal h = boundingRect.height(); + m_width = qMax(m_width,w); + m_height = qMax(m_height,h); + point.setX(point.x() + w); + if (point.x() + w > geometry.left() + geometry.width() - right) { + // Next item would go off rect. + point.setX(0); + point.setY(point.y() + h); + if (i+1 < markers.count()) { + m_height += h; + } + } + } + } + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + + m_minOffsetX = -left; + m_minOffsetY = -top; + m_maxOffsetX = m_width - geometry.width() - right; + m_maxOffsetY = m_height - geometry.height() - bottom; + } + break; + case Qt::AlignBottom: { + QPointF point(0, geometry.height()); + m_width = 0; + m_height = 0; + for (int i = 0; i < markers.count(); i++) { + LegendMarkerItem *item = markers.at(i)->d_ptr->item(); + if (item->isVisible()) { + item->setGeometry(geometry); + const QRectF &boundingRect = item->boundingRect(); + qreal w = boundingRect.width(); + qreal h = boundingRect.height(); + m_width = qMax(m_width,w); + m_height = qMax(m_height,h); + item->setPos(point.x(),point.y() - h); + point.setX(point.x() + w); + if (point.x() + w > geometry.left() + geometry.width() - right) { + // Next item would go off rect. + point.setX(0); + point.setY(point.y() - h); + if (i+1 < markers.count()) { + m_height += h; + } + } + } + } + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + + m_minOffsetX = -left; + m_minOffsetY = -m_height + geometry.height() - top; + m_maxOffsetX = m_width - geometry.width() - right; + m_maxOffsetY = -bottom; + } + break; + case Qt::AlignLeft: { + QPointF point(0, 0); + m_width = 0; + m_height = 0; + qreal maxWidth = 0; + for (int i = 0; i < markers.count(); i++) { + LegendMarkerItem *item = markers.at(i)->d_ptr->item(); + if (item->isVisible()) { + item->setGeometry(geometry); + const QRectF &boundingRect = item->boundingRect(); + qreal w = boundingRect.width(); + qreal h = boundingRect.height(); + m_height = qMax(m_height,h); + maxWidth = qMax(maxWidth,w); + item->setPos(point.x(),point.y()); + point.setY(point.y() + h); + if (point.y() + h > geometry.bottom() - bottom) { + // Next item would go off rect. + point.setX(point.x() + maxWidth); + point.setY(0); + if (i+1 < markers.count()) { + m_width += maxWidth; + maxWidth = 0; + } + } + } + } + m_width += maxWidth; + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + + m_minOffsetX = -left; + m_minOffsetY = -top; + m_maxOffsetX = m_width - geometry.width() - right; + m_maxOffsetY = m_height - geometry.height() - bottom; + } + break; + case Qt::AlignRight: { + QPointF point(geometry.width(), 0); + m_width = 0; + m_height = 0; + qreal maxWidth = 0; + for (int i = 0; i < markers.count(); i++) { + LegendMarkerItem *item = markers.at(i)->d_ptr->item(); + if (item->isVisible()) { + item->setGeometry(geometry); + const QRectF &boundingRect = item->boundingRect(); + qreal w = boundingRect.width(); + qreal h = boundingRect.height(); + m_height = qMax(m_height,h); + maxWidth = qMax(maxWidth,w); + item->setPos(point.x() - w,point.y()); + point.setY(point.y() + h); + if (point.y() + h > geometry.bottom()-bottom) { + // Next item would go off rect. + point.setX(point.x() - maxWidth); + point.setY(0); + if (i+1 < markers.count()) { + m_width += maxWidth; + maxWidth = 0; + } + } + } + } + m_width += maxWidth; + m_legend->d_ptr->items()->setPos(geometry.topLeft()); + + m_minOffsetX = - m_width + geometry.width() - left; + m_minOffsetY = -top; + m_maxOffsetX = - right; + m_maxOffsetY = m_height - geometry.height() - bottom; + } + break; + default: + break; + } + + setOffset(oldOffsetX, oldOffsetY); +} + +QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + QSizeF size(0, 0); + qreal left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + + if(constraint.isValid()) { + foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { + LegendMarkerItem *item = marker->d_ptr->item(); + size = size.expandedTo(item->effectiveSizeHint(which)); + } + size = size.boundedTo(constraint); + } + else if (constraint.width() >= 0) { + qreal width = 0; + qreal height = 0; + foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { + LegendMarkerItem *item = marker->d_ptr->item(); + width+=item->effectiveSizeHint(which).width(); + height=qMax(height,item->effectiveSizeHint(which).height()); + } + + size = QSizeF(qMin(constraint.width(),width), height); + } + else if (constraint.height() >= 0) { + qreal width = 0; + qreal height = 0; + foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { + LegendMarkerItem *item = marker->d_ptr->item(); + width=qMax(width,item->effectiveSizeHint(which).width()); + height+=height,item->effectiveSizeHint(which).height(); + } + size = QSizeF(width,qMin(constraint.height(),height)); + } + else { + foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) { + LegendMarkerItem *item = marker->d_ptr->item(); + size = size.expandedTo(item->effectiveSizeHint(which)); + } + } + size += QSize(left + right, top + bottom); + return size; +} + +bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1, + const LegendWidthStruct *item2) +{ + return item1->width > item2->width; +} + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/legendlayout_p.h b/src/charts/legend/legendlayout_p.h new file mode 100644 index 00000000..ec96aa31 --- /dev/null +++ b/src/charts/legend/legendlayout_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef LEGENDLAYOUT_H +#define LEGENDLAYOUT_H +#include <QGraphicsLayout> +#include "qchartglobal.h" + +QT_CHARTS_BEGIN_NAMESPACE + +class QLegend; +class LegendMarkerItem; + +class LegendLayout : public QGraphicsLayout +{ +public: + + LegendLayout(QLegend *legend); + virtual ~LegendLayout(); + + void setGeometry(const QRectF &rect); + + void setOffset(qreal x, qreal y); + QPointF offset() const; + + void invalidate(); +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + int count() const { return 0; } + QGraphicsLayoutItem *itemAt(int) const { return 0; }; + void removeAt(int) {}; + +private: + void setAttachedGeometry(const QRectF &rect); + void setDettachedGeometry(const QRectF &rect); + + struct LegendWidthStruct { + LegendMarkerItem *item; + qreal width; + }; + static bool widthLongerThan(const LegendWidthStruct *item1, + const LegendWidthStruct *item2); + +private: + QLegend *m_legend; + qreal m_offsetX; + qreal m_offsetY; + qreal m_minOffsetX; + qreal m_minOffsetY; + qreal m_maxOffsetX; + qreal m_maxOffsetY; + qreal m_width; + qreal m_height; +}; + +QT_CHARTS_END_NAMESPACE + +#endif diff --git a/src/charts/legend/legendmarkeritem.cpp b/src/charts/legend/legendmarkeritem.cpp new file mode 100644 index 00000000..f40e4dd0 --- /dev/null +++ b/src/charts/legend/legendmarkeritem.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** + ** + ** 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 <QPainter> +#include <QGraphicsSceneEvent> +#include <QGraphicsTextItem> +#include <QTextDocument> + +#include "qlegend.h" +#include "qlegend_p.h" +#include "qlegendmarker.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "chartpresenter_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) : + QGraphicsObject(parent), + m_marker(marker), + m_markerRect(0,0,10.0,10.0), + m_boundingRect(0,0,0,0), + m_textItem(new QGraphicsTextItem(this)), + m_rectItem(new QGraphicsRectItem(this)), + m_margin(3), + m_space(4), + m_hovering(false), + m_pressPos(0, 0) +{ + m_rectItem->setRect(m_markerRect); + m_textItem->document()->setDocumentMargin(ChartPresenter::textMargin()); + setAcceptHoverEvents(true); +} + +LegendMarkerItem::~LegendMarkerItem() +{ + if (m_hovering) { + emit m_marker->q_ptr->hovered(false); + } +} + +void LegendMarkerItem::setPen(const QPen &pen) +{ + m_rectItem->setPen(pen); +} + +QPen LegendMarkerItem::pen() const +{ + return m_rectItem->pen(); +} + +void LegendMarkerItem::setBrush(const QBrush &brush) +{ + m_rectItem->setBrush(brush); +} + +QBrush LegendMarkerItem::brush() const +{ + return m_rectItem->brush(); +} + +void LegendMarkerItem::setFont(const QFont &font) +{ + m_textItem->setFont(font); + QFontMetrics fn(font); + m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2); + updateGeometry(); +} + +QFont LegendMarkerItem::font() const +{ + return m_textItem->font(); +} + +void LegendMarkerItem::setLabel(const QString label) +{ + m_label = label; + updateGeometry(); +} + +QString LegendMarkerItem::label() const +{ + return m_label; +} + +void LegendMarkerItem::setLabelBrush(const QBrush &brush) +{ + m_textItem->setDefaultTextColor(brush.color()); +} + +QBrush LegendMarkerItem::labelBrush() const +{ + return QBrush(m_textItem->defaultTextColor()); +} + +void LegendMarkerItem::setGeometry(const QRectF &rect) +{ + qreal width = rect.width(); + qreal x = m_margin + m_markerRect.width() + m_space + m_margin; + QRectF truncatedRect; + + m_textItem->setHtml(ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0), + width - x, rect.height(), truncatedRect)); + m_textItem->setTextWidth(truncatedRect.width()); + + qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin); + + const QRectF &textRect = m_textItem->boundingRect(); + + m_textItem->setPos(x - m_margin, y / 2 - textRect.height() / 2); + m_rectItem->setRect(m_markerRect); + // The textMargin adjustments to position are done to make default case rects less blurry with anti-aliasing + m_rectItem->setPos(m_margin - ChartPresenter::textMargin(), y / 2.0 - m_markerRect.height() / 2.0 + ChartPresenter::textMargin()); + + prepareGeometryChange(); + m_boundingRect = QRectF(0, 0, x + textRect.width() + m_margin, y); +} + +QRectF LegendMarkerItem::boundingRect() const +{ + return m_boundingRect; +} + +void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + Q_UNUSED(painter) +} + +QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const +{ + Q_UNUSED(constraint) + + QSizeF sh; + + switch (which) { + case Qt::MinimumSize: { + QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), + QStringLiteral("...")); + sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(), + qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin)); + break; + } + case Qt::PreferredSize: { + QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), m_label); + sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(), + qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin)); + break; + } + default: + break; + } + + return sh; +} + +void LegendMarkerItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) + m_hovering = true; + emit m_marker->q_ptr->hovered(true); +} + +void LegendMarkerItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) + m_hovering = false; + emit m_marker->q_ptr->hovered(false); +} + + +#include "moc_legendmarkeritem_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/legendmarkeritem_p.h b/src/charts/legend/legendmarkeritem_p.h new file mode 100644 index 00000000..8c49b9d0 --- /dev/null +++ b/src/charts/legend/legendmarkeritem_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef LEGENDMARKERITEM_P_H +#define LEGENDMARKERITEM_P_H + +#include <qchartglobal.h> +#include <QGraphicsObject> +#include <QFont> +#include <QBrush> +#include <QPen> +#include <QGraphicsTextItem> +#include <QGraphicsLayoutItem> + +QT_CHARTS_BEGIN_NAMESPACE + +class QLegendMarkerPrivate; + +class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem +{ + Q_OBJECT + Q_INTERFACES(QGraphicsLayoutItem) +public: + explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = 0); + ~LegendMarkerItem(); + + void setPen(const QPen &pen); + QPen pen() const; + + void setBrush(const QBrush &brush); + QBrush brush() const; + + void setFont(const QFont &font); + QFont font() const; + + void setLabel(const QString label); + QString label() const; + + void setLabelBrush(const QBrush &brush); + QBrush labelBrush() const; + + void setGeometry(const QRectF &rect); + QRectF boundingRect() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + QSizeF sizeHint (Qt::SizeHint which, const QSizeF &constraint) const; + + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + +protected: + QLegendMarkerPrivate *m_marker; // Knows + QRectF m_markerRect; + QRectF m_boundingRect; + QGraphicsTextItem *m_textItem; + QGraphicsRectItem *m_rectItem; + qreal m_margin; + qreal m_space; + QString m_label; + + QBrush m_labelBrush; + QPen m_pen; + QBrush m_brush; + bool m_hovering; + + QPointF m_pressPos; + + friend class QLegendMarker; + friend class QLegendMarkerPrivate; + friend class LegendLayout; +}; + +QT_CHARTS_END_NAMESPACE + +#endif // LEGENDMARKERITEM_P_H diff --git a/src/charts/legend/legendscroller.cpp b/src/charts/legend/legendscroller.cpp new file mode 100644 index 00000000..ac1784b3 --- /dev/null +++ b/src/charts/legend/legendscroller.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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 <QDebug> +#include <QGraphicsSceneMouseEvent> +#include <QGraphicsScene> +#include <QLegendMarker> +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "legendscroller_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +LegendScroller::LegendScroller(QChart *chart) : QLegend(chart) +{ +} + +void LegendScroller::setOffset(const QPointF &point) +{ + d_ptr->setOffset(point); +} + +QPointF LegendScroller::offset() const +{ + return d_ptr->offset(); +} + +void LegendScroller::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Scroller::handleMousePressEvent(event); +} + +void LegendScroller::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + Scroller::handleMouseMoveEvent(event); +} + +void LegendScroller::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Scroller::handleMouseReleaseEvent(event); + + if (!event->isAccepted()) { + QList<QGraphicsItem *> items = scene()->items(event->scenePos()); + + foreach (QGraphicsItem *i, items) { + if (d_ptr->m_markerHash.contains(i)) { + QLegendMarker *marker = d_ptr->m_markerHash.value(i); + emit marker->clicked(); + } + } + event->accept(); + } +} + + +#include "moc_legendscroller_p.cpp" +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/legendscroller_p.h b/src/charts/legend/legendscroller_p.h new file mode 100644 index 00000000..8ea63d78 --- /dev/null +++ b/src/charts/legend/legendscroller_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + + +#ifndef LEGENDSCROLLER_P_H +#define LEGENDSCROLLER_P_H + +#include <QtCharts/qlegend.h> +#include "qlegend_p.h" +#include "scroller_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +class LegendScroller: public QLegend, public Scroller +{ + Q_OBJECT + +public: + LegendScroller(QChart *chart); + + void setOffset(const QPointF &point); + QPointF offset() const; + + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); +}; + +QT_CHARTS_END_NAMESPACE + +#endif diff --git a/src/charts/legend/qarealegendmarker.cpp b/src/charts/legend/qarealegendmarker.cpp new file mode 100644 index 00000000..6e8a1d53 --- /dev/null +++ b/src/charts/legend/qarealegendmarker.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** 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 "qarealegendmarker.h" +#include "qarealegendmarker_p.h" +#include "qareaseries_p.h" +#include <QAreaSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QAreaLegendMarker + \inmodule Qt Charts + \brief QLegendMarker subclass for area series. + \mainclass + + QAreaLegendMarker is related to QAreaSeries. One QAreaSeries results in one marker. + + \sa QLegend, QAreaSeries +*/ + +/*! + \fn virtual LegendMarkerType QAreaLegendMarker::type() + Returns QLegendMarker::LegendMarkerTypeArea +*/ + +/*! + \internal +*/ +QAreaLegendMarker::QAreaLegendMarker(QAreaSeries *series, QLegend *legend, QObject *parent) : + QLegendMarker(*new QAreaLegendMarkerPrivate(this,series,legend), parent) +{ + d_ptr->updated(); +} + +/*! + Destructor +*/ +QAreaLegendMarker::~QAreaLegendMarker() +{ +} + +/*! + \internal +*/ +QAreaLegendMarker::QAreaLegendMarker(QAreaLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +/*! + Returns related series of marker +*/ +QAreaSeries* QAreaLegendMarker::series() +{ + Q_D(QAreaLegendMarker); + return d->m_series; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QAreaLegendMarkerPrivate::QAreaLegendMarkerPrivate(QAreaLegendMarker *q, QAreaSeries *series, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series) +{ + QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(updated())); + QObject::connect(m_series, SIGNAL(nameChanged()), this, SLOT(updated())); +} + +QAreaLegendMarkerPrivate::~QAreaLegendMarkerPrivate() +{ +} + +QAreaSeries* QAreaLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QAreaLegendMarkerPrivate::relatedObject() +{ + return m_series; +} + +void QAreaLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + + if (!m_customBrush && (m_item->brush() != m_series->brush())) { + m_item->setBrush(m_series->brush()); + brushChanged = true; + } + if (!m_customLabel && (m_item->label() != m_series->name())) { + m_item->setLabel(m_series->name()); + labelChanged = true; + } + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); +} + +#include "moc_qarealegendmarker.cpp" +#include "moc_qarealegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/qarealegendmarker.h b/src/charts/legend/qarealegendmarker.h new file mode 100644 index 00000000..687b4431 --- /dev/null +++ b/src/charts/legend/qarealegendmarker.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QAREALEGENDMARKER_H +#define QAREALEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/QLegendMarker> +#include <QtCharts/QAreaSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QAreaLegendMarkerPrivate; + +class QT_CHARTS_EXPORT QAreaLegendMarker : public QLegendMarker +{ + Q_OBJECT + +public: + explicit QAreaLegendMarker(QAreaSeries *series, QLegend *legend, QObject *parent = 0); + virtual ~QAreaLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypeArea; } + + // Related series + virtual QAreaSeries* series(); + +protected: + QAreaLegendMarker(QAreaLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QAreaLegendMarker) + Q_DISABLE_COPY(QAreaLegendMarker) + +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QAREALEGENDMARKER_H diff --git a/src/charts/legend/qarealegendmarker_p.h b/src/charts/legend/qarealegendmarker_p.h new file mode 100644 index 00000000..54d4e657 --- /dev/null +++ b/src/charts/legend/qarealegendmarker_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QAREALEGENDMARKER_P_H +#define QAREALEGENDMARKER_P_H + +#include "qchartglobal.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include <QAreaSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QAreaLegendMarker; + +class QAreaLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QAreaLegendMarkerPrivate(QAreaLegendMarker *q, QAreaSeries *series, QLegend *legend); + virtual ~QAreaLegendMarkerPrivate(); + + virtual QAreaSeries* series(); + virtual QObject* relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QAreaLegendMarker *q_ptr; + QAreaSeries *m_series; + + Q_DECLARE_PUBLIC(QAreaLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QAREALEGENDMARKER_P_H diff --git a/src/charts/legend/qbarlegendmarker.cpp b/src/charts/legend/qbarlegendmarker.cpp new file mode 100644 index 00000000..710c4129 --- /dev/null +++ b/src/charts/legend/qbarlegendmarker.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** 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 "qbarlegendmarker.h" +#include "qbarlegendmarker_p.h" +#include <QAbstractBarSeries> +#include <QBarSet> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QBarLegendMarker + \inmodule Qt Charts + \brief QLegendMarker subclass for bar series. + \mainclass + + QBarLegendMarker is related to QAbstractBarSeries derived classes. With bar series, each marker is related to one QBarSet. + + \sa QLegend, QAbstractBarSeries, QBarSet +*/ + +/*! + \fn virtual LegendMarkerType QBarLegendMarker::type() + Returns QLegendMarker::LegendMarkerTypeBar +*/ + +/*! + \internal + Constructor +*/ +QBarLegendMarker::QBarLegendMarker(QAbstractBarSeries *series, QBarSet *barset, QLegend *legend, QObject *parent) : + QLegendMarker(*new QBarLegendMarkerPrivate(this,series,barset,legend), parent) +{ + d_ptr->updated(); +} + +/*! + Desturctor +*/ +QBarLegendMarker::~QBarLegendMarker() +{ +} + +/*! + \internal +*/ +QBarLegendMarker::QBarLegendMarker(QBarLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +/*! + Returns the related series of marker +*/ +QAbstractBarSeries *QBarLegendMarker::series() +{ + Q_D(QBarLegendMarker); + return d->m_series; +} + +/*! + Returns the related barset of marker +*/ +QBarSet* QBarLegendMarker::barset() +{ + Q_D(QBarLegendMarker); + return d->m_barset; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QBarLegendMarkerPrivate::QBarLegendMarkerPrivate(QBarLegendMarker *q, QAbstractBarSeries *series, QBarSet *barset, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series), + m_barset(barset) +{ + QObject::connect(m_barset, SIGNAL(penChanged()), this, SLOT(updated())); + QObject::connect(m_barset, SIGNAL(labelChanged()), this, SLOT(updated())); + QObject::connect(m_barset, SIGNAL(brushChanged()), this, SLOT(updated())); +} + +QBarLegendMarkerPrivate::~QBarLegendMarkerPrivate() +{ +} + +QAbstractBarSeries* QBarLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QBarLegendMarkerPrivate::relatedObject() +{ + return m_barset; +} + +void QBarLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + bool penChanged = false; + + if (!m_customPen && (m_item->pen() != m_barset->pen())) { + m_item->setPen(m_barset->pen()); + penChanged = true; + } + if (!m_customBrush && (m_item->brush() != m_barset->brush())) { + m_item->setBrush(m_barset->brush()); + brushChanged = true; + } + if (!m_customLabel && (m_item->label() != m_barset->label())) { + m_item->setLabel(m_barset->label()); + labelChanged = true; + } + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); + if (penChanged) + emit q_ptr->penChanged(); +} + +#include "moc_qbarlegendmarker.cpp" +#include "moc_qbarlegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE + diff --git a/src/charts/legend/qbarlegendmarker.h b/src/charts/legend/qbarlegendmarker.h new file mode 100644 index 00000000..4af967f7 --- /dev/null +++ b/src/charts/legend/qbarlegendmarker.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#ifndef QBARLEGENDMARKER_H +#define QBARLEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/QLegendMarker> +#include <QtCharts/QAbstractBarSeries> +#include <QtCharts/QBarSet> + +QT_CHARTS_BEGIN_NAMESPACE + +class QLegend; +class QBarLegendMarkerPrivate; + +class QT_CHARTS_EXPORT QBarLegendMarker : public QLegendMarker +{ + Q_OBJECT +public: + explicit QBarLegendMarker(QAbstractBarSeries *series, QBarSet *barset, QLegend *legend, QObject *parent = 0); + virtual ~QBarLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypeBar; } + + // Related series and barset + virtual QAbstractBarSeries* series(); + QBarSet* barset(); + +protected: + QBarLegendMarker(QBarLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QBarLegendMarker) + Q_DISABLE_COPY(QBarLegendMarker) + +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QBARLEGENDMARKER_H diff --git a/src/charts/legend/qbarlegendmarker_p.h b/src/charts/legend/qbarlegendmarker_p.h new file mode 100644 index 00000000..a42fd0fa --- /dev/null +++ b/src/charts/legend/qbarlegendmarker_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QBARLEGENDMARKER_P_H +#define QBARLEGENDMARKER_P_H + +#include "qchartglobal.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include <QAbstractBarSeries> +#include <QBarSet> + +QT_CHARTS_BEGIN_NAMESPACE + +class QBarLegendMarker; + +class QBarLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QBarLegendMarkerPrivate(QBarLegendMarker *q, QAbstractBarSeries *series, QBarSet *barset, QLegend *legend); + virtual ~QBarLegendMarkerPrivate(); + + virtual QAbstractBarSeries* series(); + virtual QObject* relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QBarLegendMarker *q_ptr; + QAbstractBarSeries *m_series; + QBarSet *m_barset; + + Q_DECLARE_PUBLIC(QBarLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QBARLEGENDMARKER_P_H diff --git a/src/charts/legend/qboxplotlegendmarker.cpp b/src/charts/legend/qboxplotlegendmarker.cpp new file mode 100644 index 00000000..53594737 --- /dev/null +++ b/src/charts/legend/qboxplotlegendmarker.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** 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 "qboxplotlegendmarker.h" +#include "qboxplotlegendmarker_p.h" +#include "qboxplotseries.h" +#include "qboxplotseries_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QBoxPlotLegendMarker + \inmodule Qt Charts + \brief QLegendMarker subclass for box plot series. + \mainclass + + QBoxPlotLegendMarker is related to QBoxPlotSeries classes. + + \sa QLegend, QBoxPlotSeries +*/ + +/*! + \fn virtual LegendMarkerType QBoxPlotLegendMarker::type() + Returns QLegendMarker::LegendMarkerTypeBoxPlot +*/ + +/*! + \internal +*/ +QBoxPlotLegendMarker::QBoxPlotLegendMarker(QBoxPlotSeries *series, QLegend *legend, QObject *parent) : + QLegendMarker(*new QBoxPlotLegendMarkerPrivate(this,series,legend), parent) +{ + d_ptr->updated(); +} + +/*! + Destructor +*/ +QBoxPlotLegendMarker::~QBoxPlotLegendMarker() +{ +} + +/*! + \internal +*/ +QBoxPlotLegendMarker::QBoxPlotLegendMarker(QBoxPlotLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +/*! + Returns the related series +*/ +QBoxPlotSeries* QBoxPlotLegendMarker::series() +{ + Q_D(QBoxPlotLegendMarker); + return d->m_series; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QBoxPlotLegendMarkerPrivate::QBoxPlotLegendMarkerPrivate(QBoxPlotLegendMarker *q, QBoxPlotSeries *series, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series) +{ + QObject::connect(m_series, SIGNAL(nameChanged()), this, SLOT(updated())); + QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(updated())); +} + +QBoxPlotLegendMarkerPrivate::~QBoxPlotLegendMarkerPrivate() +{ +} + +QAbstractSeries* QBoxPlotLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QBoxPlotLegendMarkerPrivate::relatedObject() +{ + return m_series; +} + +void QBoxPlotLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + + if (!m_customLabel && (m_item->label() != m_series->name())) { + m_item->setLabel(m_series->name()); + labelChanged = true; + } + if (!m_customBrush && (m_item->brush() != m_series->brush())) { + m_item->setBrush(m_series->brush()); + brushChanged = true; + } + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); +} + +#include "moc_qboxplotlegendmarker.cpp" +#include "moc_qboxplotlegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE + diff --git a/src/charts/legend/qboxplotlegendmarker.h b/src/charts/legend/qboxplotlegendmarker.h new file mode 100644 index 00000000..49a5859a --- /dev/null +++ b/src/charts/legend/qboxplotlegendmarker.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QBOXPLOTLEGENDMARKER_H +#define QBOXPLOTLEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/QLegendMarker> +#include <QtCharts/QBoxPlotSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QBoxPlotLegendMarkerPrivate; + +class QT_CHARTS_EXPORT QBoxPlotLegendMarker : public QLegendMarker +{ + Q_OBJECT + +public: + explicit QBoxPlotLegendMarker(QBoxPlotSeries *series, QLegend *legend, QObject *parent = 0); + virtual ~QBoxPlotLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypeBoxPlot; } + + // Related series + virtual QBoxPlotSeries* series(); + +protected: + QBoxPlotLegendMarker(QBoxPlotLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QBoxPlotLegendMarker) + Q_DISABLE_COPY(QBoxPlotLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QBOXPLOTLEGENDMARKER_H diff --git a/src/charts/legend/qboxplotlegendmarker_p.h b/src/charts/legend/qboxplotlegendmarker_p.h new file mode 100644 index 00000000..cdabb688 --- /dev/null +++ b/src/charts/legend/qboxplotlegendmarker_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QBOXPLOTLEGENDMARKER_P_H +#define QBOXPLOTLEGENDMARKER_P_H + +#include "qchartglobal.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include <QBoxPlotSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QBoxPlotLegendMarker; + +class QBoxPlotLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QBoxPlotLegendMarkerPrivate(QBoxPlotLegendMarker *q, QBoxPlotSeries *series, QLegend *legend); + virtual ~QBoxPlotLegendMarkerPrivate(); + + virtual QAbstractSeries *series(); + virtual QObject *relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QBoxPlotLegendMarker *q_ptr; + QBoxPlotSeries *m_series; + + Q_DECLARE_PUBLIC(QBoxPlotLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QBOXPLOTLEGENDMARKER_P_H diff --git a/src/charts/legend/qlegend.cpp b/src/charts/legend/qlegend.cpp new file mode 100644 index 00000000..ead1fac8 --- /dev/null +++ b/src/charts/legend/qlegend.cpp @@ -0,0 +1,632 @@ +/**************************************************************************** + ** + ** 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 "qlegend.h" +#include "qlegend_p.h" +#include "qabstractseries.h" +#include "qabstractseries_p.h" +#include "qchart_p.h" +#include "legendlayout_p.h" +#include "chartpresenter_p.h" +#include "abstractchartlayout_p.h" +#include "qlegendmarker.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "chartdataset_p.h" +#include <QPainter> +#include <QPen> +#include <QGraphicsItemGroup> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QLegend + \inmodule Qt Charts + \brief Legend object. + \mainclass + + QLegend is a graphical object for displaying the legend of the chart. Legend state is updated by QChart, when + series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and + handle the drawing manually. + User isn't supposed to create or delete legend objects, but can reference it via QChart class. + + \image examples_percentbarchart_legend.png + + \sa QChart +*/ +/*! + \qmltype Legend + \instantiates QLegend + \inqmlmodule QtCharts + + \brief Legend is part of Qt Chart QML API. + + Legend is a graphical object, whics displays legend of the chart. Legend state is updated by + ChartView, when series have been changed. Legend is used via ChartView class. For example: + \code + ChartView { + legend.visible: true + legend.alignment: Qt.AlignBottom + // Add a few series... + } + \endcode + + \image examples_percentbarchart_legend.png + + Please note that there is no QML API available for modifying legend markers, unlike in the Qt + API of Charts. The use case of modifying markers can be implemented for example by creating your + own custom legend. For an example on how to do this, + see \l {qmlcustomlegend}{Qml Custom Example} application. +*/ + +/*! + \property QLegend::alignment + \brief The alignment of the legend. + + Legend paints on the defined position in the chart. The following alignments are supported: + Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined. +*/ +/*! + \qmlproperty Qt.Alignment Legend::alignment + \brief The alignment of the legend. + + Legend paints on the defined position in the chart. The following alignments are supported: + Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined. +*/ + +/*! + \property QLegend::backgroundVisible + Whether the legend background is visible or not. +*/ +/*! + \qmlproperty bool Legend::backgroundVisible + Whether the legend background is visible or not. +*/ + +/*! + \property QLegend::color + The color of the legend, i.e. the background (brush) color. Note that if you change the color + of the legend, the style of the legend brush is set to Qt::SolidPattern. +*/ +/*! + \qmlproperty color Legend::color + The color of the legend, i.e. the background (brush) color. +*/ + +/*! + \property QLegend::borderColor + The border color of the legend, i.e. the line color. +*/ +/*! + \qmlproperty color Legend::borderColor + The border color of the legend, i.e. the line color. +*/ + +/*! + \property QLegend::font + The font of markers used by legend. +*/ +/*! + \qmlproperty Font Legend::font + The font of markers used by legend. +*/ + +/*! + \property QLegend::labelColor + The color of brush used to draw labels. +*/ +/*! + \qmlproperty color Legend::labelColor + The color of brush used to draw labels. +*/ + +/*! + \property QLegend::reverseMarkers + Whether reverse order is used for the markers in legend or not. False by default. +*/ +/*! + \qmlproperty bool Legend::reverseMarkers + Whether reverse order is used for the markers in legend or not. False by default. +*/ + +/*! + \fn void QLegend::backgroundVisibleChanged(bool) + The visibility of the legend background changed to \a visible. +*/ + +/*! + \fn void QLegend::colorChanged(QColor) + The color of the legend background changed to \a color. +*/ + +/*! + \fn void QLegend::borderColorChanged(QColor) + The border color of the legend background changed to \a color. +*/ + +/*! + \fn void QLegend::fontChanged(QFont) + The font of markers of the legend changed to \a font. +*/ + +/*! + \fn void QLegend::labelColorChanged(QColor color) + This signal is emitted when the color of brush used to draw labels has changed to \a color. +*/ + +/*! + \fn void QLegend::reverseMarkersChanged(bool) + The use of reverse order for the markers in legend is changed to \a reverseMarkers. +*/ + +QLegend::QLegend(QChart *chart): QGraphicsWidget(chart), + d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this)) +{ + setZValue(ChartPresenter::LegendZValue); + setFlags(QGraphicsItem::ItemClipsChildrenToShape); + QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*))); + QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*))); + setLayout(d_ptr->m_layout); +} + +/*! + Destroys the legend object. Legend is always owned by a QChart, so an application should never call this. +*/ +QLegend::~QLegend() +{ +} + +/*! + \internal + */ +void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + if (!d_ptr->m_backgroundVisible) + return; + + painter->setOpacity(opacity()); + painter->setPen(d_ptr->m_pen); + painter->setBrush(d_ptr->m_brush); + painter->drawRoundRect(rect(), d_ptr->roundness(rect().width()), d_ptr->roundness(rect().height())); +} + + +/*! + Sets the \a brush of legend. Brush affects the background of legend. + */ +void QLegend::setBrush(const QBrush &brush) +{ + if (d_ptr->m_brush != brush) { + d_ptr->m_brush = brush; + update(); + emit colorChanged(brush.color()); + } +} + +/*! + Returns the brush used by legend. + */ +QBrush QLegend::brush() const +{ + return d_ptr->m_brush; +} + +void QLegend::setColor(QColor color) +{ + QBrush b = d_ptr->m_brush; + if (b.style() != Qt::SolidPattern || b.color() != color) { + b.setStyle(Qt::SolidPattern); + b.setColor(color); + setBrush(b); + } +} + +QColor QLegend::color() +{ + return d_ptr->m_brush.color(); +} + +/*! + Sets the \a pen of legend. Pen affects the legend borders. + */ +void QLegend::setPen(const QPen &pen) +{ + if (d_ptr->m_pen != pen) { + d_ptr->m_pen = pen; + update(); + emit borderColorChanged(pen.color()); + } +} + +/*! + Returns the pen used by legend. + */ + +QPen QLegend::pen() const +{ + return d_ptr->m_pen; +} + +void QLegend::setFont(const QFont &font) +{ + if (d_ptr->m_font != font) { + // Hide items to avoid flickering + d_ptr->items()->setVisible(false); + d_ptr->m_font = font; + foreach (QLegendMarker *marker, d_ptr->markers()) { + marker->setFont(d_ptr->m_font); + } + layout()->invalidate(); + emit fontChanged(font); + } +} + +QFont QLegend::font() const +{ + return d_ptr->m_font; +} + +void QLegend::setBorderColor(QColor color) +{ + QPen p = d_ptr->m_pen; + if (p.color() != color) { + p.setColor(color); + setPen(p); + } +} + +QColor QLegend::borderColor() +{ + return d_ptr->m_pen.color(); +} + +/*! + Set brush used to draw labels to \a brush. +*/ +void QLegend::setLabelBrush(const QBrush &brush) +{ + if (d_ptr->m_labelBrush != brush) { + d_ptr->m_labelBrush = brush; + foreach (QLegendMarker *marker, d_ptr->markers()) { + marker->setLabelBrush(d_ptr->m_labelBrush); + // Note: The pen of the marker rectangle could be exposed in the public QLegend API + // instead of mapping it from label brush color + marker->setPen(brush.color()); + } + emit labelColorChanged(brush.color()); + } +} + +/*! + Brush used to draw labels. +*/ +QBrush QLegend::labelBrush() const +{ + return d_ptr->m_labelBrush; +} + +void QLegend::setLabelColor(QColor color) +{ + QBrush b = d_ptr->m_labelBrush; + if (b.style() != Qt::SolidPattern || b.color() != color) { + b.setStyle(Qt::SolidPattern); + b.setColor(color); + setLabelBrush(b); + } +} + +QColor QLegend::labelColor() const +{ + return d_ptr->m_labelBrush.color(); +} + + +void QLegend::setAlignment(Qt::Alignment alignment) +{ + if (d_ptr->m_alignment != alignment) { + d_ptr->m_alignment = alignment; + layout()->invalidate(); + } +} + +Qt::Alignment QLegend::alignment() const +{ + return d_ptr->m_alignment; +} + +/*! + Detaches the legend from chart. Chart won't change layout of the legend. + */ +void QLegend::detachFromChart() +{ + d_ptr->m_attachedToChart = false; +// layout()->invalidate(); + d_ptr->m_chart->layout()->invalidate(); + setParent(0); + +} + +/*! + Attaches the legend to chart. Chart may change layout of the legend. + */ +void QLegend::attachToChart() +{ + d_ptr->m_attachedToChart = true; +// layout()->invalidate(); + d_ptr->m_chart->layout()->invalidate(); + setParent(d_ptr->m_chart); +} + +/*! + Returns true, if legend is attached to chart. + */ +bool QLegend::isAttachedToChart() +{ + return d_ptr->m_attachedToChart; +} + +/*! + Sets the visibility of legend background to \a visible + */ +void QLegend::setBackgroundVisible(bool visible) +{ + if (d_ptr->m_backgroundVisible != visible) { + d_ptr->m_backgroundVisible = visible; + update(); + emit backgroundVisibleChanged(visible); + } +} + +/*! + Returns the visibility of legend background + */ +bool QLegend::isBackgroundVisible() const +{ + return d_ptr->m_backgroundVisible; +} + +/*! + Returns the list of markers in legend. The list can be filtered with \a series parameter. + If \a series is given, only markers related to that series are returned. +*/ +QList<QLegendMarker*> QLegend::markers(QAbstractSeries *series) const +{ + return d_ptr->markers(series); +} + +bool QLegend::reverseMarkers() +{ + return d_ptr->m_reverseMarkers; +} + +void QLegend::setReverseMarkers(bool reverseMarkers) +{ + if (d_ptr->m_reverseMarkers != reverseMarkers) { + d_ptr->m_reverseMarkers = reverseMarkers; + layout()->invalidate(); + emit reverseMarkersChanged(reverseMarkers); + } +} + +/*! + \internal \a event see QGraphicsWidget for details + */ +void QLegend::hideEvent(QHideEvent *event) +{ + if (isAttachedToChart()) + d_ptr->m_presenter->layout()->invalidate(); + QGraphicsWidget::hideEvent(event); +} +/*! + \internal \a event see QGraphicsWidget for details + */ +void QLegend::showEvent(QShowEvent *event) +{ + if (isAttachedToChart()) + layout()->invalidate(); + QGraphicsWidget::showEvent(event); + //layout activation will show the items +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q) + : q_ptr(q), + m_presenter(presenter), + m_layout(new LegendLayout(q)), + m_chart(chart), + m_items(new QGraphicsItemGroup(q)), + m_alignment(Qt::AlignTop), + m_brush(QBrush()), + m_pen(QPen()), + m_labelBrush(QBrush()), + m_diameter(5), + m_attachedToChart(true), + m_backgroundVisible(false), + m_reverseMarkers(false) +{ + m_items->setHandlesChildEvents(false); +} + +QLegendPrivate::~QLegendPrivate() +{ + +} + +void QLegendPrivate::setOffset(const QPointF &offset) +{ + m_layout->setOffset(offset.x(), offset.y()); +} + +QPointF QLegendPrivate::offset() const +{ + return m_layout->offset(); +} + +int QLegendPrivate::roundness(qreal size) +{ + return 100 * m_diameter / int(size); +} + +QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series) +{ + // Return all markers + if (!series) { + return m_markers; + } + + // Create filtered list + QList<QLegendMarker *> markers; + foreach (QLegendMarker *marker, m_markers) { + if (marker->series() == series) { + markers.append(marker); + } + } + return markers; +} + +void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series) +{ + if (m_series.contains(series)) { + return; + } + + QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(q_ptr); + decorateMarkers(newMarkers); + addMarkers(newMarkers); + + QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged())); + QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged())); + + m_series.append(series); + m_items->setVisible(false); + m_layout->invalidate(); +} + +void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series) +{ + if (m_series.contains(series)) { + m_series.removeOne(series); + } + + // Find out, which markers to remove + QList<QLegendMarker *> removed; + foreach (QLegendMarker *m, m_markers) { + if (m->series() == series) { + removed << m; + } + } + removeMarkers(removed); + + QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged())); + QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged())); + + m_layout->invalidate(); +} + +void QLegendPrivate::handleSeriesVisibleChanged() +{ + QAbstractSeries *series = qobject_cast<QAbstractSeries *> (sender()); + Q_ASSERT(series); + + foreach (QLegendMarker *marker, m_markers) { + if (marker->series() == series) { + marker->setVisible(series->isVisible()); + } + } + + if (m_chart->isVisible()) + m_layout->invalidate(); +} + +void QLegendPrivate::handleCountChanged() +{ + // Here we handle the changes in marker count. + // Can happen for example when pieslice(s) have been added to or removed from pieseries. + + QAbstractSeriesPrivate *series = qobject_cast<QAbstractSeriesPrivate *> (sender()); + QList<QLegendMarker *> createdMarkers = series->createLegendMarkers(q_ptr); + + // Find out removed markers and created markers + QList<QLegendMarker *> removedMarkers; + foreach (QLegendMarker *oldMarker, m_markers) { + // we have marker, which is related to sender. + if (oldMarker->series() == series->q_ptr) { + bool found = false; + foreach(QLegendMarker *newMarker, createdMarkers) { + // New marker considered existing if: + // - d_ptr->relatedObject() is same for both markers. + if (newMarker->d_ptr->relatedObject() == oldMarker->d_ptr->relatedObject()) { + // Delete the new marker, since we already have existing marker, that might be connected on user side. + found = true; + createdMarkers.removeOne(newMarker); + delete newMarker; + } + } + if (!found) { + // No related object found for marker, add to removedMarkers list + removedMarkers << oldMarker; + } + } + } + + removeMarkers(removedMarkers); + decorateMarkers(createdMarkers); + addMarkers(createdMarkers); + + q_ptr->layout()->invalidate(); +} + +void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers) +{ + foreach (QLegendMarker *marker, markers) { + m_items->addToGroup(marker->d_ptr.data()->item()); + m_markers << marker; + m_markerHash.insert(marker->d_ptr->item(), marker); + } +} + +void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers) +{ + foreach (QLegendMarker *marker, markers) { + marker->d_ptr->item()->setVisible(false); + m_items->removeFromGroup(marker->d_ptr->item()); + m_markers.removeOne(marker); + m_markerHash.remove(marker->d_ptr->item()); + delete marker; + } +} + +void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers) +{ + foreach (QLegendMarker *marker, markers) { + marker->setFont(m_font); + marker->setLabelBrush(m_labelBrush); + } +} + + +#include "moc_qlegend.cpp" +#include "moc_qlegend_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/qlegend.h b/src/charts/legend/qlegend.h new file mode 100644 index 00000000..c727e8f3 --- /dev/null +++ b/src/charts/legend/qlegend.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QLEGEND_H +#define QLEGEND_H + +#include <QtCharts/qchartglobal.h> +#include <QGraphicsWidget> +#include <QPen> +#include <QBrush> + +QT_CHARTS_BEGIN_NAMESPACE + +class QChart; +class QLegendPrivate; +class QLegendMarker; +class QAbstractSeries; + +class QT_CHARTS_EXPORT QLegend : public QGraphicsWidget +{ + Q_OBJECT + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) + Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible NOTIFY backgroundVisibleChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor NOTIFY labelColorChanged) + Q_PROPERTY(bool reverseMarkers READ reverseMarkers WRITE setReverseMarkers NOTIFY reverseMarkersChanged) + +private: + explicit QLegend(QChart *chart); + +public: + ~QLegend(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + void setBrush(const QBrush &brush); + QBrush brush() const; + void setColor(QColor color); + QColor color(); + + void setPen(const QPen &pen); + QPen pen() const; + void setBorderColor(QColor color); + QColor borderColor(); + + void setFont(const QFont &font); + QFont font() const; + void setLabelBrush(const QBrush &brush); + QBrush labelBrush() const; + + void setLabelColor(QColor color); + QColor labelColor() const; + + void setAlignment(Qt::Alignment alignment); + Qt::Alignment alignment() const; + + void detachFromChart(); + void attachToChart(); + bool isAttachedToChart(); + + void setBackgroundVisible(bool visible = true); + bool isBackgroundVisible() const; + + QList <QLegendMarker*> markers(QAbstractSeries *series = 0) const; + + bool reverseMarkers(); + void setReverseMarkers(bool reverseMarkers = true); + +protected: + void hideEvent(QHideEvent *event); + void showEvent(QShowEvent *event); + +Q_SIGNALS: + void backgroundVisibleChanged(bool visible); + void colorChanged(QColor color); + void borderColorChanged(QColor color); + void fontChanged(QFont font); + void labelColorChanged(QColor color); + void reverseMarkersChanged(bool reverseMarkers); + +private: + QScopedPointer<QLegendPrivate> d_ptr; + Q_DISABLE_COPY(QLegend) + friend class LegendScroller; + friend class LegendLayout; + friend class ChartLayout; + friend class LegendMarkerItem; + friend class QLegendMarkerPrivate; +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QLEGEND_H diff --git a/src/charts/legend/qlegend_p.h b/src/charts/legend/qlegend_p.h new file mode 100644 index 00000000..655825c6 --- /dev/null +++ b/src/charts/legend/qlegend_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QLEGEND_P_H +#define QLEGEND_P_H + +#include "qlegend.h" + +QT_CHARTS_BEGIN_NAMESPACE + +class QChart; +class ChartPresenter; +class QAbstractSeries; +class LegendLayout; +class QLegendMarker; + +class QLegendPrivate : public QObject +{ + Q_OBJECT +public: + QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q); + ~QLegendPrivate(); + + void setOffset(const QPointF &offset); + QPointF offset() const; + int roundness(qreal size); + + QGraphicsItemGroup* items() { return m_items; } + + QList<QLegendMarker*> markers(QAbstractSeries *series = 0); + +public Q_SLOTS: + void handleSeriesAdded(QAbstractSeries *series); + void handleSeriesRemoved(QAbstractSeries *series); + void handleSeriesVisibleChanged(); + void handleCountChanged(); + +private: + // Internal helpers + void addMarkers(QList<QLegendMarker *> markers); + void removeMarkers(QList<QLegendMarker *> markers); + void decorateMarkers(QList<QLegendMarker *> markers); + +private: + QLegend *q_ptr; + ChartPresenter *m_presenter; + LegendLayout *m_layout; + QChart *m_chart; + QGraphicsItemGroup *m_items; + Qt::Alignment m_alignment; + QBrush m_brush; + QPen m_pen; + QFont m_font; + QBrush m_labelBrush; + + qreal m_diameter; + bool m_attachedToChart; + bool m_backgroundVisible; + bool m_reverseMarkers; + + QList<QLegendMarker *> m_markers; + QList<QAbstractSeries *> m_series; + + QHash<QGraphicsItem *, QLegendMarker *> m_markerHash; + + friend class QLegend; + friend class LegendMarkerItem; + friend class LegendLayout; + friend class QLegendMarkerPrivate; + friend class LegendScroller; +}; + +QT_CHARTS_END_NAMESPACE + +#endif diff --git a/src/charts/legend/qlegendmarker.cpp b/src/charts/legend/qlegendmarker.cpp new file mode 100644 index 00000000..e170cb4d --- /dev/null +++ b/src/charts/legend/qlegendmarker.cpp @@ -0,0 +1,294 @@ +/**************************************************************************** + ** + ** 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 "qlegendmarker.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include "qlegend.h" +#include "qlegend_p.h" +#include "legendlayout_p.h" +#include <QFontMetrics> +#include <QGraphicsSceneEvent> +#include <QAbstractSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QLegendMarker + \inmodule Qt Charts + \brief LegendMarker object. + \mainclass + + QLegendMarker is abstract object that can be used to access markers inside QLegend. Legend marker consists of two + items: The colored box, which reflects the color of series and label, which is the name of series (or label of slice/barset + in case of pie or bar series) + The QLegendMarker is always related to one series. + + \image examples_percentbarchart_legend.png + + \sa QLegend +*/ +/*! + \enum QLegendMarker::LegendMarkerType + + The type of the legendmarker object. + + \value LegendMarkerTypeArea + \value LegendMarkerTypeBar + \value LegendMarkerTypePie + \value LegendMarkerTypeXY + \value LegendMarkerTypeBoxPlot +*/ + +/*! + \fn virtual LegendMarkerType QLegendMarker::type() = 0; + Returns the type of legendmarker. Type depends of the related series. LegendMarkerTypeXY is used for all QXYSeries derived + classes. +*/ + +/*! + \fn virtual QAbstractSeries* QLegendMarker::series() = 0; + Returns pointer to series, which is related to this marker. Marker is always related to some series. +*/ + +/*! + \fn void QLegendMarker::clicked(); + This signal is emitted, when marker is clicked with mouse. +*/ + +/*! + \fn void QLegendMarker::hovered(bool status); + This signal is emitted, when mouse is hovered over marker. \a status is true, when mouse enters the marker + and false when it leaves the marker. +*/ + +/*! + \fn void QLegendMarker::labelChanged() + This signal is emitted when the label of the legend marker has changed. +*/ + +/*! + \fn void QLegendMarker::labelBrushChanged() + This signal is emitted when the label brush of the legend marker has changed. +*/ + +/*! + \fn void QLegendMarker::fontChanged() + This signal is emitted when the (label) font of the legend marker has changed. +*/ + +/*! + \fn void QLegendMarker::penChanged() + This signal is emitted when the pen of the legend marker has changed. +*/ + +/*! + \fn void QLegendMarker::brushChanged() + This signal is emitted when the brush of the legend marker has changed. +*/ + +/*! + \fn void QLegendMarker::visibleChanged() + This signal is emitted when the visibility of the legend marker has changed. +*/ + +/*! + \property QLegendMarker::label + Label of the marker. This is the text that is shown in legend. +*/ + +/*! + \property QLegendMarker::labelBrush + Brush of the label +*/ + +/*! + \property QLegendMarker::font + Font of the label +*/ + +/*! + \property QLegendMarker::pen + Pen of the marker. This is the outline of the colored square. +*/ + +/*! + \property QLegendMarker::brush + Brush of the marker. This is the inside of the colored square. +*/ + +/*! + \property QLegendMarker::visible + Visibility of the legend marker. Affects label and the colored square. +*/ + + +/*! + \internal + */ +QLegendMarker::QLegendMarker(QLegendMarkerPrivate &d, QObject *parent) : + QObject(parent), + d_ptr(&d) +{ + d_ptr->m_item->setVisible(d_ptr->series()->isVisible()); +} + +/*! + Destructor of marker +*/ +QLegendMarker::~QLegendMarker() +{ +} + +/*! + Returns the label of the marker. +*/ +QString QLegendMarker::label() const +{ + return d_ptr->m_item->label(); +} + +/*! + Sets the \a label of marker. Note that changing name of series will also change label of its marker. +*/ +void QLegendMarker::setLabel(const QString &label) +{ + if (label.isEmpty()) { + d_ptr->m_customLabel = false; + } else { + d_ptr->m_customLabel = true; + d_ptr->m_item->setLabel(label); + } +} +/*! + Returns the brush which is used to draw label. +*/ +QBrush QLegendMarker::labelBrush() const +{ + return d_ptr->m_item->labelBrush(); +} + +/*! + Sets the \a brush of label +*/ +void QLegendMarker::setLabelBrush(const QBrush &brush) +{ + d_ptr->m_item->setLabelBrush(brush); +} + +/*! + Retuns the font of label +*/ +QFont QLegendMarker::font() const +{ + return d_ptr->m_item->font(); +} + +/*! + Sets the \a font of label +*/ +void QLegendMarker::setFont(const QFont &font) +{ + d_ptr->m_item->setFont(font); +} + +/*! + Returns the pen of marker item +*/ +QPen QLegendMarker::pen() const +{ + return d_ptr->m_item->pen(); +} + +/*! + Sets the \a pen of marker item +*/ +void QLegendMarker::setPen(const QPen &pen) +{ + if (pen == QPen(Qt::NoPen)) { + d_ptr->m_customPen = false; + } else { + d_ptr->m_customPen = true; + d_ptr->m_item->setPen(pen); + } +} + +/*! + Returns the brush of marker item +*/ +QBrush QLegendMarker::brush() const +{ + return d_ptr->m_item->brush(); +} + +/*! + Sets the \a brush of marker item. Note that changing color of the series also changes this. +*/ +void QLegendMarker::setBrush(const QBrush &brush) +{ + if (brush == QBrush(Qt::NoBrush)) { + d_ptr->m_customBrush = false; + } else { + d_ptr->m_customBrush = true; + d_ptr->m_item->setBrush(brush); + } +} + +/*! + Returns visibility of the marker +*/ +bool QLegendMarker::isVisible() const +{ + return d_ptr->m_item->isVisible(); +} + +/*! + Sets markers visibility to \a visible +*/ +void QLegendMarker::setVisible(bool visible) +{ + d_ptr->m_item->setVisible(visible); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +QLegendMarkerPrivate::QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend) : + m_legend(legend), + m_customLabel(false), + m_customBrush(false), + m_customPen(false), + q_ptr(q) +{ + m_item = new LegendMarkerItem(this); +} + +QLegendMarkerPrivate::~QLegendMarkerPrivate() +{ + delete m_item; +} + +void QLegendMarkerPrivate::invalidateLegend() +{ + m_legend->d_ptr->m_layout->invalidate(); +} + +#include "moc_qlegendmarker.cpp" +#include "moc_qlegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/qlegendmarker.h b/src/charts/legend/qlegendmarker.h new file mode 100644 index 00000000..0d683886 --- /dev/null +++ b/src/charts/legend/qlegendmarker.h @@ -0,0 +1,105 @@ +/**************************************************************************** + ** + ** 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$ + ** + ****************************************************************************/ + +#ifndef QLEGENDMARKER_H +#define QLEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QObject> +#include <QPen> +#include <QBrush> +#include <QFont> + +QT_CHARTS_BEGIN_NAMESPACE + +class QLegendMarkerPrivate; +class QAbstractSeries; +class QLegend; + +class QT_CHARTS_EXPORT QLegendMarker : public QObject +{ + Q_OBJECT + +public: + enum LegendMarkerType { + LegendMarkerTypeArea, + LegendMarkerTypeBar, + LegendMarkerTypePie, + LegendMarkerTypeXY, + LegendMarkerTypeBoxPlot + }; + + Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged) + Q_PROPERTY(QBrush labelBrush READ labelBrush WRITE setLabelBrush NOTIFY labelBrushChanged) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) + Q_ENUMS(LegendMarkerType) + +public: + virtual ~QLegendMarker(); + virtual LegendMarkerType type() = 0; + + QString label() const; + void setLabel(const QString &label); + + QBrush labelBrush() const; + void setLabelBrush(const QBrush &brush); + + QFont font() const; + void setFont(const QFont &font); + + QPen pen() const; + void setPen(const QPen &pen); + + QBrush brush() const; + void setBrush(const QBrush &brush); + + bool isVisible() const; + void setVisible(bool visible); + + virtual QAbstractSeries* series() = 0; + +Q_SIGNALS: + void clicked(); + void hovered(bool status); + void labelChanged(); + void labelBrushChanged(); + void fontChanged(); + void penChanged(); + void brushChanged(); + void visibleChanged(); + +protected: + explicit QLegendMarker(QLegendMarkerPrivate &d, QObject *parent = 0); + + QScopedPointer<QLegendMarkerPrivate> d_ptr; + Q_DISABLE_COPY(QLegendMarker) + friend class QLegendPrivate; + friend class QLegendMarkerPrivate; + friend class LegendMarkerItem; + friend class LegendLayout; + friend class LegendScroller; +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QLEGENDMARKER_H diff --git a/src/charts/legend/qlegendmarker_p.h b/src/charts/legend/qlegendmarker_p.h new file mode 100644 index 00000000..09e46f09 --- /dev/null +++ b/src/charts/legend/qlegendmarker_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QLEGENDMARKERPRIVATE_H +#define QLEGENDMARKERPRIVATE_H + +#include "qchartglobal.h" +#include <QGraphicsObject> +#include <QBrush> +#include <QPen> +#include <QGraphicsLayoutItem> + +QT_CHARTS_BEGIN_NAMESPACE + +class QAbstractSeries; +class QLegend; + +class QLegendMarker; +class LegendMarkerItem; + +class QLegendMarkerPrivate : public QObject +{ + Q_OBJECT +public: + explicit QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend); + virtual ~QLegendMarkerPrivate(); + + // Helper for now. (or declare LegendLayout as friend) + LegendMarkerItem* item() const { return m_item; } + + virtual QAbstractSeries* series() = 0; + virtual QObject* relatedObject() = 0; + + void invalidateLegend(); + +public Q_SLOTS: + virtual void updated() = 0; + +protected: + LegendMarkerItem *m_item; + QLegend *m_legend; + bool m_customLabel; + bool m_customBrush; + bool m_customPen; + +private: + QLegendMarker *q_ptr; + + friend class QLegendPrivate; + friend class LegendMarkerItem; + Q_DECLARE_PUBLIC(QLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QLEGENDMARKERPRIVATE_H diff --git a/src/charts/legend/qpielegendmarker.cpp b/src/charts/legend/qpielegendmarker.cpp new file mode 100644 index 00000000..e7bc7281 --- /dev/null +++ b/src/charts/legend/qpielegendmarker.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 "qpielegendmarker.h" +#include "qpielegendmarker_p.h" +#include <QPieSeries> +#include <QPieSlice> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QPieLegendMarker + \inmodule Qt Charts + \brief QLegendMarker subclass for pie series. + \mainclass + + QPieLegendMarker is related to QPieSeries. With QPieSeries, each slice of pie is related to one marker in QLegend. + + \sa QLegend, QPieSeries, QPieSlice +*/ + +/*! + \fn virtual LegendMarkerType QPieLegendMarker::type() + Returns QLegendMarker::LegendMarkerTypePie +*/ + +/*! + \internal +*/ +QPieLegendMarker::QPieLegendMarker(QPieSeries *series, QPieSlice *slice, QLegend *legend, QObject *parent) : + QLegendMarker(*new QPieLegendMarkerPrivate(this,series,slice,legend), parent) +{ + d_ptr->updated(); +} + +/*! + Destructor +*/ +QPieLegendMarker::~QPieLegendMarker() +{ +} + +/*! + \internal +*/ +QPieLegendMarker::QPieLegendMarker(QPieLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +/*! + Returns the related series of marker. +*/ +QPieSeries* QPieLegendMarker::series() +{ + Q_D(QPieLegendMarker); + return d->m_series; +} + +/*! + Returns the related slice of marker. +*/ +QPieSlice* QPieLegendMarker::slice() +{ + Q_D(QPieLegendMarker); + return d->m_slice; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QPieLegendMarkerPrivate::QPieLegendMarkerPrivate(QPieLegendMarker *q, QPieSeries *series, QPieSlice *slice, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series), + m_slice(slice) +{ + QObject::connect(m_slice, SIGNAL(labelChanged()), this, SLOT(updated())); + QObject::connect(m_slice, SIGNAL(brushChanged()), this, SLOT(updated())); + QObject::connect(m_slice, SIGNAL(penChanged()), this, SLOT(updated())); +} + +QPieLegendMarkerPrivate::~QPieLegendMarkerPrivate() +{ +} + +QPieSeries* QPieLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QPieLegendMarkerPrivate::relatedObject() +{ + return m_slice; +} + +void QPieLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + bool penChanged = false; + + if (!m_customPen && (m_item->pen() != m_slice->pen())) { + m_item->setPen(m_slice->pen()); + penChanged = true; + } + if (!m_customBrush && (m_item->brush() != m_slice->brush())) { + m_item->setBrush(m_slice->brush()); + brushChanged = true; + } + if (!m_customLabel && (m_item->label() != m_slice->label())) { + m_item->setLabel(m_slice->label()); + labelChanged = true; + } + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); + if (penChanged) + emit q_ptr->penChanged(); +} + +#include "moc_qpielegendmarker.cpp" +#include "moc_qpielegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/qpielegendmarker.h b/src/charts/legend/qpielegendmarker.h new file mode 100644 index 00000000..c40fcf3a --- /dev/null +++ b/src/charts/legend/qpielegendmarker.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QPIELEGENDMARKER_H +#define QPIELEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/QLegendMarker> +#include <QtCharts/QPieSeries> +#include <QtCharts/QPieSlice> + +QT_CHARTS_BEGIN_NAMESPACE + +class QPieLegendMarkerPrivate; + +class QT_CHARTS_EXPORT QPieLegendMarker : public QLegendMarker +{ + Q_OBJECT + +public: + explicit QPieLegendMarker(QPieSeries *series, QPieSlice *slice, QLegend *legend, QObject *parent = 0); + virtual ~QPieLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypePie; } + + // Related series and slice + virtual QPieSeries* series(); + QPieSlice* slice(); + +protected: + QPieLegendMarker(QPieLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QPieLegendMarker) + Q_DISABLE_COPY(QPieLegendMarker) + +}; + +QT_CHARTS_END_NAMESPACE +#endif // QPIELEGENDMARKER_H diff --git a/src/charts/legend/qpielegendmarker_p.h b/src/charts/legend/qpielegendmarker_p.h new file mode 100644 index 00000000..44faf50b --- /dev/null +++ b/src/charts/legend/qpielegendmarker_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QPIELEGENDMARKER_P_H +#define QPIELEGENDMARKER_P_H + +#include "qchartglobal.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include <QPieSeries> +#include <QPieSlice> + +QT_CHARTS_BEGIN_NAMESPACE + +class QPieLegendMarker; + +class QPieLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QPieLegendMarkerPrivate(QPieLegendMarker *q, QPieSeries *series, QPieSlice *slice, QLegend *legend); + virtual ~QPieLegendMarkerPrivate(); + + // internal + virtual QPieSeries* series(); + virtual QObject* relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QPieLegendMarker *q_ptr; + + QPieSeries *m_series; + QPieSlice *m_slice; + + Q_DECLARE_PUBLIC(QPieLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QPIELEGENDMARKER_P_H diff --git a/src/charts/legend/qxylegendmarker.cpp b/src/charts/legend/qxylegendmarker.cpp new file mode 100644 index 00000000..711e74c6 --- /dev/null +++ b/src/charts/legend/qxylegendmarker.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** 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 "qxylegendmarker.h" +#include "qxylegendmarker_p.h" +#include "qxyseries_p.h" +#include <QXYSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QXYLegendMarker + \inmodule Qt Charts + \brief QLegendMarker subclass for QXYSeries. + \mainclass + + QXYLegendMarker is related to QXYSeries derived classes. Each marker is related to one series. + + \sa QLegend, QXYSeries, QSplineSeries, QScatterSeries, QLineSeries +*/ + +/*! + \fn virtual LegendMarkerType QXYLegendMarker::type() + Returns QLegendMarker::LegendMarkerTypeXY +*/ + +/*! + \internal +*/ +QXYLegendMarker::QXYLegendMarker(QXYSeries *series, QLegend *legend, QObject *parent) : + QLegendMarker(*new QXYLegendMarkerPrivate(this,series,legend), parent) +{ + d_ptr->updated(); +} + +/*! + Destructor +*/ +QXYLegendMarker::~QXYLegendMarker() +{ +} + +/*! + \internal +*/ +QXYLegendMarker::QXYLegendMarker(QXYLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +/*! + Returns the related series +*/ +QXYSeries* QXYLegendMarker::series() +{ + Q_D(QXYLegendMarker); + return d->m_series; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QXYLegendMarkerPrivate::QXYLegendMarkerPrivate(QXYLegendMarker *q, QXYSeries *series, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series) +{ + QObject::connect(m_series, SIGNAL(nameChanged()), this, SLOT(updated())); + QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(updated())); +} + +QXYLegendMarkerPrivate::~QXYLegendMarkerPrivate() +{ +} + +QAbstractSeries* QXYLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QXYLegendMarkerPrivate::relatedObject() +{ + return m_series; +} + +void QXYLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + + if (!m_customLabel && (m_item->label() != m_series->name())) { + m_item->setLabel(m_series->name()); + labelChanged = true; + } + + if (m_series->type()== QAbstractSeries::SeriesTypeScatter) { + if (!m_customBrush && (m_item->brush() != m_series->brush())) { + m_item->setBrush(m_series->brush()); + brushChanged = true; + } + } else { + QBrush emptyBrush; + if (!m_customBrush + && (m_item->brush() == emptyBrush + || m_item->brush().color() != m_series->pen().color())) { + m_item->setBrush(QBrush(m_series->pen().color())); + brushChanged = true; + } + } + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); +} + +#include "moc_qxylegendmarker.cpp" +#include "moc_qxylegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE + diff --git a/src/charts/legend/qxylegendmarker.h b/src/charts/legend/qxylegendmarker.h new file mode 100644 index 00000000..24f0fa44 --- /dev/null +++ b/src/charts/legend/qxylegendmarker.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QXYLEGENDMARKER_H +#define QXYLEGENDMARKER_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/QLegendMarker> +#include <QtCharts/QXYSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QXYLegendMarkerPrivate; + +class QT_CHARTS_EXPORT QXYLegendMarker : public QLegendMarker +{ + Q_OBJECT +public: + explicit QXYLegendMarker(QXYSeries *series, QLegend *legend, QObject *parent = 0); + virtual ~QXYLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypeXY; } + + // Related series + virtual QXYSeries* series(); + +protected: + QXYLegendMarker(QXYLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QXYLegendMarker) + Q_DISABLE_COPY(QXYLegendMarker) + +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QXYLEGENDMARKER_H diff --git a/src/charts/legend/qxylegendmarker_p.h b/src/charts/legend/qxylegendmarker_p.h new file mode 100644 index 00000000..196d942f --- /dev/null +++ b/src/charts/legend/qxylegendmarker_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Enterprise Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXYLEGENDMARKER_P_H +#define QXYLEGENDMARKER_P_H + +#include "qchartglobal.h" +#include "qlegendmarker_p.h" +#include "legendmarkeritem_p.h" +#include <QXYSeries> + +QT_CHARTS_BEGIN_NAMESPACE + +class QXYLegendMarker; + +class QXYLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QXYLegendMarkerPrivate(QXYLegendMarker *q, QXYSeries *series, QLegend *legend); + virtual ~QXYLegendMarkerPrivate(); + + virtual QAbstractSeries* series(); + virtual QObject* relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QXYLegendMarker *q_ptr; + QXYSeries *m_series; + + Q_DECLARE_PUBLIC(QXYLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QXYLEGENDMARKER_P_H |