summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-05-19 08:55:54 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-05-19 08:55:54 (GMT)
commit2363ac60ae80a4cb396c60749b496a88403cf234 (patch)
tree3edc1a693667a7244d86c975f2057405743bd36d
parent3d99537a86144b8f22ef10891ba6cc55820b987a (diff)
parentad17d5fcaa5984e7f11e3c8a514a24264890c827 (diff)
downloadQt-2363ac60ae80a4cb396c60749b496a88403cf234.zip
Qt-2363ac60ae80a4cb396c60749b496a88403cf234.tar.gz
Qt-2363ac60ae80a4cb396c60749b496a88403cf234.tar.bz2
Merge branch 'kinetic-animations' into kinetic-statemachine
-rw-r--r--doc/src/animation.qdoc9
-rw-r--r--doc/src/diagrams/animations-architecture.svg351
-rw-r--r--doc/src/images/animations-architecture.pngbin0 -> 27619 bytes
-rw-r--r--src/corelib/animation/qparallelanimationgroup.cpp2
-rw-r--r--src/corelib/animation/qpauseanimation.cpp2
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp4
-rw-r--r--src/corelib/animation/qpropertyanimation_p.h1
-rw-r--r--src/corelib/animation/qvariantanimation.cpp85
-rw-r--r--src/corelib/animation/qvariantanimation_p.h4
-rw-r--r--tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp69
10 files changed, 478 insertions, 49 deletions
diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc
index 5eb2eda..b4e603c 100644
--- a/doc/src/animation.qdoc
+++ b/doc/src/animation.qdoc
@@ -64,7 +64,10 @@
We will in this section take a high-level look at the animation
framework's architecture and how it is used to animate Qt
- properties.
+ properties. The following diagram shows the most important classes
+ in the animation framework.
+
+ \image animations-architecture.png
The animation framework foundation consists of the base class
QAbstractAnimation, and its two subclasses QVariantAnimation and
@@ -268,10 +271,10 @@
\code
QPushButton *bonnie = new QPushButton("Bonnie");
- bonnie.show();
+ bonnie->show();
QPushButton *clyde = new QPushButton("Clyde");
- clyde.show();
+ clyde->show();
QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
// Set up anim1
diff --git a/doc/src/diagrams/animations-architecture.svg b/doc/src/diagrams/animations-architecture.svg
new file mode 100644
index 0000000..0246510
--- /dev/null
+++ b/doc/src/diagrams/animations-architecture.svg
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="950.00006"
+ height="365.28983"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="animations-architecture.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend"
+ style="overflow:visible">
+ <path
+ id="path3736"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
+ transform="scale(-0.6,-0.6)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lend"
+ style="overflow:visible">
+ <path
+ id="path3730"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible">
+ <path
+ id="path3712"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL"
+ style="overflow:visible">
+ <path
+ id="path3852"
+ d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="scale(0.8,0.8)" />
+ </marker>
+ <linearGradient
+ id="linearGradient3165">
+ <stop
+ style="stop-color:#c8c8dc;stop-opacity:1;"
+ offset="0"
+ id="stop3167" />
+ <stop
+ style="stop-color:#b4b4c8;stop-opacity:0;"
+ offset="1"
+ id="stop3169" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient3171"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-257.93754,-842.42203)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient3183"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-383.02298,-676.69717)"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient3191"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-382.93759,-1004.922)"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient7165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-483.69907,-593.77419)"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient7195"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-571.87523,-1167.422)"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="linearGradient7203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2195969,0,0,3.7006494,-572.46592,-841.2256)"
+ x1="249.25"
+ y1="89.862183"
+ x2="475.75"
+ y2="89.862183" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="276.75951"
+ inkscape:cy="155.06417"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:snap-bbox="true"
+ inkscape:window-width="1592"
+ inkscape:window-height="1124"
+ inkscape:window-x="0"
+ inkscape:window-y="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2383"
+ visible="true"
+ enabled="true"
+ units="pt"
+ spacingx="2pt"
+ spacingy="2pt" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-121.77519,-152.95286)">
+ <rect
+ style="opacity:1;fill:url(#linearGradient3171);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect2385"
+ width="49.409317"
+ height="277.54871"
+ x="-203.03828"
+ y="-648.64777"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="380.311"
+ y="185.86879"
+ id="text3173"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan3175"
+ x="380.311"
+ y="185.86879">QAbstractAnimation</tspan></text>
+ <rect
+ style="opacity:1;fill:url(#linearGradient3183);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3177"
+ width="49.409317"
+ height="277.54871"
+ x="-328.12369"
+ y="-482.92297"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="221.80489"
+ y="310.95419"
+ id="text3179"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan3181"
+ x="221.80489"
+ y="310.95419">QVariantAnimation</tspan></text>
+ <rect
+ style="opacity:1;fill:url(#linearGradient3191);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3185"
+ width="49.409317"
+ height="277.54871"
+ x="-328.03827"
+ y="-811.14777"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="564.13324"
+ y="310.86877"
+ id="text3187"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan3189"
+ x="564.13324"
+ y="310.86877">QAnimationGroup</tspan></text>
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 346.77519,279.39048 L 346.77519,241.89048 L 509.27519,241.89048 L 509.27519,204.39048"
+ id="path3195"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 671.77519,279.39048 L 671.77519,241.89048 L 509.27519,241.89048"
+ id="path7137"
+ sodipodi:nodetypes="ccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient7165);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect7159"
+ width="49.409317"
+ height="277.54871"
+ x="-428.7998"
+ y="-400"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="131.66315"
+ y="411.63031"
+ id="text7161"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan7163"
+ x="131.66315"
+ y="411.63031">QPropertyAnimation</tspan></text>
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 309.27519,379.39048 L 309.27519,329.39048"
+ id="path7167"
+ sodipodi:nodetypes="cc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient7195);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect7189"
+ width="49.409317"
+ height="375"
+ x="-516.97589"
+ y="-1071.0991"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="703.17139"
+ y="499.8064"
+ id="text7191"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan7193"
+ x="703.17139"
+ y="499.8064">QSequentialAnimationGroup</tspan></text>
+ <rect
+ style="opacity:1;fill:url(#linearGradient7203);fill-opacity:1;stroke:#202020;stroke-width:1.35220754;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect7197"
+ width="50"
+ height="350"
+ x="-517.56659"
+ y="-647.45129"
+ ry="12.582828"
+ rx="10.562523"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
+ x="306.46109"
+ y="500.39709"
+ id="text7199"
+ sodipodi:linespacing="100%"><tspan
+ sodipodi:role="line"
+ id="tspan7201"
+ x="306.46109"
+ y="500.39709">QParallelAnimationGroup</tspan></text>
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 859.27519,466.89048 L 859.27519,391.89048 L 671.77519,391.89048"
+ id="path7205"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;marker-mid:none;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 496.77519,466.89048 L 496.77519,391.89048 L 671.77519,391.89048 L 671.77519,329.39048"
+ id="path7207"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/doc/src/images/animations-architecture.png b/doc/src/images/animations-architecture.png
new file mode 100644
index 0000000..9b581af
--- /dev/null
+++ b/doc/src/images/animations-architecture.png
Binary files differ
diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp
index e4bce6a..48c8b3e 100644
--- a/src/corelib/animation/qparallelanimationgroup.cpp
+++ b/src/corelib/animation/qparallelanimationgroup.cpp
@@ -62,7 +62,7 @@
group->start();
\endcode
-
+
In this example, \c anim1 and \c anim2 are two
\l{QPropertyAnimation}s that have already been set up.
diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp
index 685fa98..c853745 100644
--- a/src/corelib/animation/qpauseanimation.cpp
+++ b/src/corelib/animation/qpauseanimation.cpp
@@ -52,7 +52,7 @@
\l{QAbstractAnimation::finished()}{finish} before a specified
number of milliseconds have elapsed from when it was started. You
specify the duration of the pause in the constructor. It can also
- be set directly with setDuration().
+ be set directly with setDuration().
It is not necessary to construct a QPauseAnimation yourself.
QSequentialAnimationGroup provides the convenience functions
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index 96cfa6b..1755aa7 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -48,14 +48,14 @@
QPropertyAnimation interpolates over \l{Qt's Property System}{Qt
properties}. As property values are stored in \l{QVariant}s, the
class inherits QVariantAnimation, and supports animation of the
- same \l{QVariant::Type}{variant types} as its super class.
+ same \l{QVariant::Type}{variant types} as its super class.
A class declaring properties must be a QObject. To make it
possible to animate a property, it must provide a setter (so that
QPropertyAnimation can set the property's value). Note that this
makes it possible to animate many of Qt's widgets. Let's look at
an example:
-
+
\code
QPropertyAnimation animation(myWidget, "geometry");
animation.setDuration(10000);
diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h
index ed3666d..9d9dd31 100644
--- a/src/corelib/animation/qpropertyanimation_p.h
+++ b/src/corelib/animation/qpropertyanimation_p.h
@@ -70,7 +70,6 @@ public:
{
}
-
QPointer<QObject> target;
//for the QProperty
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 73ed0df..157a321 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE
animates Qt \l{Qt's Property System}{properties}. See the
QPropertyAnimation class description if you wish to animate such
properties.
-
+
You can then set start and end values for the property by calling
setStartValue() and setEndValue(), and finally call start() to
start the animation. QVariantAnimation will interpolate the
@@ -111,12 +111,12 @@ QT_BEGIN_NAMESPACE
\o \l{QMetaType::}{QSizeF}
\o \l{QMetaType::}{QRect}
\o \l{QMetaType::}{QRectF}
- \endlist
+ \endlist
If you need to interpolate other variant types, including custom
types, you have to implement interpolation for these yourself.
You do this by reimplementing interpolated(), which returns
- interpolation values for the value being interpolated.
+ interpolation values for the value being interpolated.
\omit We need some snippets around here. \endomit
@@ -152,7 +152,7 @@ template<> Q_INLINE_TEMPLATE QRectF _q_interpolate(const QRectF &f, const QRectF
f.getRect(&x1, &y1, &w1, &h1);
qreal x2, y2, w2, h2;
t.getRect(&x2, &y2, &w2, &h2);
- return QRectF( _q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress),
+ return QRectF(_q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress),
_q_interpolate(w1, w2, progress), _q_interpolate(h1, h2, progress));
}
@@ -174,47 +174,61 @@ void QVariantAnimationPrivate::convertValues(int t)
if (pair.second.userType() != t)
pair.second.convert(static_cast<QVariant::Type>(t));
}
- currentInterval.start.first = 2; // this will force the refresh
- interpolator = 0; // if the type changed we need to update the interpolator
+ interpolator = 0; // if the type changed we need to update the interpolator
}
/*!
- \fn void QVariantAnimation::updateCurrentValue(const QVariant &value) = 0;
- This pure virtual function is called when the animated value is changed.
- \a value is the new value.
+ \internal
+ The goal of this function is to update the currentInterval member. As a consequence, we also
+ need to update the currentValue.
+ Set \a force to true to always recalculate the interval.
*/
-
-void QVariantAnimationPrivate::updateCurrentValue()
+void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/)
{
- Q_Q(QVariantAnimation);
+ // can't interpolate if we have only 1 key value
+ if (keyValues.count() <= 1)
+ return;
+
const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration)));
- if (progress < currentInterval.start.first || progress > currentInterval.end.first) {
+ if (force || progress < currentInterval.start.first || progress > currentInterval.end.first) {
//let's update currentInterval
- QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), keyValues.constEnd(), qMakePair(progress, QVariant()), animationValueLessThan);
+ QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(),
+ keyValues.constEnd(),
+ qMakePair(progress, QVariant()),
+ animationValueLessThan);
QVariantAnimation::KeyValues::const_iterator itEnd = itStart;
// If we are at the end we should continue to use the last keyValues in case of extrapolation (progress > 1.0).
// This is because the easing function can return a value slightly outside the range [0, 1]
if (itStart != keyValues.constEnd()) {
-
- //this can't happen because we always prepend the default start value there
- if (itStart == keyValues.begin()) {
+ // this can't happen because we always prepend the default start value there
+ if (itStart == keyValues.constBegin()) {
++itEnd;
- if (itEnd == keyValues.constEnd())
- return; //there is no upper bound
} else {
--itStart;
}
- //update all the values of the currentInterval
+ // update all the values of the currentInterval
currentInterval.start = *itStart;
currentInterval.end = *itEnd;
}
}
+ setCurrentValueForProgress(progress);
+}
+
+void QVariantAnimationPrivate::setCurrentValue()
+{
+ const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration)));
+ setCurrentValueForProgress(progress);
+}
- const qreal startProgress = currentInterval.start.first,
- endProgress = currentInterval.end.first;
+void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+{
+ Q_Q(QVariantAnimation);
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
QVariant ret = q->interpolated(currentInterval.start.second,
@@ -227,11 +241,10 @@ void QVariantAnimationPrivate::updateCurrentValue()
#endif
if (currentValue != ret) {
//the value has changed
- emit q->valueChanged(currentValue);
+ emit q->valueChanged(currentValue);
}
}
-
QVariant QVariantAnimationPrivate::valueAt(qreal step) const
{
QVariantAnimation::KeyValues::const_iterator result =
@@ -242,7 +255,6 @@ QVariant QVariantAnimationPrivate::valueAt(qreal step) const
return QVariant();
}
-
void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value)
{
if (step < qreal(0.0) || step > qreal(1.0)) {
@@ -257,15 +269,14 @@ void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value)
keyValues.insert(result, pair);
} else {
if (value.isValid())
- result->second = value; //remove the previous value
+ result->second = value; // replaces the previous value
else if (step == 0 && !hasStartValue && defaultStartValue.isValid())
- result->second = defaultStartValue; //we reset to the default start value
+ result->second = defaultStartValue; // resets to the default start value
else
- keyValues.erase(result); //replace the previous value
+ keyValues.erase(result); // removes the previous value
}
- currentInterval.start.first = 2; // this will force the refresh
- updateCurrentValue();
+ recalculateCurrentInterval(/*force=*/true);
}
void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value)
@@ -324,7 +335,7 @@ void QVariantAnimation::setEasingCurve(const QEasingCurve &easing)
{
Q_D(QVariantAnimation);
d->easing = easing;
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
Q_GLOBAL_STATIC(QVector<QVariantAnimation::Interpolator>, registeredInterpolators)
@@ -435,7 +446,7 @@ void QVariantAnimation::setDuration(int msecs)
if (d->duration == msecs)
return;
d->duration = msecs;
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
/*!
@@ -545,8 +556,8 @@ void QVariantAnimation::setKeyValues(const KeyValues &keyValues)
Q_D(QVariantAnimation);
d->keyValues = keyValues;
qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan);
- d->currentInterval.start.first = 2; // this will force the refresh
d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0;
+ d->recalculateCurrentInterval(/*force=*/true);
}
/*!
@@ -571,7 +582,7 @@ QVariant QVariantAnimation::currentValue() const
{
Q_D(const QVariantAnimation);
if (!d->currentValue.isValid())
- const_cast<QVariantAnimationPrivate*>(d)->updateCurrentValue();
+ const_cast<QVariantAnimationPrivate*>(d)->recalculateCurrentInterval();
return d->currentValue;
}
@@ -587,12 +598,10 @@ bool QVariantAnimation::event(QEvent *event)
\reimp
*/
void QVariantAnimation::updateState(QAbstractAnimation::State oldState,
- QAbstractAnimation::State newState)
+ QAbstractAnimation::State newState)
{
Q_UNUSED(oldState);
Q_UNUSED(newState);
- Q_D(QVariantAnimation);
- d->currentValue = QVariant(); // this will force the refresh
}
/*!
@@ -635,7 +644,7 @@ void QVariantAnimation::updateCurrentTime(int msecs)
{
Q_D(QVariantAnimation);
Q_UNUSED(msecs);
- d->updateCurrentValue();
+ d->recalculateCurrentInterval();
}
QT_END_NAMESPACE
diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h
index 14a3ef6..9e81649 100644
--- a/src/corelib/animation/qvariantanimation_p.h
+++ b/src/corelib/animation/qvariantanimation_p.h
@@ -108,7 +108,9 @@ public:
quint32 changedSignalMask;
- void updateCurrentValue();
+ void setCurrentValue();
+ void setCurrentValueForProgress(const qreal progress);
+ void recalculateCurrentInterval(bool force=false);
void setValueAt(qreal, const QVariant &);
QVariant valueAt(qreal step) const;
void convertValues(int t);
diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
index 2e5fd00..7e910d4 100644
--- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
+++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
@@ -42,6 +42,7 @@
#include <QtTest/QtTest>
#include <QtCore/qpropertyanimation.h>
+#include <QtCore/qvariantanimation.h>
#include <QtGui/qwidget.h>
//TESTED_CLASS=QPropertyAnimation
@@ -95,6 +96,8 @@ private slots:
void zeroDurationStart();
void operationsInStates_data();
void operationsInStates();
+ void oneKeyValue();
+ void updateOnSetKeyValues();
};
tst_QPropertyAnimation::tst_QPropertyAnimation()
@@ -794,9 +797,9 @@ void tst_QPropertyAnimation::operationsInStates()
* | pause() |start() |resume() |stop()
* ----------+------------+-----------+-----------+-------------------+
* Stopped | Stopped |Running |Stopped |Stopped |
- * _| qWarning | |qWarning |- |
+ * _| qWarning |restart |qWarning | |
* Paused | Paused |Running |Running |Stopped |
- * _| - | | | |
+ * _| | | | |
* Running | Paused |Running |Running |Stopped |
* | |restart |qWarning | |
* ----------+------------+-----------+-----------+-------------------+
@@ -850,5 +853,67 @@ void tst_QPropertyAnimation::operationsInStates()
#undef Resume
#undef Stop
+void tst_QPropertyAnimation::oneKeyValue()
+{
+ QObject o;
+ o.setProperty("ole", 42);
+ QCOMPARE(o.property("ole").toInt(), 42);
+
+ QPropertyAnimation animation(&o, "ole");
+ animation.setStartValue(43);
+ animation.setEndValue(44);
+ animation.setDuration(100);
+
+ animation.setCurrentTime(0);
+
+ QVERIFY(animation.currentValue().isValid());
+ QCOMPARE(animation.currentValue().toInt(), 43);
+ QCOMPARE(o.property("ole").toInt(), 42);
+
+ // remove the last key value
+ animation.setKeyValueAt(1.0, QVariant());
+
+ // we will neither interpolate, nor update the current value
+ // since there is only one 1 key value defined
+ animation.setCurrentTime(100);
+
+ // the animation should not have been modified
+ QVERIFY(animation.currentValue().isValid());
+ QCOMPARE(animation.currentValue().toInt(), 43);
+ QCOMPARE(o.property("ole").toInt(), 42);
+}
+
+void tst_QPropertyAnimation::updateOnSetKeyValues()
+{
+ QObject o;
+ o.setProperty("ole", 100);
+ QCOMPARE(o.property("ole").toInt(), 100);
+
+ QPropertyAnimation animation(&o, "ole");
+ animation.setStartValue(100);
+ animation.setEndValue(200);
+ animation.setDuration(100);
+
+ animation.setCurrentTime(50);
+ QCOMPARE(animation.currentValue().toInt(), 150);
+ animation.setKeyValueAt(0.0, 300);
+ QCOMPARE(animation.currentValue().toInt(), 250);
+
+ o.setProperty("ole", 100);
+ QPropertyAnimation animation2(&o, "ole");
+ QVariantAnimation::KeyValues kValues;
+ kValues << QVariantAnimation::KeyValue(0.0, 100) << QVariantAnimation::KeyValue(1.0, 200);
+ animation2.setKeyValues(kValues);
+ animation2.setDuration(100);
+ animation2.setCurrentTime(50);
+ QCOMPARE(animation2.currentValue().toInt(), 150);
+
+ kValues.clear();
+ kValues << QVariantAnimation::KeyValue(0.0, 300) << QVariantAnimation::KeyValue(1.0, 200);
+ animation2.setKeyValues(kValues);
+
+ QCOMPARE(animation2.currentValue().toInt(), animation.currentValue().toInt());
+}
+
QTEST_MAIN(tst_QPropertyAnimation)
#include "tst_qpropertyanimation.moc"