summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Walters <ian.walters@nokia.com>2009-04-23 00:53:12 (GMT)
committerIan Walters <ian.walters@nokia.com>2009-04-23 00:53:12 (GMT)
commit49256dbed86b2ad2fde52c45808ab9ddd7159506 (patch)
tree2d6e8e2d89451ad45eefe36f81bcc4568fca11fc
parentf2c5ea07b2ed5f96bd32f9a1d71ec9613c240fa6 (diff)
downloadQt-49256dbed86b2ad2fde52c45808ab9ddd7159506.zip
Qt-49256dbed86b2ad2fde52c45808ab9ddd7159506.tar.gz
Qt-49256dbed86b2ad2fde52c45808ab9ddd7159506.tar.bz2
Continuing tutorial
Start of qdoc componenet relating to example files. Also removed t8 and replaced with Final, which will represent the final 'application', and not necissarily in terms of minor stages. However difference that will be useful or confusing to the user will still be highlighted, just not in the progressive manor of the rest of the tutorial Scheduled for review when complete.
-rw-r--r--doc/src/tutorials/kinetic.qdoc446
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml (renamed from examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_an_animation.qml)0
-rw-r--r--examples/declarative/tutorials/contacts/Final/Button.qml (renamed from examples/declarative/tutorials/contacts/t8/Button.qml)11
-rw-r--r--examples/declarative/tutorials/contacts/Final/Contact.qml57
-rw-r--r--examples/declarative/tutorials/contacts/Final/ContactField.qml36
-rw-r--r--examples/declarative/tutorials/contacts/Final/ContactView2.qml62
-rw-r--r--examples/declarative/tutorials/contacts/Final/FieldText.qml98
-rw-r--r--examples/declarative/tutorials/contacts/Final/RemoveButton.qml80
-rw-r--r--examples/declarative/tutorials/contacts/Final/SearchBar.qml18
-rw-r--r--examples/declarative/tutorials/contacts/Final/contacts.qml148
-rw-r--r--examples/declarative/tutorials/contacts/t8/Contact.qml80
-rw-r--r--examples/declarative/tutorials/contacts/t8/Field.qml54
-rw-r--r--examples/declarative/tutorials/contacts/t8/FieldRemover.qml57
-rw-r--r--examples/declarative/tutorials/contacts/t8/FieldText.qml89
-rw-r--r--examples/declarative/tutorials/contacts/t8/SearchBar.qml16
-rw-r--r--examples/declarative/tutorials/contacts/t8/contacts.qml133
16 files changed, 953 insertions, 432 deletions
diff --git a/doc/src/tutorials/kinetic.qdoc b/doc/src/tutorials/kinetic.qdoc
new file mode 100644
index 0000000..549161c
--- /dev/null
+++ b/doc/src/tutorials/kinetic.qdoc
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page tutorials-kinetic-contacts.html
+ \startpage {index.html}{Qt Reference Documentation}
+ \nextpage {tutorials/kinetic-contacts/part1}{Chapter 1}
+
+ \title Kinetic Contacts application tutorial.
+ \ingroup howto
+ \ingroup tutorials
+ \brief An introduction to using Qt Declarative UI to put together a
+ simple animated application.
+
+ \omit
+ At the time of writing the tutorial Declarative UI was still under
+ development. It is extremely likely that an update will be required
+ prior to 4.6 release.
+ \endomit
+
+ This tutorial gives an introduction to using the Qt Declarative UI
+ animation framework.
+
+ In this process we will learn about some of the basics of using
+ Declarative UI, such as
+
+ \list
+ \o Basic drawing
+ \o States and Transitions
+ \o Reuse of components
+ \o Models and Views
+ \endlist
+
+ An existing knowledge of Qt is not required.
+
+ The tutorial's source code is located in Qt's
+ \c examples/declarative/tutorials/contacts directory.
+ It is split up into a number of sub directories, and within each
+ sub directory the files are numbered in an order of increasing features.
+
+ The code in this example is not compiled, but interpreted at run time.
+ This means you should use the duiviewer application provided with
+ Qt to run the examples.
+
+ \list 1
+ \o \l{tutorials/declarative/contacts/part1}{Drawing and animation}
+ \o \l{tutorials/declarative/contacts/part2}{Reuse of QML components}
+ \o \l{tutorials/declarative/contacts/part3}{Models, Views and Delegates}
+ \o \l{tutorials/declarative/contacts/part4}{Other Tricks}
+ \endlist
+*/
+
+/*!
+ \page tutorials-declarative-contacts-part1.html
+ \contentspage {Declarative UI Tutorial}{Contents}
+ \nextpage {tutorials/declarative/contacts/part2}{Chapter 2}
+ \example tutorials/declarative/contacts/1_Drawing_and_Animation
+ \title Declarative UI 1 - Drawing and Animation
+
+ The first part of this tutorial covers basic drawing of elements on the
+ screen and causing them to animate. The file 1_Drawing_and_Animation.qml
+ loads and displays each of the five stages of this tutorial in a single
+ window. For now you don't need to worry about the contents of
+ 1_Drawing_and_Animation.qml.
+
+ \section1 Drawing
+
+ In this first chapter we will build a button that indicates something
+ can be removed and asks for confirmation. When clicked it will expand
+ from a small button with a trash can icon, to a wide button with a
+ confirm icon on the left, the text "Remove" in the middle, and a
+ cancel icon on the right.
+
+ Because Declarative UI is declarative, you don't pass instructions on
+ what to paint in a sequential manner as you may be used to. Instead
+ elements and how they appear on the screen are declared in much the
+ same was as elements on a web page are declared.
+
+ \i RemoveButton1.qml
+ \code
+ <Rect id="removeButton"
+ width="30" height="30"
+ color="red"
+ radius="5"/>
+ \endcode
+
+ This is the simplest of QML components. It describes a rectangle with
+ some simple properties. In QML all components start with a capital
+ letter, and their properties with lower case letters. Properties
+ can either be declared as XML attributes or as children of the
+ component element. The above rectangle could equally be written
+
+ \code
+ <Rect id="removeButton" color="red">
+ <width>30</width>
+ <height>30</height>
+ <radius>5</radius>
+ </Rect>
+ \endcode
+
+ The rectangle component is one of the more simple QML components. Apart
+ from the properties all QML components share, it has the properties
+
+ \list
+ \o color - The background color of the rectangle
+ \o tintColor - The overlay color of the rectangle
+ \o gradientColor - The color at the base of the rectangle to blend upwards
+ \o pen - The description of how to draw the border of the rectangle
+ \o radius - The corner radius used to draw rounded rectangles.
+ \endlist
+
+ \omit
+ For more information on the Rect element, see: TODO
+ \endomit
+
+ There are also a number of properties all QML components share. To see
+ a full description of the base QML item, see {QFxItem}. The rectangle
+ drawn in the above code uses the properties;
+
+ \list
+ \o id - An identifier of the component
+ \o width - the width of the component when drawn
+ \o height - the height of the component when drawn
+ \endlist
+
+ All items have properties to handle their position on the screen, size,
+ clipping, rotation, scale and layout in regards to other elements. In
+ the current example width and height refer to how large to draw the
+ rectangle. The identifier allows other components to refer to the
+ identified component.
+
+ Another important property of a component is its children. All components
+ have a list of children. When drawing, first any components earlier
+ siblings are drawn, then the component, then any of the components children.
+
+ The next step of the tutorial adds an image over the rectangle.
+
+ \code
+ <Rect id="removeButton"
+ width="30" height="30"
+ color="red"
+ radius="5">
+ <Image id="trashIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/trash.png"/>
+ </Rect>
+ \endcode
+
+ The trashIcon image is added as a child of the Rectangle. In this case
+ the <children> tag isn't used because the default property of the
+ Rect component is its children. Some elements don't often have children
+ and use some other default component, when this is the case its possible
+ to explicitly list the sub component as a child as follows:
+
+ \code
+ <Rect id="removeButton"
+ width="30" height="30"
+ color="red"
+ radius="5">
+ <children>
+ <Image id="trashIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/trash.png"/>
+ </children>
+ </Rect>
+ \endcode
+
+ The Image element allows loading an image file for display. The source
+ specified is a URL, and in this case refers to a portable network graphics
+ file in a relative directory to where the QML file was loaded from.
+
+ Also new in this code is the use of anchors. In QML components can either
+ have their position and size specified explicitly using x, y, width
+ and height, or they can instead specify the size and position in relation
+ to elements either parent or sibling elements. The Image component uses
+ a combination of both styles. It has a fixed size, but specifies its
+ position to align to the right of its parent and for its vertical center
+ to align with the vertical center of its parent. The braces "{}" are
+ used to indicate that the value is not a static value, but instead a
+ binding to an expression. In this case it binds to the parent
+ element, which is a special identifier that always refers to the
+ parent component of a component. The removeButton identifier can
+ be used interchangeably with parent in this case, however it must
+ always be a parent or sibling. Because of this its most common to
+ use the parent identifier as it makes later refactoring of code easier.
+
+ Anchors are most useful when the size of items might change based on
+ the component state or contents.
+
+ \omit
+ See TODO for full list of anchor properties.
+ \endomit
+
+ At this point the initial state of the RemoveButton is complete. A small
+ rounded rectangle with a trash icon. The description of the alternate
+ state of the button can be written as:
+
+ \code
+ <Rect id="removeButton"
+ width="230" height="30"
+ color="red"
+ radius="5">
+ <Image id="cancelIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/cancel.png"/>
+ <Image id="confirmIcon"
+ width="22" height="22"
+ anchors.left="{parent.left}" anchors.leftMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/ok.png"/>
+ <Text id="text"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ anchors.left="{confirmIcon.right}" anchors.leftMargin="4"
+ anchors.right="{cancelIcon.left}" anchors.rightMargin="4"
+ font.bold="true"
+ color="white"
+ hAlign="AlignHCenter"
+ text="Remove"/>
+ </Rect>
+ \endcode
+
+ The rectangle with is now wider, by 200 pixels. Also the trashIcon has
+ been replaced with the confirm state children. Normally we wouldn't
+ remove the trashIcon when developing an alternate state of the RemoveButton,
+ however since this is a tutorial its been done so that its easier to
+ understand the alternate state we are aiming for and how it relates to
+ transitioning between states.
+
+ We also introduce the Text element, which is used to display read only
+ text. \omit see {Text} for more information on the text element \endomit
+ Because we want text to fill the space between the icons, rather than
+ a fixed with the left and right anchors are specified instead. This
+ means as the parent removeButton gets wider, so will the text component.
+ It also means that if we animate a width change on the removeButton,
+ any bindings, that is the values specified by a braced expression such as
+ "{parent.left}" will be evaluated and animated as well.
+
+ When designing a component with multiple states, it should be developed
+ with the initial state and the changes that would be made specified
+ as a state changed. Because we cannot add children to an element from
+ a state change we instead start with the children that should be present
+ and then set their opacity or position such that they won't appear. Thus
+ for the RemoveButton we specify the starting size of the removeButton
+ and hide any items that should not initially be visible.
+
+ The code snippet below shows what the start of the duel state specification
+ might look like.
+
+ \code
+ <Rect id="removeButton"
+ width="30" height="30"
+ color="red"
+ radius="5">
+ <Image id="trashIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/trash.png"/>
+ <Image id="cancelIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/cancel.png"
+ opacity="0"/>
+ \endcode
+
+ Which includes both components, but by setting opacity="0" means the
+ second components won't be drawn unless their is a state change.
+ The base state of a component always has an empty name, however new
+ states can be added that describe how a component and its children
+ should be changed. For the RemoveButton there is only one non-base state
+ required. In this tutorial we will name it the 'opened' state.
+
+ \code
+ <states>
+ <State name="opened">
+ <SetProperty target="{removeButton}" property="width" value="230"/>
+ <SetProperty target="{text}" property="opacity" value="1"/>
+ <SetProperty target="{confirmIcon}" property="opacity" value="1"/>
+ <SetProperty target="{cancelIcon}" property="opacity" value="1"/>
+ <SetProperty target="{trashIcon}" property="opacity" value="0"/>
+ </State>
+ </states>
+ \endcode
+
+ In the opened state the width of the button itself changes from the base
+ width of 30 to the new width of 230. Also the opacity of the children
+ are changed so that the trash icon is hidden and the other elements
+ appear.
+
+ To trigger the change we will react to the 'clicked' signal of a
+ MouseRegion component.
+
+ \code
+ <Image id="trashIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/trash.png"
+ opacity="1">
+ <MouseRegion
+ anchors.fill="{parent}"
+ onClicked="toggle()"/>
+ </Image>
+ \endcode
+
+ MouseRegion components handle mouse actions within their geometry. This
+ geometry behaves the same way as painted components, such that children
+ cover their parents and later siblings will cover earlier siblings and
+ all the children of the earlier sibling, should they overlap.
+
+ When a component has a signal, such as clicked, the action for the signal
+ can be specified using on<SignalName>, as is done above. In this
+ case when the clicked signal is emitted by the MouseRegion component,
+ a function called toggle() is called. It might also have been written
+
+ \code
+ onClicked="removeButton.state='opened'"
+ \endcode
+
+ However in this case we are using a function because it allows multiple
+ mouse regions to use the same functionality, and also makes it
+ easier to specify complex behavior in response to a signal.
+
+ The toggle() function is a new function specified as part of the remove
+ button element.
+
+ \code
+ <resources>
+ <Script>
+ function toggle() {
+ print('removeButton.toggle()');
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+ </Script>
+ </resources>
+ \endcode
+
+ Any QML component can have a set of resources specified. One of those
+ resources is any Script that might be needed. See the
+ {QtScript Module}{QtScript Module} for more information on how to write
+ script code in Qt. There are only a couple of additional items to
+ note when using Script with QML components. The first is that it
+ is an xml file, that means either CDATA or other forms of escaping
+ should be used if special characters are needed. For example,
+ the expression;
+
+ \code
+ if (a && b) {}
+ \endcode
+
+ Should either be escaped as:
+
+ \code
+ if (a &amp;&amp; b) {}
+ \endcode
+
+ or enclosed in a CDATA section as
+
+ \code
+ <![CDATA[if (a && b) {}]]>
+ \endcode
+
+ The other item to note is that you can refer to identified QML components
+ within the script. Hence the function for our RemoveButton will check
+ if the state is already open to determine what the new state should be.
+
+ We also have added a print function. This isn't required for the button
+ to function, but is useful for tracking down possible bugs when
+ working with QML.
+
+ See the file RemoveButton4.qml for the full multi-state specification.
+
+ \section Animation
+
+ Currently the RemoveButton is function, but snaps between our two states.
+ Fortunately making the transition between states smooth is very simple.
+ We only need one more bit of code at the end of our removeButton component.
+
+ \code
+ <transitions>
+ <Transition fromState="*" toState="opened" reversible="true">
+ <NumericAnimation properties="opacity,x,width" duration="200"/>
+ </Transition>
+ </transitions>
+ \endcode
+
+ All QML components have a transitions property. This describes how
+ properties of items within the component should change. In this case
+ we specify that if the x, width or opacity of the removeButton or its
+ children change due to a change in state, that they should take 200ms
+ to complete their transition.
+
+ \omit TODO More on types of animation
+
+ In the next chapter we will show how we can use the remove button in
+ other QML components.
+*/
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_an_animation.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml
index 06c9f5a..06c9f5a 100644
--- a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_an_animation.qml
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml
diff --git a/examples/declarative/tutorials/contacts/t8/Button.qml b/examples/declarative/tutorials/contacts/Final/Button.qml
index 63c4636..8290d35 100644
--- a/examples/declarative/tutorials/contacts/t8/Button.qml
+++ b/examples/declarative/tutorials/contacts/Final/Button.qml
@@ -1,16 +1,21 @@
-<Item width="30" height="30" id="button">
+<Item id="button" width="30" height="30">
<properties>
<Property name="icon"/>
</properties>
<signals>
<Signal name="clicked"/>
</signals>
- <Rect id="buttonRect" color="lightgreen" anchors.fill="{parent}" radius="5">
+ <Rect id="buttonRect"
+ anchors.fill="{parent}"
+ color="lightgreen"
+ radius="5">
<Image id="iconImage"
src="{button.icon}"
anchors.horizontalCenter="{buttonRect.horizontalCenter}"
anchors.verticalCenter="{buttonRect.verticalCenter}"/>
- <MouseRegion id="buttonMouseRegion" anchors.fill="{buttonRect}" onClicked="button.clicked.emit()"/>
+ <MouseRegion id="buttonMouseRegion"
+ anchors.fill="{buttonRect}"
+ onClicked="button.clicked.emit()"/>
<states>
<State name="pressed" when="{buttonMouseRegion.pressed == true}">
<SetProperty target="{buttonRect}" property="color" value="green"/>
diff --git a/examples/declarative/tutorials/contacts/Final/Contact.qml b/examples/declarative/tutorials/contacts/Final/Contact.qml
new file mode 100644
index 0000000..679f4a8
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/Contact.qml
@@ -0,0 +1,57 @@
+<Item id="contactDetails"
+ anchors.fill="{parent}">
+ <properties>
+ <Property name="contactid" value=""/>
+ <Property name="label" onValueChanged="labelField.value = label"/>
+ <Property name="phone" onValueChanged="phoneField.value = phone"/>
+ <Property name="email" onValueChanged="emailField.value = email"/>
+ </properties>
+ <signals>
+ <Signal name="update"/>
+ <Signal name="insert"/>
+ </signals>
+ <resources>
+ <SqlQuery id="updateContactQuery" connection="{contactDatabase}">
+ <query>UPDATE contacts SET label = :l, email = :e, phone = :p WHERE recid = :r</query>
+ <bindings>
+ <SqlBind name=":r" value="{contactid}"/>
+ <SqlBind name=":l" value="{labelField.value}"/>
+ <SqlBind name=":e" value="{emailField.value}"/>
+ <SqlBind name=":p" value="{phoneField.value}"/>
+ </bindings>
+ </SqlQuery>
+ <SqlQuery id="insertContactQuery" connection="{contactDatabase}">
+ <query>INSERT INTO contacts (label, email, phone) VALUES(:l, :e, :p)</query>
+ <bindings>
+ <SqlBind name=":l" value="{labelField.value}"/>
+ <SqlBind name=":e" value="{emailField.value}"/>
+ <SqlBind name=":p" value="{phoneField.value}"/>
+ </bindings>
+ </SqlQuery>
+ </resources>
+ <Connection sender="{contactDetails}" signal="update()">
+ updateContactQuery.exec();
+ </Connection>
+ <Connection sender="{contactDetails}" signal="insert()">
+ insertContactQuery.exec();
+ </Connection>
+ <VerticalLayout id="layout"
+ anchors.fill="{parent}"
+ spacing="5"
+ margin="5">
+ <ContactField id="labelField"
+ anchors.left="{layout.left}" anchors.leftMargin="5"
+ anchors.right="{layout.right}" anchors.rightMargin="5"
+ label="Name"/>
+ <ContactField id="phoneField"
+ anchors.left="{layout.left}" anchors.leftMargin="5"
+ anchors.right="{layout.right}" anchors.rightMargin="5"
+ icon="../shared/pics/phone.png"
+ label="Phone"/>
+ <ContactField id="emailField"
+ anchors.left="{layout.left}" anchors.leftMargin="5"
+ anchors.right="{layout.right}" anchors.rightMargin="5"
+ icon="../shared/pics/email.png"
+ label="Email"/>
+ </VerticalLayout>
+</Item>
diff --git a/examples/declarative/tutorials/contacts/Final/ContactField.qml b/examples/declarative/tutorials/contacts/Final/ContactField.qml
new file mode 100644
index 0000000..fe9329a
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/ContactField.qml
@@ -0,0 +1,36 @@
+<Item id="contactField"
+ clip="true"
+ height="30">
+ <properties>
+ <Property name="label"/>
+ <Property name="icon"/>
+ <Property name="value" onValueChanged="fieldText.text=field.value"/>
+ </properties>
+ <RemoveButton id="removeButton"
+ anchors.right="{parent.right}"
+ anchors.top="{parent.top}" anchors.bottom="{parent.bottom}"
+ expandedWidth="{contactField.width}"
+ onConfirmed="print('Clear field text'); fieldText.text=''"/>
+ <FieldText id="fieldText"
+ width="{contactField.width-70}"
+ anchors.right="{removeButton.left}" anchors.rightMargin="5"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ label="{contactField.label}"
+ text="{contactField.value}"
+ onConfirmed="contactField.value=fieldText.text"/>
+ <Image
+ anchors.right="{fieldText.left}" anchors.rightMargin="5"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="{contactField.icon}"/>
+ <states>
+ <State name="editingText" when="{fieldText.state == 'editing'}">
+ <SetProperty target="{removeButton.anchors}" property="rightMargin" value="-35"/>
+ <SetProperty target="{fieldText}" property="width" value="{contactField.width}"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition fromState='' toState="*" reversible="true">
+ <NumericAnimation properties="width,rightMargin" duration="200"/>
+ </Transition>
+ </transitions>
+</Item>
diff --git a/examples/declarative/tutorials/contacts/Final/ContactView2.qml b/examples/declarative/tutorials/contacts/Final/ContactView2.qml
new file mode 100644
index 0000000..da1e5db
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/ContactView2.qml
@@ -0,0 +1,62 @@
+<Item id="contacts">
+ <resources>
+ <SqlConnection id="contactDatabase" name="qmlConnection" driver="QSQLITE" databaseName="../shared/contacts.sqlite"/>
+ <SqlQuery id="contactList" connection="{contactDatabase}">
+ <query>SELECT recid AS contactid, label, email, phone FROM contacts ORDER BY label, recid</query>
+ </SqlQuery>
+ <Component id="contactDelegate">
+ <Item id="wrapper"
+ x="0"
+ width="{ListView.view.width}" height="34">
+ <Text id="label"
+ x="40" y="12"
+ width="{parent.width-30}"
+ text="{model.label}"
+ color="white"
+ font.bold="true">
+ </Text>
+ <MouseRegion
+ anchors.fill="{label}"
+ onClicked="wrapper.state='opened'"/>
+ <Contact id="details"
+ anchors.fill="{parent}"
+ contactid="{model.contactid}"
+ label="{model.label}"
+ email="{model.email}"
+ phone="{model.phone}"
+ opacity="0"/>
+ <states>
+ <State name='opened'>
+ <SetProperty target="{wrapper}" property="height" value="{contactListView.height}"/>
+ <SetProperty target="{contactListView}" property="yPosition" value="{wrapper.y}"/>
+ <SetProperty target="{contactListView}" property="locked" value="1"/>
+ <SetProperty target="{label}" property="opacity" value="0"/>
+ <SetProperty target="{details}" property="opacity" value="1"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition>
+ <NumericAnimation duration="500" properties="yPosition,height,opacity"/>
+ </Transition>
+ </transitions>
+ <Connection sender="{cancelEditButton}" signal="clicked()">
+ if (wrapper.state == 'opened') {
+ wrapper.state = '';
+ }
+ </Connection>
+ </Item>
+ </Component>
+ </resources>
+ <Button id="cancelEditButton"
+ anchors.top="{parent.top}" anchors.topMargin="5"
+ anchors.right="{parent.right}" anchors.rightMargin="5"
+ icon="../shared/pics/cancel.png"/>
+ <ListView id="contactListView"
+ anchors.left="{parent.left}"
+ anchors.right="{parent.right}"
+ anchors.top="{cancelEditButton.bottom}"
+ anchors.bottom="{parent.bottom}"
+ clip="true"
+ model="{contactList}"
+ delegate="{contactDelegate}"/>
+</Item>
diff --git a/examples/declarative/tutorials/contacts/Final/FieldText.qml b/examples/declarative/tutorials/contacts/Final/FieldText.qml
new file mode 100644
index 0000000..a82cecd
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/FieldText.qml
@@ -0,0 +1,98 @@
+<Rect id="fieldText"
+ height="30"
+ radius="5"
+ color="black">
+ <properties>
+ <Property
+ name="text"
+ value=""
+ onValueChanged="reset()"/>
+ <Property
+ name="label"
+ value=""/>
+ </properties>
+ <signals>
+ <Signal name="confirmed"/>
+ </signals>
+ <resources>
+ <Script>
+ function edit() {
+ if (!contacts.mouseGrabbed) {
+ fieldText.state='editing';
+ contacts.mouseGrabbed=true;
+ }
+ }
+ function confirm() {
+ fieldText.text = textEdit.text;
+ fieldText.state='';
+ contacts.mouseGrabbed=false;
+ fieldText.confirmed.emit();
+ }
+ function reset() {
+ textEdit.text = fieldText.text;
+ fieldText.state='';
+ contacts.mouseGrabbed=false;
+ }
+ </Script>
+ </resources>
+ <Image id="cancelIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/cancel.png"
+ opacity="0"/>
+ <Image id="confirmIcon"
+ width="22" height="22"
+ anchors.left="{parent.left}" anchors.leftMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/ok.png"
+ opacity="0"/>
+ <TextEdit id="textEdit"
+ anchors.left="{parent.left}" anchors.leftMargin="0"
+ anchors.right="{parent.right}" anchors.rightMargin="0"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ color="white"
+ font.bold="true"
+ readOnly="true"
+ wrap="false"
+ />
+ <Text id="textLabel"
+ x="5" width="{parent.width-10}"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ hAlign="AlignHCenter"
+ color="#505050"
+ font.italic="true"
+ text="{fieldText.label}"
+ opacity="{textEdit.text != '' ? 0 : 1}">
+ <opacity>
+ <Behaviour>
+ <NumericAnimation property="opacity" duration="250"/>
+ </Behaviour>
+ </opacity>
+ </Text>
+ <MouseRegion anchors.fill="{cancelIcon}" onClicked="reset()"/>
+ <MouseRegion anchors.fill="{confirmIcon}" onClicked="confirm()"/>
+ <MouseRegion
+ id="editRegion"
+ anchors.fill="{textEdit}"
+ onClicked="edit()"/>
+ <states>
+ <State name="editing">
+ <SetProperty target="{confirmIcon}" property="opacity" value="1"/>
+ <SetProperty target="{cancelIcon}" property="opacity" value="1"/>
+ <SetProperty target="{fieldText}" property="color" value="white"/>
+ <SetProperty target="{textEdit}" property="color" value="black"/>
+ <SetProperty target="{textEdit}" property="readOnly" value="false"/>
+ <SetProperty target="{textEdit}" property="focus" value="true"/>
+ <SetProperty target="{editRegion}" property="opacity" value="0"/>
+ <SetProperty target="{textEdit.anchors}" property="leftMargin" value="34"/>
+ <SetProperty target="{textEdit.anchors}" property="rightMargin" value="34"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition fromState='' toState="*" reversible="true">
+ <NumericAnimation properties="opacity,leftMargin,rightMargin" duration="200"/>
+ <ColorAnimation duration="150"/>
+ </Transition>
+ </transitions>
+</Rect>
diff --git a/examples/declarative/tutorials/contacts/Final/RemoveButton.qml b/examples/declarative/tutorials/contacts/Final/RemoveButton.qml
new file mode 100644
index 0000000..493ab7a
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/RemoveButton.qml
@@ -0,0 +1,80 @@
+<Rect id="removeButton"
+ width="30" height="30"
+ color="red"
+ radius="5">
+ <properties>
+ <Property name="expandedWidth" value="230"/>
+ </properties>
+ <signals>
+ <Signal name="confirmed"/>
+ </signals>
+ <resources>
+ <Script>
+ function toggle() {
+ print('removeButton.toggle()');
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ contacts.mouseGrabbed=false;
+ } else {
+ if (!contacts.mouseGrabbed) {
+ removeButton.state = 'opened';
+ contacts.mouseGrabbed=true;
+ }
+ }
+ }
+ </Script>
+ </resources>
+ <Image id="trashIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/trash.png"
+ opacity="1">
+ <MouseRegion
+ anchors.fill="{parent}"
+ onClicked="toggle()"/>
+ </Image>
+ <Image id="cancelIcon"
+ width="22" height="22"
+ anchors.right="{parent.right}" anchors.rightMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/cancel.png"
+ opacity="0">
+ <MouseRegion
+ anchors.fill="{parent}"
+ onClicked="toggle()"/>
+ </Image>
+ <Image id="confirmIcon"
+ width="22" height="22"
+ anchors.left="{parent.left}" anchors.leftMargin="4"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/ok.png"
+ opacity="0">
+ <MouseRegion
+ anchors.fill="{parent}"
+ onClicked="toggle(); removeButton.confirmed.emit()"/>
+ </Image>
+ <Text id="text"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ anchors.left="{confirmIcon.right}" anchors.leftMargin="4"
+ anchors.right="{cancelIcon.left}" anchors.rightMargin="4"
+ font.bold="true"
+ color="white"
+ hAlign="AlignHCenter"
+ text="Remove"
+ opacity="0"/>
+ <states>
+ <State name="opened">
+ <SetProperty target="{removeButton}" property="width" value="{removeButton.expandedWidth}"/>
+ <SetProperty target="{text}" property="opacity" value="1"/>
+ <SetProperty target="{confirmIcon}" property="opacity" value="1"/>
+ <SetProperty target="{cancelIcon}" property="opacity" value="1"/>
+ <SetProperty target="{trashIcon}" property="opacity" value="0"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition fromState="*" toState="opened" reversible="true">
+ <NumericAnimation properties="opacity,x,width" duration="200"/>
+ </Transition>
+ </transitions>
+</Rect>
diff --git a/examples/declarative/tutorials/contacts/Final/SearchBar.qml b/examples/declarative/tutorials/contacts/Final/SearchBar.qml
new file mode 100644
index 0000000..aea5a5d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/SearchBar.qml
@@ -0,0 +1,18 @@
+<Rect id="searchBar"
+ color="white">
+ <properties>
+ <Property name="text" value="{searchEdit.text}"/>
+ </properties>
+ <Image id="searchIcon"
+ anchors.left="{parent.left}" anchors.leftMargin="5"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ src="../shared/pics/search.png"/>
+ <TextEdit id="searchEdit"
+ anchors.left="{searchIcon.right}" anchors.right="{parent.right}"
+ anchors.leftMargin="5" anchors.rightMargin="5"
+ anchors.verticalCenter="{parent.verticalCenter}"
+ readOnly="false"
+ wrap="false"
+ focus="true"/>
+</Rect>
+
diff --git a/examples/declarative/tutorials/contacts/Final/contacts.qml b/examples/declarative/tutorials/contacts/Final/contacts.qml
new file mode 100644
index 0000000..8b0d6d0
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/Final/contacts.qml
@@ -0,0 +1,148 @@
+<Rect id="contacts"
+ width="240"
+ height="320"
+ color="black">
+ <properties>
+ <Property name="mode" value="list"/>
+ <Property name="mouseGrabbed" value="false"/>
+ </properties>
+ <resources>
+ <SqlConnection id="contactDatabase" name="qmlConnection" driver="QSQLITE" databaseName="../shared/contacts.sqlite"/>
+ <SqlQuery id="contactList" connection="{contactDatabase}">
+ <query>SELECT recid AS contactid, label, email, phone FROM contacts WHERE lower(label) LIKE lower(:searchTerm) ORDER BY label, recid</query>
+ <bindings>
+ <SqlBind name=":searchTerm" value="{searchBar.text + '%' }"/>
+ </bindings>
+ </SqlQuery>
+ <Component id="contactDelegate">
+ <Item id="wrapper"
+ x="0"
+ width="{ListView.view.width}"
+ height="34">
+ <Text id="label"
+ x="40" y="12"
+ width="{parent.width-30}"
+ text="{model.label}"
+ color="white"
+ font.bold="true">
+ <children>
+ <MouseRegion
+ anchors.fill="{parent}">
+ <onClicked>
+ Details.qml = 'Contact.qml';
+ wrapper.state='opened';
+ contacts.mode = 'edit';
+ </onClicked>
+ </MouseRegion>
+ </children>
+ </Text>
+ <Item id="Details"
+ anchors.fill="{wrapper}"
+ opacity="0">
+ <Bind target="{Details.qmlItem}" property="contactid" value="{model.contactid}"/>
+ <Bind target="{Details.qmlItem}" property="label" value="{model.label}"/>
+ <Bind target="{Details.qmlItem}" property="phone" value="{model.phone}"/>
+ <Bind target="{Details.qmlItem}" property="email" value="{model.email}"/>
+ </Item>
+ <states>
+ <State name='opened'>
+ <SetProperty target="{wrapper}" property="height" value="{contactListView.height}"/>
+ <SetProperty target="{contactListView}" property="yPosition" value="{wrapper.y}"/>
+ <SetProperty target="{contactListView}" property="locked" value="1"/>
+ <SetProperty target="{label}" property="opacity" value="0"/>
+ <SetProperty target="{Details}" property="opacity" value="1"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition>
+ <NumericAnimation duration="500" properties="yPosition,height,opacity"/>
+ </Transition>
+ </transitions>
+ <Connection sender="{cancelEditButton}" signal="clicked()">
+ if (wrapper.state == 'opened' &amp;&amp; !contacts.mouseGrabbed) {
+ wrapper.state = '';
+ contacts.mode = 'list';
+ }
+ </Connection>
+ <Connection sender="{confirmEditButton}" signal="clicked()">
+ if (wrapper.state == 'opened' &amp;&amp; !contacts.mouseGrabbed) {
+ print('confirm and close edit');
+ Details.qmlItem.update.emit();
+ wrapper.state = '';
+ contacts.mode = 'list';
+ contactList.exec();
+ }
+ </Connection>
+ </Item>
+ </Component>
+ </resources>
+ <Button id="newContactButton"
+ anchors.top="{parent.top}" anchors.topMargin="5"
+ anchors.right="{parent.right}" anchors.rightMargin="5"
+ icon="../shared/pics/new.png"
+ onClicked="newContactItem.label = ''; newContactItem.phone = ''; newContactItem.email = ''; contacts.mode = 'new'"
+ opacity="{contacts.mode == 'list' ? 1 : 0}"/>
+ <Button id="confirmEditButton"
+ anchors.top="{parent.top}" anchors.topMargin="5"
+ anchors.left="{parent.left}" anchors.leftMargin="5"
+ icon="../shared/pics/ok.png"
+ opacity="{contacts.mode == 'list' || contacts.mouseGrabbed ? 0 : 1}"/>
+ <Button id="cancelEditButton"
+ anchors.top="{parent.top}" anchors.topMargin="5"
+ anchors.right="{parent.right}" anchors.rightMargin="5"
+ icon="../shared/pics/cancel.png"
+ opacity="{contacts.mode == 'list' || contacts.mouseGrabbed ? 0 : 1}"/>
+ <ListView id="contactListView"
+ anchors.left="{parent.left}"
+ anchors.right="{parent.right}"
+ anchors.top="{cancelEditButton.bottom}"
+ anchors.bottom="{searchBarWrapper.bottom}"
+ clip="true"
+ model="{contactList}"
+ delegate="{contactDelegate}"
+ focus="{contacts.mode != 'list'}"/>
+ <Contact id="newContactItem"
+ anchors.fill="{contactListView}"
+ opacity="0"/>
+ <Connection sender="{confirmEditButton}" signal="clicked()">
+ if (contacts.mode == 'new' &amp;&amp; contacts.mouseGrabbed != 'true') {
+ newContactItem.insert.emit();
+ contacts.mode = 'list';
+ contactList.exec();
+ }
+ </Connection>
+ <Connection sender="{cancelEditButton}" signal="clicked()">
+ if (contacts.mode == 'new' &amp;&amp; contacts.mouseGrabbed != 'true') {
+ contacts.mode = 'list';
+ }
+ </Connection>
+ <FocusRealm id="searchBarWrapper"
+ height="30"
+ anchors.bottom="{parent.bottom}"
+ anchors.left="{parent.left}" anchors.right="{parent.right}"
+ anchors.bottomMargin="0"
+ focus="{contacts.mode == 'list'}">
+ <SearchBar id="searchBar" anchors.fill="{parent}"/>
+ <states>
+ <State name="searchHidden" when="{searchBar.text == '' || contacts.mode != 'list'}">
+ <SetProperty target="{searchBarWrapper.anchors}" property="bottomMargin" value="-30"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition fromState="*" toState="*">
+ <NumericAnimation property="bottomMargin" duration="250"/>
+ </Transition>
+ </transitions>
+ </FocusRealm>
+ <states>
+ <State name="editNewState" when="{contacts.mode == 'new'}">
+ <SetProperty target="{contactListView}" property="opacity" value="0"/>
+ <SetProperty target="{newContactItem}" property="opacity" value="1"/>
+ </State>
+ </states>
+ <transitions>
+ <Transition fromState="*" toState="*">
+ <NumericAnimation property="opacity" duration="500"/>
+ </Transition>
+ </transitions>
+</Rect>
diff --git a/examples/declarative/tutorials/contacts/t8/Contact.qml b/examples/declarative/tutorials/contacts/t8/Contact.qml
deleted file mode 100644
index 5852b43..0000000
--- a/examples/declarative/tutorials/contacts/t8/Contact.qml
+++ /dev/null
@@ -1,80 +0,0 @@
-<Item id="contactDetails" anchors.fill="{parent}">
- <properties>
- <Property name="label" onValueChanged="c_label.value = label"/>
- <Property name="contactid" value=""/>
- <Property name="phone" onValueChanged="c_phone.value = phone"/>
- <Property name="email" onValueChanged="c_email.value = email"/>
- <Property name="mode" value="closed"/>
- </properties>
- <signals>
- <Signal name="open"/>
- <Signal name="close"/>
- <Signal name="confirm"/>
- <Signal name="cancel"/>
- </signals>
- <resources>
- <SqlQuery id="updateContactQuery" connection="{contactDatabase}">
- <query>UPDATE contacts SET label = :l, email = :e, phone = :p WHERE recid = :r</query>
- <bindings>
- <SqlBind name=":r" value="{contactid}"/>
- <SqlBind name=":l" value="{c_label.value}"/>
- <SqlBind name=":e" value="{c_email.value}"/>
- <SqlBind name=":p" value="{c_phone.value}"/>
- </bindings>
- </SqlQuery>
- <SqlQuery id="insertContactQuery" connection="{contactDatabase}">
- <query>INSERT INTO contacts (label, email, phone) VALUES(:l, :e, :p)</query>
- <bindings>
- <SqlBind name=":l" value="{c_label.value}"/>
- <SqlBind name=":e" value="{c_email.value}"/>
- <SqlBind name=":p" value="{c_phone.value}"/>
- </bindings>
- </SqlQuery>
- </resources>
- <Connection sender="{contactDetails}" signal="cancel()">
- c_label.value = label;
- c_phone.value = phone;
- c_email.value = email;
- contactDetails.close.emit();
- </Connection>
- <Connection sender="{contactDetails}" signal="confirm()">
- if (c_label.value != '') {
- if (contactid == '') {
- insertContactQuery.exec();
- c_label.value = label;
- c_phone.value = phone;
- c_email.value = email;
- } else {
- updateContactQuery.exec();
- }
- contactList.exec();
- }
- contactDetails.close.emit();
- </Connection>
- <VerticalLayout id="layout" anchors.fill="{parent}" spacing="5" margin="5">
- <Field id="c_label" label="Name"
- editable="{mode == 'opened' ? 1 : 0}"
- anchors.left="{layout.left}" anchors.leftMargin="5"
- anchors.right="{layout.right}" anchors.rightMargin="5"/>
- <Field id="c_phone" icon="../shared/pics/phone.png" label="Phone"
- opacity="0" editable="{mode == 'opened' ? 1 : 0}"
- anchors.left="{layout.left}" anchors.leftMargin="5"
- anchors.right="{layout.right}" anchors.rightMargin="5"/>
- <Field id="c_email" icon="../shared/pics/email.png" label="Email"
- opacity="0" editable="{mode == 'opened' ? 1 : 0}"
- anchors.left="{layout.left}" anchors.leftMargin="5"
- anchors.right="{layout.right}" anchors.rightMargin="5"/>
- </VerticalLayout>
- <MouseRegion anchors.fill="{contactDetails}" onClicked="contactDetails.open.emit()" z="{mode=='opened' ? -1 : 1}"/>
- <states>
- <State name="opened" when="{mode == 'opened'}">
- <SetProperty target="{c_phone}" property="opacity" value="1"/>
- <SetProperty target="{c_email}" property="opacity" value="1"/>
- </State>
- </states>
- <transitions>
- <Transition fromState="*" toState="opened" reversible="true">
- <NumericAnimation target="{contactFields}" properties="opacity" duration="200"/>
- </Transition>
- </transitions>
-</Item>
diff --git a/examples/declarative/tutorials/contacts/t8/Field.qml b/examples/declarative/tutorials/contacts/t8/Field.qml
deleted file mode 100644
index 0191ef8..0000000
--- a/examples/declarative/tutorials/contacts/t8/Field.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-<Item height="30" width="200" id="field">
- <properties>
- <Property name="value" onValueChanged="fieldText.text=field.value"/>
- <Property name="icon"/>
- <Property name="editable" value="0"/>
- <Property name="label"/>
- </properties>
- <Item id="fieldSelector" width="30" height="30"
- x="0"
- anchors.top="{parent.top}"
- anchors.bottom="{parent.bottom}">
- <Image src="{field.icon}"
- anchors.verticalCenter="{parent.verticalCenter}"
- anchors.horizontalCenter="{parent.horizontalCenter}"/>
- </Item>
- <FieldText id="fieldText"
- label="{field.label}"
- width="{field.width-70}"
- anchors.left="{fieldSelector.right}"
- anchors.leftMargin="5"
- anchors.top="{parent.top}"
- anchors.bottom="{parent.bottom}"
- onTextEdited="field.value = fieldText.text"/>
- <FieldRemover id="fieldRemover"
- anchors.left="{fieldText.right}"
- anchors.leftMargin="5"
- anchors.top="{parent.top}"
- anchors.bottom="{parent.bottom}"
- onConfirm="fieldText.text = ''"
- opacity="{field.editable}"/>
- <states>
- <State name="textFill" when="{fieldText.open == 'true'}">
- <SetProperty target="{fieldText}" property="width" value="{field.width}"/>
- <SetProperty target="{fieldText}" property="x" value="0"/>
- <SetProperty target="{fieldRemover}" property="opacity" value="0"/>
- <SetProperty target="{fieldSelector}" property="opacity" value="0"/>
- <SetProperty target="{fieldSelector}" property="x" value="{-5-fieldSelector.width}"/>
- </State>
- <State name="removerFill" when="{fieldRemover.open == 'true'}">
- <SetProperty target="{fieldRemover}" property="width" value="{field.width}"/>
- <SetProperty target="{fieldRemover}" property="x" value="0"/>
- <SetProperty target="{fieldText}" property="opacity" value="0"/>
- <SetProperty target="{fieldSelector}" property="opacity" value="0"/>
- <SetProperty target="{fieldSelector}" property="x" value="{-10-fieldText.width-fieldSelector.width}"/>
- </State>
- </states>
- <transitions>
- <Transition fromState="*" toState="*">
- <NumericAnimation target="{fieldSelector}" properties="width,x,opacity" duration="200"/>
- <NumericAnimation target="{fieldText}" properties="width,x,opacity" duration="200"/>
- <NumericAnimation target="{fieldRemover}" properties="width,x,opacity" duration="200"/>
- </Transition>
- </transitions>
-</Item>
diff --git a/examples/declarative/tutorials/contacts/t8/FieldRemover.qml b/examples/declarative/tutorials/contacts/t8/FieldRemover.qml
deleted file mode 100644
index a7dad64..0000000
--- a/examples/declarative/tutorials/contacts/t8/FieldRemover.qml
+++ /dev/null
@@ -1,57 +0,0 @@
-<Item height="30" width="30" id="fieldRemover" clip="true">
- <properties>
- <Property name="open" value="false"/>
- </properties>
- <signals>
- <Signal name="confirm"/>
- </signals>
- <resources>
- <Script>
- function toggle() {
- if (fieldRemover.state=='opened') {
- fieldRemover.state='';
- open='false';
- Page.mouseGrabbed='false';
- } else {
- if (Page.mouseGrabbed != 'true') {
- fieldRemover.state='opened';
- open='true';
- Page.mouseGrabbed='true';
- }
- }
- }
- </Script>
- </resources>
- <Rect id="border" anchors.fill="{parent}" color="red" radius="5"/>
- <Image id="trashIcon" src="../shared/pics/trash.png"
- width="22" height="22"
- anchors.right="{parent.right}" anchors.rightMargin="4"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <Image id="cancelIcon" src="../shared/pics/cancel.png"
- width="22" height="22" opacity="0"
- anchors.right="{parent.right}" anchors.rightMargin="4"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <Image id="confirmIcon" src="../shared/pics/ok.png"
- width="22" height="22" opacity="0"
- anchors.left="{parent.left}" anchors.leftMargin="4"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <Text id="text" opacity="0" text="Remove" font.bold="true" color="white" hAlign="AlignHCenter"
- anchors.verticalCenter="{parent.verticalCenter}"
- anchors.left="{confirmIcon.right}" anchors.leftMargin="4"
- anchors.right="{cancelIcon.left}" anchors.rightMargin="4"/>
- <MouseRegion anchors.fill="{confirmIcon}" onClicked="toggle(); fieldRemover.confirm.emit()"/>
- <MouseRegion anchors.fill="{trashIcon}" onClicked="toggle()"/>
- <states>
- <State name="opened">
- <SetProperty target="{text}" property="opacity" value="1"/>
- <SetProperty target="{confirmIcon}" property="opacity" value="1"/>
- <SetProperty target="{cancelIcon}" property="opacity" value="1"/>
- <SetProperty target="{trashIcon}" property="opacity" value="0"/>
- </State>
- </states>
- <transitions>
- <Transition fromState="*" toState="opened" reversible="true">
- <NumericAnimation properties="opacity,x,width" duration="200"/>
- </Transition>
- </transitions>
-</Item>
diff --git a/examples/declarative/tutorials/contacts/t8/FieldText.qml b/examples/declarative/tutorials/contacts/t8/FieldText.qml
deleted file mode 100644
index d3a158a..0000000
--- a/examples/declarative/tutorials/contacts/t8/FieldText.qml
+++ /dev/null
@@ -1,89 +0,0 @@
-<Item height="30" id="fieldText">
- <properties>
- <Property name="open" value="false"/>
- <Property name="text" value="" onValueChanged="setText(fieldText.text)"/>
- <Property name="label" value=""/>
- </properties>
- <signals>
- <Signal name="textEdited"/>
- </signals>
- <resources>
- <Script>
- function start() {
- if (Page.mouseGrabbed != 'true') {
- fieldText.state='editing';
- open='true';
- Page.mouseGrabbed='true';
- }
- }
- function confirm() {
- fieldText.text = textEdit.text;
- fieldText.state='';
- open='false';
- Page.mouseGrabbed='false';
- fieldText.textEdited.emit();
- }
- function cancel() {
- textEdit.text = fieldText.text;
- fieldText.state='';
- open='false';
- Page.mouseGrabbed='false';
- }
- function setText(value) {
- if (textEdit.text != value) {
- fieldText.state='';
- open='false';
- textEdit.text = value;
- }
- }
- </Script>
- </resources>
- <Rect id="border" radius="5" anchors.fill="{parent}" color="{field.editable == 1 ? '#202020' : '#000000'}">
- <TextEdit id="textEdit" vAlign="AlignVCenter" text=""
- readOnly="true" font.bold="true" wrap="false" color="white"
- x="5" width="{parent.width-10}"
- anchors.verticalCenter="{parent.verticalCenter}"
- />
- <Text id="textLabel" vAlign="AlignVCenter" hAlign="AlignHCenter"
- color="#505050" font.italic="true"
- anchors.fill="{border}" text="{fieldText.label}"
- opacity="{textEdit.text == '' ? 1 : 0}">
- <opacity>
- <Behaviour>
- <NumericAnimation target="{textLabel}" property="opacity" duration="250"/>
- </Behaviour>
- </opacity>
- </Text>
- <Image id="cancelIcon" src="../shared/pics/cancel.png"
- width="22" height="22" opacity="0"
- anchors.right="{parent.right}" anchors.rightMargin="4"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <Image id="confirmIcon" src="../shared/pics/ok.png"
- width="22" height="22" opacity="0"
- anchors.left="{parent.left}" anchors.leftMargin="4"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <MouseRegion anchors.fill="{cancelIcon}" onClicked="cancel()"/>
- <MouseRegion anchors.fill="{confirmIcon}" onClicked="confirm()"/>
- <MouseRegion id="editRegion" anchors.fill="{textEdit}" onClicked="start()"/>
- </Rect>
- <states>
- <State name="editing">
- <SetProperty target="{confirmIcon}" property="opacity" value="1"/>
- <SetProperty target="{cancelIcon}" property="opacity" value="1"/>
- <SetProperty target="{border}" property="color" value="white"/>
- <SetProperty target="{textEdit}" property="color" value="black"/>
- <SetProperty target="{textEdit}" property="readOnly" value="false"/>
- <SetProperty target="{textEdit}" property="focus" value="true"/>
- <SetProperty target="{textEdit}" property="x" value="35"/>
- <SetProperty target="{editRegion}" property="opacity" value="0"/>
- </State>
- </states>
- <transitions>
- <Transition fromState='' toState="*" reversible="true">
- <NumericAnimation target="{textEdit}" properties="x" duration="200"/>
- <NumericAnimation target="{confirmIcon}" properties="opacity" duration="200"/>
- <NumericAnimation target="{cancelIcon}" properties="opacity" duration="200"/>
- <ColorAnimation duration="150"/>
- </Transition>
- </transitions>
-</Item>
diff --git a/examples/declarative/tutorials/contacts/t8/SearchBar.qml b/examples/declarative/tutorials/contacts/t8/SearchBar.qml
deleted file mode 100644
index f8e1a6a..0000000
--- a/examples/declarative/tutorials/contacts/t8/SearchBar.qml
+++ /dev/null
@@ -1,16 +0,0 @@
-<Item height="30" width="{parent.width}">
- <properties>
- <Property name="text" value="{searchEdit.text}"/>
- </properties>
- <Rect color="white" anchors.fill="{parent}">
- <Image id="searchIcon" src="../shared/pics/search.png"
- anchors.left="{parent.left}" anchors.leftMargin="5"
- anchors.verticalCenter="{parent.verticalCenter}"/>
- <TextEdit id="searchEdit" focus="{Page.listShown == 1}"
- anchors.left="{searchIcon.right}" anchors.right="{parent.right}"
- anchors.leftMargin="5" anchors.rightMargin="5"
- anchors.verticalCenter="{parent.verticalCenter}"
- readOnly="false" wrap="false"/>
- </Rect>
-</Item>
-
diff --git a/examples/declarative/tutorials/contacts/t8/contacts.qml b/examples/declarative/tutorials/contacts/t8/contacts.qml
deleted file mode 100644
index f76ccfd..0000000
--- a/examples/declarative/tutorials/contacts/t8/contacts.qml
+++ /dev/null
@@ -1,133 +0,0 @@
-<Rect id="Page" color="black" width="240" height="320">
- <properties>
- <Property name="listShown" value="1"/>
- <Property name="mode" value="list"/>
- <Property name="mouseGrabbed" value="false"/>
- </properties>
- <resources>
- <SqlConnection id="contactDatabase" name="qmlConnection" driver="QSQLITE" databaseName="../shared/contacts.sqlite"/>
- <SqlQuery id="contactList" connection="{contactDatabase}">
- <query>SELECT recid, label, email, phone FROM contacts WHERE lower(label) LIKE lower(:searchTerm) ORDER BY label, recid</query>
- <bindings>
- <SqlBind name=":searchTerm" value="{searchBar.text + '%' }"/>
- </bindings>
- </SqlQuery>
- <Component id="contactDelegate">
- <Item id="wrapper" x="0" width="{ListView.view.width}" height="34">
- <Text id="label" x="45" y="12" text="{model.label}" color="white" font.bold="true" width="{parent.width-30}" opacity="{listShown}"/>
- <Item id="Details" anchors.fill="{wrapper}">
- <Bind target="{Details.qmlItem}" property="contactid" value="{model.recid}"/>
- <Bind target="{Details.qmlItem}" property="mode" value="{wrapper.state}"/>
- <Bind target="{Details.qmlItem}" property="label" value="{model.label}"/>
- <Bind target="{Details.qmlItem}" property="phone" value="{model.phone}"/>
- <Bind target="{Details.qmlItem}" property="email" value="{model.email}"/>
- </Item>
- <MouseRegion anchors.fill="{label}" opacity="{listShown}">
- <onClicked>
- Details.qml = 'Contact.qml';
- wrapper.state='opened';
- </onClicked>
- </MouseRegion>
- <states>
- <State name='opened'>
- <SetProperty target="{wrapper}" property="height" value="{contactListView.height}"/>
- <SetProperty target="{contactListView}" property="yPosition" value="{wrapper.y}"/>
- <SetProperty target="{contactListView}" property="locked" value="1"/>
- <SetProperty target="{Details.qmlItem}" property="mode" value="opened"/>
- <SetProperty target="{Page}" property="mode" value="editExisting"/>
- </State>
- </states>
- <transitions>
- <Transition>
- <NumericAnimation duration="500" properties="yPosition,height,opacity"/>
- </Transition>
- </transitions>
- <Connection sender="{confirmEditButton}" signal="clicked()">
- if (Details.qmlItem.mode == 'opened' &amp;&amp; Page.mouseGrabbed != 'true') {
- Details.qmlItem.mode = 'closed';
- wrapper.state = "";
- Details.qmlItem.confirm.emit();
- }
- </Connection>
- <Connection sender="{cancelEditButton}" signal="clicked()">
- if (Details.qmlItem.mode == 'opened' &amp;&amp; Page.mouseGrabbed != 'true') {
- Details.qmlItem.mode = 'closed';
- wrapper.state = "";
- Details.qmlItem.cancel.emit();
- }
- </Connection>
- </Item>
- </Component>
- </resources>
- <Button id="newContactButton" icon="../shared/pics/new.png"
- anchors.top="{parent.top}" anchors.topMargin="5"
- anchors.right="{parent.right}" anchors.rightMargin="5"
- onClicked="newContactItem.label = ''; newContactItem.phone = ''; newContactItem.email = ''; Page.mode = 'editNew'"
- opacity="{Page.mode == 'list' ? 1 : 0}"/>
- <Button id="cancelEditButton" icon="../shared/pics/cancel.png"
- anchors.top="{parent.top}" anchors.topMargin="5"
- anchors.right="{parent.right}" anchors.rightMargin="5"
- opacity="{Page.mode == 'list' || Page.mouseGrabbed == 'true' ? 0 : 1}"/>
- <Button id="confirmEditButton" icon="../shared/pics/ok.png"
- anchors.top="{parent.top}" anchors.topMargin="5"
- anchors.left="{parent.left}" anchors.leftMargin="5"
- opacity="{Page.mode == 'list' || Page.mouseGrabbed == 'true' ? 0 : 1}"/>
- <FocusRealm id="searchBarRealm"
- height="30"
- anchors.bottom="{parent.bottom}"
- anchors.left="{parent.left}" anchors.right="{parent.right}"
- focus="{Page.mode == 'list' ? 'true' : 'false'}">
- <SearchBar id="searchBar" anchors.fill="{parent}">
- <states>
- <State name="searchHidden" when="{searchBar.text == '' || Page.listShown == 0}">
- <SetProperty target="{searchBarRealm}" property="anchors.bottomMargin" value="-30"/>
- </State>
- </states>
- <transitions>
- <Transition fromState="*" toState="*">
- <NumericAnimation property="bottomMargin" duration="250"/>
- </Transition>
- </transitions>
- </SearchBar>
- </FocusRealm>
- <ListView id="contactListView" model="{contactList}" delegate="{contactDelegate}"
- anchors.top="{newContactButton.bottom}" anchors.topMargin="10"
- anchors.left="{parent.left}" anchors.right="{parent.right}"
- anchors.bottom="{searchBarRealm.top}"
- clip="true"
- focus="{Page.mode == 'list' ? 'false' : 'true'}"
- />
- <Contact id="newContactItem"
- mode="opened"
- anchors.top="{newContactButton.bottom}" anchors.topMargin="10"
- anchors.left="{parent.left}" anchors.right="{parent.right}"
- anchors.bottom="{searchBarRealm.top}"
- onClose="Page.mode='list'"
- opacity="0"
- />
- <Connection sender="{confirmEditButton}" signal="clicked()">
- if (Page.mode == 'editNew' &amp;&amp; Page.mouseGrabbed != 'true') {
- newContactItem.confirm.emit()
- }
- </Connection>
- <Connection sender="{cancelEditButton}" signal="clicked()">
- if (Page.mode == 'editNew' &amp;&amp; Page.mouseGrabbed != 'true') {
- newContactItem.cancel.emit()
- }
- </Connection>
- <states>
- <State name="editExistingState" when="{Page.mode == 'editExisting'}">
- <SetProperty target="{Page}" property="listShown" value="0"/>
- </State>
- <State name="editNewState" when="{Page.mode == 'editNew'}">
- <SetProperty target="{Page}" property="listShown" value="0"/>
- <SetProperty target="{contactListView}" property="opacity" value="0"/>
- <SetProperty target="{newContactItem}" property="opacity" value="1"/>
- </State>
- </states>
- <transitions>
- <Transition fromState="*" toState="*">
- <NumericAnimation property="opacity" duration="500"/>
- </Transition>
- </transitions>
-</Rect>