chartanimator.cpp
301 lines
| 8.6 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r794 | /**************************************************************************** | ||
** | ||||
** 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$ | ||||
** | ||||
****************************************************************************/ | ||||
Michal Klocek
|
r530 | #include "chartanimator_p.h" | ||
#include "axisanimation_p.h" | ||||
#include "xyanimation_p.h" | ||||
Michal Klocek
|
r622 | #include "splineanimation_p.h" | ||
Michal Klocek
|
r530 | #include "xychartitem_p.h" | ||
Jani Honkonen
|
r618 | #include "pieanimation_p.h" | ||
sauimone
|
r671 | #include "baranimation_p.h" | ||
#include "barchartitem_p.h" | ||||
Michal Klocek
|
r560 | #include "areachartitem_p.h" | ||
Michal Klocek
|
r622 | #include "splinechartitem_p.h" | ||
#include "scatterchartitem_p.h" | ||||
Michal Klocek
|
r530 | #include <QTimer> | ||
Q_DECLARE_METATYPE(QVector<QPointF>) | ||||
Q_DECLARE_METATYPE(QVector<qreal>) | ||||
sauimone
|
r681 | Q_DECLARE_METATYPE(QVector<QRectF>) | ||
Michal Klocek
|
r530 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
const static int duration = 1000; | ||||
Marek Rosa
|
r738 | ChartAnimator::ChartAnimator(QObject *parent):QObject(parent), | ||
m_state(ShowState) | ||||
Michal Klocek
|
r530 | { | ||
} | ||||
ChartAnimator::~ChartAnimator() | ||||
{ | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(Axis *item) | ||
Michal Klocek
|
r530 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
Michal Klocek
|
r530 | animation = new AxisAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
Michal Klocek
|
r530 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(SplineChartItem *item) | ||
Michal Klocek
|
r622 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
Michal Klocek
|
r622 | animation = new SplineAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
Michal Klocek
|
r622 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(ScatterChartItem *item) | ||
Michal Klocek
|
r622 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
Michal Klocek
|
r622 | animation = new XYAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
Michal Klocek
|
r622 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(LineChartItem *item) | ||
Michal Klocek
|
r530 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
Michal Klocek
|
r530 | animation = new XYAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
Michal Klocek
|
r530 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(PieChartItem *item) | ||
Jani Honkonen
|
r618 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
Jani Honkonen
|
r618 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
Jani Honkonen
|
r618 | animation = new PieAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
Jani Honkonen
|
r618 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(BarChartItem *item) | ||
sauimone
|
r671 | { | ||
Marek Rosa
|
r738 | ChartAnimation *animation = m_animations.value(item); | ||
sauimone
|
r671 | |||
Marek Rosa
|
r738 | if (!animation) { | ||
sauimone
|
r671 | animation = new BarAnimation(item); | ||
Marek Rosa
|
r738 | m_animations.insert(item, animation); | ||
sauimone
|
r671 | } | ||
item->setAnimator(this); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::removeAnimation(Chart *item) | ||
Michal Klocek
|
r530 | { | ||
item->setAnimator(0); | ||||
m_animations.remove(item); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(Axis *item , QVector<qreal> &newLayout) | ||
Michal Klocek
|
r530 | { | ||
Marek Rosa
|
r738 | AxisAnimation *animation = static_cast<AxisAnimation*>(m_animations.value(item)); | ||
Michal Klocek
|
r530 | |||
Michal Klocek
|
r560 | Q_ASSERT(animation); | ||
Michal Klocek
|
r530 | |||
QVector<qreal> oldLayout = item->layout(); | ||||
Marek Rosa
|
r738 | if (newLayout.count() == 0) | ||
return; | ||||
switch (m_state) { | ||||
case ZoomOutState: { | ||||
QRectF rect = item->geometry(); | ||||
oldLayout.resize(newLayout.count()); | ||||
Michal Klocek
|
r974 | for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) { | ||
Marek Rosa
|
r738 | oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.bottom(); | ||
oldLayout[j] = item->axisType() == Axis::X_AXIS ? rect.right() : rect.top(); | ||||
} | ||||
} | ||||
break; | ||||
case ZoomInState: { | ||||
int index = qMin(oldLayout.count() * (item->axisType() == Axis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0); | ||||
oldLayout.resize(newLayout.count()); | ||||
for(int i = 0; i < oldLayout.count(); i++) | ||||
oldLayout[i]= oldLayout[index]; | ||||
Michal Klocek
|
r530 | } | ||
Marek Rosa
|
r738 | break; | ||
case ScrollDownState: | ||||
case ScrollRightState: { | ||||
oldLayout.resize(newLayout.count()); | ||||
Michal Klocek
|
r974 | for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j) | ||
Marek Rosa
|
r738 | oldLayout[i]= oldLayout[j]; | ||
} | ||||
break; | ||||
case ScrollUpState: | ||||
case ScrollLeftState: { | ||||
oldLayout.resize(newLayout.count()); | ||||
Michal Klocek
|
r974 | for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j) | ||
Marek Rosa
|
r738 | oldLayout[i]= oldLayout[j]; | ||
} | ||||
break; | ||||
default: { | ||||
oldLayout.resize(newLayout.count()); | ||||
QRectF rect = item->geometry(); | ||||
Michal Klocek
|
r974 | for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j) | ||
Marek Rosa
|
r738 | oldLayout[i] = item->axisType() == Axis::X_AXIS ? rect.left() : rect.top(); | ||
} | ||||
break; | ||||
} | ||||
if (animation->state() != QAbstractAnimation::Stopped) | ||||
animation->stop(); | ||||
Michal Klocek
|
r530 | |||
animation->setDuration(duration); | ||||
animation->setEasingCurve(QEasingCurve::OutQuart); | ||||
QVariantAnimation::KeyValues value; | ||||
animation->setKeyValues(value); //workaround for wrong interpolation call | ||||
animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout)); | ||||
animation->setKeyValueAt(1.0, qVariantFromValue(newLayout)); | ||||
Marek Rosa
|
r738 | QTimer::singleShot(0, animation, SLOT(start())); | ||
Michal Klocek
|
r530 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(SplineChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index) | ||
Michal Klocek
|
r530 | { | ||
Marek Rosa
|
r738 | SplineAnimation *animation = static_cast<SplineAnimation *>(m_animations.value(item)); | ||
Michal Klocek
|
r530 | |||
Michal Klocek
|
r560 | Q_ASSERT(animation); | ||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | if (newPoints.count() < 2 || newControlPoints.count() < 2) | ||
return; | ||||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | bool empty = oldPoints.count() == 0; | ||
Michal Klocek
|
r622 | |||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | if (animation->state() != QAbstractAnimation::Stopped) | ||
animation->stop(); | ||||
Michal Klocek
|
r530 | |||
animation->setDuration(duration); | ||||
Marek Rosa
|
r738 | if (!empty) | ||
animation->setAnimationType(ChartAnimation::MoveDownAnimation); | ||||
Michal Klocek
|
r530 | else | ||
Marek Rosa
|
r738 | animation->setAnimationType(ChartAnimation::LineDrawAnimation); | ||
Michal Klocek
|
r622 | |||
Michal Klocek
|
r530 | animation->setEasingCurve(QEasingCurve::OutQuart); | ||
Marek Rosa
|
r738 | animation->setValues(oldPoints, newPoints, oldControlPoints, newControlPoints, index); | ||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | QTimer::singleShot(0, animation, SLOT(start())); | ||
Michal Klocek
|
r530 | } | ||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(XYChartItem *item, QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index) | ||
Michal Klocek
|
r530 | { | ||
Marek Rosa
|
r738 | XYAnimation *animation = static_cast<XYAnimation *>(m_animations.value(item)); | ||
Michal Klocek
|
r530 | |||
Michal Klocek
|
r560 | Q_ASSERT(animation); | ||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | if (newPoints.count() == 0) | ||
return; | ||||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | bool empty = oldPoints.count() == 0; | ||
Michal Klocek
|
r622 | |||
Marek Rosa
|
r738 | if (animation->state() != QAbstractAnimation::Stopped) | ||
Michal Klocek
|
r622 | animation->stop(); | ||
Michal Klocek
|
r530 | animation->setDuration(duration); | ||
Marek Rosa
|
r738 | if (!empty) | ||
animation->setAnimationType(ChartAnimation::MoveDownAnimation); | ||||
Michal Klocek
|
r622 | else | ||
Marek Rosa
|
r738 | animation->setAnimationType(ChartAnimation::LineDrawAnimation); | ||
Michal Klocek
|
r622 | |||
Michal Klocek
|
r530 | animation->setEasingCurve(QEasingCurve::OutQuart); | ||
Marek Rosa
|
r738 | animation->setValues(oldPoints, newPoints, index); | ||
Michal Klocek
|
r530 | |||
Marek Rosa
|
r738 | QTimer::singleShot(0, animation, SLOT(start())); | ||
Michal Klocek
|
r530 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::addAnimation(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty) | ||
Jani Honkonen
|
r618 | { | ||
Marek Rosa
|
r738 | PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item)); | ||
Jani Honkonen
|
r618 | Q_ASSERT(animation); | ||
Jani Honkonen
|
r668 | animation->addSlice(slice, sliceData, isEmpty); | ||
Jani Honkonen
|
r621 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::removeAnimation(PieChartItem *item, QPieSlice *slice) | ||
Jani Honkonen
|
r621 | { | ||
Marek Rosa
|
r738 | PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item)); | ||
Jani Honkonen
|
r621 | Q_ASSERT(animation); | ||
animation->removeSlice(slice); | ||||
} | ||||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(PieChartItem *item, const PieLayout &layout) | ||
Jani Honkonen
|
r621 | { | ||
Marek Rosa
|
r738 | PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item)); | ||
Jani Honkonen
|
r621 | Q_ASSERT(animation); | ||
animation->updateValues(layout); | ||||
Jani Honkonen
|
r618 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(PieChartItem *item, QPieSlice *slice, const PieSliceData &sliceData) | ||
Jani Honkonen
|
r618 | { | ||
Marek Rosa
|
r738 | PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item)); | ||
Jani Honkonen
|
r618 | Q_ASSERT(animation); | ||
Jani Honkonen
|
r668 | animation->updateValue(slice, sliceData); | ||
Jani Honkonen
|
r618 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout) | ||
sauimone
|
r671 | { | ||
Marek Rosa
|
r738 | BarAnimation *animation = static_cast<BarAnimation *>(m_animations.value(item)); | ||
sauimone
|
r671 | Q_ASSERT(animation); | ||
sauimone
|
r681 | animation->setDuration(duration); | ||
animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout)); | ||||
animation->setKeyValueAt(1.0, qVariantFromValue(newLayout)); | ||||
Marek Rosa
|
r738 | QTimer::singleShot(0, animation, SLOT(start())); | ||
sauimone
|
r671 | } | ||
Marek Rosa
|
r738 | void ChartAnimator::setState(State state, const QPointF &point) | ||
Michal Klocek
|
r531 | { | ||
Marek Rosa
|
r738 | m_state = state; | ||
m_point = point; | ||||
Michal Klocek
|
r531 | } | ||
Michal Klocek
|
r974 | #include "moc_chartanimator_p.cpp" | ||
Michal Klocek
|
r530 | QTCOMMERCIALCHART_END_NAMESPACE | ||