From 2b4630c673068db1d49e071ce6892ad36f40a34a 2012-04-10 10:31:11 From: Michal Klocek Date: 2012-04-10 10:31:11 Subject: [PATCH] Adds qlegend pimpl * refactors switch case to -> createLegendMarker in series pimpl * adds qlegend_p * adds legendscroller_p --- diff --git a/src/areachart/qareaseries.cpp b/src/areachart/qareaseries.cpp index 3e28da8..fb4f193 100644 --- a/src/areachart/qareaseries.cpp +++ b/src/areachart/qareaseries.cpp @@ -22,6 +22,7 @@ #include "qareaseries_p.h" #include "qlineseries.h" #include "areachartitem_p.h" +#include "legendmarker_p.h" #include "domain_p.h" #include "chartdataset_p.h" #include "charttheme_p.h" @@ -261,6 +262,13 @@ Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter) return area; } +QList QAreaSeriesPrivate::createLegendMarker(QLegend* legend) +{ + Q_Q(QAreaSeries); + QList list; + return list << new AreaLegendMarker(q,legend); +} + #include "moc_qareaseries.cpp" #include "moc_qareaseries_p.cpp" diff --git a/src/areachart/qareaseries_p.h b/src/areachart/qareaseries_p.h index e5bffd4..1b77996 100644 --- a/src/areachart/qareaseries_p.h +++ b/src/areachart/qareaseries_p.h @@ -45,6 +45,7 @@ public: void scaleDomain(Domain& domain); Chart* createGraphics(ChartPresenter* presenter); + QList createLegendMarker(QLegend* legend); Q_SIGNALS: void updated(); diff --git a/src/barchart/qbarseries.cpp b/src/barchart/qbarseries.cpp index e9eb86a..b30cfb8 100644 --- a/src/barchart/qbarseries.cpp +++ b/src/barchart/qbarseries.cpp @@ -24,6 +24,7 @@ #include "qbarset_p.h" #include "barchartmodel_p.h" #include "domain_p.h" +#include "legendmarker_p.h" #include "chartdataset_p.h" #include "charttheme_p.h" #include "chartanimator_p.h" @@ -805,6 +806,18 @@ Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter) } +QList QBarSeriesPrivate::createLegendMarker(QLegend* legend) +{ + Q_Q(QBarSeries); + QList markers; + foreach(QBarSet* set, q->barSets()) { + BarLegendMarker* marker = new BarLegendMarker(q,set,legend); + markers << marker; + } + + return markers; +} + #include "moc_qbarseries.cpp" #include "moc_qbarseries_p.cpp" diff --git a/src/barchart/qbarseries_p.h b/src/barchart/qbarseries_p.h index db644d7..a7223f4 100644 --- a/src/barchart/qbarseries_p.h +++ b/src/barchart/qbarseries_p.h @@ -19,6 +19,7 @@ public: void scaleDomain(Domain& domain); Chart* createGraphics(ChartPresenter* presenter); + QList createLegendMarker(QLegend* legend); bool setModel(QAbstractItemModel *model); void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical); diff --git a/src/legendscroller_p.h b/src/legendscroller_p.h new file mode 100644 index 0000000..ccfe701 --- /dev/null +++ b/src/legendscroller_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the QtCommercial 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 "qlegend.h" +#include "scroller_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class LegendScroller: public QLegend, public Scroller +{ + +public: + LegendScroller(QChart *chart):QLegend(chart) + { + } + + void setOffset(const QPointF& point) + { + QLegend::setOffset(point); + } + QPointF offset() const + { + return QLegend::offset(); + } + + void mousePressEvent(QGraphicsSceneMouseEvent* event){ + Scroller::mousePressEvent(event); + //QLegend::mousePressEvent(event); + } + void mouseMoveEvent(QGraphicsSceneMouseEvent* event){ + Scroller::mouseMoveEvent(event); + //QLegend::mouseMoveEvent(event); + } + void mouseReleaseEvent(QGraphicsSceneMouseEvent* event){ + Scroller::mouseReleaseEvent(event); + //QLegend::mouseReleaseEvent(event); + } +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif diff --git a/src/piechart/qpieseries.cpp b/src/piechart/qpieseries.cpp index 1f7a713..5c1116a 100644 --- a/src/piechart/qpieseries.cpp +++ b/src/piechart/qpieseries.cpp @@ -25,6 +25,7 @@ #include "chartdataset_p.h" #include "charttheme_p.h" #include "chartanimator_p.h" +#include "legendmarker_p.h" #include #include @@ -716,6 +717,17 @@ Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter) return pie; } +QList QPieSeriesPrivate::createLegendMarker(QLegend* legend) +{ + Q_Q(QPieSeries); + QList markers; + foreach(QPieSlice* slice, q->slices()) { + PieLegendMarker* marker = new PieLegendMarker(q,slice,legend); + markers << marker; + } + return markers; +} + #include "moc_qpieseries.cpp" #include "moc_qpieseries_p.cpp" diff --git a/src/piechart/qpieseries_p.h b/src/piechart/qpieseries_p.h index e2ee3f1..580d8c1 100644 --- a/src/piechart/qpieseries_p.h +++ b/src/piechart/qpieseries_p.h @@ -38,6 +38,7 @@ public: void scaleDomain(Domain& domain); Chart* createGraphics(ChartPresenter* presenter); + QList createLegendMarker(QLegend* legend); void updateDerivativeData(); diff --git a/src/qchart.cpp b/src/qchart.cpp index b3654ab..bfd34c2 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -20,6 +20,8 @@ #include "qchart.h" #include "qchart_p.h" +#include "legendscroller_p.h" +#include "qlegend_p.h" #include #include @@ -67,12 +69,13 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags), d_ptr(new QChartPrivate()) { - d_ptr->m_legend = new ScrolledQLegend(this); - d_ptr->m_legend->setVisible(false); d_ptr->m_dataset = new ChartDataSet(this); d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset); - d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false); d_ptr->createConnections(); + d_ptr->m_legend = new LegendScroller(this); + // d_ptr->m_legend->setVisible(false); + d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false); + //TODO:fix me setMinimumSize(d_ptr->m_padding.left() * 3, d_ptr->m_padding.top() * 3); } @@ -400,8 +403,7 @@ QChartPrivate::~QChartPrivate() void QChartPrivate::createConnections() { - QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*))); - QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*))); + QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_presenter,SLOT(handleSeriesAdded(QSeries*,Domain*))); QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_presenter,SLOT(handleSeriesRemoved(QSeries*))); QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QChartAxis*,Domain*))); diff --git a/src/qlegend.cpp b/src/qlegend.cpp index 61b4e3f..7e2701b 100644 --- a/src/qlegend.cpp +++ b/src/qlegend.cpp @@ -1,26 +1,29 @@ /**************************************************************************** -** -** Copyright (C) 2012 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://qt.digia.com -** -** This file is part of the Qt Commercial Charts Add-on. -** -** $QT_BEGIN_LICENSE$ -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. -** -** If you have questions regarding the use of this file, please use -** contact form at http://qt.digia.com -** $QT_END_LICENSE$ -** -****************************************************************************/ + ** + ** Copyright (C) 2012 Digia Plc + ** All rights reserved. + ** For any questions to Digia, please use contact form at http://qt.digia.com + ** + ** This file is part of the Qt Commercial Charts Add-on. + ** + ** $QT_BEGIN_LICENSE$ + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Digia. + ** + ** If you have questions regarding the use of this file, please use + ** contact form at http://qt.digia.com + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ #include "qlegend.h" -#include "qchart_p.h" +#include "qlegend_p.h" #include "qseries.h" +#include "qseries_p.h" +#include "qchart_p.h" + #include "legendmarker_p.h" #include "qxyseries.h" #include "qlineseries.h" @@ -43,366 +46,287 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE /*! - \class QLegend - \brief part of QtCommercial chart API. + \class QLegend + \brief part of QtCommercial chart API. - QLegend is a graphical object, whics displays 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. + QLegend is a graphical object, whics displays 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. - \mainclass + \mainclass - \sa QChart, QSeries -*/ + \sa QChart, QSeries + */ /*! - \enum QLegend::Alignment + \enum QLegend::Alignment - This enum describes the possible position for legend inside chart. + This enum describes the possible position for legend inside chart. - \value AlignmentTop - \value AlignmentBottom - \value AlignmentLeft - \value AlignmentRight -*/ + \value AlignmentTop + \value AlignmentBottom + \value AlignmentLeft + \value AlignmentRight + */ /*! - \fn qreal QLegend::minWidth() const - Returns minimum width of the legend -*/ + \fn qreal QLegend::minWidth() const + Returns minimum width of the legend + */ /*! - \fn qreal QLegend::minHeight() const - Returns minimum height of the legend -*/ + \fn qreal QLegend::minHeight() const + Returns minimum height of the legend + */ /*! - Constructs the legend object and sets the parent to \a parent -*/ + Constructs the legend object and sets the parent to \a parent + */ QLegend::QLegend(QChart *chart):QGraphicsWidget(chart), - m_margin(5), - m_offsetX(0), - m_offsetY(0), - m_brush(Qt::darkGray), // TODO: default should come from theme - m_alignment(QLegend::AlignmentTop), - m_markers(new QGraphicsItemGroup(this)), - m_attachedToChart(true), - m_chart(chart), - m_minWidth(0), - m_minHeight(0), - m_width(0), - m_height(0), - m_backgroundVisible(false) +d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this)) { setZValue(ChartPresenter::LegendZValue); setFlags(QGraphicsItem::ItemClipsChildrenToShape); - setVisible(false); // By default legend is invisible + setEnabled(false); // By default legend is disabled + + QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QSeries*,Domain*))); + QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QSeries*))); +} + +QLegend::~QLegend() +{ + } /*! - Paints the legend to given \a painter. Paremeters \a option and \a widget arent used. -*/ + Paints the legend to given \a painter. Paremeters \a option and \a widget arent used. + */ void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - Q_UNUSED(option) - Q_UNUSED(widget) - if(!m_backgroundVisible) return; + Q_UNUSED(option) + Q_UNUSED(widget) + if(!d_ptr->m_backgroundVisible) return; painter->setOpacity(opacity()); - painter->setPen(m_pen); - painter->setBrush(m_brush); + painter->setPen(d_ptr->m_pen); + painter->setBrush(d_ptr->m_brush); painter->drawRect(boundingRect()); } /*! - Bounding rect of legend. -*/ + Bounding rect of legend. + */ QRectF QLegend::boundingRect() const { - return m_rect; + return d_ptr->m_rect; } /*! - Sets the \a brush of legend. Brush affects the background of legend. -*/ + Sets the \a brush of legend. Brush affects the background of legend. + */ void QLegend::setBrush(const QBrush &brush) { - if (m_brush != brush) { - m_brush = brush; + if (d_ptr->m_brush != brush) { + d_ptr->m_brush = brush; update(); } } /*! - Returns the brush used by legend. -*/ + Returns the brush used by legend. + */ QBrush QLegend::brush() const { - return m_brush; + return d_ptr->m_brush; } /*! - Sets the \a pen of legend. Pen affects the legend borders. -*/ + Sets the \a pen of legend. Pen affects the legend borders. + */ void QLegend::setPen(const QPen &pen) { - if (m_pen != pen) { - m_pen = pen; + if (d_ptr->m_pen != pen) { + d_ptr->m_pen = pen; update(); } } /*! - Returns the pen used by legend -*/ + Returns the pen used by legend + */ QPen QLegend::pen() const { - return m_pen; + return d_ptr->m_pen; } /*! - Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart. - \sa QLegend::Alignment -*/ + Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart. + \sa QLegend::Alignment + */ void QLegend::setAlignment(QLegend::Alignments alignment) { - if(m_alignment!=alignment && m_attachedToChart) { - m_alignment = alignment; - updateLayout(); + if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) { + d_ptr->m_alignment = alignment; + d_ptr->updateLayout(); } } /*! - Returns the preferred layout for legend -*/ + Returns the preferred layout for legend + */ QLegend::Alignments QLegend::alignment() const { - return m_alignment; + return d_ptr->m_alignment; } /*! - \internal \a series \a domain Should be called when series is added to chart. -*/ -void QLegend::handleSeriesAdded(QSeries *series, Domain *domain) + Detaches the legend from chart. Chart won't change layout of the legend. + */ +void QLegend::detachFromChart() { - Q_UNUSED(domain) - - switch (series->type()) - { - case QSeries::SeriesTypeLine: { - QLineSeries *lineSeries = static_cast(series); - appendMarkers(lineSeries); - break; - } - case QSeries::SeriesTypeArea: { - QAreaSeries *areaSeries = static_cast(series); - appendMarkers(areaSeries); - break; - } - case QSeries::SeriesTypeBar: { - QBarSeries *barSeries = static_cast(series); - appendMarkers(barSeries); - break; - } - case QSeries::SeriesTypeStackedBar: { - QStackedBarSeries *stackedBarSeries = static_cast(series); - appendMarkers(stackedBarSeries); - break; - } - case QSeries::SeriesTypePercentBar: { - QPercentBarSeries *percentBarSeries = static_cast(series); - appendMarkers(percentBarSeries); - break; - } - case QSeries::SeriesTypeScatter: { - QScatterSeries *scatterSeries = static_cast(series); - appendMarkers(scatterSeries); - break; - } - case QSeries::SeriesTypePie: { - QPieSeries *pieSeries = static_cast(series); - appendMarkers(pieSeries); - connect(pieSeries,SIGNAL(added(QList)),this,SLOT(handleAdded(QList))); - break; - } - case QSeries::SeriesTypeSpline: { - QSplineSeries *splineSeries = static_cast(series); - appendMarkers(splineSeries); - break; - } - default: { - qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type."; - break; - } - } - - updateLayout(); + d_ptr->m_attachedToChart = false; } /*! - \internal \a series Should be called when series is removed from chart. -*/ -void QLegend::handleSeriesRemoved(QSeries *series) + Attaches the legend to chart. Chart may change layout of the legend. + */ +void QLegend::attachToChart() { - switch (series->type()) - { - case QSeries::SeriesTypeArea: { - QAreaSeries *areaSeries = static_cast(series); - deleteMarkers(areaSeries); - break; - } - case QSeries::SeriesTypePie: { - QPieSeries *pieSeries = static_cast(series); - disconnect(pieSeries, SIGNAL(added(QList)), this, SLOT(handleAdded(QList))); - deleteMarkers(series); - break; - } - default: { - // All other types - deleteMarkers(series); - break; - } - } - - updateLayout(); + d_ptr->m_attachedToChart = true; } /*! - \internal \a slices Should be called when slices are added to pie chart. -*/ -void QLegend::handleAdded(QList slices) + Returns true, if legend is attached to chart. + */ +bool QLegend::isAttachedToChart() { - QPieSeries* series = static_cast (sender()); - foreach(QPieSlice* slice, slices) { - PieLegendMarker* marker = new PieLegendMarker(series,slice, this); - m_markers->addToGroup(marker); - } - updateLayout(); + return d_ptr->m_attachedToChart; } -/*! - \internal \a slices Should be called when slices are removed from pie chart. Currently unused, - because removed slices are also deleted and we listen destroyed signal -*/ -void QLegend::handleRemoved(QList slices) +void QLegend::setOffset(const QPointF& point) { - Q_UNUSED(slices) + d_ptr->setOffset(point.x(),point.y()); } -/*! - Detaches the legend from chart. Chart won't change layout of the legend. -*/ -void QLegend::detachFromChart() +QPointF QLegend::offset() const { - m_attachedToChart = false; + return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY); } /*! - Attaches the legend to chart. Chart may change layout of the legend. -*/ -void QLegend::attachToChart() + Sets the visibility of legend background to \a visible + */ +void QLegend::setBackgroundVisible(bool visible) { - m_attachedToChart = true; + if(d_ptr->m_backgroundVisible!=visible) + { + d_ptr->m_backgroundVisible=visible; + update(); + } } /*! - Returns true, if legend is attached to chart. -*/ -bool QLegend::isAttachedToChart() + Returns the visibility of legend background + */ +bool QLegend::isBackgroundVisible() const { - return m_attachedToChart; + return d_ptr->m_backgroundVisible; } /*! - \internal Helper function. Appends markers from \a series to legend. -*/ -void QLegend::appendMarkers(QAreaSeries* series) + \internal \a event see QGraphicsWidget for details + */ +void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event) { - AreaLegendMarker* marker = new AreaLegendMarker(series,this); - m_markers->addToGroup(marker); + const QRectF& rect = QRectF(QPoint(0,0),event->newSize()); + QGraphicsWidget::resizeEvent(event); + if(d_ptr->m_rect != rect) { + d_ptr->m_rect = rect; + d_ptr->updateLayout(); + } } /*! - \internal Helper function. Appends markers from \a series to legend. -*/ -void QLegend::appendMarkers(QXYSeries* series) + \internal \a event see QGraphicsWidget for details + */ +void QLegend::hideEvent(QHideEvent *event) { - XYLegendMarker* marker = new XYLegendMarker(series,this); - m_markers->addToGroup(marker); + QGraphicsWidget::hideEvent(event); + setEnabled(false); + d_ptr->updateLayout(); } /*! - \internal Helper function. Appends markers from \a series to legend. -*/ -void QLegend::appendMarkers(QBarSeries *series) + \internal \a event see QGraphicsWidget for details + */ +void QLegend::showEvent(QShowEvent *event) { - foreach(QBarSet* set, series->barSets()) { - BarLegendMarker* marker = new BarLegendMarker(series,set, this); - m_markers->addToGroup(marker); - } + QGraphicsWidget::showEvent(event); + setEnabled(true); + d_ptr->updateLayout(); } -/*! - \internal Helper function. Appends markers from \a series to legend. -*/ -void QLegend::appendMarkers(QPieSeries *series) +qreal QLegend::minWidth() const { - foreach(QPieSlice* slice, series->slices()) { - PieLegendMarker* marker = new PieLegendMarker(series,slice, this); - m_markers->addToGroup(marker); - } + return d_ptr->m_minWidth; } -/*! - \internal Deletes all markers that are created from \a series -*/ -void QLegend::deleteMarkers(QSeries *series) +qreal QLegend::minHeight() const { - // Search all markers that belong to given series and delete them. + return d_ptr->m_minHeight; +} - QList items = m_markers->childItems(); +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q): +q_ptr(q), +m_presenter(presenter), +m_markers(new QGraphicsItemGroup(q)), +m_alignment(QLegend::AlignmentTop), +m_offsetX(0), +m_offsetY(0), +m_minWidth(0), +m_minHeight(0), +m_width(0), +m_height(0), +m_attachedToChart(true), +m_backgroundVisible(false) +{ - foreach (QGraphicsItem *markers, items) { - LegendMarker *marker = static_cast(markers); - if (marker->series() == series) { - delete marker; - } - } } -/*! - \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend. - If items don't fit, sets the visibility of scroll buttons accordingly. - Causes legend to be resized. -*/ +QLegendPrivate::~QLegendPrivate() +{ -void QLegend::setOffset(const QPointF& point) +} + +void QLegendPrivate::setOffset(qreal x, qreal y) { switch(m_alignment) { - case AlignmentTop: - case AlignmentBottom: { + case QLegend::AlignmentTop: + case QLegend::AlignmentBottom: { if(m_width<=m_rect.width()) return; - if (point.x() != m_offsetX) { - m_offsetX = qBound(0.0, point.x(), m_width - m_rect.width()); + if (x != m_offsetX) { + m_offsetX = qBound(0.0, x, m_width - m_rect.width()); m_markers->setPos(-m_offsetX,m_rect.top()); } break; } - case AlignmentLeft: - case AlignmentRight: { + case QLegend::AlignmentLeft: + case QLegend::AlignmentRight: { if(m_height<=m_rect.height()) return; - if (point.y() != m_offsetY) { - m_offsetY = qBound(0.0, point.y(), m_height - m_rect.height()); + if (y != m_offsetY) { + m_offsetY = qBound(0.0, y, m_height - m_rect.height()); m_markers->setPos(m_rect.left(),-m_offsetY); } break; @@ -410,15 +334,10 @@ void QLegend::setOffset(const QPointF& point) } } -QPointF QLegend::offset() const -{ - return QPointF(m_offsetX,m_offsetY); -} -// this function runs first to set min max values -void QLegend::updateLayout() +void QLegendPrivate::updateLayout() { - m_offsetX=0; + m_offsetX=0; QList items = m_markers->childItems(); if(items.isEmpty()) return; @@ -428,8 +347,8 @@ void QLegend::updateLayout() switch(m_alignment) { - case AlignmentTop: - case AlignmentBottom: { + case QLegend::AlignmentTop: + case QLegend::AlignmentBottom: { QPointF point = m_rect.topLeft(); m_width = 0; foreach (QGraphicsItem *item, items) { @@ -441,16 +360,17 @@ void QLegend::updateLayout() m_width+=w; point.setX(point.x() + w); } - if(m_widthsetPos(m_rect.width()/2-m_width/2,m_rect.top()); - }else{ + } + else { m_markers->setPos(m_rect.topLeft()); } m_height=m_minHeight; } break; - case AlignmentLeft: - case AlignmentRight:{ + case QLegend::AlignmentLeft: + case QLegend::AlignmentRight: { QPointF point = m_rect.topLeft(); m_height = 0; foreach (QGraphicsItem *item, items) { @@ -462,9 +382,10 @@ void QLegend::updateLayout() m_height+=h; point.setY(point.y() + h); } - if(m_heightsetPos(m_rect.left(),m_rect.height()/2-m_height/2); - }else{ + } + else { m_markers->setPos(m_rect.topLeft()); } m_width=m_minWidth; @@ -472,62 +393,36 @@ void QLegend::updateLayout() break; } - m_chart->d_ptr->m_presenter->updateLayout(); //TODO fixme; + m_presenter->updateLayout(); } -/*! - Sets the visibility of legend background to \a visible -*/ -void QLegend::setBackgroundVisible(bool visible) +void QLegendPrivate::handleSeriesAdded(QSeries *series, Domain *domain) { - if(m_backgroundVisible!=visible) - { - m_backgroundVisible=visible; - update(); - } -} - -/*! - Returns the visibility of legend background -*/ -bool QLegend::isBackgroundVisible() const -{ - return m_backgroundVisible; -} + Q_UNUSED(domain) -/*! - \internal \a event see QGraphicsWidget for details -*/ -void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event) -{ - const QRectF& rect = QRectF(QPoint(0,0),event->newSize()); - QGraphicsWidget::resizeEvent(event); - if(m_rect != rect){ - m_rect = rect; - updateLayout(); - } -} + QList markers = series->d_ptr->createLegendMarker(q_ptr); + foreach(LegendMarker* marker , markers) + m_markers->addToGroup(marker); -/*! - \internal \a event see QGraphicsWidget for details -*/ -void QLegend::hideEvent(QHideEvent *event) -{ - QGraphicsWidget::hideEvent(event); - setEnabled(false); updateLayout(); } -/*! - \internal \a event see QGraphicsWidget for details -*/ -void QLegend::showEvent(QShowEvent *event) +void QLegendPrivate::handleSeriesRemoved(QSeries *series) { - QGraphicsWidget::showEvent(event); - setEnabled(true); + + QList items = m_markers->childItems(); + + foreach (QGraphicsItem *markers, items) { + LegendMarker *marker = static_cast(markers); + if (marker->series() == series) { + delete marker; + } + } + updateLayout(); } #include "moc_qlegend.cpp" +#include "moc_qlegend_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qlegend.h b/src/qlegend.h index 3d25715..355074c 100644 --- a/src/qlegend.h +++ b/src/qlegend.h @@ -25,7 +25,6 @@ #include #include #include -#include "private/scroller_p.h" //TODO fixme QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -39,7 +38,9 @@ class QPieSeries; class QAreaSeries; class LegendScrollButton; class QSeries; + class QChart; +class QLegendPrivate; class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget { @@ -60,6 +61,8 @@ private: explicit QLegend(QChart *chart); public: + ~QLegend(); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); QRectF boundingRect() const; @@ -76,8 +79,8 @@ public: void attachToChart(); bool isAttachedToChart(); - qreal minWidth() const { return m_minWidth;} - qreal minHeight() const { return m_minHeight;} + qreal minWidth() const; + qreal minHeight() const; void setBackgroundVisible(bool visible = true); bool isBackgroundVisible() const; @@ -90,79 +93,10 @@ protected: void hideEvent(QHideEvent *event); void showEvent(QShowEvent *event); -public Q_SLOTS: - // PIMPL ---> - void handleSeriesAdded(QSeries *series, Domain *domain); - void handleSeriesRemoved(QSeries *series); - void handleAdded(QList slices); - void handleRemoved(QList slices); - // PIMPL <--- - -private: - // PIMPL ---> - void appendMarkers(QAreaSeries *series); - void appendMarkers(QXYSeries *series); - void appendMarkers(QBarSeries *series); - void appendMarkers(QPieSeries *series); - void deleteMarkers(QSeries *series); - void updateLayout(); - private: - qreal m_margin; - - QRectF m_rect; - qreal m_offsetX; - qreal m_offsetY; - - //QList m_markers; - - QBrush m_brush; - QPen m_pen; - QLegend::Alignments m_alignment; - QGraphicsItemGroup* m_markers; - - - bool m_attachedToChart; - - QChart *m_chart; - qreal m_minWidth; - qreal m_minHeight; - qreal m_width; - qreal m_height; - bool m_backgroundVisible; - friend class ScrolledQLegend; - // <--- PIMPL -}; - -class ScrolledQLegend: public QLegend, public Scroller -{ - -public: - ScrolledQLegend(QChart *chart):QLegend(chart) - { - } - - void setOffset(const QPointF& point) - { - QLegend::setOffset(point); - } - QPointF offset() const - { - return QLegend::offset(); - } - - void mousePressEvent(QGraphicsSceneMouseEvent* event){ - Scroller::mousePressEvent(event); - //QLegend::mousePressEvent(event); - } - void mouseMoveEvent(QGraphicsSceneMouseEvent* event){ - Scroller::mouseMoveEvent(event); - //QLegend::mouseMoveEvent(event); - } - void mouseReleaseEvent(QGraphicsSceneMouseEvent* event){ - Scroller::mouseReleaseEvent(event); - //QLegend::mouseReleaseEvent(event); - } + QScopedPointer d_ptr; + Q_DISABLE_COPY(QLegend); + friend class LegendScroller; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qlegend_p.h b/src/qlegend_p.h new file mode 100644 index 0000000..36373e4 --- /dev/null +++ b/src/qlegend_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the QtCommercial 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" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class ChartPresenter; + +class QLegendPrivate : public QObject +{ + Q_OBJECT +public: + QLegendPrivate(ChartPresenter *chart,QLegend *q); + ~QLegendPrivate(); + + void setOffset(qreal x, qreal y); + void updateLayout(); + +public Q_SLOTS: + void handleSeriesAdded(QSeries *series, Domain *domain); + void handleSeriesRemoved(QSeries *series); + +private: + QLegend *q_ptr; + ChartPresenter *m_presenter; + QGraphicsItemGroup* m_markers; + QLegend::Alignments m_alignment; + QBrush m_brush; + QPen m_pen; + QRectF m_rect; + qreal m_offsetX; + qreal m_offsetY; + qreal m_minWidth; + qreal m_minHeight; + qreal m_width; + qreal m_height; + bool m_attachedToChart; + bool m_backgroundVisible; + +friend class QLegend; + +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif diff --git a/src/qseries.h b/src/qseries.h index c3038ca..052f092 100644 --- a/src/qseries.h +++ b/src/qseries.h @@ -65,6 +65,7 @@ protected: QScopedPointer d_ptr; friend class ChartDataSet; friend class ChartPresenter; + friend class QLegendPrivate; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qseries_p.h b/src/qseries_p.h index bbb3bba..ad20c0a 100644 --- a/src/qseries_p.h +++ b/src/qseries_p.h @@ -39,6 +39,8 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class Domain; class ChartPresenter; class Chart; +class LegendMarker; +class QLegend; class QSeriesPrivate : public QObject { @@ -48,6 +50,7 @@ public: virtual void scaleDomain(Domain& domain) = 0; virtual Chart* createGraphics(ChartPresenter* presenter) = 0; + virtual QList createLegendMarker(QLegend* legend) = 0; protected: QSeries *q_ptr; diff --git a/src/src.pro b/src/src.pro index 306835e..b550321 100644 --- a/src/src.pro +++ b/src/src.pro @@ -33,7 +33,9 @@ PRIVATE_HEADERS += \ $$PWD/qchart_p.h \ $$PWD/qchartview_p.h \ $$PWD/scroller_p.h \ - $$PWD/qseries_p.h + $$PWD/qseries_p.h \ + $$PWD/qlegend_p.h \ + $$PWD/legendscroller_p.h PUBLIC_HEADERS += \ $$PWD/qchart.h \ $$PWD/qchartglobal.h \ diff --git a/src/xychart/qxyseries.cpp b/src/xychart/qxyseries.cpp index c44c772..d3ee496 100644 --- a/src/xychart/qxyseries.cpp +++ b/src/xychart/qxyseries.cpp @@ -21,6 +21,7 @@ #include "qxyseries.h" #include "qxyseries_p.h" #include "domain_p.h" +#include "legendmarker_p.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -646,6 +647,13 @@ void QXYSeriesPrivate::scaleDomain(Domain& domain) domain.setRangeY(minY,maxY,tickYCount); } +QList QXYSeriesPrivate::createLegendMarker(QLegend* legend) +{ + Q_Q(QXYSeries); + QList list; + return list << new XYLegendMarker(q,legend); +} + #include "moc_qxyseries.cpp" #include "moc_qxyseries_p.cpp" diff --git a/src/xychart/qxyseries_p.h b/src/xychart/qxyseries_p.h index 724845c..c7e0077 100644 --- a/src/xychart/qxyseries_p.h +++ b/src/xychart/qxyseries_p.h @@ -44,6 +44,7 @@ public: QXYSeriesPrivate(QXYSeries* q); void scaleDomain(Domain& domain); + QList createLegendMarker(QLegend* legend); Q_SIGNALS: void updated();