[Qt-qml] Behavior vs. Follow - 4:1
Matthias Ettrich
matthias.ettrich at nokia.com
Tue Jun 29 12:59:37 CEST 2010
Hi,
here's a summary from an irc discussion on the topic of Behavior vs. Follow.
Thesis: Follow is not needed, Behavior does all we need and more.
Consequence: Now that we have SmoothAnimation, all we need is SpringAnimation
and then we can depricate and remove all follows (SpringFollow and
SmoothFollow).
A Behavior is a QDeclarativePropertyValueInterceptor and thus a very nice
abstraction to what a follow does.
In the dial example Dial.qml, instead of doing
angle: -130
SpringFollow on angle {
spring: 1.4
damping: .15
to: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
}
we would simply do
angle: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
Behavior {
SpringAnimation{ spring: 1.4; damping: .15 }
}
There are several advantages of the behaviour approach:
1. the property value is written as declarative binding, the behavior comes
simply in addition to that. The logic of the code does not change.
2. when you disable the behaviour object, the animation goes away, but the
property still changes value. When you disable a follow object, the value does
not change anymore. This is where people hack with duration:0 or by setting
both the to-property of the follow object *and* the property (see same game)
I looked at the example which used follows and found they could all be written
nicer with behaviours. Attached is a patch for the clocks toy and for the same
game (which still lacks SpringAnimation).
There's one small corner case where the follow-approach had an advantage,
although we haven't found a true use case yet which didn't have a different
solution: follow makes it possible to apply a different initial value to the
property and to the follow's to-property, thus it can give you an initial
startup animation.
This has been used in the clocks example, where my patch shows, that you can
solve it differently. The behaviour version initially animates from the
initial values of the hours/minutes/seconds properties to the current time.
In the general case, where you do not have a timer, you can solve this the
following way:
1. declare the property value where the animation should start
2. change it to whatever you like in a Component.onCompleted-handler.
Example:
Item {
property int prop: <pre_initial_value>
Behaviour on prop{ <funky animation> }
Component.onCompleted: prop = <initial_value>
}
Alternatively, and probably nicer, you can declare the initial value in a
different state "Initial" and simply do
Component.onCompleted: state = "Initial"
To me the onCompleted-approach is appropriate, given that the usecase seems
rather esoteric.
Main advantage for the follow-removal: no more asymetric API, simpler API,
more exposure to the great and flexible Behavior.
Matthias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clocks.patch
Type: text/x-patch
Size: 2546 bytes
Desc: not available
Url : http://lists.qt.nokia.com/pipermail/qt-qml/attachments/20100629/6854a3b0/attachment.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: samegame.patch
Type: text/x-patch
Size: 2530 bytes
Desc: not available
Url : http://lists.qt.nokia.com/pipermail/qt-qml/attachments/20100629/6854a3b0/attachment-0001.bin
More information about the Qt-qml
mailing list