Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / doc / src / declarative / dynamicview-tutorial.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
13 ** this file.
14 **
15 ** Other Usage
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
18 ** and Nokia.
19 **
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29 \page qml-dynamicview-tutorial.html
30 \inqmlmodule QtQuick 2
31 \title QML Dynamic View Ordering Tutorial
32 \brief A tutorial describing how to re-arrange items in a QML ListView
33 \nextpage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
34
35 This tutorial shows how items in a ListView can be re-ordered without modifying the source model.
36 It demonstrates using drag and drop to reposition individual items within a view and using model
37 data to dynamically sort all items in a view.
38
39 Tutorial chapters:
40
41 \list 1
42 \o \l {declarative/tutorials/dynamicview/dynamicview1}{A Simple ListView and Delegate}
43 \o \l {declarative/tutorials/dynamicview/dynamicview2}{Dragging View Items}
44 \o \l {declarative/tutorials/dynamicview/dynamicview3}{Moving Dragged Items}
45 \o \l {declarative/tutorials/dynamicview/dynamicview4}{Sorting Items}
46 \endlist
47
48 All the code in this tutorial can be found in Qt's \c examples/declarative/tutorials/dynamicview
49 directory.
50 */
51
52 /*!
53 \page qml-dynamicview-tutorial1.html
54 \inqmlmodule QtQuick 2
55 \title QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
56 \contentspage QML Dynamic View Ordering Tutorial
57 \previouspage QML Dynamic View Ordering Tutorial
58 \nextpage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
59
60 \example declarative/tutorials/dynamicview/dynamicview1
61
62 We begin our application by defining a ListView, a model which will provide data to the view, and a
63 delegate which provides a template for constructing items in the view.
64
65 The code for the ListView and delegate looks like this:
66
67 \snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 0
68
69 The model is defined in a separate QML file which looks like this:
70
71 \snippet declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml 0
72 \snippet declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml 1
73
74 \section2 Walkthrough
75
76 The first item defined within the application's root Rectangle is the delegate Component.  This
77 is the template from which each item in the ListView is constructed.
78
79 The \c name, \c age, \c type, and \c size variables referenced in the delegate are sourced from
80 the model data.  The names correspond to roles defined in the model.
81
82 \snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 1
83
84 The second part of the application is the ListView itself to which we bind the model and delegate.
85
86 \snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 2
87 */
88
89 /*!
90 \page qml-dynamicview-tutorial2.html
91 \inqmlmodule QtQuick 2
92 \title QML Dynamic View Ordering Tutorial 2 - Dragging View Items
93 \contentspage QML Dynamic View Ordering Tutorial
94 \previouspage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
95 \nextpage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
96
97 \example declarative/tutorials/dynamicview/dynamicview2
98
99 Now that we have a visible list of items we want to be able to interact with them. We'll start
100 by extending the delegate so the visible content can be dragged up and down the screen.  The
101 updated delegate looks like this:
102
103 \snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 0
104
105 \section2 Walkthrough
106
107 The major change here is the root item of the delegate is now a MouseArea which provides handlers
108 for mouse events and will allow us to drag the delegate's content item.  It also acts as
109 a container for the content item which is important as a delegate's root item is positioned by
110 the view and cannot be moved by other means.
111
112 \snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 1
113 \snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 2
114
115 Dragging the content item is enabled by binding it to the MouseArea's
116 \l {QtQuick2::MouseArea::drag.target}{drag.target} property.  Because we still want the view to be
117 flickable we wait until the MouseArea's \l {QtQuick2::MouseArea::onPressAndHold}{onPressAndHold}
118 handler is triggered before binding the drag target. This way when mouse moves before the hold
119 timeout has expired it is interpreted as moving the list and if it moves after it is interpreted as
120 dragging an item.  To make it more obvious to the user when an item can be dragged we'll change the
121 background color of the content item when the timeout has expired.
122
123 \snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 3
124
125 The other thing we'll need to do before an item can be dragged is to unset any anchors on the
126 content item so it can be freely moved around.  We do this in a state change that is triggered
127 when the delegate item is held, at the same time we can reparent the content item to the root item
128 so that is above other items in the stacking order and isn't obscured as it is dragged around.
129
130 \snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 4
131
132 */
133
134 /*!
135 \page qml-dynamicview-tutorial3.html
136 \inqmlmodule QtQuick 2
137 \title QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
138 \contentspage QML Dynamic View Ordering Tutorial
139 \previouspage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
140 \nextpage QML Dynamic View Ordering Tutorial 4 - Sorting Items
141
142 \example declarative/tutorials/dynamicview/dynamicview3
143
144 The next step in our application to move items within the list as they're dragged so that we
145 can re-order the list.  To achieve this we introduce three new elements to our application;
146 VisualDataModel, \l Drag and DropArea.
147
148 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 0
149 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 1
150 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 2
151 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 5
152
153 \section2 Walkthrough
154
155 In order to re-order the view we need to determine when one item has been dragged over another. With
156 the Drag attached property we can generate events that are sent to the scene graph whenever the item
157 it is attached to moves.
158
159 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 1
160
161 Drag events are only sent while the active property is true, so in this example the first event
162 would be sent when the delegate was held with additional event sents when dragging.  The
163 \l {QtQuick2::Drag::hotSpot}{hotSpot} property specifies the relative position of the drag events
164 within the dragged item, the center of the item in this instance.
165
166 Then we use a DropArea in each view item to determine when the hot spot of the dragged item
167 intersects another item, when a drag enters one of these DropAreas we can move the dragged item
168 to the index of the item it was dragged over.
169
170 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 3
171
172 To move the items within the view we use a VisualDataModel.  The VisualDataModel element is used by
173 the view elements to instantiate delegate items from model data and when constructed explicitly can
174 be used to filter and re-order the model items provided to ListView.  The
175 \l {QtQuick2::VisualDataModel::items}{items} property of VisualDataModel provides access to the
176 view's items and allows us to change the visible order without modifying the source model.  To
177 determine the current visible index of the items we use \l {QtQuick2::VisualDataModel::itemsIndex}
178 {itemsIndex} property on the VisualDataModel attached property of the delegate item.
179
180 To utilize a VisualDataModel with a ListView we bind it to the \l {QtQuick2::ListView::model}{model}
181 property of the view and bind the \l {QtQuick2::VisualDataModel::model}{model} and
182 \l {QtQuick2::VisualDataModel::delegate}{delegate} to the VisualDataModel.
183
184 \snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 4
185
186 */
187
188 /*!
189 \page qml-dynamicview-tutorial4.html
190 \inqmlmodule QtQuick 2
191 \title QML Dynamic View Ordering Tutorial 4 - Sorting Items
192 \contentspage QML Dynamic View Ordering Tutorial
193 \previouspage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
194
195 \example declarative/tutorials/dynamicview/dynamicview4
196
197 Drag and drop isn't the only way items in a view can be re-ordered, using a VisualDataModel it is
198 also possible to sort items based on model data.  To do that we extend our VisualDataModel instance
199 like this:
200
201 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 0
202
203 \section2 Walkthrough
204
205 Items in a VisualDataModel are filtered into groups represented by the VisualDataGroup type,
206 normally all items in the model belong to a default \l {QtQuick2::VisualDataModel::items}{items}
207 group but this default can be changed with the includeByDefault property.  To implement our sorting
208 we want items to first be added to an unsorted group from where we can transfer them to a sorted
209 position in the items group.  To do that we clear includeByDefault on the items group and set it on
210 a new group name 'unsorted'.
211
212 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 1
213 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 2
214
215 We sort the items by first finding the position in the items group to insert the first unsorted
216 item and then transfer the item to the items group before moving it to the pre-determined index and
217 repeat until the unsorted group is empty.
218
219 To find the insert position for an item we request a handle for the item from the unsorted group
220 with the \l {QtQuick2::VisualDataModel::get} {get} function.  Through the model property on this
221 handle we can access the same model data that is available in a delegate instance of that item and
222 compare against other items to determine relative position.
223
224 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 3
225
226 The lessThan argument to the sort function is a comparsion function which will determine the order
227 of the list.  In this example it can be one of the following:
228
229 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 4
230
231 A sort is triggered whenever new items are added to the unsorted VisualDataGroup which we are
232 notified of by the \l {QtQuick2::VisualDataGroup::onChanged}{onChanged} handler.  If no sort
233 function is currently selected we simply transfer all items from the unsorted group to the items
234 group, otherwise we call sort with the selected sort function.
235
236 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 5
237
238 Finally when the selected sort order changes we can trigger a full re-sort of the list by moving
239 all items from the items group to the unsorted group, which will trigger the
240 \l {QtQuick2::VisualDataGroup::onChanged}{onChanged} handler and transfer the items back to the
241 items group in correct order.  Note that the \l {QtQuick2::VisualDataGroup::onChanged}{onChanged}
242 handler will not be invoked recursively so there's no issue with it being invoked during a sort.
243
244 \snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 6
245
246 */