Add a tutorial describing how to re-arrange items in a ListView.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Wed, 7 Dec 2011 03:03:08 +0000 (13:03 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 14 Dec 2011 05:23:57 +0000 (06:23 +0100)
This example describes both how to use drag and drop to re-order items
and how to use VisualDataGroup to sort a view using model data.

Change-Id: I034963ea87c8ab0c30555536ac28495a396c0577
Reviewed-by: Martin Jones <martin.jones@nokia.com>
doc/src/declarative/dynamicview-tutorial.qdoc [new file with mode: 0644]
doc/src/declarative/examples.qdoc
examples/declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview2/PetsModel.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview3/PetsModel.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview4/ListSelector.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview4/PetsModel.qml [new file with mode: 0644]
examples/declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml [new file with mode: 0644]

diff --git a/doc/src/declarative/dynamicview-tutorial.qdoc b/doc/src/declarative/dynamicview-tutorial.qdoc
new file mode 100644 (file)
index 0000000..0771165
--- /dev/null
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qml-dynamicview-tutorial.html
+\inqmlmodule QtQuick 2
+\title QML Dynamic View Ordering Tutorial
+\brief A tutorial describing how to re-arrange items in a QML ListView
+\nextpage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
+
+This tutorial shows how items in a ListView can be re-ordered without modifying the source model.
+It demonstrates using drag and drop to reposition individual items within a view and using model
+data to dynamically sort all items in a view.
+
+Tutorial chapters:
+
+\list 1
+\o \l {declarative/tutorials/dynamicview/dynamicview1}{A Simple ListView and Delegate}
+\o \l {declarative/tutorials/dynamicview/dynamicview2}{Dragging View Items}
+\o \l {declarative/tutorials/dynamicview/dynamicview3}{Moving Dragged Items}
+\o \l {declarative/tutorials/dynamicview/dynamicview4}{Sorting Items}
+\endlist
+
+All the code in this tutorial can be found in Qt's \c examples/declarative/tutorials/dynamicview
+directory.
+*/
+
+/*!
+\page qml-dynamicview-tutorial1.html
+\inqmlmodule QtQuick 2
+\title QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
+\contentspage QML Dynamic View Ordering Tutorial
+\previouspage QML Dynamic View Ordering Tutorial
+\nextpage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
+
+\example declarative/tutorials/dynamicview/dynamicview1
+
+We begin our application by defining a ListView, a model which will provide data to the view, and a
+delegate which provides a template for constructing items in the view.
+
+The code for the ListView and delegate looks like this:
+
+\snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 0
+
+The model is defined in a separate QML file which looks like this:
+
+\snippet declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml 0
+\snippet declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml 1
+
+\section2 Walkthrough
+
+The first item defined within the application's root Rectangle is the delegate Component.  This
+is the template from which each item in the ListView is constructed.
+
+The \c name, \c age, \c type, and \c size variables referenced in the delegate are sourced from
+the model data.  The names correspond to roles defined in the model.
+
+\snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 1
+
+The second part of the application is the ListView itself to which we bind the model and delegate.
+
+\snippet declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml 2
+*/
+
+/*!
+\page qml-dynamicview-tutorial2.html
+\inqmlmodule QtQuick 2
+\title QML Dynamic View Ordering Tutorial 2 - Dragging View Items
+\contentspage QML Dynamic View Ordering Tutorial
+\previouspage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
+\nextpage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
+
+\example declarative/tutorials/dynamicview/dynamicview2
+
+Now that we have a visible list of items we want to be able to interact with them. We'll start
+by extending the delegate so the visible content can be dragged up and down the screen.  The
+updated delegate looks like this:
+
+\snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 0
+
+\section2 Walkthrough
+
+The major change here is the root item of the delegate is now a MouseArea which provides handlers
+for mouse events and will allow us to drag the delegate's content item.  It also acts as
+a container for the content item which is important as a delegate's root item is positioned by
+the view and cannot be moved by other means.
+
+\snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 1
+\snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 2
+
+Dragging the content item is enabled by binding it to the MouseArea's
+\l {QtQuick2::MouseArea::drag.target}{drag.target} property.  Because we still want the view to be
+flickable we wait until the MouseArea's \l {QtQuick2::MouseArea::onPressAndHold}{onPressAndHold}
+handler is triggered before binding the drag target. This way when mouse moves before the hold
+timeout has expired it is interpreted as moving the list and if it moves after it is interpreted as
+dragging an item.  To make it more obvious to the user when an item can be dragged we'll change the
+background color of the content item when the timeout has expired.
+
+\snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 3
+
+The other thing we'll need to do before an item can be dragged is to unset any anchors on the
+content item so it can be freely moved around.  We do this in a state change that is triggered
+when the delegate item is held, at the same time we can reparent the content item to the root item
+so that is above other items in the stacking order and isn't obscured as it is dragged around.
+
+\snippet declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml 4
+
+*/
+
+/*!
+\page qml-dynamicview-tutorial3.html
+\inqmlmodule QtQuick 2
+\title QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
+\contentspage QML Dynamic View Ordering Tutorial
+\previouspage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
+\nextpage QML Dynamic View Ordering Tutorial 4 - Sorting Items
+
+\example declarative/tutorials/dynamicview/dynamicview3
+
+The next step in our application to move items within the list as they're dragged so that we
+can re-order the list.  To achieve this we introduce three new elements to our application;
+VisualDataModel, \l Drag and DropArea.
+
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 0
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 1
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 2
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 5
+
+\section2 Walkthrough
+
+In order to re-order the view we need to determine when one item has been dragged over another. With
+the Drag attached property we can generate events that are sent to the scene graph whenever the item
+it is attached to moves.
+
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 1
+
+Drag events are only sent while the active property is true, so in this example the first event
+would be sent when the delegate was held with additional event sents when dragging.  The
+\l {QtQuick2::Drag::hotSpot}{hotSpot} property specifies the relative position of the drag events
+within the dragged item, the center of the item in this instance.
+
+Then we use a DropArea in each view item to determine when the hot spot of the dragged item
+intersects another item, when a drag enters one of these DropAreas we can move the dragged item
+to the index of the item it was dragged over.
+
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 3
+
+To move the items within the view we use a VisualDataModel.  The VisualDataModel element is used by
+the view elements to instantiate delegate items from model data and when constructed explicitly can
+be used to filter and re-order the model items provided to ListView.  The
+\l {QtQuick2::VisualDataModel::items}{items} property of VisualDataModel provides access to the
+view's items and allows us to change the visible order without modifying the source model.  To
+determine the current visible index of the items we use \l {QtQuick2::VisualDataModel::itemsIndex}
+{itemsIndex} property on the VisualDataModel attached property of the delegate item.
+
+To utilize a VisualDataModel with a ListView we bind it to the \l {QtQuick2::ListView::model}{model}
+property of the view and bind the \l {QtQuick2::VisualDataModel::model}{model} and
+\l {QtQuick2::VisualDataModel::delegate}{delegate} to the VisualDataModel.
+
+\snippet declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml 4
+
+*/
+
+/*!
+\page qml-dynamicview-tutorial4.html
+\inqmlmodule QtQuick 2
+\title QML Dynamic View Ordering Tutorial 4 - Sorting Items
+\contentspage QML Dynamic View Ordering Tutorial
+\previouspage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
+
+\example declarative/tutorials/dynamicview/dynamicview4
+
+Drag and drop isn't the only way items in a view can be re-ordered, using a VisualDataModel it is
+also possible to sort items based on model data.  To do that we extend our VisualDataModel instance
+like this:
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 0
+
+\section2 Walkthrough
+
+Items in a VisualDataModel are filtered into groups represented by the VisualDataGroup type,
+normally all items in the model belong to a default \l {QtQuick2::VisualDataModel::items}{items}
+group but this default can be changed with the includeByDefault property.  To implement our sorting
+we want items to first be added to an unsorted group from where we can transfer them to a sorted
+position in the items group.  To do that we clear includeByDefault on the items group and set it on
+a new group name 'unsorted'.
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 1
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 2
+
+We sort the items by first finding the position in the items group to insert the first unsorted
+item and then transfer the item to the items group before moving it to the pre-determined index and
+repeat until the unsorted group is empty.
+
+To find the insert position for an item we request a handle for the item from the unsorted group
+with the \l {QtQuick2::VisualDataModel::get} {get} function.  Through the model property on this
+handle we can access the same model data that is available in a delegate instance of that item and
+compare against other items to determine relative position.
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 3
+
+The lessThan argument to the sort function is a comparsion function which will determine the order
+of the list.  In this example it can be one of the following:
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 4
+
+A sort is triggered whenever new items are added to the unsorted VisualDataGroup which we are
+notified of by the \l {QtQuick2::VisualDataGroup::onChanged}{onChanged} handler.  If no sort
+function is currently selected we simply transfer all items from the unsorted group to the items
+group, otherwise we call sort with the selected sort function.
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 5
+
+Finally when the selected sort order changes we can trigger a full re-sort of the list by moving
+all items from the items group to the unsorted group, which will trigger the
+\l {QtQuick2::VisualDataGroup::onChanged}{onChanged} handler and transfer the items back to the
+items group in correct order.  Note that the \l {QtQuick2::VisualDataGroup::onChanged}{onChanged}
+handler will not be invoked recursively so there's no issue with it being invoked during a sort.
+
+\snippet declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml 6
+
+*/
index 9f67b72..198ef75 100644 (file)
@@ -107,7 +107,6 @@ can be used to produce sophisticated interfaces and applications:
 
 \endtable
 
-
 \section1 Code Snippets
 
 These QML examples are small, simple applications that show how to use a particular
@@ -241,5 +240,14 @@ to QML, you may also find the \l{QML Tutorial}{Hello World} and
 \o \l{src/imports/folderlistmodel}{Folder List Model} - a C++ model plugin
 \endlist
 
+\section1 Tutorials
+
+\list
+\o \l {QML Tutorial}{Hello World}
+\o \l {QML Advanced Tutorial}{Same Game}
+\o \l {Tutorial: Writing QML Extensions with C++}{Writing QML Extensions with C++}
+\o \l {QML Dynamic View Ordering Tutorial}{Dynamic View Ordering}
+\endlist
+
 */
 
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml b/examples/declarative/tutorials/dynamicview/dynamicview1/PetsModel.qml
new file mode 100644 (file)
index 0000000..dbe273a
--- /dev/null
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![0]
+import QtQuick 2.0
+
+ListModel {
+    ListElement {
+        name: "Polly"
+        type: "Parrot"
+        age: 12
+        size: "Small"
+    }
+    ListElement {
+        name: "Penny"
+        type: "Turtle"
+        age: 4
+        size: "Small"
+    }
+//![0]
+    ListElement {
+        name: "Warren"
+        type: "Rabbit"
+        age: 2
+        size: "Small"
+    }
+    ListElement {
+        name: "Spot"
+        type: "Dog"
+        age: 9
+        size: "Medium"
+    }
+    ListElement {
+        name: "Schrödinger"
+        type: "Cat"
+        age: 2
+        size: "Medium"
+    }
+    ListElement {
+        name: "Joey"
+        type: "Kangaroo"
+        age: 1
+        size: "Medium"
+    }
+    ListElement {
+        name: "Kimba"
+        type: "Bunny"
+        age: 65
+        size: "Large"
+    }
+    ListElement {
+        name: "Rover"
+        type: "Dog"
+        age: 5
+        size: "Large"
+    }
+    ListElement {
+        name: "Tiny"
+        type: "Elephant"
+        age: 15
+        size: "Large"
+    }
+//![1]
+}
+//![1]
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml b/examples/declarative/tutorials/dynamicview/dynamicview1/dynamicview.qml
new file mode 100644 (file)
index 0000000..a316ee6
--- /dev/null
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![0]
+import QtQuick 2.0
+
+Rectangle {
+    id: root
+
+    width: 300; height: 400
+
+//![1]
+    Component {
+        id: dragDelegate
+
+        Rectangle {
+            id: content
+
+            anchors { left: parent.left; right: parent.right }
+            height: column.implicitHeight + 4
+
+            border.width: 1
+            border.color: "lightsteelblue"
+
+            radius: 2
+
+            Column {
+                id: column
+                anchors { fill: parent; margins: 2 }
+
+                Text { text: 'Name: ' + name }
+                Text { text: 'Type: ' + type }
+                Text { text: 'Age: ' + age }
+                Text { text: 'Size: ' + size }
+            }
+        }
+    }
+//![1]
+//![2]
+    ListView {
+        id: view
+
+        anchors { fill: parent; margins: 2 }
+
+        model: PetsModel {}
+        delegate: dragDelegate
+
+        spacing: 4
+        cacheBuffer: 50
+    }
+//![2]
+}
+//![0]
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview2/PetsModel.qml b/examples/declarative/tutorials/dynamicview/dynamicview2/PetsModel.qml
new file mode 100644 (file)
index 0000000..e55d274
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ListModel {
+    ListElement {
+        name: "Polly"
+        type: "Parrot"
+        age: 12
+        size: "Small"
+    }
+    ListElement {
+        name: "Penny"
+        type: "Turtle"
+        age: 4
+        size: "Small"
+    }
+    ListElement {
+        name: "Warren"
+        type: "Rabbit"
+        age: 2
+        size: "Small"
+    }
+    ListElement {
+        name: "Spot"
+        type: "Dog"
+        age: 9
+        size: "Medium"
+    }
+    ListElement {
+        name: "Schrödinger"
+        type: "Cat"
+        age: 2
+        size: "Medium"
+    }
+    ListElement {
+        name: "Joey"
+        type: "Kangaroo"
+        age: 1
+        size: "Medium"
+    }
+    ListElement {
+        name: "Kimba"
+        type: "Bunny"
+        age: 65
+        size: "Large"
+    }
+    ListElement {
+        name: "Rover"
+        type: "Dog"
+        age: 5
+        size: "Large"
+    }
+    ListElement {
+        name: "Tiny"
+        type: "Elephant"
+        age: 15
+        size: "Large"
+    }
+}
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml b/examples/declarative/tutorials/dynamicview/dynamicview2/dynamicview.qml
new file mode 100644 (file)
index 0000000..b084d63
--- /dev/null
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+    id: root
+
+    width: 300; height: 400
+
+//![0]
+    Component {
+        id: dragDelegate
+
+//![1]
+        MouseArea {
+            id: dragArea
+
+            property bool held: false
+
+            anchors { left: parent.left; right: parent.right }
+            height: content.height
+
+            drag.target: held ? content : undefined
+            drag.axis: Drag.YAxis
+
+            onPressAndHold: held = true
+            onReleased: held = false
+
+            Rectangle {
+                id: content
+//![1]
+                anchors {
+                    horizontalCenter: parent.horizontalCenter
+                    verticalCenter: parent.verticalCenter
+                }
+                width: dragArea.width; height: column.implicitHeight + 4
+
+                border.width: 1
+                border.color: "lightsteelblue"
+//![3]
+                color: dragArea.held ? "lightsteelblue" : "white"
+                Behavior on color { ColorAnimation { duration: 100 } }
+//![3]
+                radius: 2
+//![4]
+                states: State {
+                    when: dragArea.held
+
+                    ParentChange { target: content; parent: root }
+                    AnchorChanges {
+                        target: content
+                        anchors { horizontalCenter: undefined; verticalCenter: undefined }
+                    }
+                }
+//![4]
+                Column {
+                    id: column
+                    anchors { fill: parent; margins: 2 }
+
+                    Text { text: 'Name: ' + name }
+                    Text { text: 'Type: ' + type }
+                    Text { text: 'Age: ' + age }
+                    Text { text: 'Size: ' + size }
+                }
+//![2]
+            }
+        }
+//![2]
+    }
+//![0]
+
+    ListView {
+        id: view
+
+        anchors { fill: parent; margins: 2 }
+
+        model: PetsModel {}
+        delegate: dragDelegate
+
+        spacing: 4
+        cacheBuffer: 50
+    }
+}
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview3/PetsModel.qml b/examples/declarative/tutorials/dynamicview/dynamicview3/PetsModel.qml
new file mode 100644 (file)
index 0000000..e55d274
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ListModel {
+    ListElement {
+        name: "Polly"
+        type: "Parrot"
+        age: 12
+        size: "Small"
+    }
+    ListElement {
+        name: "Penny"
+        type: "Turtle"
+        age: 4
+        size: "Small"
+    }
+    ListElement {
+        name: "Warren"
+        type: "Rabbit"
+        age: 2
+        size: "Small"
+    }
+    ListElement {
+        name: "Spot"
+        type: "Dog"
+        age: 9
+        size: "Medium"
+    }
+    ListElement {
+        name: "Schrödinger"
+        type: "Cat"
+        age: 2
+        size: "Medium"
+    }
+    ListElement {
+        name: "Joey"
+        type: "Kangaroo"
+        age: 1
+        size: "Medium"
+    }
+    ListElement {
+        name: "Kimba"
+        type: "Bunny"
+        age: 65
+        size: "Large"
+    }
+    ListElement {
+        name: "Rover"
+        type: "Dog"
+        age: 5
+        size: "Large"
+    }
+    ListElement {
+        name: "Tiny"
+        type: "Elephant"
+        age: 15
+        size: "Large"
+    }
+}
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml b/examples/declarative/tutorials/dynamicview/dynamicview3/dynamicview.qml
new file mode 100644 (file)
index 0000000..86f8014
--- /dev/null
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+//![0]
+Rectangle {
+    id: root
+
+    width: 300; height: 400
+
+    Component {
+        id: dragDelegate
+
+        MouseArea {
+            id: dragArea
+
+            property bool held: false
+
+            anchors { left: parent.left; right: parent.right }
+            height: content.height
+
+            drag.target: held ? content : undefined
+            drag.axis: Drag.YAxis
+
+            onPressAndHold: held = true
+            onReleased: held = false
+
+            Rectangle {
+                id: content
+//![0]
+                anchors {
+                    horizontalCenter: parent.horizontalCenter
+                    verticalCenter: parent.verticalCenter
+                }
+                width: dragArea.width; height: column.implicitHeight + 4
+
+                border.width: 1
+                border.color: "lightsteelblue"
+
+                color: dragArea.held ? "lightsteelblue" : "white"
+                Behavior on color { ColorAnimation { duration: 100 } }
+
+                radius: 2
+//![1]
+                Drag.active: dragArea.held
+                Drag.source: dragArea
+                Drag.hotSpot.x: width / 2
+                Drag.hotSpot.y: height / 2
+//![1]
+                states: State {
+                    when: dragArea.held
+
+                    ParentChange { target: content; parent: root }
+                    AnchorChanges {
+                        target: content
+                        anchors { horizontalCenter: undefined; verticalCenter: undefined }
+                    }
+                }
+
+                Column {
+                    id: column
+                    anchors { fill: parent; margins: 2 }
+
+                    Text { text: 'Name: ' + name }
+                    Text { text: 'Type: ' + type }
+                    Text { text: 'Age: ' + age }
+                    Text { text: 'Size: ' + size }
+                }
+//![2]
+            }
+//![3]
+            DropArea {
+                anchors { fill: parent; margins: 10 }
+
+                onEntered: {
+                    visualModel.items.move(
+                            drag.source.VisualDataModel.itemsIndex,
+                            dragArea.VisualDataModel.itemsIndex)
+                }
+            }
+//![3]
+        }
+    }
+//![2]
+//![4]
+    VisualDataModel {
+        id: visualModel
+
+        model: PetsModel {}
+        delegate: dragDelegate
+    }
+
+    ListView {
+        id: view
+
+        anchors { fill: parent; margins: 2 }
+
+        model: visualModel
+
+        spacing: 4
+        cacheBuffer: 50
+    }
+//![4]
+//![5]
+}
+//![5]
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview4/ListSelector.qml b/examples/declarative/tutorials/dynamicview/dynamicview4/ListSelector.qml
new file mode 100644 (file)
index 0000000..6881714
--- /dev/null
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+    id: selector
+
+    property alias list: view.model
+    property alias selectedIndex: view.currentIndex
+    property alias label: labelText.text
+    property bool expanded
+
+    width: 100; height: labelText.implicitHeight + 26
+
+    Rectangle {
+        anchors { left: parent.left; right: parent.right; bottom: parent.bottom; }
+
+        height: labelText.implicitHeight + 4 + (expanded ? 20 * view.count : 20)
+        Behavior on height { NumberAnimation { duration: 300 } }
+
+        radius: 2
+        border.width: 1
+        border.color: "yellow"
+        color: "yellow"
+
+        MouseArea {
+            anchors.fill: parent
+
+            onClicked: selector.expanded = !selector.expanded
+
+            Text {
+                id: labelText
+                anchors { left: parent.left; top: parent.top; margins: 2 }
+            }
+
+            Rectangle {
+                anchors {
+                    left: parent.left; top: labelText.bottom;
+                    right: parent.right; bottom: parent.bottom;
+                    margins: 2
+                    leftMargin: 10
+                }
+
+                radius: 2
+                color: "white"
+
+                ListView {
+                    id: view
+
+                    anchors.fill: parent
+
+                    clip: true
+
+                    delegate: Text {
+                        anchors { left: parent.left; right: parent.right }
+                        height: 20
+
+                        verticalAlignment: Text.AlignVCenter
+
+                        text: modelData
+
+                        MouseArea {
+                            anchors.fill: parent
+
+                            onClicked: {
+                                view.currentIndex = index
+                                selector.expanded = !selector.expanded
+                            }
+                        }
+                    }
+                    highlight: Rectangle {
+                        anchors { left: parent.left; right: parent.right }
+                        height: 20
+                        radius: 2
+
+                        color: "yellow"
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview4/PetsModel.qml b/examples/declarative/tutorials/dynamicview/dynamicview4/PetsModel.qml
new file mode 100644 (file)
index 0000000..e55d274
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ListModel {
+    ListElement {
+        name: "Polly"
+        type: "Parrot"
+        age: 12
+        size: "Small"
+    }
+    ListElement {
+        name: "Penny"
+        type: "Turtle"
+        age: 4
+        size: "Small"
+    }
+    ListElement {
+        name: "Warren"
+        type: "Rabbit"
+        age: 2
+        size: "Small"
+    }
+    ListElement {
+        name: "Spot"
+        type: "Dog"
+        age: 9
+        size: "Medium"
+    }
+    ListElement {
+        name: "Schrödinger"
+        type: "Cat"
+        age: 2
+        size: "Medium"
+    }
+    ListElement {
+        name: "Joey"
+        type: "Kangaroo"
+        age: 1
+        size: "Medium"
+    }
+    ListElement {
+        name: "Kimba"
+        type: "Bunny"
+        age: 65
+        size: "Large"
+    }
+    ListElement {
+        name: "Rover"
+        type: "Dog"
+        age: 5
+        size: "Large"
+    }
+    ListElement {
+        name: "Tiny"
+        type: "Elephant"
+        age: 15
+        size: "Large"
+    }
+}
diff --git a/examples/declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml b/examples/declarative/tutorials/dynamicview/dynamicview4/dynamicview.qml
new file mode 100644 (file)
index 0000000..ae16c78
--- /dev/null
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+    id: root
+
+    width: 300; height: 400
+
+    Component {
+        id: dragDelegate
+
+        MouseArea {
+            id: dragArea
+
+            property bool held: false
+
+            anchors { left: parent.left; right: parent.right }
+            height: content.height
+
+            enabled: visualModel.sortOrder == visualModel.lessThan.length
+
+            drag.target: held ? content : undefined
+            drag.axis: Drag.YAxis
+
+            onPressAndHold: held = true
+            onReleased: held = false
+
+            Rectangle {
+                id: content
+
+                anchors {
+                    horizontalCenter: parent.horizontalCenter
+                    verticalCenter: parent.verticalCenter
+                }
+                width: dragArea.width; height: column.implicitHeight + 4
+
+                border.width: 1
+                border.color: "lightsteelblue"
+
+                color: dragArea.held ? "lightsteelblue" : "white"
+                Behavior on color { ColorAnimation { duration: 100 } }
+
+                radius: 2
+
+                Drag.active: dragArea.held
+                Drag.source: dragArea
+                Drag.hotSpot.x: width / 2
+                Drag.hotSpot.y: height / 2
+
+                states: State {
+                    when: dragArea.held
+
+                    ParentChange { target: content; parent: root }
+                    AnchorChanges {
+                        target: content
+                        anchors { horizontalCenter: undefined; verticalCenter: undefined }
+                    }
+                }
+
+                Column {
+                    id: column
+                    anchors { fill: parent; margins: 2 }
+
+                    Text { text: 'Name: ' + name }
+                    Text { text: 'Type: ' + type }
+                    Text { text: 'Age: ' + age }
+                    Text { text: 'Size: ' + size }
+                }
+            }
+
+            DropArea {
+                anchors { fill: parent; margins: 10 }
+
+                onEntered: {
+                    visualModel.items.move(
+                            drag.source.VisualDataModel.itemsIndex,
+                            dragArea.VisualDataModel.itemsIndex)
+                }
+            }
+        }
+    }
+//![0]
+    VisualDataModel {
+        id: visualModel
+//![4]
+        property var lessThan: [
+            function(left, right) { return left.name < right.name },
+            function(left, right) { return left.type < right.type },
+            function(left, right) { return left.age < right.age },
+            function(left, right) {
+                if (left.size == "Small")
+                    return true
+                else if (right.size == "Small")
+                    return false
+                else if (left.size == "Medium")
+                    return true
+                else
+                    return false
+            }
+        ]
+//![4]
+//![6]
+
+        property int sortOrder: orderSelector.selectedIndex
+        onSortOrderChanged: items.setGroups(0, items.count, "unsorted")
+
+//![6]
+//![3]
+        function insertPosition(lessThan, item) {
+            var lower = 0
+            var upper = items.count
+            while (lower < upper) {
+                var middle = Math.floor(lower + (upper - lower) / 2)
+                var result = lessThan(item.model, items.get(middle).model);
+                if (result) {
+                    upper = middle
+                } else {
+                    lower = middle + 1
+                }
+            }
+            return lower
+        }
+
+        function sort(lessThan) {
+            while (unsortedItems.count > 0) {
+                var item = unsortedItems.get(0)
+                var index = insertPosition(lessThan, item)
+
+                item.groups = "items"
+                items.move(item.itemsIndex, index)
+            }
+        }
+//![3]
+
+//![1]
+        items.includeByDefault: false
+//![5]
+        groups: VisualDataGroup {
+            id: unsortedItems
+            name: "unsorted"
+
+            includeByDefault: true
+//![1]
+            onChanged: {
+                if (visualModel.sortOrder == visualModel.lessThan.length)
+                    setGroups(0, count, "items")
+                else
+                    visualModel.sort(visualModel.lessThan[visualModel.sortOrder])
+            }
+//![2]
+        }
+//![2]
+//![5]
+        model: PetsModel {}
+        delegate: dragDelegate
+    }
+//![0]
+    ListView {
+        id: view
+
+        anchors {
+            left: parent.left; top: parent.top; right: parent.right; bottom: orderSelector.top;
+            margins: 2
+        }
+
+        model: visualModel
+
+        spacing: 4
+        cacheBuffer: 50
+    }
+
+    ListSelector {
+        id: orderSelector
+
+        anchors { left: parent.left; right: parent.right; bottom: parent.bottom; margins: 2 }
+
+        label: "Sort By"
+        list: [ "Name", "Type", "Age", "Size", "Custom" ]
+    }
+}