From 5a6d23b6b72f4476fcba26e656bcc6eb7f32b3a1 2013-04-25 09:52:56 From: Miikka Heikkinen Date: 2013-04-25 09:52:56 Subject: [PATCH] Further animation fixes - Scatter animation didn't update points correctly after remove - Spline animation crashed at insert/removal at zero index Change-Id: I181cfb195aa3f152fb1df1cf9f74b7592c1a8f19 Reviewed-by: Tomi Korpipää --- diff --git a/src/animations/animations.pri b/src/animations/animations.pri index f3f7907..9323942 100644 --- a/src/animations/animations.pri +++ b/src/animations/animations.pri @@ -7,7 +7,8 @@ SOURCES += \ $$PWD/pieanimation.cpp \ $$PWD/piesliceanimation.cpp \ $$PWD/splineanimation.cpp \ - $$PWD/baranimation.cpp + $$PWD/baranimation.cpp \ + $$PWD/scatteranimation.cpp PRIVATE_HEADERS += \ $$PWD/axisanimation_p.h \ @@ -16,4 +17,5 @@ PRIVATE_HEADERS += \ $$PWD/pieanimation_p.h \ $$PWD/piesliceanimation_p.h \ $$PWD/splineanimation_p.h \ - $$PWD/baranimation_p.h + $$PWD/baranimation_p.h \ + $$PWD/scatteranimation_p.h diff --git a/src/animations/scatteranimation.cpp b/src/animations/scatteranimation.cpp new file mode 100644 index 0000000..602b7c5 --- /dev/null +++ b/src/animations/scatteranimation.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** + ** + ** Copyright (C) 2013 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 "scatteranimation_p.h" +#include "scatterchartitem_p.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +ScatterAnimation::ScatterAnimation(ScatterChartItem *item) + : XYAnimation(item) +{ +} + +ScatterAnimation::~ScatterAnimation() +{ +} + +void ScatterAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) +{ + XYAnimation::updateState(newState, oldState); + + if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped + && animationType() == RemovePointAnimation) { + // Removing a point from scatter chart will keep extra marker item after animation stops. + // Also, if the removed point was not the last one in series, points after the removed one + // will report wrong coordinates when clicked. To fix these issues, update geometry after + // point removal animation has finished. + chartItem()->updateGeometry(); + } +} + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/animations/scatteranimation_p.h b/src/animations/scatteranimation_p.h new file mode 100644 index 0000000..2fc0a38 --- /dev/null +++ b/src/animations/scatteranimation_p.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 SCATTERANIMATION_P_H +#define SCATTERANIMATION_P_H +#include "xyanimation_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class ScatterChartItem; + +class ScatterAnimation : public XYAnimation +{ +public: + ScatterAnimation(ScatterChartItem *item); + ~ScatterAnimation(); + +protected: + void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif diff --git a/src/animations/splineanimation.cpp b/src/animations/splineanimation.cpp index bf4432b..390120e 100644 --- a/src/animations/splineanimation.cpp +++ b/src/animations/splineanimation.cpp @@ -77,9 +77,9 @@ void SplineAnimation::setup(QVector &oldPoints, QVector &newPo m_newSpline.second.insert((index - 1) * 2, newPoints[index - 1]); m_newSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]); } else { - m_newSpline.first.insert(index, newPoints[index]); - m_newSpline.second.insert(index * 2, newPoints[index]); - m_newSpline.second.insert(index * 2 + 1, newPoints[index]); + m_newSpline.first.insert(0, newPoints[index]); + m_newSpline.second.insert(0, newPoints[index]); + m_newSpline.second.insert(1, newPoints[index]); } m_index = index; m_type = RemovePointAnimation; @@ -92,9 +92,9 @@ void SplineAnimation::setup(QVector &oldPoints, QVector &newPo m_oldSpline.second.insert((index - 1) * 2, newPoints[index - 1]); m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]); } else { - m_oldSpline.first.insert(index, newPoints[index]); - m_oldSpline.second.insert((index - 1) * 2, newPoints[index]); - m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index]); + m_oldSpline.first.insert(0, newPoints[index]); + m_oldSpline.second.insert(0, newPoints[index]); + m_oldSpline.second.insert(1, newPoints[index]); } m_index = index; m_type = AddPointAnimation; @@ -186,9 +186,15 @@ void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractA if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) { if (m_item->isDirty() && m_type == RemovePointAnimation) { if (!m_newSpline.first.isEmpty()) { - m_newSpline.first.remove(m_index); - m_newSpline.second.remove((m_index - 1) * 2); - m_newSpline.second.remove((m_index - 1) * 2); + if (m_index) { + m_newSpline.first.remove(m_index); + m_newSpline.second.remove((m_index - 1) * 2); + m_newSpline.second.remove((m_index - 1) * 2); + } else { + m_newSpline.first.remove(0); + m_newSpline.second.remove(0); + m_newSpline.second.remove(0); + } } m_item->setGeometryPoints(m_newSpline.first); m_item->setControlGeometryPoints(m_newSpline.second); diff --git a/src/animations/xyanimation_p.h b/src/animations/xyanimation_p.h index b7c5a5d..213a197 100644 --- a/src/animations/xyanimation_p.h +++ b/src/animations/xyanimation_p.h @@ -51,6 +51,7 @@ protected: QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const; void updateCurrentValue(const QVariant &value); void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + XYChart *chartItem() { return m_item; } protected: Animation m_type; bool m_dirty; diff --git a/src/scatterchart/qscatterseries.cpp b/src/scatterchart/qscatterseries.cpp index 2692ea8..e9605f4 100644 --- a/src/scatterchart/qscatterseries.cpp +++ b/src/scatterchart/qscatterseries.cpp @@ -23,6 +23,7 @@ #include "scatterchartitem_p.h" #include "chartdataset_p.h" #include "charttheme_p.h" +#include "scatteranimation_p.h" /*! \class QScatterSeries @@ -282,6 +283,19 @@ void QScatterSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool f } } +void QScatterSeriesPrivate::initializeAnimations(QChart::AnimationOptions options) +{ + ScatterChartItem *item = static_cast(m_item.data()); + Q_ASSERT(item); + + if (options.testFlag(QChart::SeriesAnimations)) + item->setAnimation(new ScatterAnimation(item)); + else + item->setAnimation(0); + + QAbstractSeriesPrivate::initializeAnimations(options); +} + #include "moc_qscatterseries.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/scatterchart/qscatterseries_p.h b/src/scatterchart/qscatterseries_p.h index 2ca11e9..c95c8f2 100644 --- a/src/scatterchart/qscatterseries_p.h +++ b/src/scatterchart/qscatterseries_p.h @@ -40,6 +40,7 @@ public: QScatterSeriesPrivate(QScatterSeries *q); void initializeGraphics(QGraphicsItem* parent); void initializeTheme(int index, ChartTheme* theme, bool forced = false); + void initializeAnimations(QtCommercialChart::QChart::AnimationOptions options); private: QScatterSeries::MarkerShape m_shape; diff --git a/src/scatterchart/scatterchartitem.cpp b/src/scatterchart/scatterchartitem.cpp index fe6c9de..42fb66a 100644 --- a/src/scatterchart/scatterchartitem.cpp +++ b/src/scatterchart/scatterchartitem.cpp @@ -133,13 +133,13 @@ void ScatterChartItem::updateGeometry() QGraphicsItem *item = items.at(i); const QPointF &point = points.at(i); const QRectF &rect = item->boundingRect(); - // During remove/append animation series may have different number of points, + // During remove animation series may have different number of points, // so ensure we don't go over the index. Animation handling itself ensures that // if there is actually no points in the series, then it won't generate a fake point, // so we can be assured there is always at least one point in m_series here. // Note that marker map values can be technically incorrect during the animation, // if it was caused by an insert, but this shouldn't be a problem as the points are - // fake anyway. + // fake anyway. After remove animation stops, geometry is updated to correct one. m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i)); item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2); diff --git a/src/xychart/xychart.cpp b/src/xychart/xychart.cpp index 5f57cc5..7b21f8b 100644 --- a/src/xychart/xychart.cpp +++ b/src/xychart/xychart.cpp @@ -73,7 +73,7 @@ QVector XYChart::offGridStatusVector() QVector returnVector; returnVector.resize(m_points.size()); - // During remove/append animation series may have different number of points, + // During remove animation series may have different number of points, // so ensure we don't go over the index. No need to check for zero points, this // will not be called in such a situation. const int seriesLastIndex = m_series->count() - 1;