dfdfc943c1c5abe7a6c89e3b7300caec7194a3b6
[profile/ivi/qtdeclarative.git] / doc / src / qtquick1 / behaviors-and-states.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the documentation of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:FDL$
10 ** GNU Free Documentation License
11 ** Alternatively, this file may be used under the terms of the GNU Free
12 ** Documentation License version 1.3 as published by the Free Software
13 ** Foundation and appearing in the file included in the packaging of
14 ** this file.
15 **
16 ** Other Usage
17 ** Alternatively, this file may be used in accordance with the terms
18 ** and conditions contained in a signed written agreement between you
19 ** and Nokia.
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29 \page qml-behaviors-and-states.html
30 \inqmlmodule QtQuick 1
31 \title Using QML Behaviors with States
32
33 \section1 Using Behaviors with States
34
35 In some cases you may choose to use a Behavior to animate a property change caused by a state change. While this works well for some situations, in other situations it may lead to unexpected behavior.
36
37 Here's an example that shows the problem:
38
39 \qml
40 import QtQuick 1.0
41
42 Rectangle {
43     width: 400
44     height: 400
45
46     Rectangle {
47         id: coloredRect
48         width: 100
49         height: 100
50         anchors.centerIn: parent
51
52         color: "red"
53         Behavior on color {
54             ColorAnimation {}
55         }
56
57         MouseArea {
58             id: mouser
59             anchors.fill: parent
60             hoverEnabled: true
61         }
62
63         states: State {
64             name: "GreenState"
65             when: mouser.containsMouse
66
67             PropertyChanges {
68                 target: coloredRect
69                 color: "green"
70             }
71         }
72     }
73 }
74 \endqml
75
76 Testing the example by quickly and repeatedly moving the mouse in to and out of the colored rectangle shows that the colored rectangle will settle into a green color over time, never returning to full red. This is not what we wanted! The
77 problem occurs because we have used a Behavior to animate the change in color, and our state change is trigged by the mouse entering or exiting the MouseArea, which is easily interrupted.
78
79 To state the problem more formally, using States and Behaviors together can cause unexpected behavior when:
80 \list
81 \o a Behavior is used to animate a property change, specifically when moving from an explicitly defined state back to the implicit base state; and
82 \o this Behavior can be interrupted to (re-)enter an explicitly defined state.
83 \endlist
84
85 The problem occurs because of the way the base state is defined for QML: as the "snapshot" state of the application just prior to entering an explicitly defined state. In this case, if we are in the process of animating from green back
86 to red, and interrupt the animation to return to "GreenState", the base state will include the color in its intermediate, mid-animation form.
87
88 While future versions of QML should be able to handle this situation more gracefully, there are currently several ways to rework your application to avoid this problem.
89
90 1. Use a transition to animate the change, rather than a Behavior.
91
92 \qml
93 import QtQuick 1.0
94
95 Rectangle {
96     width: 400
97     height: 400
98
99     Rectangle {
100         id: coloredRect
101         width: 100
102         height: 100
103         anchors.centerIn: parent
104
105         color: "red"
106
107         MouseArea {
108             id: mouser
109             anchors.fill: parent
110             hoverEnabled: true
111         }
112
113         states: State {
114             name: "GreenState"
115             when: mouser.containsMouse
116
117             PropertyChanges {
118                 target: coloredRect
119                 color: "green"
120             }
121         }
122
123         transitions: Transition {
124             ColorAnimation {}
125         }
126     }
127 }
128 \endqml
129
130 2. Use a conditional binding to change the property value, rather than a state
131
132 \qml
133 import QtQuick 1.0
134
135 Rectangle {
136     width: 400
137     height: 400
138
139     Rectangle {
140         id: coloredRect
141         width: 100
142         height: 100
143         anchors.centerIn: parent
144
145         color: mouser.containsMouse ? "green" : "red"
146         Behavior on color {
147             ColorAnimation {}
148         }
149
150         MouseArea {
151             id: mouser
152             anchors.fill: parent
153             hoverEnabled: true
154         }
155     }
156 }
157 \endqml
158
159 3. Use only explicitly defined states, rather than an implicit base state
160
161 \qml
162 import QtQuick 1.0
163
164 Rectangle {
165     width: 400
166     height: 400
167
168     Rectangle {
169         id: coloredRect
170         width: 100
171         height: 100
172         anchors.centerIn: parent
173
174         Behavior on color {
175             ColorAnimation {}
176         }
177
178         MouseArea {
179             id: mouser
180             anchors.fill: parent
181             hoverEnabled: true
182         }
183
184         states: [
185         State {
186             name: "GreenState"
187             when: mouser.containsMouse
188
189             PropertyChanges {
190                 target: coloredRect
191                 color: "green"
192             }
193         },
194         State {
195             name: "RedState"
196             when: !mouser.containsMouse
197
198             PropertyChanges {
199                 target: coloredRect
200                 color: "red"
201             }
202         }]
203     }
204 }
205 \endqml
206
207 */