summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@digia.com>2012-05-29 18:00:17 +0300
committerMichal Klocek <michal.klocek@digia.com>2012-05-29 18:01:30 +0300
commit77f0ec7651021d6cfcaeec75bb05b8f68b37e128 (patch)
treedb9d7f084ca681c992deee188fa7e26bd3d2faa7
parentb2453e3ca6792e61bef118406604f65fe3b9f379 (diff)
Refactors spline animations:
* removes complex cases * simple animation to improve stability * fixes spilne unit test cases
-rw-r--r--src/animations/splineanimation.cpp266
-rw-r--r--src/animations/splineanimation_p.h3
-rw-r--r--src/animations/xyanimation.cpp11
-rw-r--r--src/animations/xyanimation_p.h12
4 files changed, 190 insertions, 102 deletions
diff --git a/src/animations/splineanimation.cpp b/src/animations/splineanimation.cpp
index 8229744f..b6555711 100644
--- a/src/animations/splineanimation.cpp
+++ b/src/animations/splineanimation.cpp
@@ -1,22 +1,22 @@
/****************************************************************************
-**
-** 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 "splineanimation_p.h"
#include "splinechartitem_p.h"
@@ -28,8 +28,7 @@ Q_DECLARE_METATYPE(SplineVector)
QTCOMMERCIALCHART_BEGIN_NAMESPACE
SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
- m_item(item),
- m_dirty(true)
+m_item(item)
{
}
@@ -39,98 +38,167 @@ SplineAnimation::~SplineAnimation()
void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
{
- int x = oldPoints.count();
- int y = newPoints.count();
-
Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
- if (x != y && abs(x - y) != 1) {
- m_oldSpline.first = newPoints;
- m_oldSpline.second = newControlPoints;
- oldPoints.resize(newPoints.size());
- oldControlPoints.resize(newControlPoints.size());
- SplineVector oldPair;
- oldPair.first = oldPoints;
- oldPair.second = oldControlPoints;
- SplineVector newPair;
- newPair.first = newPoints;
- newPair.second = newControlPoints;
- setKeyValueAt(0.0, qVariantFromValue(oldPair));
- setKeyValueAt(1.0, qVariantFromValue(newPair));
- m_dirty = false;
+ m_type = NewAnimation;
+
+ if (state() != QAbstractAnimation::Stopped) {
+ stop();
+ m_dirty=false;
}
- else {
- if(m_dirty) {
- m_oldSpline.first = oldPoints;
- m_oldSpline.second = oldControlPoints;
- m_dirty = false;
- }
- oldPoints = newPoints;
- oldControlPoints = newControlPoints;
- if (y < x) {
- m_oldSpline.first.remove(index); //remove
- m_oldSpline.second.remove(index * 2);
- m_oldSpline.second.remove(index * 2);
+
+ if(!m_dirty) {
+ m_dirty = true;
+ m_oldSpline.first = oldPoints;
+ m_oldSpline.second = oldControlPoints;
+ }
+
+ m_newSpline.first=newPoints;
+ m_newSpline.second=newControlPoints;
+
+ int x = m_oldSpline.first.count();
+ int y = m_newSpline.first.count();
+
+ if(x - y == 1 && index >= 0 && y>0) {
+ //remove point
+ if(index>0){
+ m_newSpline.first.insert(index, newPoints[index-1]);
+ 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]);
}
- if (y > x) {
- m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
- m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
- m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
+ m_index=index;
+ m_type = RemovePointAnimation;
+ }
+
+ if(x - y == -1 && index >= 0) {
+ //add point
+ if(index>0){
+ m_oldSpline.first.insert(index, newPoints[index-1]);
+ 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]);
}
- SplineVector newPair;
- newPair.first=newPoints;
- newPair.second=newControlPoints;
- setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
- setKeyValueAt(1.0, qVariantFromValue(newPair));
+ m_index=index;
+ m_type = AddPointAnimation;
+ }
+
+ x = m_oldSpline.first.count();
+ y = m_newSpline.first.count();
+
+ if(x != y)
+ {
+ m_type = NewAnimation;
+ }
+ else if(m_type == NewAnimation)
+ {
+ m_type = ReplacePointAnimation;
}
+
+
+ setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
+ setKeyValueAt(1.0, qVariantFromValue(m_newSpline));
+ /*
+ int x = oldPoints.count();
+ int y = newPoints.count();
+
+ Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
+
+ if (x != y && abs(x - y) != 1) {
+ m_oldSpline.first = newPoints;
+ m_oldSpline.second = newControlPoints;
+ oldPoints.resize(newPoints.size());
+ oldControlPoints.resize(newControlPoints.size());
+ SplineVector oldPair;
+ oldPair.first = oldPoints;
+ oldPair.second = oldControlPoints;
+ SplineVector newPair;
+ newPair.first = newPoints;
+ newPair.second = newControlPoints;
+ setKeyValueAt(0.0, qVariantFromValue(oldPair));
+ setKeyValueAt(1.0, qVariantFromValue(newPair));
+ m_dirty = false;
+ }
+ else {
+ if(m_dirty) {
+ m_oldSpline.first = oldPoints;
+ m_oldSpline.second = oldControlPoints;
+ m_dirty = false;
+ }
+ oldPoints = newPoints;
+ oldControlPoints = newControlPoints;
+ if (y < x) {
+ m_oldSpline.first.remove(index); //remove
+ m_oldSpline.second.remove(index * 2);
+ m_oldSpline.second.remove(index * 2);
+ }
+ if (y > x) {
+ m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
+ m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
+ m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
+ }
+ SplineVector newPair;
+ newPair.first=newPoints;
+ newPair.second=newControlPoints;
+ setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
+ setKeyValueAt(1.0, qVariantFromValue(newPair));
+ }
+ */
+
}
QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
{
- SplineVector startPair = qVariantValue< SplineVector >(start);
- SplineVector endPair = qVariantValue< SplineVector >(end);
+ SplineVector startPair = qVariantValue< SplineVector >(start);
+ SplineVector endPair = qVariantValue< SplineVector >(end);
SplineVector result;
switch (animationType()) {
- case RemovePointAnimation:
- case AddPointAnimation:
- case ReplacePointAnimation:
- {
- if (startPair.first.count() != endPair.first.count())
+ case RemovePointAnimation:
+ case AddPointAnimation:
+ case ReplacePointAnimation:
+ {
+ if (startPair.first.count() != endPair.first.count())
break;
- Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
- Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
- for(int i = 0; i < endPair.first.count(); i++) {
- qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
- qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
- result.first << QPointF(x,y);
- if (i + 1 >= endPair.first.count())
+ Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
+ Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
+ for(int i = 0; i < endPair.first.count(); i++) {
+ qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
+ qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
+ result.first << QPointF(x,y);
+ if (i + 1 >= endPair.first.count())
continue;
- x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
- y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
- result.second << QPoint(x,y);
- x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
- y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
- result.second << QPoint(x,y);
- }
+ x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
+ y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
+ result.second << QPoint(x,y);
+ x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
+ y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
+ result.second << QPoint(x,y);
+ }
- }
+ }
break;
- case NewAnimation:{
- Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
- int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
- for(int i = 0; i < count; i++) {
- result.first << endPair.first[i];
- if(i + 1 == count)
+ case NewAnimation: {
+ Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
+ int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
+ for(int i = 0; i < count; i++) {
+ result.first << endPair.first[i];
+ if(i + 1 == count)
break;
- result.second << endPair.second[2 * i];
- result.second << endPair.second[2 * i + 1];
+ result.second << endPair.second[2 * i];
+ result.second << endPair.second[2 * i + 1];
+ }
}
- }
break;
- default:
+ default:
qWarning() << "Unknown type of animation";
break;
}
@@ -141,13 +209,29 @@ QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
void SplineAnimation::updateCurrentValue (const QVariant &value )
{
if (state() != QAbstractAnimation::Stopped) { //workaround
- m_dirty = true;
QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
m_item->setGeometryPoints(pair.first);
m_item->setControlGeometryPoints(pair.second);
m_item->updateGeometry();
+ m_item->setDirty(true);
+ m_dirty = false;
}
}
+void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+{
+ 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);
+ }
+ m_item->setGeometryPoints(m_newSpline.first);
+ m_item->setControlGeometryPoints(m_newSpline.second);
+ }
+ }
+}
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/splineanimation_p.h b/src/animations/splineanimation_p.h
index 6ca2f422..e4521532 100644
--- a/src/animations/splineanimation_p.h
+++ b/src/animations/splineanimation_p.h
@@ -39,11 +39,12 @@ public:
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);
private:
SplineVector m_oldSpline;
+ SplineVector m_newSpline;
SplineChartItem *m_item;
- bool m_dirty;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/xyanimation.cpp b/src/animations/xyanimation.cpp
index e93e6fb7..a033d7a8 100644
--- a/src/animations/xyanimation.cpp
+++ b/src/animations/xyanimation.cpp
@@ -27,9 +27,10 @@ Q_DECLARE_METATYPE(QVector<QPointF>)
QTCOMMERCIALCHART_BEGIN_NAMESPACE
XYAnimation::XYAnimation(XYChart *item):ChartAnimation(item),
- m_item(item),
+ m_type(NewAnimation),
m_dirty(false),
- m_type(NewAnimation)
+ m_index(-1),
+ m_item(item)
{
setDuration(ChartAnimationDuration);
setEasingCurve(QEasingCurve::OutQuart);
@@ -58,16 +59,16 @@ void XYAnimation::setup(const QVector<QPointF> &oldPoints, const QVector<QPointF
int x = m_oldPoints.count();
int y = m_newPoints.count();
- if(x - y == 1 && index >= 0 && !newPoints.isEmpty()){
+ if(x - y == 1 && index >= 0 && y > 0){
//remove point
- m_newPoints.insert(index, index >= 1 ? m_newPoints[index-1] : newPoints[index]);
+ m_newPoints.insert(index, index > 0 ? newPoints[index-1] : newPoints[index]);
m_index=index;
m_type = RemovePointAnimation;
}
if(x - y == -1 && index >= 0){
//add point
- m_oldPoints.insert(index, x > 0 && index > 1 ? m_oldPoints[index-1] : newPoints[index]);
+ m_oldPoints.insert(index, index > 0 ? newPoints[index-1] : newPoints[index]);
m_index=index;
m_type = AddPointAnimation;
}
diff --git a/src/animations/xyanimation_p.h b/src/animations/xyanimation_p.h
index 5c887402..ef9ca422 100644
--- a/src/animations/xyanimation_p.h
+++ b/src/animations/xyanimation_p.h
@@ -30,8 +30,9 @@ class XYChart;
class XYAnimation : public ChartAnimation
{
-public:
+protected:
enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
+public:
XYAnimation(XYChart *item);
~XYAnimation();
void setup(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints,int index = -1);
@@ -40,14 +41,15 @@ public:
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 );
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+protected:
+ Animation m_type;
+ bool m_dirty;
+ int m_index;
private:
XYChart *m_item;
QVector<QPointF> m_oldPoints;
QVector<QPointF> m_newPoints;
- int m_index;
- bool m_dirty;
- Animation m_type;
};
QTCOMMERCIALCHART_END_NAMESPACE