From 5397c9eef2aaeb85d80e0fc55a7edd0cad431185 2012-10-17 07:46:13 From: sauimone Date: 2012-10-17 07:46:13 Subject: [PATCH] Added createLegendMarkers to private series. This will replace old createLegendMarker method. Notice the s in new method name. PIMPL for QLegendMarker. Newlegend example updated a bit --- diff --git a/examples/newlegend/mainwidget.cpp b/examples/newlegend/mainwidget.cpp index 9f40373..4494d12 100644 --- a/examples/newlegend/mainwidget.cpp +++ b/examples/newlegend/mainwidget.cpp @@ -28,6 +28,7 @@ #include #include #include +#include QTCOMMERCIALCHART_USE_NAMESPACE @@ -53,11 +54,15 @@ MainWidget::MainWidget(QWidget *parent) : QPushButton *boldButton = new QPushButton("Toggle bold"); connect(boldButton, SIGNAL(clicked()), this, SLOT(toggleBold())); - m_buttonLayout->addWidget(boldButton, 8, 0); + m_buttonLayout->addWidget(boldButton, 5, 0); QPushButton *italicButton = new QPushButton("Toggle italic"); connect(italicButton, SIGNAL(clicked()), this, SLOT(toggleItalic())); - m_buttonLayout->addWidget(italicButton, 9, 0); + m_buttonLayout->addWidget(italicButton, 6, 0); + + QPushButton *infoButton = new QPushButton("Debug info"); + connect(infoButton, SIGNAL(clicked()), this, SLOT(showDebugInfo())); + m_buttonLayout->addWidget(infoButton, 7, 0); m_legendPosX = new QDoubleSpinBox(); m_legendPosY = new QDoubleSpinBox(); @@ -227,6 +232,14 @@ void MainWidget::toggleItalic() m_chart->legend()->setFont(font); } +void MainWidget::showDebugInfo() +{ + qDebug() << "marker count:" << m_chart->legend()->markers().count(); + foreach (QLegendMarker* marker, m_chart->legend()->markers()) { + qDebug() << "label:" << marker->label(); + } +} + void MainWidget::fontSizeChanged() { QFont font = m_chart->legend()->font(); diff --git a/examples/newlegend/mainwidget.h b/examples/newlegend/mainwidget.h index 549eac3..aa40b0b 100644 --- a/examples/newlegend/mainwidget.h +++ b/examples/newlegend/mainwidget.h @@ -55,6 +55,7 @@ public slots: void toggleBold(); void toggleItalic(); + void showDebugInfo(); void fontSizeChanged(); void updateLegendLayout(); diff --git a/src/areachart/qareaseries.cpp b/src/areachart/qareaseries.cpp index 6b8f0e0..d98c5d4 100644 --- a/src/areachart/qareaseries.cpp +++ b/src/areachart/qareaseries.cpp @@ -382,6 +382,15 @@ QList QAreaSeriesPrivate::createLegendMarker(QLegend *legend) return list << new AreaLegendMarker(q, legend); } +QList QAreaSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_UNUSED(legend); +// Q_Q(QAreaSeries); + QList list; +// TODO: +// return list << new AreaLegendMarker(q,legend); + return list; +} void QAreaSeriesPrivate::initializeAxis(QAbstractAxis *axis) { diff --git a/src/areachart/qareaseries_p.h b/src/areachart/qareaseries_p.h index 24ddc34..63d0822 100644 --- a/src/areachart/qareaseries_p.h +++ b/src/areachart/qareaseries_p.h @@ -46,7 +46,9 @@ public: void scaleDomain(Domain &domain); ChartElement *createGraphics(ChartPresenter *presenter); QList createLegendMarker(QLegend *legend); + QList createLegendMarkers(QLegend* legend); void initializeAxis(QAbstractAxis *axis); + QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const; Q_SIGNALS: diff --git a/src/barchart/qabstractbarseries.cpp b/src/barchart/qabstractbarseries.cpp index a694235..06af863 100644 --- a/src/barchart/qabstractbarseries.cpp +++ b/src/barchart/qabstractbarseries.cpp @@ -659,6 +659,22 @@ QList QAbstractBarSeriesPrivate::createLegendMarker(QLegend *leg return markers; } +QList QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_UNUSED(legend); +// Q_Q(QAbstractBarSeries); + QList markers; +// TODO: when QBarLegendMarker is implemented +/* + foreach(QBarSet* set, q->barSets()) { + BarLegendMarker* marker = new BarLegendMarker(q,set,legend); + markers << marker; + } +*/ + return markers; +} + + bool QAbstractBarSeriesPrivate::append(QBarSet *set) { if ((m_barSets.contains(set)) || (set == 0)) diff --git a/src/barchart/qabstractbarseries_p.h b/src/barchart/qabstractbarseries_p.h index cffce0b..8b98821 100644 --- a/src/barchart/qabstractbarseries_p.h +++ b/src/barchart/qabstractbarseries_p.h @@ -39,6 +39,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class QBarModelMapper; class QBarCategoryAxis; +class QLegendMarker; class QAbstractBarSeriesPrivate : public QAbstractSeriesPrivate { @@ -56,6 +57,7 @@ public: void scaleDomain(Domain &domain); ChartElement *createGraphics(ChartPresenter *presenter); QList createLegendMarker(QLegend *legend); + QList createLegendMarkers(QLegend* legend); void initializeAxis(QAbstractAxis *axis); virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const; diff --git a/src/legend/legend.pri b/src/legend/legend.pri index a22b5c2..28c7c7c 100644 --- a/src/legend/legend.pri +++ b/src/legend/legend.pri @@ -12,7 +12,8 @@ PRIVATE_HEADERS += \ $$PWD/legendmarker_p.h \ $$PWD/legendscroller_p.h \ $$PWD/qlegend_p.h \ - $$PWD/legendlayout_p.h + $$PWD/legendlayout_p.h \ + $$PWD/qlegendmarker_p.h PUBLIC_HEADERS += \ diff --git a/src/legend/qlegend.cpp b/src/legend/qlegend.cpp index a35fdfc..ad45a61 100644 --- a/src/legend/qlegend.cpp +++ b/src/legend/qlegend.cpp @@ -44,6 +44,8 @@ #include #include +#include + QTCOMMERCIALCHART_BEGIN_NAMESPACE /*! @@ -465,7 +467,21 @@ void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain) { Q_UNUSED(domain) - QList markers = series->d_ptr->createLegendMarker(q_ptr); +// New markers ---> + QList newMarkers = series->d_ptr->createLegendMarkers(q_ptr); + foreach (QLegendMarker* marker, newMarkers) { + marker->setFont(m_font); + marker->setLabelBrush(m_labelBrush); + marker->setVisible(series->isVisible()); +// TODO: QLegendMarker has QGraphicsItem vs QLegendMarker is QGraphicsItem +// m_items->addToGroup(marker); + m_legendMarkers << marker; + } + + QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged())); +// <--- New markers + + QList markers = series->d_ptr->createLegendMarker(q_ptr); foreach (LegendMarker *marker, markers) { marker->setFont(m_font); @@ -484,6 +500,17 @@ void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain) void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series) { +// New markers ---> + foreach (QLegendMarker *marker, m_legendMarkers) { + if (marker->series() == series) { + delete marker; + m_legendMarkers.removeAll(marker); + } + } + + QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged())); +// <--- New markers + foreach (LegendMarker *marker, m_markers) { if (marker->series() == series) { delete marker; @@ -501,8 +528,17 @@ void QLegendPrivate::handleSeriesVisibleChanged() QAbstractSeries *series = qobject_cast (sender()); Q_ASSERT(series); - foreach (LegendMarker *marker, m_markers) { - if (marker->series() == series) +// New markers ---> + foreach (QLegendMarker* marker, m_legendMarkers) { + if (marker->series() == series) { + marker->setVisible(series->isVisible()); + } + } + +// <--- New markers + + foreach (LegendMarker* marker, m_markers) { + if (marker->series() == series) { marker->setVisible(series->isVisible()); } m_layout->invalidate(); @@ -510,10 +546,13 @@ void QLegendPrivate::handleSeriesVisibleChanged() void QLegendPrivate::handleCountChanged() { - QAbstractSeriesPrivate *series = qobject_cast (sender()); - Q_ASSERT(series); - handleSeriesRemoved(series->q_ptr); - handleSeriesAdded(series->q_ptr, 0); + // With new markers, the series shoud notify markers directly? + + // Handle new or removed markers + // Handle changes of marker pen/brush/label. every property that legend is interested + handleSeriesRemoved(series); + Domain domain; + handleSeriesAdded(series, &domain); } #include "moc_qlegend.cpp" diff --git a/src/legend/qlegendmarker.cpp b/src/legend/qlegendmarker.cpp index f1d2baa..a7057d3 100644 --- a/src/legend/qlegendmarker.cpp +++ b/src/legend/qlegendmarker.cpp @@ -19,15 +19,15 @@ ****************************************************************************/ #include "qlegendmarker.h" -//#include "qlegendmarker_p.h" +#include "qlegendmarker_p.h" #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE QLegendMarker::QLegendMarker(QAbstractSeries* series, QObject *parent) : QObject(parent), - m_series(series) -// d_ptr(new QLegendMarkerPrivate(this)) + d_ptr(new QLegendMarkerPrivate(series, this)) { } @@ -37,50 +37,149 @@ QLegendMarker::~QLegendMarker() QString QLegendMarker::label() const { - return m_label; + return d_ptr->m_label; } void QLegendMarker::setLabel(const QString &label) { - m_label = label; + d_ptr->m_label = label; +} + +QBrush QLegendMarker::labelBrush() const +{ + return d_ptr->m_labelBrush; +} + +void QLegendMarker::setLabelBrush(const QBrush &brush) +{ + d_ptr->m_labelBrush = brush; +} + +QFont QLegendMarker::font() const +{ + return d_ptr->m_font; +} + +void QLegendMarker::setFont(const QFont &font) +{ + d_ptr->m_font = font; } QPen QLegendMarker::pen() const { - return m_pen; + return d_ptr->m_pen; } void QLegendMarker::setPen(const QPen &pen) { - m_pen = pen; + d_ptr->m_pen = pen; } QBrush QLegendMarker::brush() const { - return m_brush; + return d_ptr->m_brush; } void QLegendMarker::setBrush(const QBrush &brush) { - m_brush = brush; + d_ptr->m_brush = brush; } bool QLegendMarker::isVisible() const { - return m_visible; + return d_ptr->m_visible; } void QLegendMarker::setVisible(bool visible) { - m_visible = visible; + d_ptr->m_visible = visible; } -void QLegendMarker::markersUpdated() +QAbstractSeries* QLegendMarker::series() { - // TODO: + return d_ptr->m_series; } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QLegendMarkerPrivate::QLegendMarkerPrivate(QAbstractSeries *series, QLegendMarker *q) : + q_ptr(q), + m_series(series) +{ + +} + +void QLegendMarkerPrivate::setGeometry(const QRectF& rect) +{ + QFontMetrics fn (m_font); + + + int width = rect.width(); + qreal x = m_margin + m_markerRect.width() + m_space + m_margin; + qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin); + + if (fn.boundingRect(m_label).width() + x > width) + { + QString string = m_label + "..."; + while(fn.boundingRect(string).width() + x > width && string.length() > 3) + string.remove(string.length() - 4, 1); + m_textItem->setText(string); + } + else + m_textItem->setText(m_label); + + const QRectF& textRect = m_textItem->boundingRect(); + + + m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2); + m_rectItem->setRect(m_markerRect); + m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2); + + prepareGeometryChange(); + m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y); +} + +QRectF QLegendMarkerPrivate::boundingRect() const +{ + return m_boundingRect; +} + +void QLegendMarkerPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + Q_UNUSED(painter) +} + +QSizeF QLegendMarkerPrivate::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const +{ + Q_UNUSED(constraint) + + QFontMetrics fn(m_textItem->font()); + QSizeF sh; + + switch (which) { + case Qt::MinimumSize: + sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin)); + break; + case Qt::PreferredSize: + sh = QSizeF(fn.boundingRect(m_label).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin)); + break; + default: + break; + } + + return sh; +} + +void QLegendMarkerPrivate::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsObject::mousePressEvent(event); + //TODO: selected signal removed for now +} + + #include "moc_qlegendmarker.cpp" -//#include "moc_qlegendmarker_p.cpp" +#include "moc_qlegendmarker_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/legend/qlegendmarker.h b/src/legend/qlegendmarker.h index 44d78e5..b743d0b 100644 --- a/src/legend/qlegendmarker.h +++ b/src/legend/qlegendmarker.h @@ -25,14 +25,14 @@ #include #include #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE -// TODO: -//class QLegendMarkerPrivate; +class QLegendMarkerPrivate; class QAbstractSeries; -// TODO: should this be abstract? +// TODO: should this be QAbstractLegendMarker? class QTCOMMERCIALCHART_EXPORT QLegendMarker : public QObject { Q_OBJECT @@ -49,6 +49,12 @@ public: 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); @@ -59,7 +65,7 @@ public: void setVisible(bool visible); // virtual QAbstractSeries::SeriesType type() = 0; - virtual QAbstractSeries* series() { return m_series; } + virtual QAbstractSeries* series(); virtual QObject* peerObject() = 0; Q_SIGNALS: @@ -67,19 +73,12 @@ Q_SIGNALS: void hovered(bool status); public Q_SLOTS: - void markersUpdated(); // TODO: private? Idea is that series signals, when for example pieslices have been added/removed. + virtual void updated() = 0; // TODO: private. Idea is that series signals, when some property has changed public: -// TODO: -// QScopedPointer d_ptr; + QScopedPointer d_ptr; Q_DISABLE_COPY(QLegendMarker) -// TODO: move to PIMPL - QAbstractSeries* m_series; - QString m_label; - QPen m_pen; - QBrush m_brush; - bool m_visible; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/legend/qlegendmarker_p.h b/src/legend/qlegendmarker_p.h new file mode 100644 index 0000000..3046b8e --- /dev/null +++ b/src/legend/qlegendmarker_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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 QLEGENDMARKERPRIVATE_H +#define QLEGENDMARKERPRIVATE_H + +#include "qchartglobal.h" +#include +#include +#include +#include +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +// TODO: check these +class QAbstractSeries; +class QAreaSeries; +class QXYSeries; +class QBarSet; +class QAbstractBarSeries; +class QPieSlice; +class QLegend; +class QPieSeries; + +class QLegendMarker; + +class QLegendMarkerPrivate : public QGraphicsObject, public QGraphicsLayoutItem +{ + Q_OBJECT + Q_INTERFACES(QGraphicsLayoutItem) +public: + explicit QLegendMarkerPrivate(QAbstractSeries *series, QLegendMarker *q); +/* + 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; + +protected: + // From QGraphicsObject + void mousePressEvent(QGraphicsSceneMouseEvent *event); + +public Q_SLOTS: + virtual void updated() {}; + +private: + QLegendMarker *q_ptr; + +/* + QLegend* m_legend; +*/ + +// New legend marker properties + QAbstractSeries* m_series; + QString m_label; + QBrush m_labelBrush; + QFont m_font; + QPen m_pen; + QBrush m_brush; + bool m_visible; + +// Implementation details of new marker + QRectF m_markerRect; + QRectF m_boundingRect; + QGraphicsSimpleTextItem *m_textItem; + QGraphicsRectItem *m_rectItem; + qreal m_margin; + qreal m_space; + + friend class QLegendPrivate; // TODO: Is this needed? + Q_DECLARE_PUBLIC(QLegendMarker) +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // QLEGENDMARKERPRIVATE_H diff --git a/src/legend/qpielegendmarker.cpp b/src/legend/qpielegendmarker.cpp index 9652405..535bbb3 100644 --- a/src/legend/qpielegendmarker.cpp +++ b/src/legend/qpielegendmarker.cpp @@ -27,8 +27,17 @@ QPieLegendMarker::QPieLegendMarker(QPieSeries* series, QPieSlice* slice, QObject QLegendMarker(series, parent), m_slice(slice) { + QObject::connect(slice, SIGNAL(labelChanged()), this, SLOT(updated())); + QObject::connect(slice, SIGNAL(brushChanged()), this, SLOT(updated())); + updated(); } +void QPieLegendMarker::updated() +{ + // TODO: to PIMPL. + setBrush(m_slice->brush()); + setLabel(m_slice->label()); +} #include "moc_qpielegendmarker.cpp" //#include "moc_qpielegendmarker_p.cpp" diff --git a/src/legend/qpielegendmarker.h b/src/legend/qpielegendmarker.h index fe0d2c3..c5f2cae 100644 --- a/src/legend/qpielegendmarker.h +++ b/src/legend/qpielegendmarker.h @@ -36,6 +36,9 @@ public: virtual QPieSlice* peerObject() { return m_slice; } +// TODO: to pimp. + void updated(); + //Q_SIGNALS: //public Q_SLOTS: diff --git a/src/piechart/qpieseries.cpp b/src/piechart/qpieseries.cpp index 49d7948..a8fc5a1 100644 --- a/src/piechart/qpieseries.cpp +++ b/src/piechart/qpieseries.cpp @@ -29,6 +29,8 @@ #include "qabstractaxis.h" #include "pieanimation_p.h" +#include "qpielegendmarker.h" + QTCOMMERCIALCHART_BEGIN_NAMESPACE /*! @@ -861,6 +863,17 @@ QList QPieSeriesPrivate::createLegendMarker(QLegend *legend) return markers; } +QList QPieSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_Q(QPieSeries); + QList markers; + foreach(QPieSlice* slice, q->slices()) { + QPieLegendMarker* marker = new QPieLegendMarker(q,slice,legend); + markers << marker; + } + return markers; +} + void QPieSeriesPrivate::initializeAxis(QAbstractAxis *axis) { Q_UNUSED(axis); diff --git a/src/piechart/qpieseries_p.h b/src/piechart/qpieseries_p.h index 16c7e27..357ff57 100644 --- a/src/piechart/qpieseries_p.h +++ b/src/piechart/qpieseries_p.h @@ -47,6 +47,7 @@ public: void scaleDomain(Domain &domain); ChartElement *createGraphics(ChartPresenter *presenter); QList createLegendMarker(QLegend *legend); + QList createLegendMarkers(QLegend *legend); void initializeAxis(QAbstractAxis *axis); QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const; diff --git a/src/qabstractseries_p.h b/src/qabstractseries_p.h index dd2e890..d12d596 100644 --- a/src/qabstractseries_p.h +++ b/src/qabstractseries_p.h @@ -41,6 +41,7 @@ class LegendMarker; class QLegend; class ChartDataSet; class QAbstractAxis; +class QLegendMarker; class QAbstractSeriesPrivate : public QObject { @@ -52,6 +53,7 @@ public: virtual void scaleDomain(Domain &domain) = 0; virtual ChartElement *createGraphics(ChartPresenter *presenter) = 0; virtual QList createLegendMarker(QLegend *legend) = 0; + virtual QList createLegendMarkers(QLegend* legend) = 0; virtual void initializeAxis(QAbstractAxis *axis) = 0; virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation) const = 0; diff --git a/src/xychart/qxyseries.cpp b/src/xychart/qxyseries.cpp index bef6c87..f015570 100644 --- a/src/xychart/qxyseries.cpp +++ b/src/xychart/qxyseries.cpp @@ -454,6 +454,16 @@ QList QXYSeriesPrivate::createLegendMarker(QLegend *legend) return list << new XYLegendMarker(q, legend); } +QList QXYSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_UNUSED(legend); +// Q_Q(QXYSeries); + QList list; +// TODO: +// return list << new QXYLegendMarker(q,legend); + return list; +} + void QXYSeriesPrivate::initializeAxis(QAbstractAxis *axis) { Q_UNUSED(axis); diff --git a/src/xychart/qxyseries_p.h b/src/xychart/qxyseries_p.h index 896d84a..3f2d485 100644 --- a/src/xychart/qxyseries_p.h +++ b/src/xychart/qxyseries_p.h @@ -46,6 +46,7 @@ public: void scaleDomain(Domain &domain); QList createLegendMarker(QLegend *legend); + QList createLegendMarkers(QLegend* legend); void initializeAxis(QAbstractAxis *axis); QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;