summaryrefslogtreecommitdiffstats
path: root/examples/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'examples/declarative')
-rw-r--r--examples/declarative/animation/animation.qml51
-rw-r--r--examples/declarative/aspectratio/face_fit.qml26
-rw-r--r--examples/declarative/aspectratio/face_fit_animated.qml28
-rw-r--r--examples/declarative/aspectratio/pics/face.pngbin0 -> 905 bytes
-rw-r--r--examples/declarative/aspectratio/scale_and_crop.qml21
-rw-r--r--examples/declarative/aspectratio/scale_and_sidecrop.qml22
-rw-r--r--examples/declarative/aspectratio/scale_to_fit.qml21
-rw-r--r--examples/declarative/behaviours/MyRect.qml11
-rw-r--r--examples/declarative/behaviours/test.qml103
-rw-r--r--examples/declarative/connections/connections.qml29
-rw-r--r--examples/declarative/declarative.pro4
-rw-r--r--examples/declarative/dial/DialLibrary/Dial.qml34
-rw-r--r--examples/declarative/dial/DialLibrary/background.pngbin0 -> 35876 bytes
-rw-r--r--examples/declarative/dial/DialLibrary/needle.pngbin0 -> 342 bytes
-rw-r--r--examples/declarative/dial/DialLibrary/needle_shadow.pngbin0 -> 632 bytes
-rw-r--r--examples/declarative/dial/DialLibrary/overlay.pngbin0 -> 3564 bytes
-rw-r--r--examples/declarative/dial/dial.qml31
-rw-r--r--examples/declarative/easing/easing.qml92
-rw-r--r--examples/declarative/follow/follow.qml50
-rw-r--r--examples/declarative/follow/pong.qml67
-rw-r--r--examples/declarative/listview/content/MediaButton.qml37
-rw-r--r--examples/declarative/listview/content/pics/button-pressed.pngbin0 -> 571 bytes
-rw-r--r--examples/declarative/listview/content/pics/button.pngbin0 -> 564 bytes
-rw-r--r--examples/declarative/listview/content/pics/fruit-salad.jpgbin0 -> 17952 bytes
-rw-r--r--examples/declarative/listview/content/pics/hamburger.jpgbin0 -> 8572 bytes
-rw-r--r--examples/declarative/listview/content/pics/lemonade.jpgbin0 -> 6645 bytes
-rw-r--r--examples/declarative/listview/content/pics/moreDown.pngbin0 -> 217 bytes
-rw-r--r--examples/declarative/listview/content/pics/moreUp.pngbin0 -> 212 bytes
-rw-r--r--examples/declarative/listview/content/pics/pancakes.jpgbin0 -> 9163 bytes
-rw-r--r--examples/declarative/listview/content/pics/vegetable-soup.jpgbin0 -> 8639 bytes
-rw-r--r--examples/declarative/listview/dummydata/MyPetsModel.qml59
-rw-r--r--examples/declarative/listview/dummydata/Recipes.qml88
-rw-r--r--examples/declarative/listview/highlight.qml57
-rw-r--r--examples/declarative/listview/listview.qml80
-rw-r--r--examples/declarative/listview/recipes.qml133
-rw-r--r--examples/declarative/listview/sections.qml69
-rw-r--r--examples/declarative/minehunt/Description.qml36
-rw-r--r--examples/declarative/minehunt/Explosion.qml18
-rw-r--r--examples/declarative/minehunt/main.cpp312
-rw-r--r--examples/declarative/minehunt/minehunt.pro8
-rw-r--r--examples/declarative/minehunt/minehunt.qml160
-rw-r--r--examples/declarative/minehunt/pics/No-Ones-Laughing-3.jpgbin0 -> 30730 bytes
-rw-r--r--examples/declarative/minehunt/pics/back.pngbin0 -> 558 bytes
-rw-r--r--examples/declarative/minehunt/pics/bomb-color.pngbin0 -> 284 bytes
-rw-r--r--examples/declarative/minehunt/pics/bomb.pngbin0 -> 535 bytes
-rw-r--r--examples/declarative/minehunt/pics/face-sad.pngbin0 -> 14844 bytes
-rw-r--r--examples/declarative/minehunt/pics/face-smile-big.pngbin0 -> 13810 bytes
-rw-r--r--examples/declarative/minehunt/pics/face-smile.pngbin0 -> 15408 bytes
-rw-r--r--examples/declarative/minehunt/pics/flag-color.pngbin0 -> 219 bytes
-rw-r--r--examples/declarative/minehunt/pics/flag.pngbin0 -> 196 bytes
-rw-r--r--examples/declarative/minehunt/pics/front.pngbin0 -> 580 bytes
-rw-r--r--examples/declarative/minehunt/pics/star.pngbin0 -> 2677 bytes
-rw-r--r--examples/declarative/mouseregion/mouse.qml38
-rw-r--r--examples/declarative/scrollbar/ScrollBar.qml29
-rw-r--r--examples/declarative/scrollbar/display.qml63
-rw-r--r--examples/declarative/scrollbar/pics/niagara_falls.jpgbin0 -> 604121 bytes
-rw-r--r--examples/declarative/slideswitch/Switch.qml56
-rw-r--r--examples/declarative/slideswitch/background.svg23
-rw-r--r--examples/declarative/slideswitch/display.qml8
-rw-r--r--examples/declarative/slideswitch/knob.svg867
-rw-r--r--examples/declarative/states/states.qml40
-rw-r--r--examples/declarative/states/transitions.qml60
-rw-r--r--examples/declarative/support/contact.cpp83
-rw-r--r--examples/declarative/support/contact.h141
-rw-r--r--examples/declarative/support/contactmodel.cpp159
-rw-r--r--examples/declarative/support/contactmodel.h55
-rw-r--r--examples/declarative/support/support.pro12
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1/Removebutton.qml9
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml34
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2/RemoveButton.qml18
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2a/RemoveButton.qml20
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/3/RemoveButton.qml39
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml110
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4a/RemoveButton.qml117
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/5/RemoveButton.qml117
-rw-r--r--examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml57
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1/ContactField.qml30
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1/RemoveButton.qml115
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1a/ContactField.qml33
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1a/RemoveButton.qml115
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1b/BlueRect.qml33
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/1b/lib/RemoveButton.qml117
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/2/ContactField.qml32
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml123
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/2_Reuse.qml37
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/3/Contact.qml47
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/3/ContactField.qml61
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml148
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/3/RemoveButton.qml119
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/4/Contact.qml50
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/4/ContactField.qml58
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml149
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/4/RemoveButton.qml123
-rw-r--r--examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml57
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/1/ContactView.qml44
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml126
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml139
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/3_Collections.qml29
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml57
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml57
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/lib/Contact.qml46
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/lib/ContactField.qml58
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml149
-rw-r--r--examples/declarative/tutorials/contacts/3_Collections/lib/RemoveButton.qml121
-rwxr-xr-xexamples/declarative/tutorials/contacts/shared/contactGenSQL.pl82
-rw-r--r--examples/declarative/tutorials/contacts/shared/contacts.sqlitebin0 -> 86016 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/email.txt7
-rw-r--r--examples/declarative/tutorials/contacts/shared/english-f.txt143
-rw-r--r--examples/declarative/tutorials/contacts/shared/english-m.txt130
-rw-r--r--examples/declarative/tutorials/contacts/shared/english-s.txt1003
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/cancel.pngbin0 -> 1038 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/email.pngbin0 -> 977 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/new.pngbin0 -> 688 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/ok.pngbin0 -> 655 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/phone.pngbin0 -> 624 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/search.pngbin0 -> 635 bytes
-rw-r--r--examples/declarative/tutorials/contacts/shared/pics/trash.pngbin0 -> 989 bytes
-rw-r--r--examples/declarative/tutorials/helloworld/t1/tutorial1.qml14
-rw-r--r--examples/declarative/tutorials/helloworld/t2/Cell.qml16
-rw-r--r--examples/declarative/tutorials/helloworld/t2/tutorial2.qml27
-rw-r--r--examples/declarative/tutorials/helloworld/t3/Cell.qml15
-rw-r--r--examples/declarative/tutorials/helloworld/t3/tutorial3.qml59
-rw-r--r--examples/declarative/velocity/Day.qml111
-rw-r--r--examples/declarative/velocity/cork.jpgbin0 -> 88766 bytes
-rw-r--r--examples/declarative/velocity/sticky.pngbin0 -> 15319 bytes
-rw-r--r--examples/declarative/velocity/tack.pngbin0 -> 7282 bytes
-rw-r--r--examples/declarative/velocity/velocity.qml113
-rw-r--r--examples/declarative/webview/autosize.qml59
-rw-r--r--examples/declarative/webview/content/SpinSquare.qml24
-rw-r--r--examples/declarative/webview/inline-html.qml12
-rw-r--r--examples/declarative/webview/qml-in-html.qml30
-rw-r--r--examples/declarative/webview/transparent.qml11
-rw-r--r--examples/declarative/xmldata/daringfireball.qml59
-rw-r--r--examples/declarative/xmldata/yahoonews.qml113
134 files changed, 8103 insertions, 0 deletions
diff --git a/examples/declarative/animation/animation.qml b/examples/declarative/animation/animation.qml
new file mode 100644
index 0000000..5cb471e
--- /dev/null
+++ b/examples/declarative/animation/animation.qml
@@ -0,0 +1,51 @@
+Rect {
+ width: 400
+ height: 200
+ color: "white"
+ Rect {
+ width: 40
+ height: 40
+ y: 80
+ color: "#FF0000"
+ radius: 10
+ // Animate the x property. Setting repeat to true makes the
+ // animation repeat indefinitely, otherwise it would only run once.
+ x: SequentialAnimation {
+ running: true
+ repeat: true
+ // Move from 0 to 360 in 500ms, using the easeInOutQuad easing function
+ NumericAnimation {
+ from: 0
+ to: 360
+ easing: "easeInOutQuad"
+ duration: 500
+ }
+ // Then pause for 200ms
+ PauseAnimation {
+ duration: 200
+ }
+ // Then move back to 0 in 2 seconds, using the easeInOutElastic easing function
+ NumericAnimation {
+ from: 360
+ to: 0
+ easing: "easeInOutElastic"
+ duration: 2000
+ }
+ }
+ // Alternate color between red and green
+ color: SequentialAnimation {
+ running: true
+ repeat: true
+ ColorAnimation {
+ from: "#FF0000"
+ to: "#00FF00"
+ duration: 5000
+ }
+ ColorAnimation {
+ from: "#00FF00"
+ to: "#FF0000"
+ duration: 5000
+ }
+ }
+ }
+}
diff --git a/examples/declarative/aspectratio/face_fit.qml b/examples/declarative/aspectratio/face_fit.qml
new file mode 100644
index 0000000..35c63ce
--- /dev/null
+++ b/examples/declarative/aspectratio/face_fit.qml
@@ -0,0 +1,26 @@
+// The Image primitive does not have any special handling for maintaining
+// aspect ratio. This example shows that you can provide whatever specific
+// behaviour you like.
+//
+// Here, we implement a hybrid of the "scale to fit" and "scale and crop"
+// behaviours which will crop up to 25% from *one* dimension if necessary
+// to fully scale the other. This is a realistic algorithm, for example
+// when the edges of the image contain less vital information than the
+// center - such as a face.
+//
+Rect {
+ // default size: whole image, unscaled
+ width: Image.width
+ height: Image.height
+ color: "gray"
+ clip: true
+
+ Image {
+ id: Image
+ source: "pics/face.png"
+ x: (parent.width-width*scale)/2
+ y: (parent.height-height*scale)/2
+ scale: Math.max(Math.min(parent.width/width*1.333,parent.height/height),
+ Math.min(parent.width/width,parent.height/height*1.333))
+ }
+}
diff --git a/examples/declarative/aspectratio/face_fit_animated.qml b/examples/declarative/aspectratio/face_fit_animated.qml
new file mode 100644
index 0000000..366d27b
--- /dev/null
+++ b/examples/declarative/aspectratio/face_fit_animated.qml
@@ -0,0 +1,28 @@
+// The Image primitive does not have any special handling for maintaining
+// aspect ratio. This example shows that you can provide whatever specific
+// behaviour you like.
+//
+// Here, we extend the "face_fit" example with animation to show how truly
+// diverse and usage-specific behaviours are made possible by NOT putting a
+// hard-coded aspect ratio feature into the Image primitive.
+//
+Rect {
+ // default size: whole image, unscaled
+ width: Image.width
+ height: Image.height
+ color: "gray"
+ clip: true
+
+ Image {
+ id: Image
+ source: "pics/face.png"
+ x: (parent.width-width*scale)/2
+ y: (parent.height-height*scale)/2
+ scale: Follow {
+ source: Math.max(Math.min(Image.parent.width/Image.width*1.333,Image.parent.height/Image.height),
+ Math.min(Image.parent.width/Image.width,Image.parent.height/Image.height*1.333))
+ spring: 1
+ damping: 0.05
+ }
+ }
+}
diff --git a/examples/declarative/aspectratio/pics/face.png b/examples/declarative/aspectratio/pics/face.png
new file mode 100644
index 0000000..9623b1a
--- /dev/null
+++ b/examples/declarative/aspectratio/pics/face.png
Binary files differ
diff --git a/examples/declarative/aspectratio/scale_and_crop.qml b/examples/declarative/aspectratio/scale_and_crop.qml
new file mode 100644
index 0000000..a5409f9
--- /dev/null
+++ b/examples/declarative/aspectratio/scale_and_crop.qml
@@ -0,0 +1,21 @@
+// The Image primitive does not have any special handling for maintaining
+// aspect ratio. This example shows that you can provide whatever specific
+// behaviour you like.
+//
+// Here, we implement "Scale and Crop" behaviour.
+//
+Rect {
+ // default size: whole image, unscaled
+ width: Image.width
+ height: Image.height
+ color: "gray"
+ clip: true
+
+ Image {
+ id: Image
+ source: "pics/face.png"
+ x: (parent.width-width*scale)/2
+ y: (parent.height-height*scale)/2
+ scale: Math.max(parent.width/width,parent.height/height)
+ }
+}
diff --git a/examples/declarative/aspectratio/scale_and_sidecrop.qml b/examples/declarative/aspectratio/scale_and_sidecrop.qml
new file mode 100644
index 0000000..e076735
--- /dev/null
+++ b/examples/declarative/aspectratio/scale_and_sidecrop.qml
@@ -0,0 +1,22 @@
+// The Image primitive does not have any special handling for maintaining
+// aspect ratio. This example shows that you can provide whatever specific
+// behaviour you like.
+//
+// Here, we implement a variant of "Scale and Crop" behaviour, where we
+// crop the sides if necessary to fully fit vertically, but not the reverse.
+//
+Rect {
+ // default size: whole image, unscaled
+ width: Image.width
+ height: Image.height
+ color: "gray"
+ clip: true
+
+ Image {
+ id: Image
+ source: "pics/face.png"
+ x: (parent.width-width*scale)/2
+ y: (parent.height-height*scale)/2
+ scale: parent.height/height
+ }
+}
diff --git a/examples/declarative/aspectratio/scale_to_fit.qml b/examples/declarative/aspectratio/scale_to_fit.qml
new file mode 100644
index 0000000..61a4082
--- /dev/null
+++ b/examples/declarative/aspectratio/scale_to_fit.qml
@@ -0,0 +1,21 @@
+// The Image primitive does not have any special handling for maintaining
+// aspect ratio. This example shows that you can provide whatever specific
+// behaviour you like.
+//
+// Here, we implement "Scale to Fit" behaviour.
+//
+Rect {
+ // default size: whole image, unscaled
+ width: Image.width
+ height: Image.height
+ color: "gray"
+ clip: true
+
+ Image {
+ id: Image
+ source: "pics/face.png"
+ x: (parent.width-width*scale)/2
+ y: (parent.height-height*scale)/2
+ scale: Math.min(parent.width/width,parent.height/height)
+ }
+}
diff --git a/examples/declarative/behaviours/MyRect.qml b/examples/declarative/behaviours/MyRect.qml
new file mode 100644
index 0000000..dc9a094
--- /dev/null
+++ b/examples/declarative/behaviours/MyRect.qml
@@ -0,0 +1,11 @@
+Rect {
+ radius: 15
+ pen.color: "black"
+ width: 100
+ height: 100
+ id: Page
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { bluerect.parent = Page; bluerect.x=0 }
+ }
+}
diff --git a/examples/declarative/behaviours/test.qml b/examples/declarative/behaviours/test.qml
new file mode 100644
index 0000000..bb7109e
--- /dev/null
+++ b/examples/declarative/behaviours/test.qml
@@ -0,0 +1,103 @@
+Rect {
+ color: "lightsteelblue"
+ width: 800
+ height: 600
+ id: Page
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { bluerect.parent = Page; bluerect.x = mouseX; }
+ }
+ MyRect {
+ color: "green"
+ x: 200
+ y: 200
+ }
+ MyRect {
+ color: "red"
+ x: 400
+ y: 200
+ }
+ MyRect {
+ color: "yellow"
+ x: 400
+ y: 400
+ }
+ MyRect {
+ color: "orange"
+ x: 400
+ y: 500
+ }
+ MyRect {
+ color: "pink"
+ x: 400
+ y: 0
+ }
+ MyRect {
+ color: "lightsteelblue"
+ x: 100
+ y: 500
+ }
+ MyRect {
+ color: "black"
+ x: 0
+ y: 200
+ }
+ MyRect {
+ color: "white"
+ x: 400
+ y: 0
+ }
+ Rect {
+ color: "blue"
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ id: bluerect
+ x: Behaviour {
+ SequentialAnimation {
+ NumericAnimation {
+ target: bluerect
+ properties: "y"
+ from: 0
+ to: 10
+ easing: "easeOutBounce(amplitude:30)"
+ duration: 250
+ }
+ NumericAnimation {
+ target: bluerect
+ properties: "y"
+ from: 10
+ to: 0
+ easing: "easeOutBounce(amplitude:30)"
+ duration: 250
+ }
+ }
+ NumericAnimation {
+ target: bluerect
+ property: "x"
+ duration: 500
+ }
+ }
+ parent: Behaviour {
+ SequentialAnimation {
+ NumericAnimation {
+ target: bluerect
+ properties: "opacity"
+ to: 0
+ duration: 150
+ }
+ SetPropertyAction {
+ target: bluerect
+ property: "parent"
+ }
+ NumericAnimation {
+ target: bluerect
+ properties: "opacity"
+ to: 1
+ duration: 150
+ }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/connections/connections.qml b/examples/declarative/connections/connections.qml
new file mode 100644
index 0000000..e66875a
--- /dev/null
+++ b/examples/declarative/connections/connections.qml
@@ -0,0 +1,29 @@
+Rect {
+ id: rect
+ color: "blue"
+ width: 40
+ height: 30
+ Rect {
+ id: dot
+ color: "red"
+ width: 3
+ height: 3
+ x: rect.width/2
+ y: rect.height/2
+ }
+ MouseRegion {
+ id: mr
+ anchors.fill: rect
+ }
+ Connection {
+ sender: mr
+ signal: "clicked(mouse)"
+ script: {
+
+ color="green";
+ dot.x = mouse.x-1;
+ dot.y = mouse.y-1;
+
+ }
+ }
+}
diff --git a/examples/declarative/declarative.pro b/examples/declarative/declarative.pro
new file mode 100644
index 0000000..3083800
--- /dev/null
+++ b/examples/declarative/declarative.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+CONFIG = ordered
+
+SUBDIRS += minehunt \
diff --git a/examples/declarative/dial/DialLibrary/Dial.qml b/examples/declarative/dial/DialLibrary/Dial.qml
new file mode 100644
index 0000000..6cd42df
--- /dev/null
+++ b/examples/declarative/dial/DialLibrary/Dial.qml
@@ -0,0 +1,34 @@
+Item {
+ property real value : 0
+
+ width: 210; height: 210
+
+ Image { id: Background; source: "background.png" }
+
+ Image {
+ x: 93
+ y: 35
+ source: "needle_shadow.png"
+ transform: Rotation {
+ originX: 11; originY: 67
+ angle: NeedleRotation.angle
+ }
+ }
+ Image {
+ id: Needle
+ x: 95
+ y: 33
+ source: "needle.png"
+ transform: Rotation {
+ id: NeedleRotation
+ originX: 7; originY: 65
+ angle: -130
+ angle: Follow {
+ spring: 1.4
+ damping: .15
+ source: Math.min(Math.max(-130, value*2.2 - 130), 133)
+ }
+ }
+ }
+ Image { x: 21; y: 18; source: "overlay.png" }
+}
diff --git a/examples/declarative/dial/DialLibrary/background.png b/examples/declarative/dial/DialLibrary/background.png
new file mode 100644
index 0000000..75d555d
--- /dev/null
+++ b/examples/declarative/dial/DialLibrary/background.png
Binary files differ
diff --git a/examples/declarative/dial/DialLibrary/needle.png b/examples/declarative/dial/DialLibrary/needle.png
new file mode 100644
index 0000000..2d19f75
--- /dev/null
+++ b/examples/declarative/dial/DialLibrary/needle.png
Binary files differ
diff --git a/examples/declarative/dial/DialLibrary/needle_shadow.png b/examples/declarative/dial/DialLibrary/needle_shadow.png
new file mode 100644
index 0000000..8d8a928
--- /dev/null
+++ b/examples/declarative/dial/DialLibrary/needle_shadow.png
Binary files differ
diff --git a/examples/declarative/dial/DialLibrary/overlay.png b/examples/declarative/dial/DialLibrary/overlay.png
new file mode 100644
index 0000000..3860a7b
--- /dev/null
+++ b/examples/declarative/dial/DialLibrary/overlay.png
Binary files differ
diff --git a/examples/declarative/dial/dial.qml b/examples/declarative/dial/dial.qml
new file mode 100644
index 0000000..b183798
--- /dev/null
+++ b/examples/declarative/dial/dial.qml
@@ -0,0 +1,31 @@
+import "DialLibrary"
+Rect {
+ color: "white"
+ width: 210; height: 240
+
+ // Dial with a slider to adjust it
+ Dial { id: Dial; value: Slider.x-2 }
+
+ Rect {
+ anchors.top: Dial.bottom
+ x: 20; width: 160; height: 16
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "steelblue" }
+ GradientStop { position: 1.0; color: "lightsteelblue" }
+ }
+ radius: 8; opacity: 0.7
+ Rect {
+ id: Slider
+ x: 2; y: 2; width: 30; height: 12
+ radius: 6
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "lightgray" }
+ GradientStop { position: 1.0; color: "gray" }
+ }
+ MouseRegion {
+ anchors.fill: parent
+ drag.target: parent; drag.axis: "x"; drag.xmin: 2; drag.xmax: 128
+ }
+ }
+ }
+}
diff --git a/examples/declarative/easing/easing.qml b/examples/declarative/easing/easing.qml
new file mode 100644
index 0000000..af675d1
--- /dev/null
+++ b/examples/declarative/easing/easing.qml
@@ -0,0 +1,92 @@
+Rect {
+ id: Window
+ width: 640
+ height: Layout.height
+ color: "white"
+
+ ListModel {
+ id: EasingTypes
+ ListElement { type: "easeLinear" }
+ ListElement { type: "easeInQuad" }
+ ListElement { type: "easeOutQuad" }
+ ListElement { type: "easeInOutQuad" }
+ ListElement { type: "easeOutInQuad" }
+ ListElement { type: "easeInCubic" }
+ ListElement { type: "easeOutCubic" }
+ ListElement { type: "easeInOutCubic" }
+ ListElement { type: "easeOutInCubic" }
+ ListElement { type: "easeInQuart" }
+ ListElement { type: "easeOutQuart" }
+ ListElement { type: "easeInOutQuart" }
+ ListElement { type: "easeOutInQuart" }
+ ListElement { type: "easeInQuint" }
+ ListElement { type: "easeOutQuint" }
+ ListElement { type: "easeInOutQuint" }
+ ListElement { type: "easeOutInQuint" }
+ ListElement { type: "easeInSine" }
+ ListElement { type: "easeOutSine" }
+ ListElement { type: "easeInOutSine" }
+ ListElement { type: "easeOutInSine" }
+ ListElement { type: "easeInExpo" }
+ ListElement { type: "easeOutExpo" }
+ ListElement { type: "easeInOutExpo" }
+ ListElement { type: "easeOutInExpo" }
+ ListElement { type: "easeInCirc" }
+ ListElement { type: "easeOutCirc" }
+ ListElement { type: "easeInOutCirc" }
+ ListElement { type: "easeOutInCirc" }
+ ListElement { type: "easeInElastic" }
+ ListElement { type: "easeOutElastic" }
+ ListElement { type: "easeInOutElastic" }
+ ListElement { type: "easeOutInElastic" }
+ ListElement { type: "easeInBack" }
+ ListElement { type: "easeOutBack" }
+ ListElement { type: "easeInOutBack" }
+ ListElement { type: "easeOutInBack" }
+ ListElement { type: "easeOutBounce" }
+ ListElement { type: "easeInBounce" }
+ ListElement { type: "easeInOutBounce" }
+ ListElement { type: "easeOutInBounce" }
+ }
+
+ VerticalLayout {
+ id: Layout
+ anchors.left: Window.left
+ anchors.right: Window.right
+ Repeater {
+ dataSource: EasingTypes
+ Component {
+ Text {
+ id: Text
+ text: type
+ height: 18
+ font.italic: true
+ x: SequentialAnimation {
+ id: Anim
+ NumericAnimation {
+ from: 0
+ to: Window.width / 2
+ easing: type
+ duration: 1000
+ }
+ PauseAnimation {
+ duration: 300
+ }
+ NumericAnimation {
+ to: 0
+ from: Window.width / 2
+ easing: type
+ duration: 1000
+ }
+ }
+ children: [
+ MouseRegion {
+ onClicked: { Anim.running=true }
+ anchors.fill: parent
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/follow/follow.qml b/examples/declarative/follow/follow.qml
new file mode 100644
index 0000000..3258ea6
--- /dev/null
+++ b/examples/declarative/follow/follow.qml
@@ -0,0 +1,50 @@
+Rect {
+ color: "#ffffff"
+ width: 320; height: 240
+ Rect {
+ id: Rect
+ color: "#00ff00"
+ y: 200; width: 60; height: 20
+ y: SequentialAnimation {
+ running: true; repeat: true
+ NumericAnimation {
+ to: 20; duration: 500
+ easing: "easeInOutQuad"
+ }
+ NumericAnimation {
+ to: 200; duration: 2000
+ easing: "easeOutBounce"
+ }
+ PauseAnimation { duration: 1000 }
+ }
+ }
+
+ // Velocity
+ Rect {
+ color: "#ff0000"
+ x: Rect.width; width: Rect.width; height: 20
+ y: Follow { source: Rect.y; velocity: 200 }
+ }
+ Text { x: Rect.width; y: 220; text: "Velocity" }
+
+ // Spring
+ Rect {
+ color: "#ff0000"
+ x: Rect.width * 2; width: Rect.width; height: 20
+ y: Follow { source: Rect.y; spring: 1.2; damping: 0.1 }
+ }
+ Text { x: Rect.width * 2; y: 220; text: "Spring" }
+
+ // Follow mouse
+ MouseRegion {
+ id: Mouse
+ anchors.fill: parent
+ Rect {
+ width: 20; height: 20
+ radius: 10
+ color: "#0000ff"
+ x: Follow { source: Mouse.mouseX-10; spring: 1.0; damping: 0.05 }
+ y: Follow { source: Mouse.mouseY-10; spring: 1.0; damping: 0.05 }
+ }
+ }
+}
diff --git a/examples/declarative/follow/pong.qml b/examples/declarative/follow/pong.qml
new file mode 100644
index 0000000..582b04c
--- /dev/null
+++ b/examples/declarative/follow/pong.qml
@@ -0,0 +1,67 @@
+Rect {
+ id: Page
+ width: 640; height: 480
+ color: "#000000"
+
+ // Make a ball to bounce
+ Rect {
+ // Add a property for the target y coordinate
+ property var targetY : Page.height-10
+ property var direction : "right"
+
+ id: Ball
+ color: "#00ee00"
+ x: 20; width: 20; height: 20; z: 1
+
+ // Move the ball to the right and back to the left repeatedly
+ x: SequentialAnimation {
+ running: true; repeat: true
+ NumericAnimation { to: Page.width-40; duration: 2000 }
+ SetPropertyAction { target: Ball; property: "direction"; value: "left" }
+ NumericAnimation { to: 20; duration: 2000 }
+ SetPropertyAction { target: Ball; property: "direction"; value: "right" }
+ }
+
+ // Make y follow the target y coordinate, with a velocity of 200
+ y: Follow { source: Ball.targetY; velocity: 200 }
+
+ // Detect the ball hitting the top or bottom of the view and bounce it
+ onTopChanged: {
+ if (y <= 0)
+ targetY = Page.height-20;
+ else if (y >= Page.height-20)
+ targetY = 0;
+ }
+ }
+
+ // Place bats to the left and right of the view, following the y
+ // coordinates of the ball.
+ Rect {
+ id: LeftBat
+ color: "#00ee00"
+ x: 2; width: 20; height: 90
+ y: Follow {
+ source: Ball.y-45; velocity: 300
+ enabled: Ball.direction == 'left'
+ }
+ }
+ Rect {
+ id: RightBat
+ color: "#00ee00"
+ x: Page.width-22; width: 20; height: 90
+ y: Follow {
+ source: Ball.y-45; velocity: 300
+ enabled: Ball.direction == 'right'
+ }
+ }
+
+ // The rest, to make it look realistic, if neither ever scores...
+ Rect { color: "#00ee00"; x: 320-80; y: 0; width: 40; height: 60 }
+ Rect { color: "#000000"; x: 320-70; y: 10; width: 20; height: 40 }
+ Rect { color: "#00ee00"; x: 320+40; y: 0; width: 40; height: 60 }
+ Rect { color: "#000000"; x: 320+50; y: 10; width: 20; height: 40 }
+ Repeater {
+ dataSource: 24
+ Rect { color: "#00ee00"; x: 320-5; y: index*20; width: 10; height: 10 }
+ }
+}
diff --git a/examples/declarative/listview/content/MediaButton.qml b/examples/declarative/listview/content/MediaButton.qml
new file mode 100644
index 0000000..cad36bd
--- /dev/null
+++ b/examples/declarative/listview/content/MediaButton.qml
@@ -0,0 +1,37 @@
+Item {
+ property var text
+ signal clicked
+
+ id: Container
+ Image {
+ id: Image
+ source: "pics/button.png"
+ }
+ Image {
+ id: Pressed
+ source: "pics/button-pressed.png"
+ opacity: 0
+ }
+ MouseRegion {
+ id: MouseRegion
+ anchors.fill: Image
+ onClicked: { Container.clicked.emit(); }
+ }
+ Text {
+ font.bold: true
+ color: "white"
+ anchors.centeredIn: Image
+ text: Container.text
+ }
+ width: Image.width
+ states: [
+ State {
+ name: "Pressed"
+ when: MouseRegion.pressed == true
+ SetProperties {
+ target: Pressed
+ opacity: 1
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/listview/content/pics/button-pressed.png b/examples/declarative/listview/content/pics/button-pressed.png
new file mode 100644
index 0000000..e434d32
--- /dev/null
+++ b/examples/declarative/listview/content/pics/button-pressed.png
Binary files differ
diff --git a/examples/declarative/listview/content/pics/button.png b/examples/declarative/listview/content/pics/button.png
new file mode 100644
index 0000000..56a63ce
--- /dev/null
+++ b/examples/declarative/listview/content/pics/button.png
Binary files differ
diff --git a/examples/declarative/listview/content/pics/fruit-salad.jpg b/examples/declarative/listview/content/pics/fruit-salad.jpg
new file mode 100644
index 0000000..da5a6b1
--- /dev/null
+++ b/examples/declarative/listview/content/pics/fruit-salad.jpg
Binary files differ
diff --git a/examples/declarative/listview/content/pics/hamburger.jpg b/examples/declarative/listview/content/pics/hamburger.jpg
new file mode 100644
index 0000000..d0a15be
--- /dev/null
+++ b/examples/declarative/listview/content/pics/hamburger.jpg
Binary files differ
diff --git a/examples/declarative/listview/content/pics/lemonade.jpg b/examples/declarative/listview/content/pics/lemonade.jpg
new file mode 100644
index 0000000..db445c9
--- /dev/null
+++ b/examples/declarative/listview/content/pics/lemonade.jpg
Binary files differ
diff --git a/examples/declarative/listview/content/pics/moreDown.png b/examples/declarative/listview/content/pics/moreDown.png
new file mode 100644
index 0000000..31a35d5
--- /dev/null
+++ b/examples/declarative/listview/content/pics/moreDown.png
Binary files differ
diff --git a/examples/declarative/listview/content/pics/moreUp.png b/examples/declarative/listview/content/pics/moreUp.png
new file mode 100644
index 0000000..fefb9c9
--- /dev/null
+++ b/examples/declarative/listview/content/pics/moreUp.png
Binary files differ
diff --git a/examples/declarative/listview/content/pics/pancakes.jpg b/examples/declarative/listview/content/pics/pancakes.jpg
new file mode 100644
index 0000000..60c4396
--- /dev/null
+++ b/examples/declarative/listview/content/pics/pancakes.jpg
Binary files differ
diff --git a/examples/declarative/listview/content/pics/vegetable-soup.jpg b/examples/declarative/listview/content/pics/vegetable-soup.jpg
new file mode 100644
index 0000000..9dce332
--- /dev/null
+++ b/examples/declarative/listview/content/pics/vegetable-soup.jpg
Binary files differ
diff --git a/examples/declarative/listview/dummydata/MyPetsModel.qml b/examples/declarative/listview/dummydata/MyPetsModel.qml
new file mode 100644
index 0000000..4d76ff4
--- /dev/null
+++ b/examples/declarative/listview/dummydata/MyPetsModel.qml
@@ -0,0 +1,59 @@
+// ListModel allows free form list models to be defined and populated.
+// Be sure to name the file the same as the id.
+ListModel {
+ id: MyListElementsModel
+ 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: "Whiskers"
+ 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/listview/dummydata/Recipes.qml b/examples/declarative/listview/dummydata/Recipes.qml
new file mode 100644
index 0000000..52225dd
--- /dev/null
+++ b/examples/declarative/listview/dummydata/Recipes.qml
@@ -0,0 +1,88 @@
+ListModel {
+ id: Recipes
+ ListElement {
+ title: "Pancakes"
+ picture: "content/pics/pancakes.jpg"
+ ingredients: "<html>
+ <ul>
+ <li> 1 cup (150g) self-raising flour
+ <li> 1 tbs caster sugar
+ <li> 3/4 cup (185ml) milk
+ <li> 1 egg
+ </ul>
+ </html>"
+ method: "<html>
+ <ol>
+ <li> Sift flour and sugar together into a bowl. Add a pinch of salt.
+ <li> Beat milk and egg together, then add to dry ingredients. Beat until smooth.
+ <li> Pour mixture into a pan on medium heat and cook until bubbles appear on the surface.
+ <li> Turn over and cook other side until golden.
+ </ol>
+ </html>"
+ }
+ ListElement {
+ title: "Fruit Salad"
+ picture: "content/pics/fruit-salad.jpg"
+ ingredients: "* Seasonal Fruit"
+ method: "* Chop fruit and place in a bowl."
+ }
+ ListElement {
+ title: "Vegetable Soup"
+ picture: "content/pics/vegetable-soup.jpg"
+ ingredients: "<html>
+ <ul>
+ <li> 1 onion
+ <li> 1 turnip
+ <li> 1 potato
+ <li> 1 carrot
+ <li> 1 head of celery
+ <li> 1 1/2 litres of water
+ </ul>
+ </html>"
+ method: "<html>
+ <ol>
+ <li> Chop vegetables.
+ <li> Boil in water until vegetables soften.
+ <li> Season with salt and pepper to taste.
+ </ol>
+ </html>"
+ }
+ ListElement {
+ title: "Hamburger"
+ picture: "content/pics/hamburger.jpg"
+ ingredients: "<html>
+ <ul>
+ <li> 500g minced beef
+ <li> Seasoning
+ <li> lettuce, tomato, onion, cheese
+ <li> 1 hamburger bun for each burger
+ </ul>
+ </html>"
+ method: "<html>
+ <ol>
+ <li> Mix the beef, together with seasoning, in a food processor.
+ <li> Shape the beef into burgers.
+ <li> Grill the burgers for about 5 mins on each side (until cooked through)
+ <li> Serve each burger on a bun with ketchup, cheese, lettuce, tomato and onion.
+ </ol>
+ </html>"
+ }
+ ListElement {
+ title: "Lemonade"
+ picture: "content/pics/lemonade.jpg"
+ ingredients: "<html>
+ <ul>
+ <li> 1 cup Lemon Juice
+ <li> 1 cup Sugar
+ <li> 6 Cups of Water (2 cups warm water, 4 cups cold water)
+ </ul>
+ </html>"
+ method: "<html>
+ <ol>
+ <li> Pour 2 cups of warm water into a pitcher and stir in sugar until it dissolves.
+ <li> Pour in lemon juice, stir again, and add 4 cups of cold water.
+ <li> Chill or serve over ice cubes.
+ </ol>
+ </html>"
+ }
+}
diff --git a/examples/declarative/listview/highlight.qml b/examples/declarative/listview/highlight.qml
new file mode 100644
index 0000000..9a672d9
--- /dev/null
+++ b/examples/declarative/listview/highlight.qml
@@ -0,0 +1,57 @@
+Rect {
+ width: 400; height: 300; color: "white"
+
+ // MyPets model is defined in dummydata/MyPetsModel.qml
+ // The viewer automatically loads files in dummydata/* to assist
+ // development without a real data source.
+ // This one contains my pets.
+ // Define a delegate component. A component will be
+ // instantiated for each visible item in the list.
+ Component {
+ id: PetDelegate
+ Item {
+ id: Wrapper
+ width: 200; height: 50
+ VerticalLayout {
+ Text { text: 'Name: ' + name }
+ Text { text: 'Type: ' + type }
+ Text { text: 'Age: ' + age }
+ }
+ // Use the ListView.isCurrentItem attached property to
+ // indent the item if it is the current item.
+ states: [
+ State {
+ name: "Current"
+ when: Wrapper.ListView.isCurrentItem
+ SetProperty {
+ target: Wrapper; property: "x"; value: 10
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ NumericAnimation {
+ properties: "x"; duration: 200
+ }
+ }
+ ]
+ }
+ }
+ // Specify a highlight with custom movement. Note that autoHighlight
+ // is set to false in the ListView so that we can control how the
+ // highlight moves to the current item.
+ Component {
+ id: PetHighlight
+ Rect {
+ width: 200; height: 50; color: "#FFFF88"
+ y: Follow { source: List1.current.y; spring: 3; damping: 0.1 }
+ }
+ }
+ ListView {
+ id: List1
+ width: 200; height: parent.height
+ model: MyPetsModel; delegate: PetDelegate
+ highlight: PetHighlight; autoHighlight: false
+ focus: true
+ }
+}
diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml
new file mode 100644
index 0000000..a222378
--- /dev/null
+++ b/examples/declarative/listview/listview.qml
@@ -0,0 +1,80 @@
+Rect {
+ width: 600; height: 300; color: "white"
+
+ // MyPets model is defined in dummydata/MyPetsModel.qml
+ // The viewer automatically loads files in dummydata/* to assist
+ // development without a real data source.
+ // This one contains my pets.
+ // Define a delegate component. A component will be
+ // instantiated for each visible item in the list.
+ Component {
+ id: PetDelegate
+ Item {
+ id: Wrapper
+ width: 200; height: 50
+ VerticalLayout {
+ Text { text: 'Name: ' + name }
+ Text { text: 'Type: ' + type }
+ Text { text: 'Age: ' + age }
+ }
+ }
+ }
+
+ // Define a highlight component. Just one of these will be instantiated
+ // by each ListView and placed behind the current item.
+ Component {
+ id: PetHighlight
+ Rect { color: "#FFFF88" }
+ }
+
+ // Show the model in three lists, with different currentItemPositioning.
+ // currentItemPositioning determines how the list behaves when the
+ // current item changes. Note that the second and third ListView
+ // set their currentIndex to be the same as the first, and that
+ // the first ListView is given keyboard focus.
+ // The default mode, Free, allows the currentItem to move freely
+ // within the visible area. If it would move outside the visible
+ // area, the view is scrolled to keep it visible.
+ // Snap currentItemPositioning attempts to keep the current item
+ // aligned with the snapPosition by scrolling the view, however the
+ // items will not scroll beyond the beginning or end of the view.
+ // SnapAuto currentItemPositioning always keeps the current item on
+ // the snapPosition by scrolling the view. It also automatically
+ // sets the current item as is scrolled with the mouse. Note
+ // that the first ListView sets its currentIndex to be equal to
+ // the third ListView's currentIndex. By flicking List3 with
+ // the mouse, the current index of List1 will be changed.
+ ListView {
+ id: List1
+ width: 200; height: parent.height
+ model: MyPetsModel; delegate: PetDelegate
+ highlight: PetHighlight; currentIndex: List3.currentIndex
+ focus: true
+ }
+ ListView {
+ id: List2
+ x: 200; width: 200; height: parent.height
+ model: MyPetsModel; delegate: PetDelegate; highlight: PetHighlight
+ currentItemPositioning: "Snap"; snapPosition: 125
+ currentIndex: List1.currentIndex
+ }
+ ListView {
+ id: List3
+ x: 400; width: 200; height: parent.height
+ model: MyPetsModel; delegate: PetDelegate
+ currentItemPositioning: "SnapAuto"; snapPosition: 125
+ currentIndex: List1.currentIndex
+ children: [
+ // Position a static highlight rather than a normal highlight so that
+ // when the view is flicked, the highlight does not move.
+ // By positioning the highlight at the same position as the snapPosition
+ // the item under the highlight will always be the current item.
+ // Note that we specify the 'children' property. This is because
+ // the default property of a ListView is 'delegate'.
+ Rect {
+ y: 125; width: 200; height: 50
+ color: "#FFFF88"; z: -1
+ }
+ ]
+ }
+}
diff --git a/examples/declarative/listview/recipes.qml b/examples/declarative/listview/recipes.qml
new file mode 100644
index 0000000..ae9756c
--- /dev/null
+++ b/examples/declarative/listview/recipes.qml
@@ -0,0 +1,133 @@
+import "content"
+// This example illustrates expanding a list item to show a more detailed view
+Rect {
+ id: page
+ width: 400; height: 240; color: "black"
+ resources: [
+ // Delegate for the recipes. This delegate has two modes:
+ // 1. the list mode (default), which just shows the picture and title of the recipe.
+ // 2. the details mode, which also shows the ingredients and method.
+ Component {
+ id: recipeDelegate
+ Item {
+ id: wrapper
+ width: List.width
+ // Create a property to contain the visibility of the details.
+ // We can bind multiple element's opacity to this one property,
+ // rather than having a "SetProperty" line for each element we
+ // want to fade.
+ property real detailsOpacity : 0
+
+ // A simple rounded rectangle for the background
+ Rect {
+ id: background
+ x: 1; y: 2; width: parent.width-2; height: parent.height-4
+ color: "#FEFFEE"; pen.color: "#FFBE4F"; radius: 5
+ }
+ // This mouse region covers the entire delegate.
+ // When clicked it changes mode to 'Details'. If we are already
+ // in Details mode, then no change will happen.
+ MouseRegion {
+ id: pageMouse
+ anchors.fill: parent
+ onClicked: { wrapper.state = 'Details' }
+ }
+ // Layout the page. Picture, title and ingredients at the top, method at the
+ // bottom. Note that elements that should not be visible in the list
+ // mode have their opacity set to wrapper.detailsOpacity.
+ HorizontalLayout {
+ id: topLayout
+ x: 10; y: 10; height: recipePic.height; width: parent.width
+ spacing: 10
+ Image {
+ id: recipePic
+ source: picture; width: 48; height: 48
+ }
+ VerticalLayout {
+ height: recipePic.height; width: background.width-recipePic.width-20
+ spacing: 5
+ Text { id: name; text: title; font.bold: true; font.size: 16 }
+ Text {
+ text: "Ingredients"; font.size: 12; font.bold: true
+ opacity: wrapper.detailsOpacity
+ }
+ Text {
+ text: ingredients; wrap: true; width: parent.width
+ opacity: wrapper.detailsOpacity
+ }
+ }
+ }
+ Item {
+ id: details
+ x: 10; width: parent.width-20
+ anchors.top: topLayout.bottom; anchors.topMargin: 10
+ anchors.bottom: parent.bottom; anchors.bottomMargin: 10
+ opacity: wrapper.detailsOpacity
+ Text {
+ id: methodTitle
+ text: "Method"; font.size: 12; font.bold: true
+ anchors.top: parent.top
+ }
+ Flickable {
+ id: flick
+ anchors.top: methodTitle.bottom; anchors.bottom: parent.bottom
+ width: parent.width; viewportHeight: methodText.height; clip: true
+ Text { id: methodText; text: method; wrap: true; width: details.width }
+ }
+ Image {
+ anchors.right: flick.right; anchors.top: flick.top
+ source: "content/pics/moreUp.png"; opacity: flick.atYBeginning ? 0 : 1
+ }
+ Image {
+ anchors.right: flick.right; anchors.bottom: flick.bottom
+ source: "content/pics/moreDown.png"; opacity: flick.atYEnd ? 0 : 1
+ }
+ }
+ // A button to close the detailed view, i.e. set the state back to default ('').
+ MediaButton {
+ anchors.right: background.right; anchors.rightMargin: 5
+ y: 10; opacity: wrapper.detailsOpacity
+ text: "Close"; onClicked: { wrapper.state = '' }
+ }
+ // Make the default height equal the hight of the picture, plus margin.
+ height: 68
+ states: [
+ State {
+ name: "Details"
+ SetProperty { target: background; property: "color"; value: "white" }
+ // Make the picture bigger
+ SetProperties { target: recipePic; width: 128; height: 128 }
+ // Make details visible
+ SetProperties { target: wrapper; detailsOpacity: 1; x: 0 }
+ // Make the detailed view fill the entire list area
+ SetProperty { target: wrapper; property: "height"; value: List.height }
+ // Move the list so that this item is at the top.
+ SetProperty {
+ target: wrapper.ListView.view
+ property: "yPosition"; value: wrapper.y
+ }
+ // Disallow flicking while we're in detailed view
+ SetProperty { target: wrapper.ListView.view; property: "locked"; value: 1 }
+ }
+ ]
+ transitions: [
+ Transition {
+ // Make the state changes smooth
+ ParallelAnimation {
+ ColorAnimation { duration: 500 }
+ NumericAnimation {
+ duration: 300; properties: "detailsOpacity,x,yPosition,height,width"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ // The actual list
+ ListView {
+ id: List
+ model: Recipes; delegate: recipeDelegate
+ anchors.fill: parent; clip: true
+ }
+}
diff --git a/examples/declarative/listview/sections.qml b/examples/declarative/listview/sections.qml
new file mode 100644
index 0000000..60acd62
--- /dev/null
+++ b/examples/declarative/listview/sections.qml
@@ -0,0 +1,69 @@
+//! [0]
+Rect {
+ width: 200
+ height: 240
+ color: "white"
+ // MyPets model is defined in dummydata/MyPetsModel.qml
+ // The viewer automatically loads files in dummydata/* to assist
+ // development without a real data source.
+ // This one contains my pets.
+
+ // Define a delegate component that includes a separator for sections.
+ Component {
+ id: PetDelegate
+ Item {
+ id: Wrapper
+ width: 200
+ // My height is the combined height of the description and the section separator
+ height: Separator.height + Desc.height
+ Rect {
+ id: Separator
+ color: "lightsteelblue"
+ width: parent.width
+ // Only show the section separator when we are the beginning of a new section
+ // Note that for this to work nicely, the list must be ordered by section.
+ height: Wrapper.ListView.prevSection != Wrapper.ListView.section ? 20 : 0
+ opacity: Wrapper.ListView.prevSection != Wrapper.ListView.section ? 1 : 0
+ Text {
+ text: Wrapper.ListView.section; font.bold: true
+ x: 2; height: parent.height; vAlign: 'AlignVCenter'
+ }
+ }
+ Item {
+ id: Desc
+ x: 5
+ height: Layout.height + 4
+ anchors.top: Separator.bottom
+ VerticalLayout {
+ id: Layout
+ y: 2
+ Text { text: 'Name: ' + name }
+ Text { text: 'Type: ' + type }
+ Text { text: 'Age: ' + age }
+ }
+ }
+ }
+ }
+ // Define a highlight component. Just one of these will be instantiated
+ // by each ListView and placed behind the current item.
+ Component {
+ id: PetHighlight
+ Rect {
+ color: "#FFFF88"
+ }
+ }
+ // The list
+ ListView {
+ id: List
+ width: 200
+ height: parent.height
+ model: MyPetsModel
+ delegate: PetDelegate
+ highlight: PetHighlight
+ // The sectionExpression is simply the size of the pet.
+ // We use this to determine which section we are in above.
+ sectionExpression: "size"
+ focus: true
+ }
+}
+//! [0]
diff --git a/examples/declarative/minehunt/Description.qml b/examples/declarative/minehunt/Description.qml
new file mode 100644
index 0000000..0241ae5
--- /dev/null
+++ b/examples/declarative/minehunt/Description.qml
@@ -0,0 +1,36 @@
+Item {
+ id: Page
+ height: MyText.height + 20
+ property var text
+ MouseRegion {
+ anchors.fill: parent
+ drag.target: Page
+ drag.axis: "xy"
+ drag.xmin: 0
+ drag.xmax: 1000
+ drag.ymin: 0
+ drag.ymax: 1000
+ }
+ Rect {
+ radius: 10
+ anchors.fill: parent
+ color: "lightsteelblue"
+ }
+ Item {
+ x: 10
+ y: 10
+ width: parent.width - 20
+ height: parent.height - 20
+ Text {
+ id: MyText
+ text: Page.text
+ width: parent.width
+ clip: true
+ wrap: true
+ }
+ }
+ filter: Shadow {
+ xOffset: 5
+ yOffset: 5
+ }
+}
diff --git a/examples/declarative/minehunt/Explosion.qml b/examples/declarative/minehunt/Explosion.qml
new file mode 100644
index 0000000..2886559
--- /dev/null
+++ b/examples/declarative/minehunt/Explosion.qml
@@ -0,0 +1,18 @@
+Item {
+ property bool explode : false
+
+ Particles {
+ width: 38
+ height: 21
+ lifeSpan: 3600000
+ lifeSpanDeviation: 0
+ source: "pics/star.png"
+ count: 200
+ angle: 270
+ angleDeviation: 360
+ velocity: 100
+ velocityDeviation: 20
+ z: 100
+ emitting: explode
+ }
+}
diff --git a/examples/declarative/minehunt/main.cpp b/examples/declarative/minehunt/main.cpp
new file mode 100644
index 0000000..7f10757
--- /dev/null
+++ b/examples/declarative/minehunt/main.cpp
@@ -0,0 +1,312 @@
+#include "qmlbindablevalue.h"
+#include "qmlengine.h"
+#include "qmlcontext.h"
+#include "qml.h"
+#include <qfxitem.h>
+#include <qfxview.h>
+
+#include <QWidget>
+#include <QApplication>
+#include <QFile>
+#include <QTime>
+#include <QTimer>
+#include <QVBoxLayout>
+#include <QFileInfo>
+
+QString fileName = "minehunt.qml";
+
+class Tile : public QObject
+{
+ Q_OBJECT
+public:
+ Tile() : _hasFlag(false), _hasMine(false), _hint(-1), _flipped(false) {}
+
+ Q_PROPERTY(bool hasFlag READ hasFlag WRITE setHasFlag NOTIFY hasFlagChanged);
+ bool hasFlag() const { return _hasFlag; }
+
+ Q_PROPERTY(bool hasMine READ hasMine NOTIFY hasMineChanged);
+ bool hasMine() const { return _hasMine; }
+
+ Q_PROPERTY(int hint READ hint NOTIFY hintChanged);
+ int hint() const { return _hint; }
+
+ Q_PROPERTY(bool flipped READ flipped NOTIFY flippedChanged());
+ bool flipped() const { return _flipped; }
+
+ void setHasFlag(bool flag) {if(flag==_hasFlag) return; _hasFlag = flag; emit hasFlagChanged();}
+ void setHasMine(bool mine) {if(mine==_hasMine) return; _hasMine = mine; emit hasMineChanged();}
+ void setHint(int hint) { if(hint == _hint) return; _hint = hint; emit hintChanged(); }
+ void flip() { if (_flipped) return; _flipped = true; emit flippedChanged(); }
+ void unflip() { if(!_flipped) return; _flipped = false; emit flippedChanged(); }
+
+signals:
+ void flippedChanged();
+ void hasFlagChanged();
+ void hintChanged();
+ void hasMineChanged();
+
+private:
+ bool _hasFlag;
+ bool _hasMine;
+ int _hint;
+ bool _flipped;
+};
+
+QML_DECLARE_TYPE(Tile);
+QML_DEFINE_TYPE(Tile,Tile);
+
+class MyWidget : public QWidget
+{
+Q_OBJECT
+public:
+ MyWidget(int = 370, int = 480, QWidget *parent=0, Qt::WindowFlags flags=0);
+ ~MyWidget();
+
+ Q_PROPERTY(QList<Tile *> *tiles READ tiles);
+ QList<Tile *> *tiles() { return &_tiles; }
+
+ Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY isPlayingChanged);
+ bool isPlaying() {return playing;}
+
+ Q_PROPERTY(bool hasWon READ hasWon NOTIFY hasWonChanged);
+ bool hasWon() {return won;}
+
+ Q_PROPERTY(int numMines READ numMines NOTIFY numMinesChanged);
+ int numMines() const{return nMines;}
+
+ Q_PROPERTY(int numFlags READ numFlags NOTIFY numFlagsChanged);
+ int numFlags() const{return nFlags;}
+
+public slots:
+ Q_INVOKABLE void flip(int row, int col);
+ Q_INVOKABLE void flag(int row, int col);
+ void setBoard();
+ void reset();
+
+signals:
+ void isPlayingChanged();
+ void hasWonChanged();
+ void numMinesChanged();
+ void numFlagsChanged();
+
+private:
+ bool onBoard( int r, int c ) const { return r >= 0 && r < numRows && c >= 0 && c < numCols; }
+ Tile *tile( int row, int col ) { return onBoard(row, col) ? _tiles[col+numRows*row] : 0; }
+ int getHint(int row, int col);
+ void setPlaying(bool b){if(b==playing) return; playing=b; emit isPlayingChanged();}
+
+ QFxView *canvas;
+
+ QList<Tile *> _tiles;
+ int numCols;
+ int numRows;
+ bool playing;
+ bool won;
+ int remaining;
+ int nMines;
+ int nFlags;
+};
+
+MyWidget::MyWidget(int width, int height, QWidget *parent, Qt::WindowFlags flags)
+: QWidget(parent, flags), canvas(0), numCols(9), numRows(9), playing(true), won(false)
+{
+ setObjectName("mainWidget");
+ srand(QTime(0,0,0).secsTo(QTime::currentTime()));
+
+ //initialize array
+ for(int ii = 0; ii < numRows * numCols; ++ii) {
+ _tiles << new Tile;
+ }
+
+ reset();
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->setMargin(0);
+ setLayout(vbox);
+
+ canvas = new QFxView(this);
+ canvas->setFixedSize(width, height);
+ vbox->addWidget(canvas);
+
+ QFile file(fileName);
+ file.open(QFile::ReadOnly);
+ QString qml = file.readAll();
+ canvas->setQml(qml, fileName);
+
+ QmlContext *ctxt = canvas->rootContext();
+ ctxt->activate();
+ ctxt->addDefaultObject(this);
+ ctxt->deactivate();
+
+ canvas->execute();
+}
+
+MyWidget::~MyWidget()
+{
+}
+
+void MyWidget::setBoard()
+{
+ foreach(Tile* t, _tiles){
+ t->setHasMine(false);
+ t->setHint(-1);
+ }
+ //place mines
+ int mines = nMines;
+ remaining = numRows*numCols-mines;
+ while ( mines ) {
+ int col = int((double(rand()) / double(RAND_MAX)) * numCols);
+ int row = int((double(rand()) / double(RAND_MAX)) * numRows);
+
+ Tile* t = tile( row, col );
+
+ if (t && !t->hasMine()) {
+ t->setHasMine( true );
+ mines--;
+ }
+ }
+
+ //set hints
+ for (int r = 0; r < numRows; r++)
+ for (int c = 0; c < numCols; c++) {
+ Tile* t = tile(r, c);
+ if (t && !t->hasMine()) {
+ int hint = getHint(r,c);
+ t->setHint(hint);
+ }
+ }
+
+ setPlaying(true);
+}
+
+void MyWidget::reset()
+{
+ foreach(Tile* t, _tiles){
+ t->unflip();
+ t->setHasFlag(false);
+ }
+ nMines = 12;
+ nFlags = 0;
+ setPlaying(false);
+ QTimer::singleShot(900,this, SLOT(setBoard()));
+}
+
+int MyWidget::getHint(int row, int col)
+{
+ int hint = 0;
+ for (int c = col-1; c <= col+1; c++)
+ for (int r = row-1; r <= row+1; r++) {
+ Tile* t = tile(r, c);
+ if (t && t->hasMine())
+ hint++;
+ }
+ return hint;
+}
+
+void MyWidget::flip(int row, int col)
+{
+ if(!playing)
+ return;
+
+ Tile *t = tile(row, col);
+ if (!t || t->hasFlag())
+ return;
+
+ if(t->flipped()){
+ int flags = 0;
+ for (int c = col-1; c <= col+1; c++)
+ for (int r = row-1; r <= row+1; r++) {
+ Tile *nearT = tile(r, c);
+ if(!nearT || nearT == t)
+ continue;
+ if(nearT->hasFlag())
+ flags++;
+ }
+ if(!t->hint() || t->hint() != flags)
+ return;
+ for (int c = col-1; c <= col+1; c++)
+ for (int r = row-1; r <= row+1; r++) {
+ Tile *nearT = tile(r, c);
+ if (nearT && !nearT->flipped() && !nearT->hasFlag()) {
+ flip( r, c );
+ }
+ }
+ return;
+ }
+
+ t->flip();
+
+ if (t->hint() == 0) {
+ for (int c = col-1; c <= col+1; c++)
+ for (int r = row-1; r <= row+1; r++) {
+ Tile* t = tile(r, c);
+ if (t && !t->flipped()) {
+ flip( r, c );
+ }
+ }
+ }
+
+ if(t->hasMine()){
+ for (int r = 0; r < numRows; r++)//Flip all other mines
+ for (int c = 0; c < numCols; c++) {
+ Tile* t = tile(r, c);
+ if (t && t->hasMine()) {
+ flip(r, c);
+ }
+ }
+ won = false;
+ hasWonChanged();
+ setPlaying(false);
+ }
+
+ remaining--;
+ if(!remaining){
+ won = true;
+ hasWonChanged();
+ setPlaying(false);
+ }
+}
+
+void MyWidget::flag(int row, int col)
+{
+ Tile *t = tile(row, col);
+ if(!t)
+ return;
+
+ t->setHasFlag(!t->hasFlag());
+ nFlags += (t->hasFlag()?1:-1);
+ emit numFlagsChanged();
+}
+/////////////////////////////////////////////////////////
+
+int main(int argc, char ** argv)
+{
+ QApplication app(argc, argv);
+
+ bool frameless = false;
+
+ int width = 370;
+ int height = 480;
+
+ for (int i = 1; i < argc; ++i) {
+ QString arg = argv[i];
+ if (arg == "-frameless") {
+ frameless = true;
+ } else if(arg == "-width" && i < (argc - 1)) {
+ ++i;
+ width = ::atoi(argv[i]);
+ } else if(arg == "-height" && i < (argc - 1)) {
+ ++i;
+ height = ::atoi(argv[i]);
+ } else if (arg[0] != '-') {
+ fileName = arg;
+ }
+ }
+
+ MyWidget wid(width, height, 0, frameless ? Qt::FramelessWindowHint : Qt::Widget);
+ wid.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/declarative/minehunt/minehunt.pro b/examples/declarative/minehunt/minehunt.pro
new file mode 100644
index 0000000..08b6254
--- /dev/null
+++ b/examples/declarative/minehunt/minehunt.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+
+QT += script declarative
+
+target.path = $$[QT_INSTALL_EXAMPLES]/declarative/minehunt
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS minehunt.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/declarative/minehunt
+INSTALLS += target sources
diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml
new file mode 100644
index 0000000..bf31c3d
--- /dev/null
+++ b/examples/declarative/minehunt/minehunt.qml
@@ -0,0 +1,160 @@
+Item {
+ id: field
+ width: 370
+ height: 480
+
+ property int clickx : 0
+ property int clicky : 0
+
+ resources: [
+ Component {
+ id: tile
+ Flipable {
+ id: flipable
+ width: 40
+ height: 40
+ axis: Axis {
+ startX: 20
+ startY: 20
+ endX: 20
+ endY: 0
+ }
+ front: Image {
+ source: "pics/front.png"
+ width: 40
+ height: 40
+ Image {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ source: "pics/flag.png"
+ opacity: modelData.hasFlag
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+ }
+ back: Image {
+ source: "pics/back.png"
+ width: 40
+ height: 40
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ text: modelData.hint
+ color: "white"
+ font.bold: true
+ opacity: modelData.hasMine == false && modelData.hint > 0
+ }
+ Image {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ source: "pics/bomb.png"
+ opacity: modelData.hasMine
+ }
+ Explosion {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ explode: modelData.hasMine==true && modelData.flipped==true
+ }
+ }
+ states: [
+ State {
+ name: "back"
+ when: modelData.flipped == true
+ SetProperty {
+ target: flipable
+ property: "rotation"
+ value: 180
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ SequentialAnimation {
+ PauseAnimation {
+ duration: {var ret = Math.abs(flipable.parent.x-field.clickx) + Math.abs(flipable.parent.y-field.clicky); if (ret > 0) {if(modelData.hasMine==true && modelData.flipped==true){ret*3;}else{ret;}} else {0}}
+ }
+ NumericAnimation {
+ easing: "easeInOutQuad"
+ properties: "rotation"
+ }
+ }
+ }
+ ]
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { field.clickx = flipable.parent.x; field.clicky = flipable.parent.y; row = Math.floor(index/9); col = index - (Math.floor(index/9) * 9); if(mouse.button==undefined || mouse.button==Qt.RightButton){flag(row,col);}else{flip(row,col);} }
+ }
+ }
+ }
+ ]
+ Image {
+ source: "pics/No-Ones-Laughing-3.jpg"
+ tile: true
+ }
+ Description {
+ text: "Use the 'minehunt' executable to run this demo!"
+ width: 300
+ opacity: tiles?0:1
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ Repeater {
+ dataSource: tiles
+ x: 1
+ y: 1
+ Component {
+ ComponentInstance {
+ component: tile
+ x: (index - (Math.floor(index/9) * 9)) * 41
+ y: Math.floor(index/9) * 41
+ }
+ }
+ }
+ Item {
+ id: gamedata
+ width: 370
+ height: 100
+ y: 380
+ Text {
+ color: "white"
+ font.size: 18
+ x: 20
+ y: 20
+ }
+ Image {
+ x: 100
+ y: 20
+ source: "pics/bomb-color.png"
+ }
+ Text {
+ x: 100
+ y: 60
+ color: "white"
+ text: numMines
+ }
+ Image {
+ x: 140
+ y: 20
+ source: "pics/flag-color.png"
+ }
+ Text {
+ x: 140
+ y: 60
+ color: "white"
+ text: numFlags
+ }
+ Image {
+ x: 280
+ y: 10
+ source: if(isPlaying==true){'pics/face-smile.png'}else{if(hasWon==true){'pics/face-smile-big.png'}else{'pics/face-sad.png'}}
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { reset() }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/minehunt/pics/No-Ones-Laughing-3.jpg b/examples/declarative/minehunt/pics/No-Ones-Laughing-3.jpg
new file mode 100644
index 0000000..445567f
--- /dev/null
+++ b/examples/declarative/minehunt/pics/No-Ones-Laughing-3.jpg
Binary files differ
diff --git a/examples/declarative/minehunt/pics/back.png b/examples/declarative/minehunt/pics/back.png
new file mode 100644
index 0000000..f6b3f0b
--- /dev/null
+++ b/examples/declarative/minehunt/pics/back.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/bomb-color.png b/examples/declarative/minehunt/pics/bomb-color.png
new file mode 100644
index 0000000..61ad0a9
--- /dev/null
+++ b/examples/declarative/minehunt/pics/bomb-color.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/bomb.png b/examples/declarative/minehunt/pics/bomb.png
new file mode 100644
index 0000000..a992575
--- /dev/null
+++ b/examples/declarative/minehunt/pics/bomb.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/face-sad.png b/examples/declarative/minehunt/pics/face-sad.png
new file mode 100644
index 0000000..cf00aaf
--- /dev/null
+++ b/examples/declarative/minehunt/pics/face-sad.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/face-smile-big.png b/examples/declarative/minehunt/pics/face-smile-big.png
new file mode 100644
index 0000000..f9c2335
--- /dev/null
+++ b/examples/declarative/minehunt/pics/face-smile-big.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/face-smile.png b/examples/declarative/minehunt/pics/face-smile.png
new file mode 100644
index 0000000..3d66d72
--- /dev/null
+++ b/examples/declarative/minehunt/pics/face-smile.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/flag-color.png b/examples/declarative/minehunt/pics/flag-color.png
new file mode 100644
index 0000000..aadad0f
--- /dev/null
+++ b/examples/declarative/minehunt/pics/flag-color.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/flag.png b/examples/declarative/minehunt/pics/flag.png
new file mode 100644
index 0000000..39cde4d
--- /dev/null
+++ b/examples/declarative/minehunt/pics/flag.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/front.png b/examples/declarative/minehunt/pics/front.png
new file mode 100644
index 0000000..834331b
--- /dev/null
+++ b/examples/declarative/minehunt/pics/front.png
Binary files differ
diff --git a/examples/declarative/minehunt/pics/star.png b/examples/declarative/minehunt/pics/star.png
new file mode 100644
index 0000000..3772359
--- /dev/null
+++ b/examples/declarative/minehunt/pics/star.png
Binary files differ
diff --git a/examples/declarative/mouseregion/mouse.qml b/examples/declarative/mouseregion/mouse.qml
new file mode 100644
index 0000000..471874d
--- /dev/null
+++ b/examples/declarative/mouseregion/mouse.qml
@@ -0,0 +1,38 @@
+Rect {
+ color: "white"
+ width: 200; height: 200
+ Rect {
+ width: 50; height: 50
+ color: "red"
+ Text { text: "Click"; anchors.centeredIn: parent }
+ MouseRegion {
+ onPressed: { print('press (x: ' + mouse.x + ' y: ' + mouse.y + ' button: ' + (mouse.button == Qt.RightButton ? 'right' : 'left') + ' Shift: ' + (mouse.modifiers & Qt.ShiftModifier ? 'true' : 'false') + ')') }
+ onReleased: { print('release (x: ' + mouse.x + ' y: ' + mouse.y + ' isClick: ' + mouse.isClick + ' wasHeld: ' + mouse.wasHeld + ')') }
+ onClicked: { print('click (x: ' + mouse.x + ' y: ' + mouse.y + ' wasHeld: ' + mouse.wasHeld + ')') }
+ onDoubleClicked: { print('double click (x: ' + mouse.x + ' y: ' + mouse.y + ')') }
+ onPressAndHold: { print('press and hold') }
+ onExitedWhilePressed: { print('exiting while pressed') }
+ onReenteredWhilePressed: { print('reentering while pressed') }
+ anchors.fill: parent
+ }
+ }
+ Rect {
+ y: 100; width: 50; height: 50
+ color: "blue"
+ Text { text: "Drag"; anchors.centeredIn: parent }
+ MouseRegion {
+ drag.target: parent
+ drag.axis: "x"
+ drag.xmin: 0
+ drag.xmax: 150
+ onPressed: { print('press') }
+ onReleased: { print('release (isClick: ' + mouse.isClick + ') (wasHeld: ' + mouse.wasHeld + ')') }
+ onClicked: { print('click' + '(wasHeld: ' + mouse.wasHeld + ')') }
+ onDoubleClicked: { print('double click') }
+ onPressAndHold: { print('press and hold') }
+ onExitedWhilePressed: { print('exiting while pressed') }
+ onReenteredWhilePressed: { print('reentering while pressed') }
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/examples/declarative/scrollbar/ScrollBar.qml b/examples/declarative/scrollbar/ScrollBar.qml
new file mode 100644
index 0000000..8020d62
--- /dev/null
+++ b/examples/declarative/scrollbar/ScrollBar.qml
@@ -0,0 +1,29 @@
+Item {
+ id: ScrollBar
+ // The properties that define the scrollbar's state.
+ // position and pageSize are in the range 0.0 - 1.0. They are relative to the
+ // height of the page, i.e. a pageSize of 0.5 means that you can see 50%
+ // of the height of the view.
+ // orientation can be either 'Vertical' or 'Horizontal'
+ property var position
+ property var pageSize
+ property var orientation : "Vertical"
+
+ // A light, semi-transparent background
+ Rect {
+ id: Background
+ radius: orientation == 'Vertical' ? (width/2) : (height/2)
+ color: "white"; opacity: 0.3
+ anchors.fill: parent
+ }
+ // Size the bar to the required size, depending upon the orientation.
+ Rect {
+ opacity: 0.6
+ color: "black"
+ radius: orientation == 'Vertical' ? (width/2) : (height/2)
+ x: orientation == 'Vertical' ? 2 : (ScrollBar.position * (ScrollBar.width-4) + 2)
+ y: orientation == 'Vertical' ? (ScrollBar.position * (ScrollBar.height-4) + 2) : 2
+ width: orientation == 'Vertical' ? (parent.width-4) : (ScrollBar.pageSize * (ScrollBar.width-4))
+ height: orientation == 'Vertical' ? (ScrollBar.pageSize * (ScrollBar.height-4)) : (parent.height-4)
+ }
+}
diff --git a/examples/declarative/scrollbar/display.qml b/examples/declarative/scrollbar/display.qml
new file mode 100644
index 0000000..42e8f25
--- /dev/null
+++ b/examples/declarative/scrollbar/display.qml
@@ -0,0 +1,63 @@
+Rect {
+ width: 640
+ height: 480
+ // Create a flickable to view a large image.
+ Flickable {
+ id: View
+ anchors.fill: parent
+ Image {
+ id: Picture
+ source: "pics/niagara_falls.jpg"
+ }
+ viewportWidth: Picture.width
+ viewportHeight: Picture.height
+ // Only show the scrollbars when the view is moving.
+ states: [
+ State {
+ name: "ShowBars"
+ when: View.moving
+ SetProperty {
+ target: SBV
+ property: "opacity"
+ value: 1
+ }
+ SetProperty {
+ target: SBH
+ property: "opacity"
+ value: 1
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "*"
+ NumericAnimation {
+ properties: "opacity"
+ duration: 400
+ }
+ }
+ ]
+ }
+ // Attach scrollbars to the right and bottom edges of the view.
+ ScrollBar {
+ id: SBV
+ opacity: 0
+ orientation: "Vertical"
+ position: View.pageYPosition
+ pageSize: View.pageHeight
+ width: 12
+ height: View.height-12
+ anchors.right: View.right
+ }
+ ScrollBar {
+ id: SBH
+ opacity: 0
+ orientation: "Horizontal"
+ position: View.pageXPosition
+ pageSize: View.pageWidth
+ height: 12
+ width: View.width-12
+ anchors.bottom: View.bottom
+ }
+}
diff --git a/examples/declarative/scrollbar/pics/niagara_falls.jpg b/examples/declarative/scrollbar/pics/niagara_falls.jpg
new file mode 100644
index 0000000..618d808
--- /dev/null
+++ b/examples/declarative/scrollbar/pics/niagara_falls.jpg
Binary files differ
diff --git a/examples/declarative/slideswitch/Switch.qml b/examples/declarative/slideswitch/Switch.qml
new file mode 100644
index 0000000..8bc88e4
--- /dev/null
+++ b/examples/declarative/slideswitch/Switch.qml
@@ -0,0 +1,56 @@
+Item {
+ id: Switch
+ width: Groove.width; height: Groove.height
+
+ property var on
+
+ Script {
+
+ function toggle() {
+ if(Switch.state == "On")
+ Switch.state = "Off";
+ else
+ Switch.state = "On";
+ }
+ function dorelease() {
+ if(Knob.x == 1) {
+ if(Switch.state == "Off")
+ return;
+ }
+
+ if(Knob.x == 78) {
+ if(Switch.state == "On")
+ return;
+ }
+
+ toggle();
+ }
+
+ }
+ Image { id: Groove; source: "background.svg" }
+ MouseRegion { anchors.fill: Groove; onClicked: { toggle() } }
+ Image { id: Knob; source: "knob.svg"; x: 1; y: 2 }
+ MouseRegion {
+ anchors.fill: Knob
+ onClicked: { toggle() }
+ onReleased: { dorelease() }
+ drag.target: Knob; drag.axis: "x"; drag.xmin: 1; drag.xmax: 78
+ }
+ states: [
+ State {
+ name: "On"
+ SetProperty { target: Knob; property: "x"; value: 78 }
+ SetProperty { target: Switch; property: "on"; value: true }
+ },
+ State {
+ name: "Off"
+ SetProperty { target: Knob; property: "x"; value: 1 }
+ SetProperty { target: Switch; property: "on"; value: false }
+ }
+ ]
+ transitions: [
+ Transition {
+ NumericAnimation { properties: "x"; easing: "easeInOutQuad"; duration: 200 }
+ }
+ ]
+}
diff --git a/examples/declarative/slideswitch/background.svg b/examples/declarative/slideswitch/background.svg
new file mode 100644
index 0000000..f920d3e
--- /dev/null
+++ b/examples/declarative/slideswitch/background.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ x="0px" y="0px" width="130px" height="56px" viewBox="0 0 130 56" enable-background="new 0 0 130 56" xml:space="preserve">
+<defs>
+</defs>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-37.5005" y1="-66" x2="-37.5005" y2="-121.9985" gradientTransform="matrix(1 0 0 -1 102.5 -66)">
+ <stop offset="0.0056" style="stop-color:#000000"/>
+ <stop offset="1" style="stop-color:#EAECEF"/>
+</linearGradient>
+<path fill="url(#SVGID_1_)" d="M101.998,55.998H28c-15.439,0-28-12.562-28-28C0,12.56,12.561,0,28,0h73.998
+ c15.439,0,28,12.559,28,27.998C129.998,43.438,117.438,55.998,101.998,55.998L101.998,55.998z"/>
+<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="-5.5" y1="-132.1338" x2="-69.5002" y2="-55.8613" gradientTransform="matrix(1 0 0 -1 102.5 -66)">
+ <stop offset="0.0056" style="stop-color:#000000"/>
+ <stop offset="1" style="stop-color:#828385"/>
+</linearGradient>
+<path fill="url(#SVGID_2_)" d="M127.999,27.998c0,14.359-11.642,26-26,26h-74c-14.359,0-26-11.641-26-26l0,0
+ c0-14.359,11.641-26,26-26h74C116.357,1.998,127.999,13.639,127.999,27.998L127.999,27.998z"/>
+</svg>
diff --git a/examples/declarative/slideswitch/display.qml b/examples/declarative/slideswitch/display.qml
new file mode 100644
index 0000000..cea89b6
--- /dev/null
+++ b/examples/declarative/slideswitch/display.qml
@@ -0,0 +1,8 @@
+Rect {
+ color: "white"
+ width: 150
+ height: 150
+ Switch {
+ anchors.centeredIn: parent
+ }
+}
diff --git a/examples/declarative/slideswitch/knob.svg b/examples/declarative/slideswitch/knob.svg
new file mode 100644
index 0000000..fb69337
--- /dev/null
+++ b/examples/declarative/slideswitch/knob.svg
@@ -0,0 +1,867 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ x="0px"
+ y="0px"
+ width="52px"
+ height="52px"
+ viewBox="0 0 52 52"
+ enable-background="new 0 0 52 52"
+ xml:space="preserve"
+ id="svg3883"
+ sodipodi:version="0.32"
+ inkscape:version="0.44.1"
+ sodipodi:docname="knob_on.svg"
+ sodipodi:docbase="/local/axel/embeddedwidgets/embeddedstories/skins/svgslideswitch/MetallicBrush"><metadata
+ id="metadata4200"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ inkscape:window-height="640"
+ inkscape:window-width="937"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="8.3653846"
+ inkscape:cx="26.000002"
+ inkscape:cy="26"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="svg3883" />
+<defs
+ id="defs3885">
+</defs>
+<linearGradient
+ id="SVGID_1_"
+ gradientUnits="userSpaceOnUse"
+ x1="-59.7866"
+ y1="-115.917"
+ x2="-93.2123"
+ y2="-76.0818"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#000000"
+ id="stop3888" />
+ <stop
+ offset="1"
+ style="stop-color:#EAECEF"
+ id="stop3890" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="26"
+ id="circle3892"
+ style="fill:url(#SVGID_1_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="26"
+ sodipodi:ry="26"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="-100.5"
+ y1="-96"
+ x2="-52.5"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop3895" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop3897" />
+ <stop
+ offset="0.6043"
+ style="stop-color:#E7EAED"
+ id="stop3899" />
+ <stop
+ offset="0.6751"
+ style="stop-color:#DEE4E7"
+ id="stop3901" />
+ <stop
+ offset="0.7358"
+ style="stop-color:#CFD9DD"
+ id="stop3903" />
+ <stop
+ offset="0.791"
+ style="stop-color:#B9CACF"
+ id="stop3905" />
+ <stop
+ offset="0.8425"
+ style="stop-color:#9EB6BD"
+ id="stop3907" />
+ <stop
+ offset="0.891"
+ style="stop-color:#7B9EA7"
+ id="stop3909" />
+ <stop
+ offset="0.9374"
+ style="stop-color:#53828C"
+ id="stop3911" />
+ <stop
+ offset="0.9809"
+ style="stop-color:#25626E"
+ id="stop3913" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop3915" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="24"
+ id="circle3917"
+ style="fill:url(#SVGID_2_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="24"
+ sodipodi:ry="24"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_3_"
+ gradientUnits="userSpaceOnUse"
+ x1="-98.6328"
+ y1="-96"
+ x2="-54.3672"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop3920" />
+ <stop
+ offset="0.073"
+ style="stop-color:#8FAECB"
+ id="stop3922" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop3924" />
+ <stop
+ offset="0.5902"
+ style="stop-color:#E7E9ED"
+ id="stop3926" />
+ <stop
+ offset="0.618"
+ style="stop-color:#E4E7EB"
+ id="stop3928" />
+ <stop
+ offset="0.6697"
+ style="stop-color:#E0E4E9"
+ id="stop3930" />
+ <stop
+ offset="0.7211"
+ style="stop-color:#D4DCE1"
+ id="stop3932" />
+ <stop
+ offset="0.7722"
+ style="stop-color:#C0CFD5"
+ id="stop3934" />
+ <stop
+ offset="0.809"
+ style="stop-color:#ADC2C9"
+ id="stop3936" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop3938" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="22.132999"
+ id="circle3940"
+ style="fill:url(#SVGID_3_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="22.132999"
+ sodipodi:ry="22.132999"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="-96.7671"
+ y1="-96"
+ x2="-56.2324"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop3943" />
+ <stop
+ offset="0.073"
+ style="stop-color:#86A7C4"
+ id="stop3945" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop3947" />
+ <stop
+ offset="0.577"
+ style="stop-color:#E7EAED"
+ id="stop3949" />
+ <stop
+ offset="0.618"
+ style="stop-color:#E1E6EA"
+ id="stop3951" />
+ <stop
+ offset="0.6697"
+ style="stop-color:#DDE3E8"
+ id="stop3953" />
+ <stop
+ offset="0.7211"
+ style="stop-color:#D1DBE1"
+ id="stop3955" />
+ <stop
+ offset="0.7722"
+ style="stop-color:#BDCDD5"
+ id="stop3957" />
+ <stop
+ offset="0.809"
+ style="stop-color:#AAC0CA"
+ id="stop3959" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop3961" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="20.267"
+ id="circle3963"
+ style="fill:url(#SVGID_4_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="20.267"
+ sodipodi:ry="20.267"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_5_"
+ gradientUnits="userSpaceOnUse"
+ x1="-94.8999"
+ y1="-96"
+ x2="-58.0996"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop3966" />
+ <stop
+ offset="0.073"
+ style="stop-color:#7E9FBC"
+ id="stop3968" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop3970" />
+ <stop
+ offset="0.5709"
+ style="stop-color:#E6E9ED"
+ id="stop3972" />
+ <stop
+ offset="0.618"
+ style="stop-color:#DFE4E9"
+ id="stop3974" />
+ <stop
+ offset="0.6687"
+ style="stop-color:#DBE1E7"
+ id="stop3976" />
+ <stop
+ offset="0.7193"
+ style="stop-color:#CFD9E0"
+ id="stop3978" />
+ <stop
+ offset="0.7695"
+ style="stop-color:#BBCCD6"
+ id="stop3980" />
+ <stop
+ offset="0.809"
+ style="stop-color:#A6BECA"
+ id="stop3982" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop3984" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="18.4"
+ id="circle3986"
+ style="fill:url(#SVGID_5_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="18.4"
+ sodipodi:ry="18.4"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_6_"
+ gradientUnits="userSpaceOnUse"
+ x1="-93.0332"
+ y1="-96"
+ x2="-59.9668"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop3989" />
+ <stop
+ offset="0.073"
+ style="stop-color:#7697B4"
+ id="stop3991" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop3993" />
+ <stop
+ offset="0.5636"
+ style="stop-color:#E6E9ED"
+ id="stop3995" />
+ <stop
+ offset="0.618"
+ style="stop-color:#DCE2E8"
+ id="stop3997" />
+ <stop
+ offset="0.6687"
+ style="stop-color:#D8DFE6"
+ id="stop3999" />
+ <stop
+ offset="0.7193"
+ style="stop-color:#CCD7E0"
+ id="stop4001" />
+ <stop
+ offset="0.7695"
+ style="stop-color:#B8CAD5"
+ id="stop4003" />
+ <stop
+ offset="0.809"
+ style="stop-color:#A3BCCA"
+ id="stop4005" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4007" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="16.533001"
+ id="circle4009"
+ style="fill:url(#SVGID_6_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="16.533001"
+ sodipodi:ry="16.533001"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_7_"
+ gradientUnits="userSpaceOnUse"
+ x1="-91.167"
+ y1="-96"
+ x2="-61.833"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4012" />
+ <stop
+ offset="0.073"
+ style="stop-color:#6D8FAD"
+ id="stop4014" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4016" />
+ <stop
+ offset="0.5605"
+ style="stop-color:#E5E8EC"
+ id="stop4018" />
+ <stop
+ offset="0.618"
+ style="stop-color:#DAE1E7"
+ id="stop4020" />
+ <stop
+ offset="0.6679"
+ style="stop-color:#D6DEE5"
+ id="stop4022" />
+ <stop
+ offset="0.7175"
+ style="stop-color:#CAD6DF"
+ id="stop4024" />
+ <stop
+ offset="0.7669"
+ style="stop-color:#B6C9D6"
+ id="stop4026" />
+ <stop
+ offset="0.809"
+ style="stop-color:#9FBACB"
+ id="stop4028" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4030" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="14.667"
+ id="circle4032"
+ style="fill:url(#SVGID_7_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="14.667"
+ sodipodi:ry="14.667"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_8_"
+ gradientUnits="userSpaceOnUse"
+ x1="-89.2998"
+ y1="-96"
+ x2="-63.7002"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4035" />
+ <stop
+ offset="0.073"
+ style="stop-color:#6587A5"
+ id="stop4037" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4039" />
+ <stop
+ offset="0.5588"
+ style="stop-color:#E4E8EC"
+ id="stop4041" />
+ <stop
+ offset="0.618"
+ style="stop-color:#D8DFE7"
+ id="stop4043" />
+ <stop
+ offset="0.6675"
+ style="stop-color:#D4DCE5"
+ id="stop4045" />
+ <stop
+ offset="0.7167"
+ style="stop-color:#C8D5E0"
+ id="stop4047" />
+ <stop
+ offset="0.7657"
+ style="stop-color:#B4C8D6"
+ id="stop4049" />
+ <stop
+ offset="0.809"
+ style="stop-color:#9CB8CB"
+ id="stop4051" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4053" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="12.8"
+ id="circle4055"
+ style="fill:url(#SVGID_8_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="12.8"
+ sodipodi:ry="12.8"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_9_"
+ gradientUnits="userSpaceOnUse"
+ x1="-87.4331"
+ y1="-96"
+ x2="-65.5664"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4058" />
+ <stop
+ offset="0.073"
+ style="stop-color:#5D809D"
+ id="stop4060" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4062" />
+ <stop
+ offset="0.5567"
+ style="stop-color:#E3E7EC"
+ id="stop4064" />
+ <stop
+ offset="0.618"
+ style="stop-color:#D5DDE6"
+ id="stop4066" />
+ <stop
+ offset="0.6671"
+ style="stop-color:#D1DAE4"
+ id="stop4068" />
+ <stop
+ offset="0.7159"
+ style="stop-color:#C5D3DF"
+ id="stop4070" />
+ <stop
+ offset="0.7645"
+ style="stop-color:#B1C6D6"
+ id="stop4072" />
+ <stop
+ offset="0.809"
+ style="stop-color:#98B5CB"
+ id="stop4074" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4076" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="10.933"
+ id="circle4078"
+ style="fill:url(#SVGID_9_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="10.933"
+ sodipodi:ry="10.933"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_10_"
+ gradientUnits="userSpaceOnUse"
+ x1="-85.5659"
+ y1="-96"
+ x2="-67.4336"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4081" />
+ <stop
+ offset="0.073"
+ style="stop-color:#547896"
+ id="stop4083" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4085" />
+ <stop
+ offset="0.5588"
+ style="stop-color:#E1E6EB"
+ id="stop4087" />
+ <stop
+ offset="0.618"
+ style="stop-color:#D3DCE5"
+ id="stop4089" />
+ <stop
+ offset="0.6663"
+ style="stop-color:#CFD9E3"
+ id="stop4091" />
+ <stop
+ offset="0.7143"
+ style="stop-color:#C3D2DF"
+ id="stop4093" />
+ <stop
+ offset="0.7621"
+ style="stop-color:#AFC5D7"
+ id="stop4095" />
+ <stop
+ offset="0.809"
+ style="stop-color:#94B3CC"
+ id="stop4097" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4099" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="9.066"
+ id="circle4101"
+ style="fill:url(#SVGID_10_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="9.066"
+ sodipodi:ry="9.066"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_11_"
+ gradientUnits="userSpaceOnUse"
+ x1="-83.7002"
+ y1="-96"
+ x2="-69.2998"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4104" />
+ <stop
+ offset="0.073"
+ style="stop-color:#4C708E"
+ id="stop4106" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4108" />
+ <stop
+ offset="0.5625"
+ style="stop-color:#DEE4EA"
+ id="stop4110" />
+ <stop
+ offset="0.618"
+ style="stop-color:#D0DAE4"
+ id="stop4112" />
+ <stop
+ offset="0.6663"
+ style="stop-color:#CCD7E2"
+ id="stop4114" />
+ <stop
+ offset="0.7143"
+ style="stop-color:#C0D0DE"
+ id="stop4116" />
+ <stop
+ offset="0.7621"
+ style="stop-color:#ACC3D6"
+ id="stop4118" />
+ <stop
+ offset="0.809"
+ style="stop-color:#91B1CC"
+ id="stop4120" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4122" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="7.1999998"
+ id="circle4124"
+ style="fill:url(#SVGID_11_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="7.1999998"
+ sodipodi:ry="7.1999998"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_12_"
+ gradientUnits="userSpaceOnUse"
+ x1="-81.833"
+ y1="-96"
+ x2="-71.167"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4127" />
+ <stop
+ offset="0.073"
+ style="stop-color:#446986"
+ id="stop4129" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4131" />
+ <stop
+ offset="0.5757"
+ style="stop-color:#D9E0E8"
+ id="stop4133" />
+ <stop
+ offset="0.618"
+ style="stop-color:#CED8E3"
+ id="stop4135" />
+ <stop
+ offset="0.6655"
+ style="stop-color:#CAD5E2"
+ id="stop4137" />
+ <stop
+ offset="0.7129"
+ style="stop-color:#BECEDD"
+ id="stop4139" />
+ <stop
+ offset="0.7601"
+ style="stop-color:#AAC1D6"
+ id="stop4141" />
+ <stop
+ offset="0.807"
+ style="stop-color:#8EB0CC"
+ id="stop4143" />
+ <stop
+ offset="0.809"
+ style="stop-color:#8DAFCC"
+ id="stop4145" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4147" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="5.3330002"
+ id="circle4149"
+ style="fill:url(#SVGID_12_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="5.3330002"
+ sodipodi:ry="5.3330002"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_13_"
+ gradientUnits="userSpaceOnUse"
+ x1="-79.9658"
+ y1="-96"
+ x2="-73.0342"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4152" />
+ <stop
+ offset="0.073"
+ style="stop-color:#3B617F"
+ id="stop4154" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4156" />
+ <stop
+ offset="0.6087"
+ style="stop-color:#CED9E3"
+ id="stop4158" />
+ <stop
+ offset="0.618"
+ style="stop-color:#CBD7E2"
+ id="stop4160" />
+ <stop
+ offset="0.6655"
+ style="stop-color:#C7D4E1"
+ id="stop4162" />
+ <stop
+ offset="0.7129"
+ style="stop-color:#BBCDDD"
+ id="stop4164" />
+ <stop
+ offset="0.7601"
+ style="stop-color:#A7C0D6"
+ id="stop4166" />
+ <stop
+ offset="0.807"
+ style="stop-color:#8BAECD"
+ id="stop4168" />
+ <stop
+ offset="0.809"
+ style="stop-color:#8AADCD"
+ id="stop4170" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4172" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="3.4660001"
+ id="circle4174"
+ style="fill:url(#SVGID_13_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="3.4660001"
+ sodipodi:ry="3.4660001"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+<linearGradient
+ id="SVGID_14_"
+ gradientUnits="userSpaceOnUse"
+ x1="-78.1001"
+ y1="-96"
+ x2="-74.9004"
+ y2="-96"
+ gradientTransform="matrix(1,0,0,-1,102.5,-70)">
+ <stop
+ offset="0.0056"
+ style="stop-color:#8AADCE"
+ id="stop4177" />
+ <stop
+ offset="0.073"
+ style="stop-color:#335977"
+ id="stop4179" />
+ <stop
+ offset="0.5"
+ style="stop-color:#EAECEF"
+ id="stop4181" />
+ <stop
+ offset="0.618"
+ style="stop-color:#C9D5E1"
+ id="stop4183" />
+ <stop
+ offset="0.6648"
+ style="stop-color:#C5D3E0"
+ id="stop4185" />
+ <stop
+ offset="0.7114"
+ style="stop-color:#B9CBDC"
+ id="stop4187" />
+ <stop
+ offset="0.758"
+ style="stop-color:#A5BFD6"
+ id="stop4189" />
+ <stop
+ offset="0.8042"
+ style="stop-color:#89ADCE"
+ id="stop4191" />
+ <stop
+ offset="0.809"
+ style="stop-color:#86ABCD"
+ id="stop4193" />
+ <stop
+ offset="1"
+ style="stop-color:#0E525F"
+ id="stop4195" />
+</linearGradient>
+<circle
+ cx="26"
+ cy="26"
+ r="1.6"
+ id="circle4197"
+ style="fill:url(#SVGID_14_)"
+ sodipodi:cx="26"
+ sodipodi:cy="26"
+ sodipodi:rx="1.6"
+ sodipodi:ry="1.6"
+ transform="matrix(0.923077,0,0,0.923077,2,1.999996)" />
+</svg> \ No newline at end of file
diff --git a/examples/declarative/states/states.qml b/examples/declarative/states/states.qml
new file mode 100644
index 0000000..bcde20c
--- /dev/null
+++ b/examples/declarative/states/states.qml
@@ -0,0 +1,40 @@
+Rect {
+ id: Page
+ width: 300; height: 300; color: "white"
+ // A target region. Clicking in here sets the state to '' - the default state
+ Rect {
+ x: 0; y: 0; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='' } }
+ }
+ // Another target region. Clicking in here sets the state to 'Position1'
+ Rect {
+ x: 150; y: 50; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='Position1' } }
+ }
+ // Another target region. Clicking in here sets the state to 'Position2'
+ Rect {
+ x: 0; y: 200; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='Position2' } }
+ }
+ // Rect which will be moved when my state changes
+ Rect { id: myrect; width: 50; height: 50; color: "red" }
+
+ states: [
+ // In state 'Position1', change the 'myrect' item x, y to 150, 50.
+ State {
+ name: "Position1"
+ SetProperty { target: myrect; property: "x"; value: 150 }
+ SetProperty { target: myrect; property: "y"; value: 50 }
+ },
+ // In state 'Position2', change y to 100. We do not specify 'x' here -
+ // it will therefore be restored to its default value of 0, if it
+ // had been changed.
+ State {
+ name: "Position2"
+ SetProperty { target: myrect; property: "y"; value: 200 }
+ }
+ ]
+}
diff --git a/examples/declarative/states/transitions.qml b/examples/declarative/states/transitions.qml
new file mode 100644
index 0000000..4c1dceb
--- /dev/null
+++ b/examples/declarative/states/transitions.qml
@@ -0,0 +1,60 @@
+Rect {
+ id: Page
+ width: 300; height: 300; color: "white"
+ // A target region. Clicking in here sets the state to '' - the default state
+ Rect {
+ x: 0; y: 0; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='' } }
+ }
+ // Another target region. Clicking in here sets the state to 'Position1'
+ Rect {
+ x: 150; y: 50; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='Position1' } }
+ }
+ // Another target region. Clicking in here sets the state to 'Position2'
+ Rect {
+ x: 0; y: 200; width: 50; height: 50
+ color: "transparent"; pen.color: "black"
+ MouseRegion { anchors.fill: parent; onClicked: { Page.state='Position2' } }
+ }
+ // Rect which will be moved when my state changes
+ Rect { id: myrect; width: 50; height: 50; color: "red" }
+
+ states: [
+ // In state 'Position1', change the 'myrect' item x, y to 150, 50.
+ State {
+ name: "Position1"
+ SetProperty { target: myrect; property: "x"; value: 150 }
+ SetProperty { target: myrect; property: "y"; value: 50 }
+ },
+ // In state 'Position2', change y to 100. We do not specify 'x' here -
+ // it will therefore be restored to its default value of 0, if it
+ // had been changed.
+ State {
+ name: "Position2"
+ SetProperty { target: myrect; property: "y"; value: 200 }
+ }
+ ]
+
+ // transitions define how the properties change.
+ transitions: [
+ // When transitioning to 'Position1' move x,y over a duration of 1 second,
+ // with easeOutBounce easing function.
+ Transition {
+ fromState: "*"; toState: "Position1"
+ NumericAnimation { properties: "x,y"; easing: "easeOutBounce"; duration: 1000 }
+ },
+ // When transitioning to 'Position2' move x,y over a duration of 2 seconds,
+ // with easeInOutQuad easing function.
+ Transition {
+ fromState: "*"; toState: "Position2"
+ NumericAnimation { properties: "x,y"; easing: "easeInOutQuad"; duration: 2000 }
+ },
+ // For any other state changes move x,y linearly over duration of 200ms.
+ Transition {
+ NumericAnimation { properties: "x,y"; duration: 200 }
+ }
+ ]
+}
diff --git a/examples/declarative/support/contact.cpp b/examples/declarative/support/contact.cpp
new file mode 100644
index 0000000..7d90fc4
--- /dev/null
+++ b/examples/declarative/support/contact.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ $TROLLTECH$. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "contact.h"
+#include "qmltypes.h"
+
+QML_DEFINE_TYPE(Contact,Contact);
+Contact::Contact() : QObject(0)
+{
+ m_firstName = "John";
+ m_lastName = "Smith";
+ m_portraitFile = "contact.png";
+ m_company = "Trollkia";
+ m_emails << "smith@trollkia.com" << "john45@gmail.com";
+
+ m_numbers << new PhoneNumber;
+ m_numbers << new PhoneNumber;
+ m_numbers << new PhoneNumber;
+
+ m_numbers.at(0)->setType(PhoneNumber::HomePhone);
+ m_numbers.at(0)->setNumber("35412451");
+
+ m_numbers.at(1)->setType(PhoneNumber::BusinessPhone);
+ m_numbers.at(1)->setNumber("33424994");
+
+ m_numbers.at(2)->setType(PhoneNumber::MobilePhone);
+ m_numbers.at(2)->setNumber("0424655137");
+
+ m_addresses << new Address;
+ m_addresses << new Address;
+ m_addresses << new Address;
+ m_addresses.at(0)->setNumber(13);
+ m_addresses.at(0)->setStreet("Blackhill Cr");
+ m_addresses.at(0)->setCountry("Australia");
+ m_addresses.at(1)->setNumber(116);
+ m_addresses.at(1)->setStreet("Sandankerveien");
+ m_addresses.at(1)->setCountry("Norway");
+ m_addresses.at(2)->setNumber(92);
+ m_addresses.at(2)->setStreet("Elizibeth St");
+ m_addresses.at(2)->setCountry("Australia");
+}
+
+void Contact::addNumber(PhoneNumber *newNumber)
+{
+
+ m_numbers << newNumber;
+ emit numbersChanged();
+}
+
+void Contact::addAddress(Address *newAddress)
+{
+ m_addresses << newAddress;
+ emit addressesChanged();
+}
+
+void Contact::addEmail(QString &newEmail)
+{
+
+ m_emails << newEmail;
+ emit emailsChanged();
+}
+
+QML_DEFINE_TYPE(Address,Address);
+Address::Address()
+: _number(0)
+{
+}
+
+QML_DEFINE_TYPE(PhoneNumber, PhoneNumber);
+PhoneNumber::PhoneNumber()
+: _type(HomePhone)
+{
+}
diff --git a/examples/declarative/support/contact.h b/examples/declarative/support/contact.h
new file mode 100644
index 0000000..c403f8b
--- /dev/null
+++ b/examples/declarative/support/contact.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ $TROLLTECH$. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef CONTACT_H
+#define CONTACT_H
+
+#include <qml.h>
+#include <QtGui>
+
+
+class Address : public QObject
+{
+ Q_OBJECT
+public:
+ Address();
+
+ Q_PROPERTY(int number READ number WRITE setNumber NOTIFY changed);
+ Q_PROPERTY(QString street READ street WRITE setStreet NOTIFY changed);
+ Q_PROPERTY(QString country READ country WRITE setCountry NOTIFY changed);
+
+ int number() const { return _number; }
+ void setNumber(int n) { _number = n; emit changed(); }
+
+ QString street() const { return _street; }
+ void setStreet(const QString &s) { _street = s; emit changed(); }
+
+ QString country() const { return _country; }
+ void setCountry(const QString &c) { _country = c; emit changed(); }
+
+signals:
+ void changed();
+
+private:
+ int _number;
+ QString _street;
+ QString _country;
+};
+QML_DECLARE_TYPE(Address);
+
+class PhoneNumber : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(PhoneType)
+public:
+ PhoneNumber();
+
+ enum PhoneType {
+ HomePhone,
+ BusinessPhone,
+ MobilePhone
+ };
+
+ Q_PROPERTY(QString number READ number WRITE setNumber NOTIFY changed);
+ Q_PROPERTY(PhoneType type READ type WRITE setType NOTIFY changed);
+
+ QString number() const { return _number; }
+ void setNumber(QString n) { _number = n; emit changed(); }
+
+ PhoneType type() const { return _type; }
+ void setType(PhoneType type) { _type = type; emit changed(); }
+
+signals:
+ void changed();
+
+private:
+ QString _number;
+ PhoneType _type;
+};
+QML_DECLARE_TYPE(PhoneNumber);
+
+class Contact : public QObject
+{
+ Q_OBJECT
+public:
+ Contact();
+
+ Q_PROPERTY(QString firstName READ firstName WRITE setFirstName NOTIFY nameChanged);
+ QString firstName() const { return m_firstName; }
+
+ Q_PROPERTY(QString lastName READ lastName WRITE setLastName NOTIFY nameChanged);
+ QString lastName() const { return m_lastName; }
+
+ Q_PROPERTY(QString portraitFile READ portraitFile WRITE setPortraitFile NOTIFY portraitChanged);
+ QString portraitFile() const { return m_portraitFile; }
+
+ Q_PROPERTY(QString company READ company WRITE setCompany NOTIFY companyChanged);
+ QString company() const { return m_company; }
+
+ Q_PROPERTY(QStringList emails READ emails WRITE setEmails NOTIFY emailsChanged);
+ QStringList emails() const { return m_emails; }
+
+ Q_PROPERTY(QList<Address *>* addresses READ addresses);
+ QList<Address *>* addresses() { return &m_addresses; }
+
+ Q_PROPERTY(QList<PhoneNumber *>* numbers READ numbers);
+ QList<PhoneNumber *>* numbers() { return &m_numbers; }
+
+
+ void addEmail(QString&);
+ void addAddress(Address*);
+ void addNumber(PhoneNumber*);
+
+public slots:
+ void setFirstName(const QString &name) { m_firstName = name; emit nameChanged(); }
+ void setLastName(const QString &name) { m_lastName = name; emit nameChanged(); }
+ void setPortraitFile(const QString &portraitFile) { m_portraitFile = portraitFile; emit portraitChanged(); }
+ void setCompany(const QString &company) { m_company = company; emit companyChanged(); }
+ void setEmails(const QStringList &emails) { m_emails = emails; emit emailsChanged(); }
+
+signals:
+ void nameChanged();
+ void portraitChanged();
+ void companyChanged();
+ void emailsChanged();
+ void numbersChanged();
+ void addressesChanged();
+
+private:
+ QString m_firstName;
+ QString m_lastName;
+ QString m_portraitFile;
+
+ QString m_company;
+
+ QList<Address *> m_addresses;
+ QList<PhoneNumber *>m_numbers;
+ QStringList m_emails;
+};
+QML_DECLARE_TYPE(Contact);
+
+#endif
diff --git a/examples/declarative/support/contactmodel.cpp b/examples/declarative/support/contactmodel.cpp
new file mode 100644
index 0000000..efe108fb
--- /dev/null
+++ b/examples/declarative/support/contactmodel.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ $TROLLTECH$. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "contactmodel.h"
+#include "qmltypes.h"
+
+ContactModel::ContactModel(QObject *parent) : QListModelInterface(parent)
+{
+ QFile f("../contacts/contacts.txt");
+ f.open(QIODevice::ReadOnly);
+ QTextStream ts(&f);
+ QString text = ts.readLine();
+ while(!text.isEmpty()) {
+ Contact *c = new Contact;
+ QStringList list = text.split(" ");
+ c->setFirstName(list[0]);
+ c->setLastName(list[1]);
+ for (int i = 2; i < list.count(); ++i)
+ c->addEmail(list[i]);
+ //contactList.append(c);
+ insertContact(c);
+
+ text = ts.readLine();
+ }
+ f.close();
+}
+
+ContactModel::~ContactModel()
+{
+ while (!contactList.isEmpty()) {
+ Contact *c = contactList.takeFirst();
+ delete c;
+ }
+}
+
+int ContactModel::count() const
+{
+ return contactList.count();
+}
+
+QHash<int,QVariant> ContactModel::data(int index, const QList<int> &roles) const
+{
+ QHash<int,QVariant> returnHash;
+
+ for (int i = 0; i < roles.size(); ++i) {
+ int role = roles.at(i);
+ QVariant info;
+ switch(role) {
+ case PortraitRole:
+ info = "contact.png";
+ break;
+ case FirstNameRole:
+ info = contactList.at(index)->firstName();
+ break;
+ case LastNameRole:
+ info = contactList.at(index)->lastName();
+ break;
+ case CompanyRole:
+ info = contactList.at(index)->company();
+ break;
+ case EmailsRole:
+ info = contactList.at(index)->emails();
+ break;
+ case AddressesRole:
+ //returns QVariant BOOL
+ info = QVariant::fromValue(contactList.at(index)->addresses());
+ break;
+ case NumbersRole:
+ info = QVariant::fromValue(contactList.at(index)->numbers());
+ break;
+ default:
+ break;
+ }
+ returnHash.insert(role, info);
+ }
+
+ return returnHash;
+}
+
+QString ContactModel::toString(int role) const
+{
+ switch(role) {
+ case PortraitRole:
+ return "portrait";
+ case FirstNameRole:
+ return "firstName";
+ case LastNameRole:
+ return "lastName";
+ case CompanyRole:
+ return "company";
+ case EmailsRole:
+ return "emails";
+ case AddressesRole:
+ return "addresses";
+ case NumbersRole:
+ return "numbers";
+ default:
+ return "";
+ }
+}
+
+QList<int> ContactModel::roles() const
+{
+ return QList<int>() << PortraitRole << FirstNameRole << LastNameRole << CompanyRole << EmailsRole << AddressesRole << NumbersRole;
+}
+
+void ContactModel::deleteContact(int index)
+{
+ delete contactList.takeAt(index);
+ emit itemsRemoved(index, 1);
+}
+
+int ContactModel::insertContact(Contact *contact)
+{
+ int index = 0;
+ QString fullName = contact->lastName();
+ index = findIndex(fullName);
+ contactList.insert(index, contact);
+ emit itemsInserted(index, 1);
+ return index;
+}
+
+
+//search - binary search algorithm lastname only
+
+int ContactModel::findIndex(QString &searchName) const
+{
+ int start = 0;
+ int end = contactList.size()-1;
+ int middle = 0;
+ QString middleString;
+
+ while (start <= end)
+ {
+ middle = (start+end)/2;
+ middleString = contactList.at(middle)->lastName();
+ if (isAfter(searchName, middleString) < 0) start = middle+1;
+ else if( isAfter(middleString, searchName) < 0) end = middle-1;
+ else return middle;
+ }
+ return start;
+}
+
+int ContactModel::isAfter(QString &name1, QString &name2) const
+{
+ //if c1 is after c2 alphabetically, return positive
+ int compString = QString::compare(name1, name2, Qt::CaseInsensitive);
+ return -compString;
+}
diff --git a/examples/declarative/support/contactmodel.h b/examples/declarative/support/contactmodel.h
new file mode 100644
index 0000000..e262358
--- /dev/null
+++ b/examples/declarative/support/contactmodel.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ $TROLLTECH$. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef _CONTACTMODEL_H_
+#define _CONTACTMODEL_H_
+
+#include <qlistmodelinterface.h>
+#include "contact.h"
+
+class ContactModel : public QListModelInterface
+{
+ Q_OBJECT
+public:
+ ContactModel(QObject *parent = 0);
+ ~ContactModel();
+
+ enum Roles {
+ PortraitRole,
+ FirstNameRole,
+ LastNameRole,
+ CompanyRole,
+ EmailsRole,
+ AddressesRole,
+ NumbersRole
+ };
+
+ int count() const;
+
+ QHash<int,QVariant> data(int index, const QList<int> &roles) const;
+ QList<int> roles() const;
+
+
+ QString toString(int role) const;
+
+ void deleteContact(int index);
+ int insertContact(Contact *contact);
+
+ int isAfter(QString &name1, QString &name2) const;
+ int findIndex(QString &searchName) const;
+
+private:
+ QList<Contact*> contactList;
+};
+
+#endif
diff --git a/examples/declarative/support/support.pro b/examples/declarative/support/support.pro
new file mode 100644
index 0000000..1da1a28
--- /dev/null
+++ b/examples/declarative/support/support.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+TARGET = QtFxSupport
+DEPENDPATH += .
+INCLUDEPATH += .
+MOC_DIR = .moc
+OBJECTS_DIR = .obj
+DESTDIR = ../../lib
+QT += script declarative
+
+HEADERS += contact.h contactmodel.h
+SOURCES += contact.cpp contactmodel.cpp
+
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1/Removebutton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1/Removebutton.qml
new file mode 100644
index 0000000..bbe9f55
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1/Removebutton.qml
@@ -0,0 +1,9 @@
+//! [0]
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+}
+//! [0]
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml
new file mode 100644
index 0000000..cc5ebae
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/1_Drawing_and_animation.qml
@@ -0,0 +1,34 @@
+Rect {
+ id: page
+ width: layout.width
+ height: layout.height
+ color: "white"
+ VerticalLayout {
+ id: layout
+ width: contents.width
+ GroupBox {
+ contents: "1/RemoveButton.qml"
+ label: "Rectangle Component"
+ }
+ GroupBox {
+ contents: "2/RemoveButton.qml"
+ label: "Closed Remove Item Button"
+ }
+ GroupBox {
+ contents: "2a/RemoveButton.qml"
+ label: "Alternative Closed Button"
+ }
+ GroupBox {
+ contents: "3/RemoveButton.qml"
+ label: "Open Remove Item Button"
+ }
+ GroupBox {
+ contents: "4/RemoveButton.qml"
+ label: "State Based Button"
+ }
+ GroupBox {
+ contents: "5/RemoveButton.qml"
+ label: "Animated Button"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2/RemoveButton.qml
new file mode 100644
index 0000000..247e38b
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2/RemoveButton.qml
@@ -0,0 +1,18 @@
+//! [0]
+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
+ source: "../../shared/pics/trash.png"
+ }
+}
+//! [0]
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2a/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2a/RemoveButton.qml
new file mode 100644
index 0000000..6c6a949
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/2a/RemoveButton.qml
@@ -0,0 +1,20 @@
+//! [0]
+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
+ source: "../../shared/pics/trash.png"
+ }
+ ]
+}
+//! [0]
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/3/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/3/RemoveButton.qml
new file mode 100644
index 0000000..3c20462
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/3/RemoveButton.qml
@@ -0,0 +1,39 @@
+//! [0]
+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
+ source: "../../shared/pics/cancel.png"
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../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"
+ }
+}
+//! [0]
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml
new file mode 100644
index 0000000..a359aaf
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml
@@ -0,0 +1,110 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+//! [script]
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+//! [script]
+//! [mouse region]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+//! [mouse region]
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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]
+ 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
+ }
+ }
+ ]
+//! [states]
+}
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4a/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4a/RemoveButton.qml
new file mode 100644
index 0000000..4db49ea
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/4a/RemoveButton.qml
@@ -0,0 +1,117 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+//! [script]
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+//! [script]
+//! [mouse region]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ id: trashMouseRegion
+ anchors.fill: parent
+ }
+ Connection {
+ sender: trashMouseRegion
+ signal: clicked()
+ script: {
+ toggle()
+ }
+ }
+ }
+//! [mouse region]
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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]
+ 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
+ }
+ }
+ ]
+//! [states]
+}
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/5/RemoveButton.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/5/RemoveButton.qml
new file mode 100644
index 0000000..29d464b
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/5/RemoveButton.qml
@@ -0,0 +1,117 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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: 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
+ }
+ }
+ ]
+//! [transition]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+//! [transition]
+}
diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml
new file mode 100644
index 0000000..edaae72
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml
@@ -0,0 +1,57 @@
+FocusRealm {
+ id: groupBox
+ width: Math.max(270, subItem.width+40)
+ height: Math.max(70, subItem.height+40)
+
+ property var contents
+ property var label
+
+ Rect {
+ id: wrapper
+ x: 5
+ y: 10
+ radius: 10
+ width: groupBox.width-20
+ height: groupBox.height-20
+ color: "white"
+ pen.color: "black"
+ Item {
+ id: subItem
+ qml: groupBox.contents
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ width: qmlItem.width
+ height: qmlItem.height
+ }
+ }
+ Rect {
+ x: 20
+ y: 0
+ height: text.height
+ width: text.width+10
+ color: "white"
+ Text {
+ x: 5
+ id: text
+ text: label
+ font.bold: true
+ }
+ }
+ Rect {
+ color: "black"
+ anchors.fill: parent
+ opacity: parent.focus ? 0 : 0.3
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { parent.parent.focus=true }
+ }
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1/ContactField.qml b/examples/declarative/tutorials/contacts/2_Reuse/1/ContactField.qml
new file mode 100644
index 0000000..0218c3d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1/ContactField.qml
@@ -0,0 +1,30 @@
+//! [load]
+Item {
+ id: contactField
+ clip: true
+ width: 230
+ height: 30
+ RemoveButton {
+ id: removeButton
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ }
+//! [load]
+ Text {
+ id: fieldText
+ width: contactField.width-80
+ anchors.right: removeButton.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ font.bold: true
+ color: "black"
+ text: 123123
+ }
+ Image {
+ source: "../../shared/pics/phone.png"
+ anchors.right: fieldText.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/1/RemoveButton.qml
new file mode 100644
index 0000000..3142c45
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1/RemoveButton.qml
@@ -0,0 +1,115 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1a/ContactField.qml b/examples/declarative/tutorials/contacts/2_Reuse/1a/ContactField.qml
new file mode 100644
index 0000000..62089b8
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1a/ContactField.qml
@@ -0,0 +1,33 @@
+//! [load]
+Item {
+ id: contactField
+ clip: true
+ width: 230
+ height: 30
+ Item {
+ id: removeButton
+ qml: "RemoveButton.qml"
+ width: qmlItem.width
+ height: qmlItem.height
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ }
+//! [load]
+ Text {
+ id: fieldText
+ width: contactField.width-80
+ anchors.right: removeButton.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ font.bold: true
+ color: "black"
+ text: 123123
+ }
+ Image {
+ source: "../../shared/pics/phone.png"
+ anchors.right: fieldText.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1a/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/1a/RemoveButton.qml
new file mode 100644
index 0000000..3142c45
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1a/RemoveButton.qml
@@ -0,0 +1,115 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1b/BlueRect.qml b/examples/declarative/tutorials/contacts/2_Reuse/1b/BlueRect.qml
new file mode 100644
index 0000000..92893f6
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1b/BlueRect.qml
@@ -0,0 +1,33 @@
+//! [all]
+Rect {
+ width: 100
+ height: 100
+ color: "blue"
+ resources: [
+ Component {
+ id: redRectangle
+ Rect {
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ }
+ }
+ ]
+ ComponentInstance {
+ component: redRectangle
+ anchors.right: parent.right
+ anchors.top: parent.top
+ }
+ ComponentInstance {
+ component: redRectangle
+ anchors.left: parent.left
+ anchors.top: parent.top
+ }
+ ComponentInstance {
+ component: redRectangle
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ }
+}
+//! [all]
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/1b/lib/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/1b/lib/RemoveButton.qml
new file mode 100644
index 0000000..bf6e82d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/1b/lib/RemoveButton.qml
@@ -0,0 +1,117 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ resources: [
+ Script {
+
+ function toggle() {
+ print('removeButton.toggle()');
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ 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: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/2/ContactField.qml b/examples/declarative/tutorials/contacts/2_Reuse/2/ContactField.qml
new file mode 100644
index 0000000..2542c1c
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/2/ContactField.qml
@@ -0,0 +1,32 @@
+Item {
+ id: contactField
+ clip: true
+ width: 230
+ height: 30
+//! [use properties and signals]
+ RemoveButton {
+ id: removeButton
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ expandedWidth: contactField.width
+ onConfirmed: { fieldText.text='' }
+ }
+//! [use properties and signals]
+ Text {
+ id: fieldText
+ width: contactField.width-80
+ anchors.right: removeButton.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ font.bold: true
+ color: "black"
+ text: 123123
+ }
+ Image {
+ source: "../../shared/pics/phone.png"
+ anchors.right: fieldText.left
+ anchors.rightMargin: 10
+ anchors.verticalCenter: parent.verticalCenter
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml
new file mode 100644
index 0000000..99a521d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml
@@ -0,0 +1,123 @@
+//! [define properties and signals]
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ property var expandedWidth: 230
+ signal confirmed
+//! [define properties and signals]
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+//! [use signal]
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle(); removeButton.confirmed.emit() }
+ }
+//! [use signal]
+ }
+ 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"
+//! [use width]
+ SetProperty {
+ target: removeButton
+ property: "width"
+ value: removeButton.expandedWidth
+ }
+//! [use width]
+ 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/2_Reuse.qml b/examples/declarative/tutorials/contacts/2_Reuse/2_Reuse.qml
new file mode 100644
index 0000000..6ad2eb5
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/2_Reuse.qml
@@ -0,0 +1,37 @@
+Rect {
+ id: page
+ width: layout.width
+ height: layout.height
+ color: "white"
+ GridLayout {
+ id: layout
+ columns: 2
+ rows: 4
+ width: contents.width
+ GroupBox {
+ contents: "1/ContactField.qml"
+ label: "Loading: simple"
+ }
+ GroupBox {
+ contents: "1a/ContactField.qml"
+ label: "Loading: qml property"
+ }
+ GroupBox {
+ contents: "2/ContactField.qml"
+ label: "Using properties"
+ }
+ GroupBox {
+ id: prev
+ contents: "3/ContactField.qml"
+ label: "Defining signals"
+ }
+ GroupBox {
+ contents: "3/Contact.qml"
+ label: "Multiple Items"
+ }
+ GroupBox {
+ contents: "4/Contact.qml"
+ label: "Mouse Grabbing"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/3/Contact.qml b/examples/declarative/tutorials/contacts/2_Reuse/3/Contact.qml
new file mode 100644
index 0000000..763a771
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/3/Contact.qml
@@ -0,0 +1,47 @@
+Item {
+ id: contactDetails
+ width: 230
+ height: layout.height
+
+ property var contactId: ""
+ property var label: ""
+ property var phone: ""
+ property var email: ""
+
+ onLabelChanged: { labelField.value = label }
+ onEmailChanged: { emailField.value = email }
+ onPhoneChanged: { phoneField.value = phone }
+
+ 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"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/3/ContactField.qml b/examples/declarative/tutorials/contacts/2_Reuse/3/ContactField.qml
new file mode 100644
index 0000000..890d781
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/3/ContactField.qml
@@ -0,0 +1,61 @@
+//! [all]
+Item {
+ id: contactField
+ clip: true
+ width: 230
+ height: 30
+ property var label: "Name"
+ property var icon: "../../shared/pics/phone.png"
+ property var value: ""
+ RemoveButton {
+ id: removeButton
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ expandedWidth: contactField.width
+ onConfirmed: { 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
+ }
+ Image {
+ anchors.right: fieldText.left
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ source: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "width,rightMargin"
+ duration: 200
+ }
+ }
+ ]
+}
+//! [all]
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml b/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml
new file mode 100644
index 0000000..f6cc1e4
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml
@@ -0,0 +1,148 @@
+//! [value change]
+Rect {
+ id: fieldText
+ height: 30
+ radius: 5
+ color: "white"
+ property var text: ""
+ onTextChanged: { reset() }
+//! [value change]
+ property var label: ""
+ signal confirmed
+ resources: [
+ Script {
+
+ function edit() {
+ fieldText.state='editing';
+ }
+ function confirm() {
+ fieldText.text = textEdit.text;
+ fieldText.state='';
+ fieldText.confirmed.emit();
+ }
+ function reset() {
+ textEdit.text = fieldText.text;
+ fieldText.state='';
+ }
+
+ }
+ ]
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ }
+ TextEdit {
+ id: textEdit
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ color: "black"
+ font.bold: true
+ readOnly: true
+ wrap: false
+ }
+//! [behavior]
+ 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 == '' ? 1 : 0
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+//! [behavior]
+ 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: 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: 39
+ }
+ SetProperty {
+ target: textEdit.anchors
+ property: "rightMargin"
+ value: 39
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,leftMargin,rightMargin"
+ duration: 200
+ }
+ ColorAnimation {
+ duration: 150
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/3/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/3/RemoveButton.qml
new file mode 100644
index 0000000..2f27a69
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/3/RemoveButton.qml
@@ -0,0 +1,119 @@
+//! [all]
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ property var expandedWidth: 230
+ signal confirmed
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ } else {
+ removeButton.state = 'opened';
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle(); removeButton.confirmed.emit() }
+ }
+ }
+ 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
+//! [all]
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/4/Contact.qml b/examples/declarative/tutorials/contacts/2_Reuse/4/Contact.qml
new file mode 100644
index 0000000..bcb242f
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/4/Contact.qml
@@ -0,0 +1,50 @@
+//! [grab property]
+Item {
+ id: contactDetails
+ width: 230
+ height: layout.height
+ property var mouseGrabbed: false
+//! [grab property]
+
+ property var contactId: ""
+ property var label: ""
+ property var phone: ""
+ property var email: ""
+
+ onLabelChanged: { labelField.value = label }
+ onEmailChanged: { emailField.value = email }
+ onPhoneChanged: { phoneField.value = phone }
+
+ 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"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/4/ContactField.qml b/examples/declarative/tutorials/contacts/2_Reuse/4/ContactField.qml
new file mode 100644
index 0000000..e9927e9
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/4/ContactField.qml
@@ -0,0 +1,58 @@
+Item {
+ id: contactField
+ clip: true
+ height: 30
+ property var label: "Name"
+ property var icon: "../../shared/pics/phone.png"
+ property var value: ""
+ RemoveButton {
+ id: removeButton
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ expandedWidth: contactField.width
+ onConfirmed: { 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
+ }
+ Image {
+ anchors.right: fieldText.left
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ source: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "width,rightMargin"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml b/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml
new file mode 100644
index 0000000..e969f7b
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml
@@ -0,0 +1,149 @@
+Rect {
+ id: fieldText
+ height: 30
+ radius: 5
+ color: "white"
+ property var text: ""
+ property var label: ""
+ onTextChanged: { reset() }
+ signal confirmed
+ resources: [
+ Script {
+
+ function edit() {
+ if (!contactDetails.mouseGrabbed) {
+ fieldText.state='editing';
+ contactDetails.mouseGrabbed=true;
+ }
+ }
+ function confirm() {
+ fieldText.text = textEdit.text;
+ fieldText.state='';
+ contactDetails.mouseGrabbed=false;
+ fieldText.confirmed.emit();
+ }
+ function reset() {
+ textEdit.text = fieldText.text;
+ fieldText.state='';
+ contactDetails.mouseGrabbed=false;
+ }
+
+ }
+ ]
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ }
+ TextEdit {
+ id: textEdit
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ color: "black"
+ 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 == '' ? 1 : 0
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+ 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: 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: 39
+ }
+ SetProperty {
+ target: textEdit.anchors
+ property: "rightMargin"
+ value: 39
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,leftMargin,rightMargin"
+ duration: 200
+ }
+ ColorAnimation {
+ duration: 150
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/4/RemoveButton.qml b/examples/declarative/tutorials/contacts/2_Reuse/4/RemoveButton.qml
new file mode 100644
index 0000000..bfe496e
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/4/RemoveButton.qml
@@ -0,0 +1,123 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ property var expandedWidth: 230
+ signal confirmed
+ resources: [
+//! [grab]
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ contactDetails.mouseGrabbed=false;
+ } else {
+ if (!contactDetails.mouseGrabbed) {
+ removeButton.state = 'opened';
+ contactDetails.mouseGrabbed=true;
+ }
+ }
+ }
+
+ }
+//! [grab]
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle(); removeButton.confirmed.emit() }
+ }
+ }
+ 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml b/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml
new file mode 100644
index 0000000..edaae72
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml
@@ -0,0 +1,57 @@
+FocusRealm {
+ id: groupBox
+ width: Math.max(270, subItem.width+40)
+ height: Math.max(70, subItem.height+40)
+
+ property var contents
+ property var label
+
+ Rect {
+ id: wrapper
+ x: 5
+ y: 10
+ radius: 10
+ width: groupBox.width-20
+ height: groupBox.height-20
+ color: "white"
+ pen.color: "black"
+ Item {
+ id: subItem
+ qml: groupBox.contents
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ width: qmlItem.width
+ height: qmlItem.height
+ }
+ }
+ Rect {
+ x: 20
+ y: 0
+ height: text.height
+ width: text.width+10
+ color: "white"
+ Text {
+ x: 5
+ id: text
+ text: label
+ font.bold: true
+ }
+ }
+ Rect {
+ color: "black"
+ anchors.fill: parent
+ opacity: parent.focus ? 0 : 0.3
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { parent.parent.focus=true }
+ }
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/1/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/1/ContactView.qml
new file mode 100644
index 0000000..5400544
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/1/ContactView.qml
@@ -0,0 +1,44 @@
+import "../lib"
+Item {
+ id: contacts
+ width: 240
+ height: 230
+ property var mouseGrabbed: false
+ resources: [
+//! [model]
+ SqlConnection {
+ id: contactDatabase
+ name: "qmlConnection"
+ driver: "QSQLITE"
+ databaseName: "../../shared/contacts.sqlite"
+ },
+ SqlQuery {
+ id: contactList
+ connection: contactDatabase
+ query: "SELECT recid, label, email, phone FROM contacts ORDER BY label, recid"
+ }
+//! [model]
+ ]
+//! [view]
+ ListView {
+ id: contactListView
+ anchors.fill: parent
+ clip: true
+ model: contactList
+ focus: true
+//! [delegate]
+ delegate: [
+ Text {
+ x: 45
+ y: 12
+ width: contactListView.width-45
+ height: 30
+ color: "black"
+ font.bold: true
+ text: model.label
+ }
+ ]
+//! [delegate]
+ }
+//! [view]
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml
new file mode 100644
index 0000000..0a293f5
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml
@@ -0,0 +1,126 @@
+import "../lib"
+Item {
+ id: contacts
+ width: 240
+ height: 230
+ property var mouseGrabbed: false
+ 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 ORDER BY label, recid"
+ }
+ ]
+//! [button]
+ Button {
+ id: cancelEditButton
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+ icon: "../../shared/pics/cancel.png"
+ opacity: mouseGrabbed ? 0 : 1
+ }
+//! [button]
+ ListView {
+ id: contactListView
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: cancelEditButton.bottom
+ anchors.bottom: parent.bottom
+ clip: true
+ model: contactList
+ focus: true
+ delegate: [
+//! [components]
+ Item {
+ id: wrapper
+ x: 0
+ width: ListView.view.width
+ height: 34
+ Text {
+ id: label
+ x: 45
+ y: 12
+ width: parent.width-45
+ color: "black"
+ font.bold: true
+ text: model.label
+ }
+ MouseRegion {
+ anchors.fill: label
+ onClicked: { wrapper.state='opened'; }
+ }
+ Contact {
+ id: Details
+ anchors.fill: parent
+ contactId: model.recid
+ label: model.label
+ email: model.email
+ phone: model.phone
+ opacity: 0
+ }
+//! [components]
+//! [states]
+ 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
+ }
+ }
+ ]
+//! [states]
+//! [transitions]
+ transitions: [
+ Transition {
+ NumericAnimation {
+ duration: 500
+ properties: "yPosition,height,opacity"
+ }
+ }
+ ]
+//! [transitions]
+//! [connections]
+ Connection {
+ sender: cancelEditButton
+ signal: "clicked()"
+ script: {
+ if (wrapper.state == 'opened') {
+ wrapper.state = '';
+ }
+ }
+ }
+//! [connections]
+ }
+ ]
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml
new file mode 100644
index 0000000..7a44a3f
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml
@@ -0,0 +1,139 @@
+import "../lib"
+Item {
+ id: contacts
+ width: 240
+ height: 230
+ property var mouseGrabbed: false
+ 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 ORDER BY label, recid"
+ }
+ ]
+ Button {
+ id: cancelEditButton
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+ icon: "../../shared/pics/cancel.png"
+ opacity: mouseGrabbed ? 0 : 1
+ }
+ ListView {
+ id: contactListView
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: cancelEditButton.bottom
+ anchors.bottom: parent.bottom
+ clip: true
+ model: contactList
+ focus: true
+ delegate: [
+ Item {
+ id: wrapper
+ x: 0
+ width: ListView.view.width
+ height: 34
+ Text {
+ id: label
+ x: 45
+ y: 12
+ width: parent.width-45
+ color: "black"
+ font.bold: true
+ text: model.label
+ }
+//! [setting qml]
+ MouseRegion {
+ anchors.fill: label
+ onClicked: {
+ Details.qml = 'Contact.qml';
+ wrapper.state='opened';
+ }
+ }
+ Item {
+ id: Details
+ anchors.fill: parent
+ opacity: 0
+//! [setting qml]
+//! [binding]
+ Bind {
+ target: Details.qmlItem
+ property: "contactId"
+ value: model.recid
+ }
+ 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
+ }
+//! [binding]
+ }
+ 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ NumericAnimation {
+ duration: 500
+ properties: "yPosition,height,opacity"
+ }
+ }
+ ]
+ Connection {
+ sender: cancelEditButton
+ signal: "clicked()"
+ script: {
+ if (wrapper.state == 'opened') {
+ wrapper.state = '';
+ }
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/3_Collections.qml b/examples/declarative/tutorials/contacts/3_Collections/3_Collections.qml
new file mode 100644
index 0000000..7d9937c
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/3_Collections.qml
@@ -0,0 +1,29 @@
+Rect {
+ id: page
+ width: layout.width
+ height: layout.height
+ color: "white"
+ Bind {
+ id: currentItem
+ value: true
+ }
+ // relies on the current focus behavior whereby setting focus=true on a
+ // component removes focus from any previous element
+ GridLayout {
+ id: layout
+ width: contents.width
+ height: contents.height
+ GroupBox {
+ contents: "1/ContactView.qml"
+ label: "list only"
+ }
+ GroupBox {
+ contents: "2/ContactView.qml"
+ label: "dynamic delegate"
+ }
+ GroupBox {
+ contents: "3/ContactView.qml"
+ label: "delayed loading"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml b/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml
new file mode 100644
index 0000000..edaae72
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml
@@ -0,0 +1,57 @@
+FocusRealm {
+ id: groupBox
+ width: Math.max(270, subItem.width+40)
+ height: Math.max(70, subItem.height+40)
+
+ property var contents
+ property var label
+
+ Rect {
+ id: wrapper
+ x: 5
+ y: 10
+ radius: 10
+ width: groupBox.width-20
+ height: groupBox.height-20
+ color: "white"
+ pen.color: "black"
+ Item {
+ id: subItem
+ qml: groupBox.contents
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ width: qmlItem.width
+ height: qmlItem.height
+ }
+ }
+ Rect {
+ x: 20
+ y: 0
+ height: text.height
+ width: text.width+10
+ color: "white"
+ Text {
+ x: 5
+ id: text
+ text: label
+ font.bold: true
+ }
+ }
+ Rect {
+ color: "black"
+ anchors.fill: parent
+ opacity: parent.focus ? 0 : 0.3
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { parent.parent.focus=true }
+ }
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml
new file mode 100644
index 0000000..d9f1236
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml
@@ -0,0 +1,57 @@
+Item {
+ id: button
+ width: 30
+ height: 30
+ property var icon: ""
+ signal clicked
+ Rect {
+ id: buttonRect
+ anchors.fill: parent
+ color: "lightgreen"
+ radius: 5
+ Image {
+ id: iconImage
+ source: button.icon
+ anchors.horizontalCenter: buttonRect.horizontalCenter
+ anchors.verticalCenter: buttonRect.verticalCenter
+ }
+ 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"
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "pressed"
+ ColorAnimation {
+ duration: 200
+ }
+ },
+ Transition {
+ fromState: "pressed"
+ toState: "*"
+ ColorAnimation {
+ duration: 1000
+ }
+ }
+ ]
+ }
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/Contact.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/Contact.qml
new file mode 100644
index 0000000..6832076
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/lib/Contact.qml
@@ -0,0 +1,46 @@
+Item {
+ id: contactDetails
+ anchors.fill: parent
+
+ property var contactId: ""
+ property var label: ""
+ property var phone: ""
+ property var email: ""
+
+ onLabelChanged: { labelField.value = label }
+ onEmailChanged: { emailField.value = email }
+ onPhoneChanged: { phoneField.value = phone }
+
+ 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"
+ }
+ }
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/ContactField.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/ContactField.qml
new file mode 100644
index 0000000..e9927e9
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/lib/ContactField.qml
@@ -0,0 +1,58 @@
+Item {
+ id: contactField
+ clip: true
+ height: 30
+ property var label: "Name"
+ property var icon: "../../shared/pics/phone.png"
+ property var value: ""
+ RemoveButton {
+ id: removeButton
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ expandedWidth: contactField.width
+ onConfirmed: { 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
+ }
+ Image {
+ anchors.right: fieldText.left
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ source: 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "width,rightMargin"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml
new file mode 100644
index 0000000..427e2b0
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml
@@ -0,0 +1,149 @@
+Rect {
+ id: fieldText
+ height: 30
+ radius: 5
+ color: "white"
+ property var text: ""
+ property var label: ""
+ onTextChanged: { reset() }
+ signal confirmed
+ 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;
+ }
+
+ }
+ ]
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ }
+ TextEdit {
+ id: textEdit
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+ anchors.verticalCenter: parent.verticalCenter
+ color: "black"
+ 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 == '' ? 1 : 0
+ opacity: Behaviour {
+ NumericAnimation {
+ property: "opacity"
+ duration: 250
+ }
+ }
+ }
+ 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: 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: 39
+ }
+ SetProperty {
+ target: textEdit.anchors
+ property: "rightMargin"
+ value: 39
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: ""
+ toState: "*"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,leftMargin,rightMargin"
+ duration: 200
+ }
+ ColorAnimation {
+ duration: 150
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/RemoveButton.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/RemoveButton.qml
new file mode 100644
index 0000000..c0ea79d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/3_Collections/lib/RemoveButton.qml
@@ -0,0 +1,121 @@
+Rect {
+ id: removeButton
+ width: 30
+ height: 30
+ color: "red"
+ radius: 5
+ property var expandedWidth: 230
+ signal confirmed
+ resources: [
+ Script {
+ function toggle() {
+ if (removeButton.state == 'opened') {
+ removeButton.state = '';
+ contacts.mouseGrabbed=false;
+ } else {
+ if (!contacts.mouseGrabbed) {
+ removeButton.state = 'opened';
+ contacts.mouseGrabbed=true;
+ }
+ }
+ }
+
+ }
+ ]
+ Image {
+ id: trashIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/trash.png"
+ opacity: 1
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: cancelIcon
+ width: 22
+ height: 22
+ anchors.right: parent.right
+ anchors.rightMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/cancel.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle() }
+ }
+ }
+ Image {
+ id: confirmIcon
+ width: 22
+ height: 22
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ source: "../../shared/pics/ok.png"
+ opacity: 0
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { toggle(); removeButton.confirmed.emit() }
+ }
+ }
+ 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
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "opened"
+ reversible: true
+ NumericAnimation {
+ properties: "opacity,x,width"
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/examples/declarative/tutorials/contacts/shared/contactGenSQL.pl b/examples/declarative/tutorials/contacts/shared/contactGenSQL.pl
new file mode 100755
index 0000000..2d328da
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/contactGenSQL.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+my $count = shift;
+
+open(MFIRST, "<english-m.txt") or die "Could not open male names";
+open(FFIRST, "<english-f.txt") or die "Could not open female names";
+open(SURNAME, "<english-s.txt") or die "Could not open surnames names";
+open(ISP, "<email.txt") or die "Could not open isp names";
+
+my @mnames = <MFIRST>;
+my @fnames = <FFIRST>;
+my @surnames = <SURNAME>;
+my @isps = <ISP>;
+
+print "BEGIN;\n";
+print "CREATE TABLE contacts (recid INTEGER PRIMARY KEY, label TEXT, phone TEXT, email TEXT);\n";
+print "CREATE INDEX contactSortOrder ON contacts(label, recid);\n";
+
+my $i = 0;
+while ($i < $count) {
+ $i++;
+ my $fn = randomFirstName();
+ my $sn = randomLastName();
+ my $em = randomEmail($fn, $sn);
+ my $ph = randomPhoneNumber();
+
+ $fn =~ s/'/''/g;
+ $sn =~ s/'/''/g;
+ $em =~ s/'/''/g;
+ print "INSERT INTO contacts (label, email, phone) VALUES('$fn $sn', '$em', '$ph');\n"
+}
+
+print "COMMIT;\n";
+
+
+sub randomFirstName
+{
+ my $name;
+ if (int(rand 2) == 1) {
+ $name = $mnames[int(rand @mnames)];
+ } else {
+ $name = $fnames[int(rand @fnames)];
+ }
+ chomp $name;
+ $name;
+}
+
+sub randomLastName
+{
+ my $name = $surnames[int(rand @surnames)];
+ chomp $name;
+ $name;
+}
+
+sub randomEmail
+{
+ my ($fn, $ln) = @_;
+ my $isp = $isps[int(rand @isps)];
+ chomp $isp;
+ my $path = int(rand 3);
+ my $email;
+ if ($path == 0) {
+ $email = "$fn.$ln\@$isp";
+ } elsif ($path == 1) {
+ $email = "$fn\@$isp";
+ } elsif ($path == 2) {
+ $email = "$ln\@$isp";
+ }
+}
+
+sub randomPhoneNumber
+{
+ my @digits = qw(1 2 3 4 5 6 7 8 9 0);
+ my $phonenumber;
+ for (1 .. 8) {
+ $phonenumber .= $digits[int(rand @digits)];
+ }
+ $phonenumber;
+}
diff --git a/examples/declarative/tutorials/contacts/shared/contacts.sqlite b/examples/declarative/tutorials/contacts/shared/contacts.sqlite
new file mode 100644
index 0000000..d903775
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/contacts.sqlite
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/email.txt b/examples/declarative/tutorials/contacts/shared/email.txt
new file mode 100644
index 0000000..de9894b
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/email.txt
@@ -0,0 +1,7 @@
+emails.com
+emails.net
+mailserver.org
+mailserver.net
+mailserver.com
+BobsMail.com
+BillMail.com
diff --git a/examples/declarative/tutorials/contacts/shared/english-f.txt b/examples/declarative/tutorials/contacts/shared/english-f.txt
new file mode 100644
index 0000000..7da5474
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/english-f.txt
@@ -0,0 +1,143 @@
+Aimee
+Aleksandra
+Alice
+Alicia
+Allison
+Alyssa
+Amy
+Andrea
+Angel
+Angela
+Ann
+Anna
+Anne
+Anne
+Marie
+Annie
+Ashley
+Barbara
+Beatrice
+Beth
+Betty
+Brenda
+Brooke
+Candace
+Cara
+Caren
+Carol
+Caroline
+Carolyn
+Carrie
+Cassandra
+Catherine
+Charlotte
+Chrissy
+Christen
+Christina
+Christine
+Christy
+Claire
+Claudia
+Courtney
+Crystal
+Cynthia
+Dana
+Danielle
+Deanne
+Deborah
+Deirdre
+Denise
+Diane
+Dianne
+Dorothy
+Eileen
+Elena
+Elizabeth
+Emily
+Erica
+Erin
+Frances
+Gina
+Giulietta
+Heather
+Helen
+Jane
+Janet
+Janice
+Jenna
+Jennifer
+Jessica
+Joanna
+Joyce
+Julia
+Juliana
+Julie
+Justine
+Kara
+Karen
+Katharine
+Katherine
+Kathleen
+Kathryn
+Katrina
+Kelly
+Kerry
+Kim
+Kimberly
+Kristen
+Kristina
+Kristine
+Laura
+Laurel
+Lauren
+Laurie
+Leah
+Linda
+Lisa
+Lori
+Marcia
+Margaret
+Maria
+Marina
+Marisa
+Martha
+Mary
+Mary
+Ann
+Maya
+Melanie
+Melissa
+Michelle
+Monica
+Nancy
+Natalie
+Nicole
+Nina
+Pamela
+Patricia
+Rachel
+Rebecca
+Renee
+Sandra
+Sara
+Sharon
+Sheri
+Shirley
+Sonia
+Stefanie
+Stephanie
+Susan
+Suzanne
+Sylvia
+Tamara
+Tara
+Tatiana
+Terri
+Theresa
+Tiffany
+Tracy
+Valerie
+Veronica
+Vicky
+Vivian
+Wendy
diff --git a/examples/declarative/tutorials/contacts/shared/english-m.txt b/examples/declarative/tutorials/contacts/shared/english-m.txt
new file mode 100644
index 0000000..3c7b13e
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/english-m.txt
@@ -0,0 +1,130 @@
+Aaron
+Adam
+Adrian
+Alan
+Alejandro
+Alex
+Allen
+Andrew
+Andy
+Anthony
+Art
+Arthur
+Barry
+Bart
+Ben
+Benjamin
+Bill
+Bobby
+Brad
+Bradley
+Brendan
+Brett
+Brian
+Bruce
+Bryan
+Carlos
+Chad
+Charles
+Chris
+Christopher
+Chuck
+Clay
+Corey
+Craig
+Dan
+Daniel
+Darren
+Dave
+David
+Dean
+Dennis
+Denny
+Derek
+Don
+Doug
+Duane
+Edward
+Eric
+Eugene
+Evan
+Frank
+Fred
+Gary
+Gene
+George
+Gordon
+Greg
+Harry
+Henry
+Hunter
+Ivan
+Jack
+James
+Jamie
+Jason
+Jay
+Jeff
+Jeffrey
+Jeremy
+Jim
+Joe
+Joel
+John
+Jonathan
+Joseph
+Justin
+Keith
+Ken
+Kevin
+Larry
+Logan
+Marc
+Mark
+Matt
+Matthew
+Michael
+Mike
+Nat
+Nathan
+Patrick
+Paul
+Perry
+Peter
+Philip
+Phillip
+Randy
+Raymond
+Ricardo
+Richard
+Rick
+Rob
+Robert
+Rod
+Roger
+Ross
+Ruben
+Russell
+Ryan
+Sam
+Scot
+Scott
+Sean
+Shaun
+Stephen
+Steve
+Steven
+Stewart
+Stuart
+Ted
+Thomas
+Tim
+Toby
+Todd
+Tom
+Troy
+Victor
+Wade
+Walter
+Wayne
+William
diff --git a/examples/declarative/tutorials/contacts/shared/english-s.txt b/examples/declarative/tutorials/contacts/shared/english-s.txt
new file mode 100644
index 0000000..1f3682d
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/english-s.txt
@@ -0,0 +1,1003 @@
+Adams
+Adamson
+Adler
+Akers
+Akin
+Aleman
+Alexander
+Allen
+Allison
+Allwood
+Anderson
+Andreou
+Anthony
+Appelbaum
+Applegate
+Arbore
+Arenson
+Armold
+Arntzen
+Askew
+Athanas
+Atkinson
+Ausman
+Austin
+Averitt
+Avila-Sakar
+Badders
+Baer
+Baggerly
+Bailliet
+Baird
+Baker
+Ball
+Ballentine
+Ballew
+Banks
+Baptist-Nguyen
+Barbee
+Barber
+Barchas
+Barcio
+Bardsley
+Barkauskas
+Barnes
+Barnett
+Barnwell
+Barrera
+Barreto
+Barroso
+Barrow
+Bart
+Barton
+Bass
+Bates
+Bavinger
+Baxter
+Bazaldua
+Becker
+Beeghly
+Belforte
+Bellamy
+Bellavance
+Beltran
+Belusar
+Bennett
+Benoit
+Bensley
+Berger
+Berggren
+Bergman
+Berry
+Bertelson
+Bess
+Beusse
+Bickford
+Bierner
+Bird
+Birdwell
+Bixby
+Blackmon
+Blackwell
+Blair
+Blankinship
+Blanton
+Block
+Blomkalns
+Bloomfield
+Blume
+Boeckenhauer
+Bolding
+Bolt
+Bolton
+Book
+Boucher
+Boudreau
+Bowman
+Boyd
+Boyes
+Boyles
+Braby
+Braden
+Bradley
+Brady
+Bragg
+Brandow
+Brantley
+Brauner
+Braunhardt
+Bray
+Bredenberg
+Bremer
+Breyer
+Bricout
+Briggs
+Brittain
+Brockman
+Brockmoller
+Broman
+Brooks
+Brown
+Brubaker
+Bruce
+Brumfield
+Brumley
+Bruning
+Buck
+Budd
+Buhler
+Buhr
+Burleson
+Burns
+Burton
+Bush
+Butterfield
+Byers
+Byon
+Byrd
+Bzostek
+Cabrera
+Caesar
+Caffey
+Caffrey
+Calhoun
+Call
+Callahan
+Campbell
+Cano
+Capri
+Carey
+Carlisle
+Carlson
+Carmichael
+Carnes
+Carr
+Carreira
+Carroll
+Carson
+Carswell
+Carter
+Cartwright
+Cason
+Cates
+Catlett
+Caudle
+Cavallaro
+Cave
+Cazamias
+Chabot
+Chance
+Chapman
+Characklis
+Cheatham
+Chen
+Chern
+Cheville
+Chong
+Christensen
+Church
+Claibourn
+Clark
+Clasen
+Claude
+Close
+Coakley
+Coffey
+Cohen
+Cole
+Collier
+Conant
+Connell
+Conte
+Conway
+Cooley
+Cooper
+Copeland
+Coram
+Corbett
+Cort
+Cortes
+Cousins
+Cowsar
+Cox
+Coyne
+Crain
+Crankshaw
+Craven
+Crawford
+Cressman
+Crestani
+Crier
+Crocker
+Cromwell
+Crouse
+Crowder
+Crowe
+Culpepper
+Cummings
+Cunningham
+Currie
+Cusey
+Cutcher
+Cyprus
+D'Ascenzo
+Dabak
+Dakoulas
+Daly
+Dana
+Danburg
+Danenhauer
+Darley
+Darrouzet
+Dartt
+Daugherty
+Davila
+Davis
+Dawkins
+Day
+DeHart
+DeMoss
+DeMuth
+DeVincentis
+Deaton
+Dees
+Degenhardt
+Deggeller
+Deigaard
+Delabroy
+Delaney
+Demir
+Denison
+Denney
+Derr
+Deuel
+Devitt
+Diamond
+Dickinson
+Dietrich
+Dilbeck
+Dobson
+Dodds
+Dodson
+Doherty
+Dooley
+Dorsey
+Dortch
+Doughty
+Dove
+Dowd
+Dowling
+Drescher
+Drucker
+Dryer
+Dryver
+Duckworth
+Dunbar
+Dunham
+Dunn
+Duston
+Dettweiler
+Dyson
+Eason
+Eaton
+Ebert
+Eckhoff
+Edelman
+Edmonds
+Eichhorn
+Eisbach
+Elders
+Elias
+Elijah
+Elizabeth
+Elliott
+Elliston
+Elms
+Emerson
+Engelberg
+Engle
+Eplett
+Epp
+Erickson
+Estades
+Etezadi
+Evans
+Ewing
+Fair
+Farfan
+Fargason
+Farhat
+Farry
+Fawcett
+Faye
+Federle
+Felcher
+Feldman
+Ferguson
+Fergusson
+Fernandez
+Ferrer
+Fine
+Fineman
+Fisher
+Flanagan
+Flathmann
+Fleming
+Fletcher
+Folk
+Fortune
+Fossati
+Foster
+Foulston
+Fowler
+Fox
+Francis
+Frantom
+Franz
+Frazer
+Fredericks
+Frey
+Freymann
+Fuentes
+Fuller
+Fundling
+Furlong
+Gainer
+Galang
+Galeazzi
+Gamse
+Gannaway
+Garcia
+Gardner
+Garneau
+Gartler
+Garverick
+Garza
+Gatt
+Gattis
+Gayman
+Geiger
+Gelder
+George
+Gerbino
+Gerbode
+Gibson
+Gifford
+Gillespie
+Gillingham
+Gilpin
+Gilyot
+Girgis
+Gjertsen
+Glantz
+Glaze
+Glenn
+Glotzbach
+Gobble
+Gockenbach
+Goff
+Goffin
+Golden
+Goldwyn
+Gomez
+Gonzalez
+Good
+Graham
+Gramm
+Granlund
+Grant
+Gray
+Grayson
+Greene
+Greenslade
+Greenwood
+Greer
+Griffin
+Grinstein
+Grisham
+Gross
+Grove
+Guthrie
+Guyton
+Haas
+Hackney
+Haddock
+Hagelstein
+Hagen
+Haggard
+Haines
+Hale
+Haley
+Hall
+Halladay
+Hamill
+Hamilton
+Hammer
+Hancock
+Hane
+Hansen
+Harding
+Harless
+Harms
+Harper
+Harrigan
+Harris
+Harrison
+Hart
+Harton
+Hartz
+Harvey
+Hastings
+Hauenstein
+Haushalter
+Haven
+Hawes
+Hawkins
+Hawley
+Haygood
+Haylock
+Hazard
+Heath
+Heidel
+Heins
+Hellums
+Hendricks
+Henry
+Henson
+Herbert
+Herman
+Hernandez
+Herrera
+Hertzmann
+Hewitt
+Hightower
+Hildebrand
+Hill
+Hindman
+Hirasaki
+Hirsh
+Hochman
+Hocker
+Hoffman
+Hoffmann
+Holder
+Holland
+Holloman
+Holstein
+Holt
+Holzer
+Honeyman
+Hood
+Hooks
+Hopper
+Horne
+House
+Houston
+Howard
+Howell
+Howley
+Huang
+Hudgings
+Huffman
+Hughes
+Humphrey
+Hunt
+Hunter
+Hurley
+Huston
+Hutchinson
+Hyatt
+Irving
+Jacobs
+Jaramillo
+Jaranson
+Jarboe
+Jarrell
+Jenkins
+Johnson
+Johnston
+Jones
+Joy
+Juette
+Julicher
+Jumper
+Kabir
+Kamberova
+Kamen
+Kamine
+Kampe
+Kane
+Kang
+Kapetanovic
+Kargatis
+Karlin
+Karlsson
+Kasbekar
+Kasper
+Kastensmidt
+Katz
+Kauffman
+Kavanagh
+Kaydos
+Kearsley
+Keleher
+Kelly
+Kelty
+Kendrick
+Key
+Kicinski
+Kiefer
+Kielt
+Kim
+Kimmel
+Kincaid
+King
+Kinney
+Kipp
+Kirby
+Kirk
+Kirkland
+Kirkpatrick
+Klamczynski
+Klein
+Kopnicky
+Kotsonis
+Koutras
+Kramer
+Kremer
+Krohn
+Kuhlken
+Kunitz
+LaLonde
+LaValle
+LaWare
+Lacy
+Lam
+Lamb
+Lampkin
+Lane
+Langston
+Lanier
+Larsen
+Lassiter
+Latchford
+Lawera
+LeBlanc
+LeGrand
+Leatherbury
+Lebron
+Ledman
+Lee
+Leinenbach
+Leslie
+Levy
+Lewis
+Lichtenstein
+Lisowski
+Liston
+Litvak
+Llano-Restrepo
+Lloyd
+Lock
+Lodge
+Logan
+Lomonaco
+Long
+Lopez
+Lopez-Bassols
+Loren
+Loughridge
+Love
+Ludtke
+Luers
+Lukes
+Luxemburg
+MacAllister
+MacLeod
+Mackey
+Maddox
+Magee
+Mallinson
+Mann
+Manning
+Manthos
+Marie
+Marrow
+Marshall
+Martin
+Martinez
+Martisek
+Massey
+Mathis
+Matt
+Maxwell
+Mayer
+Mazurek
+McAdams
+McAfee
+McAlexander
+McBride
+McCarthy
+McClure
+McCord
+McCoy
+McCrary
+McCrossin
+McDonald
+McElfresh
+McFarland
+McGarr
+McGhee
+McGoldrick
+McGrath
+McGuire
+McKinley
+McMahan
+McMahon
+McMath
+McNally
+Mcdonald
+Meade
+Meador
+Mebane
+Medrano
+Melton
+Merchant
+Merwin
+Millam
+Millard
+Miller
+Mills
+Milstead
+Minard
+Miner
+Minkoff
+Minnotte
+Minyard
+Mirza
+Mitchell
+Money
+Monk
+Montgomery
+Monton
+Moore
+Moren
+Moreno
+Morris
+Morse
+Moss
+Moyer
+Mueller
+Mull
+Mullet
+Mullins
+Munn
+Murdock
+Murphey
+Murphy
+Murray
+Murry
+Mutchler
+Myers
+Myrick
+Nassar
+Nathan
+Nazzal
+Neal
+Nederveld
+Nelson
+Nguyen
+Nichols
+Nielsen
+Nockton
+Nolan
+Noonan
+Norbury
+Nordlander
+Norris
+Norvell
+Noyes
+Nugent
+Nunn
+O'Brien
+O'Connell
+O'Neill
+O'Steen
+Ober
+Odegard
+Oliver
+Ollmann
+Olson
+Ongley
+Ordway
+Ortiz
+Ouellette
+Overcash
+Overfelt
+Overley
+Owens
+Page
+Paige
+Pardue
+Parham
+Parker
+Parks
+Patterson
+Patton
+Paul
+Payne
+Peck
+Penisson
+Percer
+Perez
+Perlioni
+Perrino
+Peterman
+Peters
+Pfeiffer
+Phelps
+Philip
+Philippe
+Phillips
+Pickett
+Pippenger
+Pistole
+Platzek
+Player
+Poddar
+Poirier
+Poklepovic
+Polk
+Polking
+Pond
+Popish
+Porter
+Pound
+Pounds
+Powell
+Powers
+Prado
+Preston
+Price
+Prichep
+Priour
+Prischmann
+Pryor
+Puckett
+Raglin
+Ralston
+Rampersad
+Ratner
+Rawles
+Ray
+Read
+Reddy
+Reed
+Reese
+Reeves
+Reichenbach
+Reifel
+Rein
+Reiten
+Reiter
+Reitmeier
+Reynolds
+Richardson
+Rider
+Rhinehart
+Ritchie
+Rittenbach
+Roberts
+Robinson
+Rodriguez
+Rogers
+Roper
+Rosemblun
+Rosen
+Rosenberg
+Rosenblatt
+Ross
+Roth
+Rowatt
+Roy
+Royston
+Rozendal
+Rubble
+Ruhlin
+Rupert
+Russell
+Ruthruff
+Ryan
+Rye
+Sabry
+Sachitano
+Sachs
+Sammartino
+Sands
+Saunders
+Savely
+Scales
+Schaefer
+Schafer
+Scheer
+Schild
+Schlitt
+Schmitz
+Schneider
+Schoenberger
+Schoppe
+Scott
+Seay
+Segura
+Selesnick
+Self
+Seligmann
+Sewall
+Shami
+Shampine
+Sharp
+Shaw
+Shefelbine
+Sheldon
+Sherrill
+Shidle
+Shifley
+Shillingsburg
+Shisler
+Shopbell
+Shupack
+Sievert
+Simpson
+Sims
+Sissman
+Smayling
+Smith
+Snyder
+Solomon
+Solon
+Soltero
+Sommers
+Sonneborn
+Sorensen
+Southworth
+Spear
+Speight
+Spencer
+Spruell
+Spudich
+Stacy
+Staebel
+Steele
+Steinhour
+Steinke
+Stepp
+Stevens
+Stewart
+Stickel
+Stine
+Stivers
+Stobb
+Stone
+Stratmann
+Stubbers
+Stuckey
+Stugart
+Sullivan
+Sultan
+Sumrall
+Sunley
+Sunshine
+Sutton
+Swaim
+Swales
+Sweed
+Swick
+Swift
+Swindell
+Swint
+Symonds
+Syzdek
+Szafranski
+Takimoto
+Talbott
+Talwar
+Tanner
+Taslimi
+Tate
+Tatum
+Taylor
+Tchainikov
+Terk
+Thacker
+Thomas
+Thompson
+Thomson
+Thornton
+Thurman
+Thurow
+Tilley
+Tolle
+Towns
+Trafton
+Tran
+Trevas
+Trevino
+Triggs
+Truchard
+Tunison
+Turner
+Twedell
+Tyler
+Tyree
+Unger
+Van
+Vanderzanden
+Vanlandingham
+Varanasi
+Varela
+Varman
+Venier
+Verspoor
+Vick
+Visinsky
+Voltz
+Wagner
+Wake
+Walcott
+Waldron
+Walker
+Wallace
+Walters
+Walton
+Ward
+Wardle
+Warnes
+Warren
+Washington
+Watson
+Watters
+Webber
+Weidenfeller
+Weien
+Weimer
+Weiner
+Weinger
+Weinheimer
+Weirich
+Welch
+Wells
+Wendt
+West
+Westmoreland
+Wex
+Whitaker
+White
+Whitley
+Wiediger
+Wilburn
+Williams
+Williamson
+Willman
+Wilson
+Winger
+Wise
+Wisur
+Witt
+Wong
+Woodbury
+Wooten
+Workman
+Wright
+Wyatt
+Yates
+Yeamans
+Yen
+York
+Yotov
+Younan
+Young
+Zeldin
+Zettner
+Ziegler
+Zitterkopf
+Zucker
diff --git a/examples/declarative/tutorials/contacts/shared/pics/cancel.png b/examples/declarative/tutorials/contacts/shared/pics/cancel.png
new file mode 100644
index 0000000..ecc9533
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/cancel.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/email.png b/examples/declarative/tutorials/contacts/shared/pics/email.png
new file mode 100644
index 0000000..04b3865
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/email.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/new.png b/examples/declarative/tutorials/contacts/shared/pics/new.png
new file mode 100644
index 0000000..c7ebac3
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/new.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/ok.png b/examples/declarative/tutorials/contacts/shared/pics/ok.png
new file mode 100644
index 0000000..5795f04
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/ok.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/phone.png b/examples/declarative/tutorials/contacts/shared/pics/phone.png
new file mode 100644
index 0000000..fc9c222
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/phone.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/search.png b/examples/declarative/tutorials/contacts/shared/pics/search.png
new file mode 100644
index 0000000..cc74e69
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/search.png
Binary files differ
diff --git a/examples/declarative/tutorials/contacts/shared/pics/trash.png b/examples/declarative/tutorials/contacts/shared/pics/trash.png
new file mode 100644
index 0000000..2042595
--- /dev/null
+++ b/examples/declarative/tutorials/contacts/shared/pics/trash.png
Binary files differ
diff --git a/examples/declarative/tutorials/helloworld/t1/tutorial1.qml b/examples/declarative/tutorials/helloworld/t1/tutorial1.qml
new file mode 100644
index 0000000..4e53b8e
--- /dev/null
+++ b/examples/declarative/tutorials/helloworld/t1/tutorial1.qml
@@ -0,0 +1,14 @@
+Rect {
+ id: Page
+ width: 480
+ height: 200
+ color: "LightGrey"
+ Text {
+ id: HelloText
+ text: "Hello world!"
+ font.size: 24
+ font.bold: true
+ y: 30
+ anchors.horizontalCenter: Page.horizontalCenter
+ }
+}
diff --git a/examples/declarative/tutorials/helloworld/t2/Cell.qml b/examples/declarative/tutorials/helloworld/t2/Cell.qml
new file mode 100644
index 0000000..0109251
--- /dev/null
+++ b/examples/declarative/tutorials/helloworld/t2/Cell.qml
@@ -0,0 +1,16 @@
+Item {
+ property var color
+
+ id: CellContainer
+ width: 40
+ height: 25
+
+ Rect {
+ anchors.fill: parent
+ color: CellContainer.color
+ }
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { HelloText.color = CellContainer.color }
+ }
+}
diff --git a/examples/declarative/tutorials/helloworld/t2/tutorial2.qml b/examples/declarative/tutorials/helloworld/t2/tutorial2.qml
new file mode 100644
index 0000000..6c7e68e
--- /dev/null
+++ b/examples/declarative/tutorials/helloworld/t2/tutorial2.qml
@@ -0,0 +1,27 @@
+Rect {
+ id: Page
+ width: 480
+ height: 200
+ color: "LightGrey"
+ Text {
+ id: HelloText
+ text: "Hello world!"
+ font.size: 24
+ font.bold: true
+ y: 30
+ anchors.horizontalCenter: Page.horizontalCenter
+ }
+ GridLayout {
+ id: ColorPicker
+ x: 0
+ anchors.bottom: Page.bottom
+ width: 120; height: 50
+ rows: 2; columns: 3
+ Cell { color: "#ff0000" }
+ Cell { color: "#00ff00" }
+ Cell { color: "#0000ff" }
+ Cell { color: "#ffff00" }
+ Cell { color: "#00ffff" }
+ Cell { color: "#ff00ff" }
+ }
+}
diff --git a/examples/declarative/tutorials/helloworld/t3/Cell.qml b/examples/declarative/tutorials/helloworld/t3/Cell.qml
new file mode 100644
index 0000000..e779406
--- /dev/null
+++ b/examples/declarative/tutorials/helloworld/t3/Cell.qml
@@ -0,0 +1,15 @@
+Item {
+ property var color
+
+ id: CellContainer
+ width: 40
+ height: 25
+ Rect {
+ anchors.fill: parent
+ color: CellContainer.color
+ }
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: { HelloText.color = CellContainer.color }
+ }
+}
diff --git a/examples/declarative/tutorials/helloworld/t3/tutorial3.qml b/examples/declarative/tutorials/helloworld/t3/tutorial3.qml
new file mode 100644
index 0000000..bd89ecf
--- /dev/null
+++ b/examples/declarative/tutorials/helloworld/t3/tutorial3.qml
@@ -0,0 +1,59 @@
+Rect {
+ id: Page
+ width: 480
+ height: 200
+ color: "LightGrey"
+ Text {
+ id: HelloText
+ text: "Hello world!"
+ font.size: 24
+ font.bold: true
+ y: 30
+ anchors.horizontalCenter: Page.horizontalCenter
+ states: [
+ State {
+ name: "down"
+ when: MouseRegion.pressed == true
+ SetProperty {
+ target: HelloText
+ property: "y"
+ value: 160
+ }
+ SetProperty {
+ target: HelloText
+ property: "color"
+ value: "red"
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "down"
+ reversible: true
+ ParallelAnimation {
+ NumericAnimation {
+ properties: "y"
+ duration: 500
+ easing: "easeOutBounce"
+ }
+ ColorAnimation { duration: 500 }
+ }
+ }
+ ]
+ }
+ MouseRegion { id: MouseRegion; anchors.fill: HelloText }
+ GridLayout {
+ id: ColorPicker
+ x: 0
+ anchors.bottom: Page.bottom
+ width: 120; height: 50
+ rows: 2; columns: 3
+ Cell { color: "#ff0000" }
+ Cell { color: "#00ff00" }
+ Cell { color: "#0000ff" }
+ Cell { color: "#ffff00" }
+ Cell { color: "#00ffff" }
+ Cell { color: "#ff00ff" }
+ }
+}
diff --git a/examples/declarative/velocity/Day.qml b/examples/declarative/velocity/Day.qml
new file mode 100644
index 0000000..c70a211
--- /dev/null
+++ b/examples/declarative/velocity/Day.qml
@@ -0,0 +1,111 @@
+Rect {
+ property string day
+ property var stickies
+
+ width: 400
+ height: 500
+ radius: 7
+ pen.color: "black"
+ id: Page
+ Image {
+ x: 10
+ y: 10
+ source: "cork.jpg"
+ opaque: true
+ }
+ Text {
+ x: 20
+ y: 20
+ height: 40
+ font.size: 14
+ font.bold: true
+ width: 370
+ text: day
+ style: Outline
+ styleColor: "#dedede"
+ }
+ Repeater {
+ dataSource: Page.stickies
+ Item {
+ x: Math.random() * 200 + 100
+ y: Math.random() * 300 + 50
+ id: StickyPage
+ rotation: Follow {
+ source: -Flick.xVelocity / 100
+ spring: 2.0
+ damping: 0.1
+ }
+ Item {
+ id: Sticky
+ scale: 0.5
+ Image {
+ id: StickyImage
+ source: "sticky.png"
+ smooth: true
+ y: -20
+ x: 8 + -width * 0.6 / 2
+ scale: 0.6
+ }
+ TextEdit {
+ id: MyText
+ smooth: true
+ font.size: 28
+ readOnly: false
+ x: -104
+ y: 36
+ wrap: true
+ rotation: -8
+ text: noteText
+ width: 195
+ height: 172
+ }
+ Item {
+ y: -20
+ x: StickyImage.x
+ width: StickyImage.width * StickyImage.scale
+ height: StickyImage.height * StickyImage.scale
+ MouseRegion {
+ id: Mouse
+ onClicked: { MyText.focus = true }
+ anchors.fill: parent
+ drag.target: StickyPage
+ drag.axis: "xy"
+ drag.ymin: 0
+ drag.ymax: 500
+ drag.xmin: 0
+ drag.xmax: 400
+ }
+ }
+ }
+ Image {
+ source: "tack.png"
+ x: -width / 2
+ y: -height * 0.7 / 2
+ scale: 0.7
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: Mouse.pressed
+ SetProperties {
+ target: Sticky
+ rotation: 8
+ scale: 1
+ }
+ SetProperties {
+ target: Page
+ z: 8
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ NumericAnimation {
+ properties: "rotation,scale"
+ duration: 200
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/examples/declarative/velocity/cork.jpg b/examples/declarative/velocity/cork.jpg
new file mode 100644
index 0000000..d4d706c
--- /dev/null
+++ b/examples/declarative/velocity/cork.jpg
Binary files differ
diff --git a/examples/declarative/velocity/sticky.png b/examples/declarative/velocity/sticky.png
new file mode 100644
index 0000000..73df3cd
--- /dev/null
+++ b/examples/declarative/velocity/sticky.png
Binary files differ
diff --git a/examples/declarative/velocity/tack.png b/examples/declarative/velocity/tack.png
new file mode 100644
index 0000000..cef2d1c
--- /dev/null
+++ b/examples/declarative/velocity/tack.png
Binary files differ
diff --git a/examples/declarative/velocity/velocity.qml b/examples/declarative/velocity/velocity.qml
new file mode 100644
index 0000000..786f364
--- /dev/null
+++ b/examples/declarative/velocity/velocity.qml
@@ -0,0 +1,113 @@
+Rect {
+ color: "lightSteelBlue"
+ width: 800
+ height: 600
+ ListModel {
+ id: List
+ ListElement {
+ name: "Sunday"
+ dayColor: "#808080"
+ notes: [
+ ListElement {
+ noteText: "Lunch"
+ },
+ ListElement {
+ noteText: "Party"
+ }
+ ]
+ }
+ ListElement {
+ name: "Monday"
+ dayColor: "blue"
+ notes: [
+ ListElement {
+ noteText: "Pickup kids"
+ },
+ ListElement {
+ noteText: "Checkout kinetic"
+ },
+ ListElement {
+ noteText: "Read email"
+ }
+ ]
+ }
+ ListElement {
+ name: "Tuesday"
+ dayColor: "yellow"
+ notes: [
+ ListElement {
+ noteText: "Walk dog"
+ },
+ ListElement {
+ noteText: "Buy newspaper"
+ }
+ ]
+ }
+ ListElement {
+ name: "Wednesday"
+ dayColor: "purple"
+ notes: [
+ ListElement {
+ noteText: "Cook dinner"
+ },
+ ListElement {
+ noteText: "Eat dinner"
+ }
+ ]
+ }
+ ListElement {
+ name: "Thursday"
+ dayColor: "blue"
+ notes: [
+ ListElement {
+ noteText: "5:30pm Meeting"
+ },
+ ListElement {
+ noteText: "Weed garden"
+ }
+ ]
+ }
+ ListElement {
+ name: "Friday"
+ dayColor: "green"
+ notes: [
+ ListElement {
+ noteText: "Still work"
+ },
+ ListElement {
+ noteText: "Drink"
+ }
+ ]
+ }
+ ListElement {
+ name: "Saturday"
+ dayColor: "orange"
+ notes: [
+ ListElement {
+ noteText: "Drink"
+ },
+ ListElement {
+ noteText: "Drink"
+ }
+ ]
+ }
+ }
+ Flickable {
+ id: Flick
+ anchors.fill: parent
+ viewportWidth: Lay.width
+ HorizontalLayout {
+ id: Lay
+ Repeater {
+ dataSource: List
+ Component {
+ Day {
+ day: name
+ color: dayColor
+ stickies: notes
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/webview/autosize.qml b/examples/declarative/webview/autosize.qml
new file mode 100644
index 0000000..c32b752
--- /dev/null
+++ b/examples/declarative/webview/autosize.qml
@@ -0,0 +1,59 @@
+// The WebView size is determined by the width, height,
+// idealWidth, and idealHeight properties.
+Rect {
+ id: Rect
+ color: "white"
+ width: 200
+ height: Layout.height
+ VerticalLayout {
+ id: Layout
+ spacing: 2
+ WebView {
+ html: "No width defined."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ WebView {
+ width: Rect.width
+ html: "The width is full."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ WebView {
+ width: Rect.width/2
+ html: "The width is half."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ WebView {
+ idealWidth: Rect.width/2
+ html: "The idealWidth is half."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ WebView {
+ idealWidth: Rect.width/2
+ html: "The_idealWidth_is_half."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ WebView {
+ width: Rect.width/2
+ html: "The_width_is_half."
+ Rect {
+ color: "#10000000"
+ anchors.fill: parent
+ }
+ }
+ }
+}
diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml
new file mode 100644
index 0000000..5e4735e
--- /dev/null
+++ b/examples/declarative/webview/content/SpinSquare.qml
@@ -0,0 +1,24 @@
+Item {
+ properties var period : 250
+ properties var color : "black"
+ id: Root
+
+ Item {
+ x: Root.width/2
+ y: Root.height/2
+ Rect {
+ color: Root.color
+ x: -width/2
+ y: -height/2
+ width: Root.width
+ height: width
+ }
+ rotation: NumericAnimation {
+ from: 0
+ to: 360
+ repeat: true
+ running: true
+ duration: Root.period
+ }
+ }
+}
diff --git a/examples/declarative/webview/inline-html.qml b/examples/declarative/webview/inline-html.qml
new file mode 100644
index 0000000..5f6d410
--- /dev/null
+++ b/examples/declarative/webview/inline-html.qml
@@ -0,0 +1,12 @@
+// Inline HTML with loose formatting can be
+// set on the html property.
+WebView {
+ html:"\
+ <body bgcolor=white>\
+ <table border=1>\
+ <tr><th><th>One<th>Two<th>Three\
+ <tr><th>1<td>X<td>1<td>X\
+ <tr><th>2<td>0<td>X<td>0\
+ <tr><th>3<td>X<td>1<td>X\
+ </table>"
+}
diff --git a/examples/declarative/webview/qml-in-html.qml b/examples/declarative/webview/qml-in-html.qml
new file mode 100644
index 0000000..29dded5
--- /dev/null
+++ b/examples/declarative/webview/qml-in-html.qml
@@ -0,0 +1,30 @@
+// The WebView supports QML data through the HTML OBJECT tag
+Rect {
+ color:"blue"
+ Flickable {
+ width: parent.width
+ height: parent.height/2
+ viewportWidth: Web.width*Web.scale
+ viewportHeight: Web.height*Web.scale
+ WebView {
+ id: Web
+ width: 250
+ height: 420
+ scale: 0.75
+ smooth: true
+ settings.pluginsEnabled: true
+ html: "<html>\
+ <body bgcolor=white>\
+ These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%\
+ and placed in a Flickable area...\
+ <table border=1>\
+ <tr><th>Duration <th>Color <th>Plugin\
+ <tr><td>500 <td>red <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=500 color=red />\
+ <tr><td>2000 <td>blue <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=2000 color=blue />\
+ <tr><td>1000 <td>green <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=1000 color=green />\
+ </table>\
+ </body>\
+ </html>"
+ }
+ }
+}
diff --git a/examples/declarative/webview/transparent.qml b/examples/declarative/webview/transparent.qml
new file mode 100644
index 0000000..8614822
--- /dev/null
+++ b/examples/declarative/webview/transparent.qml
@@ -0,0 +1,11 @@
+// The WebView background is transparent
+// if the HTML does not specify a background
+Rect {
+ color: "green"
+ width: Web.width
+ height: Web.height
+ WebView {
+ id: Web
+ html: "Hello <b>World!</b>"
+ }
+}
diff --git a/examples/declarative/xmldata/daringfireball.qml b/examples/declarative/xmldata/daringfireball.qml
new file mode 100644
index 0000000..3877adf
--- /dev/null
+++ b/examples/declarative/xmldata/daringfireball.qml
@@ -0,0 +1,59 @@
+Rect {
+ color: "white"
+ width: 600
+ height: 600
+ resources: [
+ XmlListModel {
+ id: feedModel
+ source: "http://daringfireball.net/index.xml"
+ query: "doc($src)/feed/entry"
+ namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';"
+ Role {
+ name: "title"
+ query: "title/string()"
+ }
+ Role {
+ name: "tagline"
+ query: "author/name/string()"
+ }
+ Role {
+ name: "content"
+ query: "content/string()"
+ isCData: true
+ }
+ },
+ Component {
+ id: feedDelegate
+ Item {
+ height: contents.height + 20
+ Text {
+ x: 10
+ id: TitleText
+ text: title
+ font.bold: true
+ }
+ Text {
+ text: 'by ' + tagline
+ anchors.left: TitleText.right
+ anchors.leftMargin: 10
+ font.italic: true
+ }
+ Text {
+ x: 10
+ text: content
+ anchors.top: TitleText.bottom
+ width: 580
+ wrap: true
+ onLinkActivated: { print('link clicked: ' + link) }
+ }
+ }
+ }
+ ]
+ ListView {
+ id: list
+ anchors.fill: parent
+ clip: true
+ model: feedModel
+ delegate: feedDelegate
+ }
+}
diff --git a/examples/declarative/xmldata/yahoonews.qml b/examples/declarative/xmldata/yahoonews.qml
new file mode 100644
index 0000000..206c85f
--- /dev/null
+++ b/examples/declarative/xmldata/yahoonews.qml
@@ -0,0 +1,113 @@
+Rect {
+ gradient: Gradient {
+ GradientStop { position: 0; color: "black" }
+ GradientStop { position: 1.0; color: "#AAAAAA" }
+ }
+ width: 600
+ height: 600
+ resources: [
+ XmlListModel {
+ id: feedModel
+ source: "http://rss.news.yahoo.com/rss/oceania"
+ query: "doc($src)/rss/channel/item"
+ Role {
+ name: "title"
+ query: "title/string()"
+ }
+ Role {
+ name: "link"
+ query: "link/string()"
+ }
+ Role {
+ name: "description"
+ query: "description/string()"
+ isCData: true
+ }
+ },
+ Component {
+ id: feedDelegate
+ Item {
+ id: Delegate
+ height: Wrapper.height + 10
+ MouseRegion {
+ anchors.fill: Wrapper
+ onPressed: { Delegate.ListView.list.currentIndex = index; }
+ onClicked: { if (Wrapper.state == 'Details') { Wrapper.state = '';} else {Wrapper.state = 'Details';} }
+ }
+ Rect {
+ id: Wrapper
+ y: 5
+ height: TitleText.height + 10
+ width: 580
+ color: "#F0F0F0"
+ radius: 5
+ Text {
+ x: 10
+ y: 5
+ id: TitleText
+ text: '<a href=\'' + link + '\'>' + title + '</a>'
+ font.bold: true
+ font.family: "Helvetica"
+ font.size: 14
+ onLinkActivated: { print('link clicked: ' + link) }
+ }
+ Text {
+ x: 10
+ id: Description
+ text: description
+ width: 560
+ wrap: true
+ font.family: "Helvetica"
+ anchors.top: TitleText.bottom
+ anchors.topMargin: 5
+ opacity: 0
+ }
+ states: [
+ State {
+ name: "Details"
+ SetProperty {
+ target: Wrapper
+ property: "height"
+ binding: "contents.height + 10"
+ }
+ SetProperty {
+ target: Description
+ property: "opacity"
+ value: 1
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ fromState: "*"
+ toState: "Details"
+ reversible: true
+ SequentialAnimation {
+ NumericAnimation {
+ duration: 200
+ properties: "height"
+ easing: "easeOutQuad"
+ }
+ NumericAnimation {
+ duration: 200
+ properties: "opacity"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ ListView {
+ id: list
+ x: 10
+ y: 10
+ width: parent.width - 20
+ height: parent.height - 20
+ clip: true
+ model: feedModel
+ delegate: feedDelegate
+ currentItemPositioning: "Snap"
+ }
+}