diff --git a/plugins/declarative/declarativechart.cpp b/plugins/declarative/declarativechart.cpp index 351be3f..e358243 100644 --- a/plugins/declarative/declarativechart.cpp +++ b/plugins/declarative/declarativechart.cpp @@ -224,22 +224,24 @@ DeclarativeChart::DeclarativeChart(QDeclarativeItem *parent) { setFlag(QGraphicsItem::ItemHasNoContents, false); // m_chart->axisX()->setNiceNumbersEnabled(false); - m_chartMargins = m_chart->margins(); + //TODO: check what should be really here margins or platArea ?! + m_chartMargins = m_chart->minimumMargins(); connect(m_chart, SIGNAL(marginsChanged(QRectF)), this, SLOT(handleMarginsChanged(QRectF))); } void DeclarativeChart::handleMarginsChanged(QRectF newMargins) { + //TODO: check what should be really here margins or platArea ?! if (m_chartMargins.top() != newMargins.top()) - topMarginChanged(m_chart->margins().top()); + topMarginChanged(m_chart->minimumMargins().top()); if (m_chartMargins.bottom() != newMargins.bottom()) - bottomMarginChanged(m_chart->margins().bottom()); + bottomMarginChanged(m_chart->minimumMargins().bottom()); if (m_chartMargins.left() != newMargins.left()) - leftMarginChanged(m_chart->margins().left()); + leftMarginChanged(m_chart->minimumMargins().left()); if (m_chartMargins.right() != newMargins.right()) - rightMarginChanged(m_chart->margins().right()); + rightMarginChanged(m_chart->minimumMargins().right()); - m_chartMargins = m_chart->margins(); + m_chartMargins = m_chart->minimumMargins(); } DeclarativeChart::~DeclarativeChart() @@ -487,22 +489,22 @@ bool DeclarativeChart::dropShadowEnabled() qreal DeclarativeChart::topMargin() { - return m_chart->margins().top(); + return m_chart->minimumMargins().top(); } qreal DeclarativeChart::bottomMargin() { - return m_chart->margins().bottom(); + return m_chart->minimumMargins().bottom(); } qreal DeclarativeChart::leftMargin() { - return m_chart->margins().left(); + return m_chart->minimumMargins().left(); } qreal DeclarativeChart::rightMargin() { - return m_chart->margins().right(); + return m_chart->minimumMargins().right(); } void DeclarativeChart::zoom(qreal factor) diff --git a/plugins/declarative/declarativechart.h b/plugins/declarative/declarativechart.h index 4d2d7f5..5769143 100644 --- a/plugins/declarative/declarativechart.h +++ b/plugins/declarative/declarativechart.h @@ -150,7 +150,7 @@ private: // Extending QChart with DeclarativeChart is not possible because QObject does not support // multi inheritance, so we now have a QChart as a member instead QChart *m_chart; - QRectF m_chartMargins; + QMargins m_chartMargins; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/chartlayout.cpp b/src/chartlayout.cpp index 047f78c..176a0a8 100644 --- a/src/chartlayout.cpp +++ b/src/chartlayout.cpp @@ -22,6 +22,7 @@ #include "chartpresenter_p.h" #include "qlegend_p.h" #include "chartaxis_p.h" +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -30,7 +31,7 @@ m_presenter(presenter), m_marginBig(60), m_marginSmall(20), m_marginTiny(10), -m_chartMargins(QPointF(m_marginBig,m_marginBig),QPointF(m_marginBig,m_marginBig)), +m_chartMargins(m_marginBig,m_marginBig,m_marginBig,m_marginBig), m_intialized(false) { @@ -74,12 +75,16 @@ void ChartLayout::setGeometry(const QRectF& rect) } QLegend* legend = m_presenter->legend(); - Q_ASSERT(legend); qreal titlePadding = m_chartMargins.top()/2; - QRectF chartMargins = m_chartMargins; + QMargins chartMargins = m_chartMargins; + + //TODO multiple axis handling; + chartMargins.setLeft(qMax(m_chartMargins.left(),int(axisWidth + 2*m_marginTiny))); + chartMargins.setBottom(qMax(m_chartMargins.bottom(),int(axisHeight + 2* m_marginTiny))); + // recalculate legend position if ((legend->isAttachedToChart() && legend->isVisible())) { @@ -88,35 +93,35 @@ void ChartLayout::setGeometry(const QRectF& rect) switch (legend->alignment()) { case Qt::AlignTop: { + QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1)); int topMargin = 2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny; - chartMargins = QRect(QPoint(m_chartMargins.left(),topMargin),QPoint(m_chartMargins.right(),m_chartMargins.bottom())); - m_legendMargins = QRect(QPoint(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny)),QPoint(chartMargins.right(),rect.height()-topMargin + m_marginTiny)); + chartMargins = QMargins(chartMargins.left(),topMargin,chartMargins.right(),chartMargins.bottom()); + m_legendMargins = QMargins(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny),chartMargins.right(),rect.height()-topMargin + m_marginTiny); titlePadding = m_marginTiny + m_marginTiny; break; } case Qt::AlignBottom: { QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1)); int bottomMargin = m_marginTiny + legendSize.height() + m_marginTiny + axisHeight; - chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomMargin)); - m_legendMargins = QRect(QPoint(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight),QPoint(chartMargins.right(),m_marginTiny + m_marginSmall)); + chartMargins = QMargins(chartMargins.left(),chartMargins.top(),chartMargins.right(),bottomMargin); + m_legendMargins = QMargins(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight,chartMargins.right(),m_marginTiny + m_marginSmall); titlePadding = chartMargins.top()/2; break; } case Qt::AlignLeft: { QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height())); int leftPadding = m_marginTiny + legendSize.width() + m_marginTiny + axisWidth; - - chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom())); - m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,chartMargins.top()),QPoint(rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom())); + chartMargins = QMargins(leftPadding,chartMargins.top(),chartMargins.right(),chartMargins.bottom()); + m_legendMargins = QMargins(m_marginTiny + m_marginSmall,chartMargins.top(),rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom()); titlePadding = chartMargins.top()/2; break; } case Qt::AlignRight: { QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height())); int rightPadding = m_marginTiny + legendSize.width() + m_marginTiny; - chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom())); - m_legendMargins = QRect(QPoint(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,chartMargins.bottom())); + chartMargins = QMargins(chartMargins.left(),chartMargins.top(),rightPadding,chartMargins.bottom()); + m_legendMargins = QMargins(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top(),m_marginTiny + m_marginSmall,chartMargins.bottom()); titlePadding = chartMargins.top()/2; break; } @@ -158,15 +163,16 @@ QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) co return QSize(-1,-1); } -void ChartLayout::setMarginsMinimum(const QRectF& margins) +void ChartLayout::setMinimumMargins(const QMargins& margins) { + if(m_chartMargins != margins){ m_chartMargins = margins; updateGeometry(); } } -QRectF ChartLayout::margins() const +QMargins ChartLayout::minimumMargins() const { return m_chartMargins; } diff --git a/src/chartlayout_p.h b/src/chartlayout_p.h index de9cd04..1c4a22c 100644 --- a/src/chartlayout_p.h +++ b/src/chartlayout_p.h @@ -21,6 +21,7 @@ #ifndef CHARTLAYOUT_H_ #define CHARTLAYOUT_H_ #include +#include #include "qchartglobal.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -34,8 +35,8 @@ public: ChartLayout(ChartPresenter* presenter); virtual ~ChartLayout(); - void setMarginsMinimum(const QRectF& margins); - QRectF margins() const; + void setMinimumMargins(const QMargins& margins); + QMargins minimumMargins() const; void setGeometry(const QRectF& rect); @@ -50,8 +51,8 @@ private: int m_marginBig; int m_marginSmall; int m_marginTiny; - QRectF m_chartMargins; - QRectF m_legendMargins; + QMargins m_chartMargins; + QMargins m_legendMargins; bool m_intialized; diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index ffe8e55..3554b63 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -419,15 +419,14 @@ QGraphicsLayout* ChartPresenter::layout() return m_layout; } -void ChartPresenter::setMarginsMinimum(const QRectF& margins) +void ChartPresenter::setMinimumMargins(const QMargins& margins) { - Q_UNUSED(margins); - // m_layout->setMarginsMinimum(margins); + m_layout->setMinimumMargins(margins); } -QRectF ChartPresenter::margins() const +QMargins ChartPresenter::minimumMargins() const { - return m_layout->margins(); + return m_layout->minimumMargins(); } QLegend* ChartPresenter::legend() diff --git a/src/chartpresenter_p.h b/src/chartpresenter_p.h index 0a08977..910e959 100644 --- a/src/chartpresenter_p.h +++ b/src/chartpresenter_p.h @@ -33,6 +33,7 @@ #include "qchartglobal.h" #include "qchart.h" //becouse of QChart::ChartThemeId //TODO #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -131,8 +132,8 @@ public: void resetAllElements(); - void setMarginsMinimum(const QRectF& margins); - QRectF margins() const; + void setMinimumMargins(const QMargins& margins); + QMargins minimumMargins() const; QGraphicsLayout* layout(); private: diff --git a/src/qchart.cpp b/src/qchart.cpp index edf9275..36fef48 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -371,12 +371,20 @@ QLegend* QChart::legend() const } /*! + Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget. +*/ +void QChart::setMinimumMargins(const QMargins& margins) +{ + d_ptr->m_presenter->setMinimumMargins(margins); +} + +/*! Returns the rect that contains information about margins (distance between chart widget edge and axes). Individual margins can be obtained by calling left, top, right, bottom on the returned rect. */ -QRectF QChart::margins() const +QMargins QChart::minimumMargins() const { - return d_ptr->m_presenter->margins(); + return d_ptr->m_presenter->minimumMargins(); } /*! @@ -447,13 +455,6 @@ QList QChart::series() const { return d_ptr->m_dataset->series(); } -/*! - Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget. -*/ -void QChart::setMarginsMinimum(const QRectF& margins) -{ - d_ptr->m_presenter->setMarginsMinimum(margins); -} /*! Sets \a axis to the chart, which will control the presentation of the \a series diff --git a/src/qchart.h b/src/qchart.h index 5c6c8e2..945370e 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -24,6 +24,7 @@ #include #include #include +#include class QGraphicsSceneResizeEvent; @@ -42,7 +43,7 @@ class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible) Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled) Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions) - Q_PROPERTY(QRectF margins READ margins NOTIFY marginsChanged) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) Q_ENUMS(ChartTheme) Q_ENUMS(AnimationOption) @@ -113,8 +114,9 @@ public: QLegend* legend() const; - void setMarginsMinimum(const QRectF& margins); - QRectF margins() const; + void setMinimumMargins(const QMargins& margins); + QMargins minimumMargins() const; + QRectF plotArea() const; Q_SIGNALS: diff --git a/src/qchartview.cpp b/src/qchartview.cpp index 439999a..a418246 100644 --- a/src/qchartview.cpp +++ b/src/qchartview.cpp @@ -122,10 +122,9 @@ void QChartView::mousePressEvent(QMouseEvent *event) { if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) { - int padding = d_ptr->m_chart->margins().top(); - QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding); + QRectF plotArea = d_ptr->m_chart->plotArea(); - if (rect.contains(event->pos())) { + if (plotArea.contains(event->pos())) { d_ptr->m_rubberBandOrigin = event->pos(); d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize())); d_ptr->m_rubberBand->show(); @@ -144,9 +143,7 @@ void QChartView::mousePressEvent(QMouseEvent *event) void QChartView::mouseMoveEvent(QMouseEvent *event) { if(d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) { - QRectF margins = d_ptr->m_chart->margins(); - QRectF geometry = d_ptr->m_chart->geometry(); - QRectF rect =geometry.adjusted(margins.left(),margins.top(),-margins.right(),-margins.bottom()); + QRectF rect = d_ptr->m_chart->plotArea(); int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x(); int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y(); if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) { diff --git a/tests/auto/qchart/tst_qchart.cpp b/tests/auto/qchart/tst_qchart.cpp index bbacc4f..5d53fde 100644 --- a/tests/auto/qchart/tst_qchart.cpp +++ b/tests/auto/qchart/tst_qchart.cpp @@ -72,8 +72,8 @@ private slots: void isBackgroundVisible(); void legend_data(); void legend(); - void margins_data(); - void margins(); + void plotArea_data(); + void plotArea(); void removeAllSeries_data(); void removeAllSeries(); void removeSeries_data(); @@ -156,12 +156,10 @@ void tst_QChart::qchart() QVERIFY(m_chart->backgroundBrush()!=QBrush()); QVERIFY(m_chart->backgroundPen()!=QPen()); QCOMPARE(m_chart->isBackgroundVisible(), true); - - QVERIFY(m_chart->margins().top()>0); - QVERIFY(m_chart->margins().left()>0); - QVERIFY(m_chart->margins().right()>0); - QVERIFY(m_chart->margins().bottom()>0); - + QVERIFY(m_chart->plotArea().top()==0); + QVERIFY(m_chart->plotArea().left()==0); + QVERIFY(m_chart->plotArea().right()==0); + QVERIFY(m_chart->plotArea().bottom()==0); QCOMPARE(m_chart->theme(), QChart::ChartThemeLight); QCOMPARE(m_chart->title(), QString()); @@ -174,6 +172,13 @@ void tst_QChart::qchart() m_chart->zoomIn(); m_chart->zoomIn(QRectF()); m_chart->zoomOut(); + + m_view->show(); + + QVERIFY(m_chart->plotArea().top()>0); + QVERIFY(m_chart->plotArea().left()>0); + QVERIFY(m_chart->plotArea().right()>0); + QVERIFY(m_chart->plotArea().bottom()>0); } void tst_QChart::addSeries_data() @@ -391,17 +396,18 @@ void tst_QChart::legend() QCOMPARE(fontSpy.count(), 1); } -void tst_QChart::margins_data() +void tst_QChart::plotArea_data() { } -void tst_QChart::margins() +void tst_QChart::plotArea() { createTestData(); QRectF rect = m_chart->geometry(); - QVERIFY(m_chart->margins().top()+m_chart->margins().bottom() < rect.height()); - QVERIFY(m_chart->margins().left()+m_chart->margins().right() < rect.width()); + QVERIFY(m_chart->plotArea().isValid()); + QVERIFY(m_chart->plotArea().height() < rect.height()); + QVERIFY(m_chart->plotArea().width() < rect.width()); } void tst_QChart::removeAllSeries_data() @@ -717,7 +723,7 @@ void tst_QChart::zoomIn() QFETCH(QRectF, rect); createTestData(); m_chart->createDefaultAxes(); - QRectF marigns = m_chart->margins(); + QRectF marigns = m_chart->plotArea(); rect.adjust(marigns.left(),marigns.top(),-marigns.right(),-marigns.bottom()); QValueAxis* axisX = qobject_cast(m_chart->axisX()); QVERIFY(axisX!=0); diff --git a/tests/auto/qchartview/tst_qchartview.cpp b/tests/auto/qchartview/tst_qchartview.cpp index ad9af17..7e51af1 100644 --- a/tests/auto/qchartview/tst_qchartview.cpp +++ b/tests/auto/qchartview/tst_qchartview.cpp @@ -116,14 +116,12 @@ void tst_QChartView::rubberBand_data() QTest::addColumn("Xcount"); QTest::addColumn("Ycount"); - QTest::addColumn("minX"); - QTest::addColumn("maxX"); - QTest::addColumn("minY"); - QTest::addColumn("maxY"); - - QTest::newRow("HorizonalRubberBand") << QChartView::RubberBands(QChartView::HorizonalRubberBand) << 0 << 1 << 20 << 180 << 0<< 200; - QTest::newRow("VerticalRubberBand") << QChartView::RubberBands(QChartView::VerticalRubberBand) << 1 << 0 << 0 << 200 << 20<< 180; - QTest::newRow("RectangleRubberBand") << QChartView::RubberBands(QChartView::RectangleRubberBand) << 1 << 1 <<20 << 180 << 20<< 180; + QTest::addColumn("min"); + QTest::addColumn("max"); + + QTest::newRow("HorizonalRubberBand") << QChartView::RubberBands(QChartView::HorizonalRubberBand) << 0 << 1 << QPoint(5,5) << QPoint(5,5); + QTest::newRow("VerticalRubberBand") << QChartView::RubberBands(QChartView::VerticalRubberBand) << 1 << 0 << QPoint(5,5) << QPoint(5,5); + QTest::newRow("RectangleRubberBand") << QChartView::RubberBands(QChartView::RectangleRubberBand) << 1 << 1 << QPoint(5,5) << QPoint(5,5); } void tst_QChartView::rubberBand() @@ -131,13 +129,11 @@ void tst_QChartView::rubberBand() QFETCH(QChartView::RubberBands, rubberBand); QFETCH(int, Xcount); QFETCH(int, Ycount); - QFETCH(int, minX); - QFETCH(int, maxX); - QFETCH(int, minY); - QFETCH(int, maxY); + QFETCH(QPoint, min); + QFETCH(QPoint, max); m_view->setRubberBand(rubberBand); - QRectF padding = m_view->chart()->margins(); + QCOMPARE(m_view->rubberBand(), rubberBand); QLineSeries* line = new QLineSeries(); @@ -145,9 +141,9 @@ void tst_QChartView::rubberBand() m_view->chart()->addSeries(line); m_view->chart()->createDefaultAxes(); - m_view->resize(200 + padding.left() + padding.right(), 200 + padding.top()+ padding.bottom()); m_view->show(); + QRectF plotArea = m_view->chart()->plotArea(); //this is hack since view does not get events otherwise m_view->setMouseTracking(true); @@ -156,11 +152,23 @@ void tst_QChartView::rubberBand() QAbstractAxis* axisX = m_view->chart()->axisX(); QSignalSpy spy1(axisX, SIGNAL(rangeChanged(qreal,qreal))); + + QValueAxis* vaxisX = qobject_cast(axisX); + QValueAxis* vaxisY = qobject_cast(axisY); + + int minX = vaxisX->min(); + int minY = vaxisY->min(); + int maxX = vaxisX->max(); + int maxY = vaxisY->max(); + QTest::qWaitForWindowShown(m_view); - QTest::mouseMove(m_view->viewport(), QPoint(minX, minY) + padding.topLeft().toPoint()); - QTest::mousePress(m_view->viewport(), Qt::LeftButton, 0, QPoint(minX, minY) + padding.topLeft().toPoint()); - QTest::mouseMove(m_view->viewport(), QPoint(maxX, maxY) + padding.topLeft().toPoint()); - QTest::mouseRelease(m_view->viewport(), Qt::LeftButton, 0, QPoint(maxX, maxY)+ padding.topLeft().toPoint()); + QTest::mouseMove(m_view->viewport(), min + plotArea.topLeft().toPoint()); + QTest::qWait(2000); + QTest::mousePress(m_view->viewport(), Qt::LeftButton, 0, min + plotArea.topLeft().toPoint()); + QTest::qWait(2000); + QTest::mouseMove(m_view->viewport(), plotArea.bottomRight().toPoint() - max); + QTest::qWait(2000); + QTest::mouseRelease(m_view->viewport(), Qt::LeftButton, 0, plotArea.bottomRight().toPoint() - max); TRY_COMPARE(spy0.count(), Xcount); TRY_COMPARE(spy1.count(), Ycount); @@ -168,13 +176,10 @@ void tst_QChartView::rubberBand() //this is hack since view does not get events otherwise m_view->setMouseTracking(false); - QValueAxis* vaxisX = qobject_cast(axisX); - QValueAxis* vaxisY = qobject_cast(axisY); - - QVERIFY(vaxisX->min() - minX < 1); - QVERIFY(vaxisX->max() - maxX < 1); - QVERIFY(vaxisY->min() - minY < 1); - QVERIFY(vaxisY->max() - maxY < 1); + QVERIFY(vaxisX->min() >= minX ); + QVERIFY(vaxisX->max() <= maxX ); + QVERIFY(vaxisY->min() >= minY ); + QVERIFY(vaxisY->max() <= maxY ); }