1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtCore/QList>
5#include "QtGraphs/QSplineSeries"
6#include "QtGraphs/QXYSeries"
7#include "private/qgraphtransition_p.h"
8#include "private/qsplinecontrolanimation_p.h"
9#include "private/qsplineseries_p.h"
10#include "private/qxyseries_p.h"
11#include "private/qxyseriesanimation_p.h"
12
13/*!
14 \qmltype GraphTransition
15 \inqmlmodule QtGraphs
16 \ingroup graphs_qml_2D
17 \brief A container in which all animations are defined.
18
19GraphTransition is a container for animations inside on Graphs2D. Define this class
20inside a graph type to enable animated changes for XYSeries within 2D graphs. To
21define individual animations, add them inside of the GraphTransition. The
22individual animations within the same GraphTransition are animated in parallel. If
23a GraphTransition is found by the graph during a call to a supported function
24which appends or replaces a point, then the values are interpolated according to
25the animations that are added.
26
27This example shows how to define a GraphTransition within a graph.
28
29\snippet doc_src_qmlgraphs.cpp 11
30
31Note: GraphTransition requires it to be defined directly inside the graph which needs to be animated.
32Currently only XYSeries are supported.
33
34\sa GraphPointAnimation, SplineControlAnimation
35*/
36
37QGraphTransition::QGraphTransition(QObject *parent)
38 : QObject(parent)
39 , m_animationGroup(this)
40 , m_initialized(false)
41{}
42
43QGraphTransition::~QGraphTransition() {}
44
45void QGraphTransition::componentComplete()
46{
47 // Currently only assuming animations in QXYSeries
48 Q_ASSERT(parent() != nullptr && qobject_cast<QXYSeries *>(parent()));
49 auto series = qobject_cast<QXYSeries *>(object: parent());
50
51 if (series)
52 series->d_func()->m_graphTransition = this;
53}
54
55void QGraphTransition::onPointChanged(TransitionType type, int index, QPointF point)
56{
57 auto series = qobject_cast<QXYSeries *>(object: parent());
58
59 if (!series || !series->hasLoaded())
60 return;
61
62 if (m_animationGroup.state() == QAbstractAnimation::Running)
63 m_animationGroup.stop();
64
65 for (auto child : m_animationGroup.children()) {
66 auto childAnimation = qobject_cast<QXYSeriesAnimation *>(object: child);
67 childAnimation->updateCurrent(tt: type, index, point);
68 }
69
70 for (auto child : m_animationGroup.children()) {
71 auto childAnimation = qobject_cast<QXYSeriesAnimation *>(object: child);
72
73 childAnimation->animate();
74 }
75
76 auto spline = qobject_cast<QSplineSeries *>(object: series);
77
78 if (spline && !contains(type: QGraphAnimation::GraphAnimationType::ControlPoint))
79 spline->d_func()->calculateSplinePoints();
80
81 m_animationGroup.start();
82}
83
84void QGraphTransition::initialize()
85{
86 auto series = qobject_cast<QXYSeries *>(object: parent());
87
88 if (!series || m_initialized)
89 return;
90
91 const auto &animationChildren = m_animationGroup.children();
92 for (qsizetype i = 0; i < animationChildren.size(); ++i) {
93 auto childAnimation = qobject_cast<QXYSeriesAnimation *>(object: animationChildren[i]);
94
95 //GraphPointAnimation needs to be the first for the transition to work
96 if (childAnimation->animationType() == QGraphAnimation::GraphAnimationType::GraphPoint
97 && i != 0)
98 return;
99 }
100
101 m_initialized = true;
102}
103
104void QGraphTransition::stop()
105{
106 m_animationGroup.stop();
107
108 for (auto child : m_animationGroup.children()) {
109 auto childAnimation = qobject_cast<QXYSeriesAnimation *>(object: child);
110 childAnimation->end();
111 }
112}
113
114bool QGraphTransition::initialized()
115{
116 return m_initialized;
117}
118
119bool QGraphTransition::contains(QGraphAnimation::GraphAnimationType type)
120{
121 for (const auto anim : m_animations) {
122 if (anim->animationType() == type)
123 return true;
124 }
125
126 return false;
127}
128
129/*!
130 \qmlproperty list<object> GraphTransition::animations
131 A container for all the animations in the GraphTransition.
132 Currently only supports animations to be added and cleared.
133 By default, the list is empty.
134 */
135QQmlListProperty<QObject> QGraphTransition::animations()
136{
137 return QQmlListProperty<QObject>{this,
138 nullptr,
139 &QGraphTransition::append,
140 nullptr,
141 nullptr,
142 &QGraphTransition::clear};
143}
144
145void QGraphTransition::classBegin() {}
146
147void QGraphTransition::append(QQmlListProperty<QObject> *animationProps, QObject *animation)
148{
149 auto graphTransition = qobject_cast<QGraphTransition *>(object: animationProps->object);
150
151 if (graphTransition) {
152 auto graphAnimation = qobject_cast<QGraphAnimation *>(object: animation);
153 graphTransition->m_animations.append(t: graphAnimation);
154 graphTransition->m_animationGroup.addAnimation(animation: graphAnimation);
155 }
156}
157
158void QGraphTransition::clear(QQmlListProperty<QObject> *)
159{
160 Q_UNIMPLEMENTED();
161}
162

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtgraphs/src/graphs2d/animation/qgraphtransition.cpp