summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorCasper van Donderen <casper.vandonderen@nokia.com>2011-06-22 13:54:56 +0200
committerQt by Nokia <qt-info@nokia.com>2011-06-24 16:47:24 +0200
commite0d5221957bf0d7857f924f1f2ae63d490de0a0a (patch)
tree580dfcaf67d95c18c3fb548b0ffa6f79f1cd60a7 /examples
parentd7c37d9bacc016b1156e15780080cfc8c24f6e6a (diff)
Move all other demos in qtbase to examples.
Change-Id: Iab0e7364d1f6b348d0e3033ea9304139f5bd6d0d Reviewed-on: http://codereview.qt.nokia.com/617 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: David Boddie
Diffstat (limited to 'examples')
-rw-r--r--examples/animation/sub-attaq/animationmanager.cpp98
-rw-r--r--examples/animation/sub-attaq/animationmanager.h73
-rw-r--r--examples/animation/sub-attaq/boat.cpp272
-rw-r--r--examples/animation/sub-attaq/boat.h95
-rw-r--r--examples/animation/sub-attaq/boat_p.h232
-rw-r--r--examples/animation/sub-attaq/bomb.cpp118
-rw-r--r--examples/animation/sub-attaq/bomb.h67
-rw-r--r--examples/animation/sub-attaq/data.xml39
-rw-r--r--examples/animation/sub-attaq/graphicsscene.cpp282
-rw-r--r--examples/animation/sub-attaq/graphicsscene.h122
-rw-r--r--examples/animation/sub-attaq/main.cpp57
-rw-r--r--examples/animation/sub-attaq/mainwindow.cpp82
-rw-r--r--examples/animation/sub-attaq/mainwindow.h63
-rw-r--r--examples/animation/sub-attaq/pics/big/background.pngbin0 -> 48858 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/boat.pngbin0 -> 5198 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/bomb.pngbin0 -> 760 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/boat/step1.pngbin0 -> 5760 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/boat/step2.pngbin0 -> 9976 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/boat/step3.pngbin0 -> 12411 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/boat/step4.pngbin0 -> 15438 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/submarine/step1.pngbin0 -> 3354 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/submarine/step2.pngbin0 -> 6205 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/submarine/step3.pngbin0 -> 6678 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/explosion/submarine/step4.pngbin0 -> 6666 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/submarine.pngbin0 -> 3202 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/surface.pngbin0 -> 575 bytes
-rw-r--r--examples/animation/sub-attaq/pics/big/torpedo.pngbin0 -> 951 bytes
-rw-r--r--examples/animation/sub-attaq/pics/scalable/background-n810.svg171
-rw-r--r--examples/animation/sub-attaq/pics/scalable/background.svg171
-rw-r--r--examples/animation/sub-attaq/pics/scalable/boat.svg279
-rw-r--r--examples/animation/sub-attaq/pics/scalable/bomb.svg138
-rw-r--r--examples/animation/sub-attaq/pics/scalable/sand.svg103
-rw-r--r--examples/animation/sub-attaq/pics/scalable/see.svg44
-rw-r--r--examples/animation/sub-attaq/pics/scalable/sky.svg45
-rw-r--r--examples/animation/sub-attaq/pics/scalable/sub-attaq.svg1473
-rw-r--r--examples/animation/sub-attaq/pics/scalable/submarine.svg214
-rw-r--r--examples/animation/sub-attaq/pics/scalable/surface.svg49
-rw-r--r--examples/animation/sub-attaq/pics/scalable/torpedo.svg127
-rw-r--r--examples/animation/sub-attaq/pics/small/background.pngbin0 -> 34634 bytes
-rw-r--r--examples/animation/sub-attaq/pics/small/boat.pngbin0 -> 2394 bytes
-rw-r--r--examples/animation/sub-attaq/pics/small/bomb.pngbin0 -> 760 bytes
-rw-r--r--examples/animation/sub-attaq/pics/small/submarine.pngbin0 -> 1338 bytes
-rw-r--r--examples/animation/sub-attaq/pics/small/surface.pngbin0 -> 502 bytes
-rw-r--r--examples/animation/sub-attaq/pics/small/torpedo.pngbin0 -> 951 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-a.pngbin0 -> 5972 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-a2.pngbin0 -> 5969 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-b.pngbin0 -> 6869 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-dash.pngbin0 -> 2255 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-excl.pngbin0 -> 2740 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-q.pngbin0 -> 7016 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-s.pngbin0 -> 5817 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-t.pngbin0 -> 3717 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-t2.pngbin0 -> 3688 bytes
-rw-r--r--examples/animation/sub-attaq/pics/welcome/logo-u.pngbin0 -> 5374 bytes
-rw-r--r--examples/animation/sub-attaq/pixmapitem.cpp76
-rw-r--r--examples/animation/sub-attaq/pixmapitem.h63
-rw-r--r--examples/animation/sub-attaq/progressitem.cpp67
-rw-r--r--examples/animation/sub-attaq/progressitem.h61
-rw-r--r--examples/animation/sub-attaq/qanimationstate.cpp150
-rw-r--r--examples/animation/sub-attaq/qanimationstate.h92
-rw-r--r--examples/animation/sub-attaq/states.cpp330
-rw-r--r--examples/animation/sub-attaq/states.h180
-rw-r--r--examples/animation/sub-attaq/sub-attaq.pro41
-rw-r--r--examples/animation/sub-attaq/subattaq.qrc39
-rw-r--r--examples/animation/sub-attaq/submarine.cpp182
-rw-r--r--examples/animation/sub-attaq/submarine.h93
-rw-r--r--examples/animation/sub-attaq/submarine_p.h137
-rw-r--r--examples/animation/sub-attaq/textinformationitem.cpp54
-rw-r--r--examples/animation/sub-attaq/textinformationitem.h55
-rw-r--r--examples/animation/sub-attaq/torpedo.cpp114
-rw-r--r--examples/animation/sub-attaq/torpedo.h67
-rw-r--r--examples/embedded/digiflip/digiflip.cpp425
-rw-r--r--examples/embedded/digiflip/digiflip.pro11
-rw-r--r--examples/embedded/embedded.pro12
-rw-r--r--examples/embedded/flickable/flickable.cpp284
-rw-r--r--examples/embedded/flickable/flickable.h80
-rw-r--r--examples/embedded/flickable/flickable.pro12
-rw-r--r--examples/embedded/flickable/main.cpp233
-rw-r--r--examples/embedded/flightinfo/aircraft.pngbin0 -> 20200 bytes
-rw-r--r--examples/embedded/flightinfo/flightinfo.cpp399
-rw-r--r--examples/embedded/flightinfo/flightinfo.pro17
-rw-r--r--examples/embedded/flightinfo/flightinfo.qrc5
-rw-r--r--examples/embedded/flightinfo/form.ui226
-rw-r--r--examples/embedded/lightmaps/lightmaps.cpp287
-rw-r--r--examples/embedded/lightmaps/lightmaps.h88
-rw-r--r--examples/embedded/lightmaps/lightmaps.pro21
-rw-r--r--examples/embedded/lightmaps/main.cpp63
-rw-r--r--examples/embedded/lightmaps/mapzoom.cpp147
-rw-r--r--examples/embedded/lightmaps/mapzoom.h69
-rw-r--r--examples/embedded/lightmaps/slippymap.cpp213
-rw-r--r--examples/embedded/lightmaps/slippymap.h87
-rw-r--r--examples/embedded/raycasting/raycasting.cpp391
-rw-r--r--examples/embedded/raycasting/raycasting.pro13
-rw-r--r--examples/embedded/raycasting/raycasting.qrc5
-rw-r--r--examples/embedded/raycasting/textures.pngbin0 -> 17669 bytes
-rwxr-xr-xexamples/embedded/styledemo/files/add.pngbin0 -> 1474 bytes
-rw-r--r--examples/embedded/styledemo/files/application.qss125
-rw-r--r--examples/embedded/styledemo/files/blue.qss38
-rw-r--r--examples/embedded/styledemo/files/khaki.qss99
-rw-r--r--examples/embedded/styledemo/files/nature_1.jpgbin0 -> 167443 bytes
-rw-r--r--examples/embedded/styledemo/files/nostyle.qss0
-rwxr-xr-xexamples/embedded/styledemo/files/remove.pngbin0 -> 865 bytes
-rw-r--r--examples/embedded/styledemo/files/transparent.qss139
-rw-r--r--examples/embedded/styledemo/main.cpp59
-rw-r--r--examples/embedded/styledemo/styledemo.pro17
-rw-r--r--examples/embedded/styledemo/styledemo.qrc13
-rw-r--r--examples/embedded/styledemo/stylewidget.cpp112
-rw-r--r--examples/embedded/styledemo/stylewidget.h65
-rw-r--r--examples/embedded/styledemo/stylewidget.ui417
-rw-r--r--examples/graphicsview/boxes/3rdparty/fbm.c207
-rw-r--r--examples/graphicsview/boxes/3rdparty/fbm.h40
-rw-r--r--examples/graphicsview/boxes/basic.fsh73
-rw-r--r--examples/graphicsview/boxes/basic.vsh61
-rw-r--r--examples/graphicsview/boxes/boxes.pro49
-rw-r--r--examples/graphicsview/boxes/boxes.qrc25
-rw-r--r--examples/graphicsview/boxes/cubemap_negx.jpgbin0 -> 41060 bytes
-rw-r--r--examples/graphicsview/boxes/cubemap_negy.jpgbin0 -> 15520 bytes
-rw-r--r--examples/graphicsview/boxes/cubemap_negz.jpgbin0 -> 68911 bytes
-rw-r--r--examples/graphicsview/boxes/cubemap_posx.jpgbin0 -> 74915 bytes
-rw-r--r--examples/graphicsview/boxes/cubemap_posy.jpgbin0 -> 24193 bytes
-rw-r--r--examples/graphicsview/boxes/cubemap_posz.jpgbin0 -> 57881 bytes
-rw-r--r--examples/graphicsview/boxes/dotted.fsh66
-rw-r--r--examples/graphicsview/boxes/fresnel.fsh79
-rw-r--r--examples/graphicsview/boxes/glass.fsh76
-rw-r--r--examples/graphicsview/boxes/glbuffers.cpp402
-rw-r--r--examples/graphicsview/boxes/glbuffers.h366
-rw-r--r--examples/graphicsview/boxes/glextensions.cpp98
-rw-r--r--examples/graphicsview/boxes/glextensions.h202
-rw-r--r--examples/graphicsview/boxes/gltrianglemesh.h91
-rw-r--r--examples/graphicsview/boxes/granite.fsh76
-rw-r--r--examples/graphicsview/boxes/main.cpp150
-rw-r--r--examples/graphicsview/boxes/marble.fsh71
-rw-r--r--examples/graphicsview/boxes/parameters.par5
-rw-r--r--examples/graphicsview/boxes/qt-logo.jpgbin0 -> 40886 bytes
-rw-r--r--examples/graphicsview/boxes/qt-logo.pngbin0 -> 13923 bytes
-rw-r--r--examples/graphicsview/boxes/qtbox.cpp480
-rw-r--r--examples/graphicsview/boxes/qtbox.h118
-rw-r--r--examples/graphicsview/boxes/reflection.fsh54
-rw-r--r--examples/graphicsview/boxes/refraction.fsh70
-rw-r--r--examples/graphicsview/boxes/roundedbox.cpp161
-rw-r--r--examples/graphicsview/boxes/roundedbox.h72
-rw-r--r--examples/graphicsview/boxes/scene.cpp1085
-rw-r--r--examples/graphicsview/boxes/scene.h245
-rw-r--r--examples/graphicsview/boxes/smiley.pngbin0 -> 14508 bytes
-rw-r--r--examples/graphicsview/boxes/square.jpgbin0 -> 14542 bytes
-rw-r--r--examples/graphicsview/boxes/trackball.cpp160
-rw-r--r--examples/graphicsview/boxes/trackball.h79
-rw-r--r--examples/graphicsview/boxes/wood.fsh70
-rw-r--r--examples/graphicsview/chip/chip.cpp183
-rw-r--r--examples/graphicsview/chip/chip.h68
-rw-r--r--examples/graphicsview/chip/chip.pro20
-rw-r--r--examples/graphicsview/chip/fileprint.pngbin0 -> 1456 bytes
-rw-r--r--examples/graphicsview/chip/images.qrc10
-rw-r--r--examples/graphicsview/chip/main.cpp57
-rw-r--r--examples/graphicsview/chip/mainwindow.cpp109
-rw-r--r--examples/graphicsview/chip/mainwindow.h68
-rw-r--r--examples/graphicsview/chip/qt4logo.pngbin0 -> 48333 bytes
-rw-r--r--examples/graphicsview/chip/rotateleft.pngbin0 -> 1754 bytes
-rw-r--r--examples/graphicsview/chip/rotateright.pngbin0 -> 1732 bytes
-rw-r--r--examples/graphicsview/chip/view.cpp276
-rw-r--r--examples/graphicsview/chip/view.h104
-rw-r--r--examples/graphicsview/chip/zoomin.pngbin0 -> 1622 bytes
-rw-r--r--examples/graphicsview/chip/zoomout.pngbin0 -> 1601 bytes
-rw-r--r--examples/graphicsview/embeddeddialogs/No-Ones-Laughing-3.jpgbin0 -> 30730 bytes
-rw-r--r--examples/graphicsview/embeddeddialogs/customproxy.cpp167
-rw-r--r--examples/graphicsview/embeddeddialogs/customproxy.h76
-rw-r--r--examples/graphicsview/embeddeddialogs/embeddeddialog.cpp106
-rw-r--r--examples/graphicsview/embeddeddialogs/embeddeddialog.h66
-rw-r--r--examples/graphicsview/embeddeddialogs/embeddeddialog.ui87
-rw-r--r--examples/graphicsview/embeddeddialogs/embeddeddialogs.pro19
-rw-r--r--examples/graphicsview/embeddeddialogs/embeddeddialogs.qrc5
-rw-r--r--examples/graphicsview/embeddeddialogs/main.cpp83
-rw-r--r--examples/itemviews/interview/README2
-rw-r--r--examples/itemviews/interview/images/folder.pngbin0 -> 3910 bytes
-rw-r--r--examples/itemviews/interview/images/interview.pngbin0 -> 174 bytes
-rw-r--r--examples/itemviews/interview/images/services.pngbin0 -> 3749 bytes
-rw-r--r--examples/itemviews/interview/interview.pro19
-rw-r--r--examples/itemviews/interview/interview.qrc7
-rw-r--r--examples/itemviews/interview/main.cpp95
-rw-r--r--examples/itemviews/interview/model.cpp147
-rw-r--r--examples/itemviews/interview/model.h90
-rw-r--r--examples/itemviews/spreadsheet/images/interview.pngbin0 -> 174 bytes
-rw-r--r--examples/itemviews/spreadsheet/main.cpp55
-rw-r--r--examples/itemviews/spreadsheet/printview.cpp59
-rw-r--r--examples/itemviews/spreadsheet/printview.h60
-rw-r--r--examples/itemviews/spreadsheet/spreadsheet.cpp633
-rw-r--r--examples/itemviews/spreadsheet/spreadsheet.h124
-rw-r--r--examples/itemviews/spreadsheet/spreadsheet.pro34
-rw-r--r--examples/itemviews/spreadsheet/spreadsheet.qrc5
-rw-r--r--examples/itemviews/spreadsheet/spreadsheetdelegate.cpp114
-rw-r--r--examples/itemviews/spreadsheet/spreadsheetdelegate.h65
-rw-r--r--examples/itemviews/spreadsheet/spreadsheetitem.cpp167
-rw-r--r--examples/itemviews/spreadsheet/spreadsheetitem.h73
-rw-r--r--examples/mainwindows/macmainwindow/macmainwindow.h137
-rw-r--r--examples/mainwindows/macmainwindow/macmainwindow.mm347
-rw-r--r--examples/mainwindows/macmainwindow/macmainwindow.pro23
-rw-r--r--examples/mainwindows/macmainwindow/main.cpp66
-rw-r--r--examples/mainwindows/mainwindow/colorswatch.cpp746
-rw-r--r--examples/mainwindows/mainwindow/colorswatch.h136
-rw-r--r--examples/mainwindows/mainwindow/main.cpp164
-rw-r--r--examples/mainwindows/mainwindow/mainwindow.cpp514
-rw-r--r--examples/mainwindows/mainwindow/mainwindow.h90
-rw-r--r--examples/mainwindows/mainwindow/mainwindow.pro17
-rw-r--r--examples/mainwindows/mainwindow/mainwindow.qrc8
-rw-r--r--examples/mainwindows/mainwindow/qt.pngbin0 -> 2037 bytes
-rw-r--r--examples/mainwindows/mainwindow/titlebarCenter.pngbin0 -> 146 bytes
-rw-r--r--examples/mainwindows/mainwindow/titlebarLeft.pngbin0 -> 5148 bytes
-rw-r--r--examples/mainwindows/mainwindow/titlebarRight.pngbin0 -> 2704 bytes
-rw-r--r--examples/mainwindows/mainwindow/toolbar.cpp383
-rw-r--r--examples/mainwindows/mainwindow/toolbar.h118
-rw-r--r--examples/painting/composition/composition.cpp544
-rw-r--r--examples/painting/composition/composition.h193
-rw-r--r--examples/painting/composition/composition.html23
-rw-r--r--examples/painting/composition/composition.pro29
-rw-r--r--examples/painting/composition/composition.qrc8
-rw-r--r--examples/painting/composition/flower.jpgbin0 -> 49616 bytes
-rw-r--r--examples/painting/composition/flower_alpha.jpgbin0 -> 67326 bytes
-rw-r--r--examples/painting/composition/main.cpp68
-rw-r--r--examples/painting/deform/deform.pro24
-rw-r--r--examples/painting/deform/deform.qrc6
-rw-r--r--examples/painting/deform/main.cpp72
-rw-r--r--examples/painting/deform/pathdeform.cpp647
-rw-r--r--examples/painting/deform/pathdeform.h153
-rw-r--r--examples/painting/deform/pathdeform.html24
-rw-r--r--examples/painting/gradients/gradients.cpp516
-rw-r--r--examples/painting/gradients/gradients.h170
-rw-r--r--examples/painting/gradients/gradients.html31
-rw-r--r--examples/painting/gradients/gradients.pro20
-rw-r--r--examples/painting/gradients/gradients.qrc6
-rw-r--r--examples/painting/gradients/main.cpp63
-rw-r--r--examples/painting/pathstroke/main.cpp71
-rw-r--r--examples/painting/pathstroke/pathstroke.cpp686
-rw-r--r--examples/painting/pathstroke/pathstroke.h171
-rw-r--r--examples/painting/pathstroke/pathstroke.html20
-rw-r--r--examples/painting/pathstroke/pathstroke.pro24
-rw-r--r--examples/painting/pathstroke/pathstroke.qrc6
-rw-r--r--examples/painting/shared/arthurstyle.cpp452
-rw-r--r--examples/painting/shared/arthurstyle.h79
-rw-r--r--examples/painting/shared/arthurwidgets.cpp371
-rw-r--r--examples/painting/shared/arthurwidgets.h137
-rw-r--r--examples/painting/shared/hoverpoints.cpp415
-rw-r--r--examples/painting/shared/hoverpoints.h162
-rw-r--r--examples/painting/shared/images/bg_pattern.pngbin0 -> 104 bytes
-rw-r--r--examples/painting/shared/images/button_normal_cap_left.pngbin0 -> 654 bytes
-rw-r--r--examples/painting/shared/images/button_normal_cap_right.pngbin0 -> 674 bytes
-rw-r--r--examples/painting/shared/images/button_normal_stretch.pngbin0 -> 185 bytes
-rw-r--r--examples/painting/shared/images/button_pressed_cap_left.pngbin0 -> 710 bytes
-rw-r--r--examples/painting/shared/images/button_pressed_cap_right.pngbin0 -> 785 bytes
-rw-r--r--examples/painting/shared/images/button_pressed_stretch.pngbin0 -> 217 bytes
-rw-r--r--examples/painting/shared/images/curve_thing_edit-6.pngbin0 -> 58097 bytes
-rw-r--r--examples/painting/shared/images/frame_bottom.pngbin0 -> 166 bytes
-rw-r--r--examples/painting/shared/images/frame_bottomleft.pngbin0 -> 602 bytes
-rw-r--r--examples/painting/shared/images/frame_bottomright.pngbin0 -> 553 bytes
-rw-r--r--examples/painting/shared/images/frame_left.pngbin0 -> 182 bytes
-rw-r--r--examples/painting/shared/images/frame_right.pngbin0 -> 175 bytes
-rw-r--r--examples/painting/shared/images/frame_top.pngbin0 -> 188 bytes
-rw-r--r--examples/painting/shared/images/frame_topleft.pngbin0 -> 801 bytes
-rw-r--r--examples/painting/shared/images/frame_topright.pngbin0 -> 851 bytes
-rw-r--r--examples/painting/shared/images/groupframe_bottom_left.pngbin0 -> 397 bytes
-rw-r--r--examples/painting/shared/images/groupframe_bottom_right.pngbin0 -> 383 bytes
-rw-r--r--examples/painting/shared/images/groupframe_bottom_stretch.pngbin0 -> 141 bytes
-rw-r--r--examples/painting/shared/images/groupframe_left_stretch.pngbin0 -> 132 bytes
-rw-r--r--examples/painting/shared/images/groupframe_right_stretch.pngbin0 -> 113 bytes
-rw-r--r--examples/painting/shared/images/groupframe_top_stretch.pngbin0 -> 115 bytes
-rw-r--r--examples/painting/shared/images/groupframe_topleft.pngbin0 -> 412 bytes
-rw-r--r--examples/painting/shared/images/groupframe_topright.pngbin0 -> 449 bytes
-rw-r--r--examples/painting/shared/images/line_dash_dot.pngbin0 -> 151 bytes
-rw-r--r--examples/painting/shared/images/line_dash_dot_dot.pngbin0 -> 155 bytes
-rw-r--r--examples/painting/shared/images/line_dashed.pngbin0 -> 121 bytes
-rw-r--r--examples/painting/shared/images/line_dotted.pngbin0 -> 116 bytes
-rw-r--r--examples/painting/shared/images/line_solid.pngbin0 -> 110 bytes
-rw-r--r--examples/painting/shared/images/radiobutton-off.pngbin0 -> 442 bytes
-rw-r--r--examples/painting/shared/images/radiobutton-on.pngbin0 -> 474 bytes
-rw-r--r--examples/painting/shared/images/radiobutton_off.pngbin0 -> 442 bytes
-rw-r--r--examples/painting/shared/images/radiobutton_on.pngbin0 -> 499 bytes
-rw-r--r--examples/painting/shared/images/slider_bar.pngbin0 -> 748 bytes
-rw-r--r--examples/painting/shared/images/slider_thumb_off.pngbin0 -> 823 bytes
-rw-r--r--examples/painting/shared/images/slider_thumb_on.pngbin0 -> 798 bytes
-rw-r--r--examples/painting/shared/images/title_cap_left.pngbin0 -> 179 bytes
-rw-r--r--examples/painting/shared/images/title_cap_right.pngbin0 -> 184 bytes
-rw-r--r--examples/painting/shared/images/title_stretch.pngbin0 -> 106 bytes
-rw-r--r--examples/painting/shared/shared.pri21
-rw-r--r--examples/painting/shared/shared.pro39
-rw-r--r--examples/painting/shared/shared.qrc39
-rw-r--r--examples/richtext/textedit/example.html79
-rw-r--r--examples/richtext/textedit/images/logo32.pngbin0 -> 1410 bytes
-rw-r--r--examples/richtext/textedit/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--examples/richtext/textedit/images/mac/editcut.pngbin0 -> 1512 bytes
-rw-r--r--examples/richtext/textedit/images/mac/editpaste.pngbin0 -> 1906 bytes
-rw-r--r--examples/richtext/textedit/images/mac/editredo.pngbin0 -> 1752 bytes
-rw-r--r--examples/richtext/textedit/images/mac/editundo.pngbin0 -> 1746 bytes
-rw-r--r--examples/richtext/textedit/images/mac/exportpdf.pngbin0 -> 1215 bytes
-rw-r--r--examples/richtext/textedit/images/mac/filenew.pngbin0 -> 1172 bytes
-rw-r--r--examples/richtext/textedit/images/mac/fileopen.pngbin0 -> 2168 bytes
-rw-r--r--examples/richtext/textedit/images/mac/fileprint.pngbin0 -> 2087 bytes
-rw-r--r--examples/richtext/textedit/images/mac/filesave.pngbin0 -> 1206 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textbold.pngbin0 -> 1611 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textcenter.pngbin0 -> 1404 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textitalic.pngbin0 -> 1164 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textjustify.pngbin0 -> 1257 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textleft.pngbin0 -> 1235 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textright.pngbin0 -> 1406 bytes
-rw-r--r--examples/richtext/textedit/images/mac/textunder.pngbin0 -> 1183 bytes
-rw-r--r--examples/richtext/textedit/images/mac/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--examples/richtext/textedit/images/mac/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--examples/richtext/textedit/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--examples/richtext/textedit/images/win/editcut.pngbin0 -> 1896 bytes
-rw-r--r--examples/richtext/textedit/images/win/editpaste.pngbin0 -> 1482 bytes
-rw-r--r--examples/richtext/textedit/images/win/editredo.pngbin0 -> 1787 bytes
-rw-r--r--examples/richtext/textedit/images/win/editundo.pngbin0 -> 1768 bytes
-rw-r--r--examples/richtext/textedit/images/win/exportpdf.pngbin0 -> 1059 bytes
-rw-r--r--examples/richtext/textedit/images/win/filenew.pngbin0 -> 768 bytes
-rw-r--r--examples/richtext/textedit/images/win/fileopen.pngbin0 -> 1662 bytes
-rw-r--r--examples/richtext/textedit/images/win/fileprint.pngbin0 -> 1456 bytes
-rw-r--r--examples/richtext/textedit/images/win/filesave.pngbin0 -> 1205 bytes
-rw-r--r--examples/richtext/textedit/images/win/textbold.pngbin0 -> 1134 bytes
-rw-r--r--examples/richtext/textedit/images/win/textcenter.pngbin0 -> 627 bytes
-rw-r--r--examples/richtext/textedit/images/win/textitalic.pngbin0 -> 829 bytes
-rw-r--r--examples/richtext/textedit/images/win/textjustify.pngbin0 -> 695 bytes
-rw-r--r--examples/richtext/textedit/images/win/textleft.pngbin0 -> 673 bytes
-rw-r--r--examples/richtext/textedit/images/win/textright.pngbin0 -> 677 bytes
-rw-r--r--examples/richtext/textedit/images/win/textunder.pngbin0 -> 971 bytes
-rw-r--r--examples/richtext/textedit/images/win/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--examples/richtext/textedit/images/win/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--examples/richtext/textedit/main.cpp54
-rw-r--r--examples/richtext/textedit/textedit.cpp734
-rw-r--r--examples/richtext/textedit/textedit.h129
-rw-r--r--examples/richtext/textedit/textedit.pro22
-rw-r--r--examples/richtext/textedit/textedit.qdoc45
-rw-r--r--examples/richtext/textedit/textedit.qrc44
-rw-r--r--examples/sql/books/bookdelegate.cpp126
-rw-r--r--examples/sql/books/bookdelegate.h73
-rw-r--r--examples/sql/books/books.pro23
-rw-r--r--examples/sql/books/books.qrc5
-rw-r--r--examples/sql/books/bookwindow.cpp121
-rw-r--r--examples/sql/books/bookwindow.h64
-rw-r--r--examples/sql/books/bookwindow.ui149
-rw-r--r--examples/sql/books/images/star.pngbin0 -> 782 bytes
-rw-r--r--examples/sql/books/initdb.h125
-rw-r--r--examples/sql/books/main.cpp56
-rw-r--r--examples/sql/sqlbrowser/browser.cpp247
-rw-r--r--examples/sql/sqlbrowser/browser.h99
-rw-r--r--examples/sql/sqlbrowser/browserwidget.ui199
-rw-r--r--examples/sql/sqlbrowser/connectionwidget.cpp165
-rw-r--r--examples/sql/sqlbrowser/connectionwidget.h79
-rw-r--r--examples/sql/sqlbrowser/main.cpp91
-rw-r--r--examples/sql/sqlbrowser/qsqlconnectiondialog.cpp115
-rw-r--r--examples/sql/sqlbrowser/qsqlconnectiondialog.h74
-rw-r--r--examples/sql/sqlbrowser/qsqlconnectiondialog.ui224
-rw-r--r--examples/sql/sqlbrowser/sqlbrowser.pro25
-rw-r--r--examples/tools/undo/commands.cpp180
-rw-r--r--examples/tools/undo/commands.h112
-rw-r--r--examples/tools/undo/document.cpp445
-rw-r--r--examples/tools/undo/document.h125
-rw-r--r--examples/tools/undo/icons/background.pngbin0 -> 93 bytes
-rw-r--r--examples/tools/undo/icons/blue.pngbin0 -> 1659 bytes
-rw-r--r--examples/tools/undo/icons/circle.pngbin0 -> 1359 bytes
-rw-r--r--examples/tools/undo/icons/exit.pngbin0 -> 1731 bytes
-rw-r--r--examples/tools/undo/icons/fileclose.pngbin0 -> 1121 bytes
-rw-r--r--examples/tools/undo/icons/filenew.pngbin0 -> 1266 bytes
-rw-r--r--examples/tools/undo/icons/fileopen.pngbin0 -> 1771 bytes
-rw-r--r--examples/tools/undo/icons/filesave.pngbin0 -> 1022 bytes
-rw-r--r--examples/tools/undo/icons/green.pngbin0 -> 1766 bytes
-rw-r--r--examples/tools/undo/icons/ok.pngbin0 -> 979 bytes
-rw-r--r--examples/tools/undo/icons/rectangle.pngbin0 -> 690 bytes
-rw-r--r--examples/tools/undo/icons/red.pngbin0 -> 1653 bytes
-rw-r--r--examples/tools/undo/icons/redo.pngbin0 -> 985 bytes
-rw-r--r--examples/tools/undo/icons/remove.pngbin0 -> 1833 bytes
-rw-r--r--examples/tools/undo/icons/triangle.pngbin0 -> 850 bytes
-rw-r--r--examples/tools/undo/icons/undo.pngbin0 -> 962 bytes
-rw-r--r--examples/tools/undo/main.cpp56
-rw-r--r--examples/tools/undo/mainwindow.cpp446
-rw-r--r--examples/tools/undo/mainwindow.h87
-rw-r--r--examples/tools/undo/mainwindow.ui322
-rw-r--r--examples/tools/undo/undo.pro18
-rw-r--r--examples/tools/undo/undo.qrc20
376 files changed, 31388 insertions, 0 deletions
diff --git a/examples/animation/sub-attaq/animationmanager.cpp b/examples/animation/sub-attaq/animationmanager.cpp
new file mode 100644
index 0000000000..c7e230e3d2
--- /dev/null
+++ b/examples/animation/sub-attaq/animationmanager.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "animationmanager.h"
+
+//Qt
+#include <QtCore/QAbstractAnimation>
+#include <QtCore/QDebug>
+
+// the universe's only animation manager
+AnimationManager *AnimationManager::instance = 0;
+
+AnimationManager::AnimationManager()
+{
+}
+
+AnimationManager *AnimationManager::self()
+{
+ if (!instance)
+ instance = new AnimationManager;
+ return instance;
+}
+
+void AnimationManager::registerAnimation(QAbstractAnimation *anim)
+{
+ QObject::connect(anim, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterAnimation_helper(QObject*)));
+ animations.append(anim);
+}
+
+void AnimationManager::unregisterAnimation_helper(QObject *obj)
+{
+ unregisterAnimation(static_cast<QAbstractAnimation*>(obj));
+}
+
+void AnimationManager::unregisterAnimation(QAbstractAnimation *anim)
+{
+ QObject::disconnect(anim, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterAnimation_helper(QObject*)));
+ animations.removeAll(anim);
+}
+
+void AnimationManager::unregisterAllAnimations()
+{
+ animations.clear();
+}
+
+void AnimationManager::pauseAll()
+{
+ foreach (QAbstractAnimation* animation, animations) {
+ if (animation->state() == QAbstractAnimation::Running)
+ animation->pause();
+ }
+}
+void AnimationManager::resumeAll()
+{
+ foreach (QAbstractAnimation* animation, animations) {
+ if (animation->state() == QAbstractAnimation::Paused)
+ animation->resume();
+ }
+}
diff --git a/examples/animation/sub-attaq/animationmanager.h b/examples/animation/sub-attaq/animationmanager.h
new file mode 100644
index 0000000000..429d656485
--- /dev/null
+++ b/examples/animation/sub-attaq/animationmanager.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANIMATIONMANAGER_H
+#define ANIMATIONMANAGER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+class QAbstractAnimation;
+QT_END_NAMESPACE
+
+class AnimationManager : public QObject
+{
+Q_OBJECT
+public:
+ AnimationManager();
+ void registerAnimation(QAbstractAnimation *anim);
+ void unregisterAnimation(QAbstractAnimation *anim);
+ void unregisterAllAnimations();
+ static AnimationManager *self();
+
+public slots:
+ void pauseAll();
+ void resumeAll();
+
+private slots:
+ void unregisterAnimation_helper(QObject *obj);
+
+private:
+ static AnimationManager *instance;
+ QList<QAbstractAnimation *> animations;
+};
+
+#endif // ANIMATIONMANAGER_H
diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp
new file mode 100644
index 0000000000..4ddf59e6a0
--- /dev/null
+++ b/examples/animation/sub-attaq/boat.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "boat.h"
+#include "boat_p.h"
+#include "bomb.h"
+#include "pixmapitem.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QHistoryState>
+#include <QtCore/QFinalState>
+#include <QtCore/QState>
+#include <QtCore/QSequentialAnimationGroup>
+
+static QAbstractAnimation *setupDestroyAnimation(Boat *boat)
+{
+ QSequentialAnimationGroup *group = new QSequentialAnimationGroup(boat);
+ for (int i = 1; i <= 4; i++) {
+ PixmapItem *step = new PixmapItem(QString("explosion/boat/step%1").arg(i),GraphicsScene::Big, boat);
+ step->setZValue(6);
+ step->setOpacity(0);
+
+ //fade-in
+ QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity");
+ anim->setEndValue(1);
+ anim->setDuration(100);
+ group->insertAnimation(i-1, anim);
+
+ //and then fade-out
+ QPropertyAnimation *anim2 = new QPropertyAnimation(step, "opacity");
+ anim2->setEndValue(0);
+ anim2->setDuration(100);
+ group->addAnimation(anim2);
+ }
+
+ AnimationManager::self()->registerAnimation(group);
+ return group;
+}
+
+
+
+Boat::Boat() : PixmapItem(QString("boat"), GraphicsScene::Big),
+ speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0)
+{
+ setZValue(4);
+ setFlags(QGraphicsItem::ItemIsFocusable);
+
+ //The movement animation used to animate the boat
+ movementAnimation = new QPropertyAnimation(this, "pos");
+
+ //The destroy animation used to explode the boat
+ destroyAnimation = setupDestroyAnimation(this);
+
+ //We setup the state machine of the boat
+ machine = new QStateMachine(this);
+ QState *moving = new QState(machine);
+ StopState *stopState = new StopState(this, moving);
+ machine->setInitialState(moving);
+ moving->setInitialState(stopState);
+ MoveStateRight *moveStateRight = new MoveStateRight(this, moving);
+ MoveStateLeft *moveStateLeft = new MoveStateLeft(this, moving);
+ LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine);
+ LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine);
+
+ //then setup the transitions for the rightMove state
+ KeyStopTransition *leftStopRight = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Left);
+ leftStopRight->setTargetState(stopState);
+ KeyMoveTransition *leftMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Left);
+ leftMoveRight->setTargetState(moveStateRight);
+ KeyMoveTransition *rightMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveRight->setTargetState(moveStateRight);
+ KeyMoveTransition *rightMoveStop = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveStop->setTargetState(moveStateRight);
+
+ //then setup the transitions for the leftMove state
+ KeyStopTransition *rightStopLeft = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightStopLeft->setTargetState(stopState);
+ KeyMoveTransition *rightMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveLeft->setTargetState(moveStateLeft);
+ KeyMoveTransition *leftMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left);
+ leftMoveLeft->setTargetState(moveStateLeft);
+ KeyMoveTransition *leftMoveStop = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left);
+ leftMoveStop->setTargetState(moveStateLeft);
+
+ //We set up the right move state
+ moveStateRight->addTransition(leftStopRight);
+ moveStateRight->addTransition(leftMoveRight);
+ moveStateRight->addTransition(rightMoveRight);
+ stopState->addTransition(rightMoveStop);
+
+ //We set up the left move state
+ moveStateLeft->addTransition(rightStopLeft);
+ moveStateLeft->addTransition(leftMoveLeft);
+ moveStateLeft->addTransition(rightMoveLeft);
+ stopState->addTransition(leftMoveStop);
+
+ //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state
+ moveStateLeft->addTransition(movementAnimation, SIGNAL(finished()), stopState);
+ moveStateRight->addTransition(movementAnimation, SIGNAL(finished()), stopState);
+
+ //We set up the keys for dropping bombs
+ KeyLaunchTransition *upFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireLeft->setTargetState(launchStateRight);
+ KeyLaunchTransition *upFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireRight->setTargetState(launchStateRight);
+ KeyLaunchTransition *upFireStop = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireStop->setTargetState(launchStateRight);
+ KeyLaunchTransition *downFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireLeft->setTargetState(launchStateLeft);
+ KeyLaunchTransition *downFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireRight->setTargetState(launchStateLeft);
+ KeyLaunchTransition *downFireMove = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireMove->setTargetState(launchStateLeft);
+
+ //We set up transitions for fire up
+ moveStateRight->addTransition(upFireRight);
+ moveStateLeft->addTransition(upFireLeft);
+ stopState->addTransition(upFireStop);
+
+ //We set up transitions for fire down
+ moveStateRight->addTransition(downFireRight);
+ moveStateLeft->addTransition(downFireLeft);
+ stopState->addTransition(downFireMove);
+
+ //Finally the launch state should come back to its original state
+ QHistoryState *historyState = new QHistoryState(moving);
+ launchStateLeft->addTransition(historyState);
+ launchStateRight->addTransition(historyState);
+
+ QFinalState *final = new QFinalState(machine);
+
+ //This state play the destroyed animation
+ QAnimationState *destroyedState = new QAnimationState(machine);
+ destroyedState->setAnimation(destroyAnimation);
+
+ //Play a nice animation when the boat is destroyed
+ moving->addTransition(this, SIGNAL(boatDestroyed()), destroyedState);
+
+ //Transition to final state when the destroyed animation is finished
+ destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()), this, SIGNAL(boatExecutionFinished()));
+
+}
+
+void Boat::run()
+{
+ //We register animations
+ AnimationManager::self()->registerAnimation(movementAnimation);
+ AnimationManager::self()->registerAnimation(destroyAnimation);
+ machine->start();
+}
+
+void Boat::stop()
+{
+ movementAnimation->stop();
+ machine->stop();
+}
+
+void Boat::updateBoatMovement()
+{
+ if (speed == 0 || direction == Boat::None) {
+ movementAnimation->stop();
+ return;
+ }
+
+ movementAnimation->stop();
+
+ if (direction == Boat::Left) {
+ movementAnimation->setEndValue(QPointF(0,y()));
+ movementAnimation->setDuration(x()/speed*15);
+ }
+ else /*if (direction == Boat::Right)*/ {
+ movementAnimation->setEndValue(QPointF(scene()->width()-size().width(),y()));
+ movementAnimation->setDuration((scene()->width()-size().width()-x())/speed*15);
+ }
+ movementAnimation->start();
+}
+
+void Boat::destroy()
+{
+ movementAnimation->stop();
+ emit boatDestroyed();
+}
+
+int Boat::bombsLaunched() const
+{
+ return bombsAlreadyLaunched;
+}
+
+void Boat::setBombsLaunched(int number)
+{
+ if (number > MAX_BOMB) {
+ qWarning("Boat::setBombsLaunched : It impossible to launch that number of bombs");
+ return;
+ }
+ bombsAlreadyLaunched = number;
+}
+
+int Boat::currentSpeed() const
+{
+ return speed;
+}
+
+void Boat::setCurrentSpeed(int speed)
+{
+ if (speed > 3 || speed < 0) {
+ qWarning("Boat::setCurrentSpeed: The boat can't run on that speed");
+ return;
+ }
+ this->speed = speed;
+}
+
+enum Boat::Movement Boat::currentDirection() const
+{
+ return direction;
+}
+
+void Boat::setCurrentDirection(Movement direction)
+{
+ this->direction = direction;
+}
+
+int Boat::type() const
+{
+ return Type;
+}
diff --git a/examples/animation/sub-attaq/boat.h b/examples/animation/sub-attaq/boat.h
new file mode 100644
index 0000000000..71e3512fc3
--- /dev/null
+++ b/examples/animation/sub-attaq/boat.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __BOAT__H__
+#define __BOAT__H__
+
+#include "pixmapitem.h"
+
+class Bomb;
+QT_BEGIN_NAMESPACE
+class QVariantAnimation;
+class QAbstractAnimation;
+class QStateMachine;
+QT_END_NAMESPACE
+
+class Boat : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Movement {
+ None = 0,
+ Left,
+ Right
+ };
+ enum { Type = UserType + 2 };
+ Boat();
+ void destroy();
+ void run();
+ void stop();
+
+ int bombsLaunched() const;
+ void setBombsLaunched(int number);
+
+ int currentSpeed() const;
+ void setCurrentSpeed(int speed);
+
+ enum Movement currentDirection() const;
+ void setCurrentDirection(Movement direction);
+
+ void updateBoatMovement();
+
+ virtual int type() const;
+
+signals:
+ void boatDestroyed();
+ void boatExecutionFinished();
+
+private:
+ int speed;
+ int bombsAlreadyLaunched;
+ Movement direction;
+ QVariantAnimation *movementAnimation;
+ QAbstractAnimation *destroyAnimation;
+ QStateMachine *machine;
+};
+
+#endif //__BOAT__H__
diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h
new file mode 100644
index 0000000000..9022a4ca51
--- /dev/null
+++ b/examples/animation/sub-attaq/boat_p.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOAT_P_H
+#define BOAT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+//Own
+#include "bomb.h"
+#include "graphicsscene.h"
+
+// Qt
+#include <QtGui/QKeyEventTransition>
+
+static const int MAX_BOMB = 5;
+
+
+//These transtion test if we have to stop the boat (i.e current speed is 1)
+class KeyStopTransition : public QKeyEventTransition
+{
+public:
+ KeyStopTransition(Boat *b, QEvent::Type t, int k)
+ : QKeyEventTransition(b, t, k), boat(b), key(k)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (boat->currentSpeed() == 1);
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//These transtion test if we have to move the boat (i.e current speed was 0 or another value)
+ class KeyMoveTransition : public QKeyEventTransition
+{
+public:
+ KeyMoveTransition(Boat *b, QEvent::Type t, int k)
+ : QKeyEventTransition(b, t, k), boat(b), key(k)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (boat->currentSpeed() >= 0);
+ }
+ void onTransition(QEvent *)
+ {
+ //We decrease the speed if needed
+ if (key == Qt::Key_Left && boat->currentDirection() == Boat::Right)
+ boat->setCurrentSpeed(boat->currentSpeed() - 1);
+ else if (key == Qt::Key_Right && boat->currentDirection() == Boat::Left)
+ boat->setCurrentSpeed(boat->currentSpeed() - 1);
+ else if (boat->currentSpeed() < 3)
+ boat->setCurrentSpeed(boat->currentSpeed() + 1);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//This transition trigger the bombs launch
+ class KeyLaunchTransition : public QKeyEventTransition
+{
+public:
+ KeyLaunchTransition(Boat *boat, QEvent::Type type, int key)
+ : QKeyEventTransition(boat, type, key), boat(boat), key(key)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ //We have enough bomb?
+ return (boat->bombsLaunched() < MAX_BOMB);
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//This state is describing when the boat is moving right
+class MoveStateRight : public QState
+{
+public:
+ MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentDirection(Boat::Right);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+ //This state is describing when the boat is moving left
+class MoveStateLeft : public QState
+{
+public:
+ MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentDirection(Boat::Left);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing when the boat is in a stand by position
+class StopState : public QState
+{
+public:
+ StopState(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentSpeed(0);
+ boat->setCurrentDirection(Boat::None);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing the launch of the torpedo on the right
+class LaunchStateRight : public QState
+{
+public:
+ LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ Bomb *b = new Bomb();
+ b->setPos(boat->x()+boat->size().width(),boat->y());
+ GraphicsScene *scene = static_cast<GraphicsScene *>(boat->scene());
+ scene->addItem(b);
+ b->launch(Bomb::Right);
+ boat->setBombsLaunched(boat->bombsLaunched() + 1);
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing the launch of the torpedo on the left
+class LaunchStateLeft : public QState
+{
+public:
+ LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ Bomb *b = new Bomb();
+ b->setPos(boat->x() - b->size().width(), boat->y());
+ GraphicsScene *scene = static_cast<GraphicsScene *>(boat->scene());
+ scene->addItem(b);
+ b->launch(Bomb::Left);
+ boat->setBombsLaunched(boat->bombsLaunched() + 1);
+ }
+private:
+ Boat * boat;
+};
+
+#endif // BOAT_P_H
diff --git a/examples/animation/sub-attaq/bomb.cpp b/examples/animation/sub-attaq/bomb.cpp
new file mode 100644
index 0000000000..6811a27e88
--- /dev/null
+++ b/examples/animation/sub-attaq/bomb.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "bomb.h"
+#include "submarine.h"
+#include "pixmapitem.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QSequentialAnimationGroup>
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+
+Bomb::Bomb() : PixmapItem(QString("bomb"), GraphicsScene::Big)
+{
+ setZValue(2);
+}
+
+void Bomb::launch(Bomb::Direction direction)
+{
+ QSequentialAnimationGroup *launchAnimation = new QSequentialAnimationGroup;
+ AnimationManager::self()->registerAnimation(launchAnimation);
+ qreal delta = direction == Right ? 20 : - 20;
+ QPropertyAnimation *anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta,y() - 20));
+ anim->setDuration(150);
+ launchAnimation->addAnimation(anim);
+ anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta*2, y() ));
+ anim->setDuration(150);
+ launchAnimation->addAnimation(anim);
+ anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta*2,scene()->height()));
+ anim->setDuration(y()/2*60);
+ launchAnimation->addAnimation(anim);
+ connect(anim,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant)));
+ connect(this, SIGNAL(bombExploded()), launchAnimation, SLOT(stop()));
+ //We setup the state machine of the bomb
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the launch animation is playing
+ QAnimationState *launched = new QAnimationState(machine);
+ launched->setAnimation(launchAnimation);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ machine->setInitialState(launched);
+
+ //### Add a nice animation when the bomb is destroyed
+ launched->addTransition(this, SIGNAL(bombExploded()),final);
+
+ //If the animation is finished, then we move to the final state
+ launched->addTransition(launched, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(bombExecutionFinished()));
+
+ machine->start();
+
+}
+
+void Bomb::onAnimationLaunchValueChanged(const QVariant &)
+{
+ foreach (QGraphicsItem * item , collidingItems(Qt::IntersectsItemBoundingRect)) {
+ if (item->type() == SubMarine::Type) {
+ SubMarine *s = static_cast<SubMarine *>(item);
+ destroy();
+ s->destroy();
+ }
+ }
+}
+
+void Bomb::destroy()
+{
+ emit bombExploded();
+}
diff --git a/examples/animation/sub-attaq/bomb.h b/examples/animation/sub-attaq/bomb.h
new file mode 100644
index 0000000000..222c3d029f
--- /dev/null
+++ b/examples/animation/sub-attaq/bomb.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __BOMB__H__
+#define __BOMB__H__
+
+#include "pixmapitem.h"
+
+class Bomb : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Direction {
+ Left = 0,
+ Right
+ };
+ Bomb();
+ void launch(Direction direction);
+ void destroy();
+
+signals:
+ void bombExploded();
+ void bombExecutionFinished();
+
+private slots:
+ void onAnimationLaunchValueChanged(const QVariant &);
+};
+
+#endif //__BOMB__H__
diff --git a/examples/animation/sub-attaq/data.xml b/examples/animation/sub-attaq/data.xml
new file mode 100644
index 0000000000..0f30515ddf
--- /dev/null
+++ b/examples/animation/sub-attaq/data.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<subattaq>
+ <submarines>
+ <submarine type="0" points="10" name="Q1" />
+ <submarine type="1" points="20" name="Q2" />
+ </submarines>
+ <levels>
+ <level id="0" name="Seaman recruit">
+ <subinstance type="0" nb="1"/>
+ </level>
+ <level id="1" name="Seaman apprentice">
+ <subinstance type="0" nb="2"/>
+ </level>
+ <level id="2" name="Seaman">
+ <subinstance type="0" nb="4"/>
+ </level>
+ <level id="3" name="Petty Officer Third Class">
+ <subinstance type="0" nb="6"/>
+ </level>
+ <level id="4" name="Petty Officer Second Class">
+ <subinstance type="0" nb="6"/>
+ </level>
+ <level id="5" name="Petty Officer First Class">
+ <subinstance type="0" nb="8"/>
+ </level>
+ <level id="6" name="Lieutenant">
+ <subinstance type="0" nb="10"/>
+ </level>
+ <level id="7" name="Commander">
+ <subinstance type="0" nb="15"/>
+ </level>
+ <level id="8" name="Captain">
+ <subinstance type="0" nb="12"/>
+ </level>
+ <level id="9" name="Admiral">
+ <subinstance type="0" nb="12"/>
+ </level>
+ </levels>
+</subattaq>
diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp
new file mode 100644
index 0000000000..f82d441068
--- /dev/null
+++ b/examples/animation/sub-attaq/graphicsscene.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "graphicsscene.h"
+#include "states.h"
+#include "boat.h"
+#include "submarine.h"
+#include "torpedo.h"
+#include "bomb.h"
+#include "pixmapitem.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+#include "progressitem.h"
+#include "textinformationitem.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QSequentialAnimationGroup>
+#include <QtCore/QParallelAnimationGroup>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+#include <QtCore/QPauseAnimation>
+#include <QtGui/QAction>
+#include <QtCore/QDir>
+#include <QtGui/QApplication>
+#include <QtGui/QMessageBox>
+#include <QtGui/QGraphicsView>
+#include <QtGui/QGraphicsSceneMouseEvent>
+#include <QtCore/QXmlStreamReader>
+
+GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode)
+ : QGraphicsScene(x , y, width, height), mode(mode), boat(new Boat)
+{
+ PixmapItem *backgroundItem = new PixmapItem(QString("background"),mode);
+ backgroundItem->setZValue(1);
+ backgroundItem->setPos(0,0);
+ addItem(backgroundItem);
+
+ PixmapItem *surfaceItem = new PixmapItem(QString("surface"),mode);
+ surfaceItem->setZValue(3);
+ surfaceItem->setPos(0,sealLevel() - surfaceItem->boundingRect().height()/2);
+ addItem(surfaceItem);
+
+ //The item that display score and level
+ progressItem = new ProgressItem(backgroundItem);
+
+ textInformationItem = new TextInformationItem(backgroundItem);
+ textInformationItem->hide();
+ //We create the boat
+ addItem(boat);
+ boat->setPos(this->width()/2, sealLevel() - boat->size().height());
+ boat->hide();
+
+ //parse the xml that contain all data of the game
+ QXmlStreamReader reader;
+ QFile file(":data.xml");
+ file.open(QIODevice::ReadOnly);
+ reader.setDevice(&file);
+ LevelDescription currentLevel;
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.tokenType() == QXmlStreamReader::StartElement) {
+ if (reader.name() == "submarine") {
+ SubmarineDescription desc;
+ desc.name = reader.attributes().value("name").toString();
+ desc.points = reader.attributes().value("points").toString().toInt();
+ desc.type = reader.attributes().value("type").toString().toInt();
+ submarinesData.append(desc);
+ } else if (reader.name() == "level") {
+ currentLevel.id = reader.attributes().value("id").toString().toInt();
+ currentLevel.name = reader.attributes().value("name").toString();
+ } else if (reader.name() == "subinstance") {
+ currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(), reader.attributes().value("nb").toString().toInt()));
+ }
+ } else if (reader.tokenType() == QXmlStreamReader::EndElement) {
+ if (reader.name() == "level") {
+ levelsData.insert(currentLevel.id, currentLevel);
+ currentLevel.submarines.clear();
+ }
+ }
+ }
+}
+
+qreal GraphicsScene::sealLevel() const
+{
+ return (mode == Big) ? 220 : 160;
+}
+
+void GraphicsScene::setupScene(QAction *newAction, QAction *quitAction)
+{
+ static const int nLetters = 10;
+ static struct {
+ char const *pix;
+ qreal initX, initY;
+ qreal destX, destY;
+ } logoData[nLetters] = {
+ {"s", -1000, -1000, 300, 150 },
+ {"u", -800, -1000, 350, 150 },
+ {"b", -600, -1000, 400, 120 },
+ {"dash", -400, -1000, 460, 150 },
+ {"a", 1000, 2000, 350, 250 },
+ {"t", 800, 2000, 400, 250 },
+ {"t2", 600, 2000, 430, 250 },
+ {"a2", 400, 2000, 465, 250 },
+ {"q", 200, 2000, 510, 250 },
+ {"excl", 0, 2000, 570, 220 } };
+
+ QSequentialAnimationGroup * lettersGroupMoving = new QSequentialAnimationGroup(this);
+ QParallelAnimationGroup * lettersGroupFading = new QParallelAnimationGroup(this);
+
+ for (int i = 0; i < nLetters; ++i) {
+ PixmapItem *logo = new PixmapItem(QLatin1String(":/logo-") + logoData[i].pix, this);
+ logo->setPos(logoData[i].initX, logoData[i].initY);
+ logo->setZValue(i + 3);
+ //creation of the animations for moving letters
+ QPropertyAnimation *moveAnim = new QPropertyAnimation(logo, "pos", lettersGroupMoving);
+ moveAnim->setEndValue(QPointF(logoData[i].destX, logoData[i].destY));
+ moveAnim->setDuration(200);
+ moveAnim->setEasingCurve(QEasingCurve::OutElastic);
+ lettersGroupMoving->addPause(50);
+ //creation of the animations for fading out the letters
+ QPropertyAnimation *fadeAnim = new QPropertyAnimation(logo, "opacity", lettersGroupFading);
+ fadeAnim->setDuration(800);
+ fadeAnim->setEndValue(0);
+ fadeAnim->setEasingCurve(QEasingCurve::OutQuad);
+ }
+
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the player is playing
+ PlayState *gameState = new PlayState(this, machine);
+
+ //Final state
+ QFinalState *final = new QFinalState(machine);
+
+ //Animation when the player enter in the game
+ QAnimationState *lettersMovingState = new QAnimationState(machine);
+ lettersMovingState->setAnimation(lettersGroupMoving);
+
+ //Animation when the welcome screen disappear
+ QAnimationState *lettersFadingState = new QAnimationState(machine);
+ lettersFadingState->setAnimation(lettersGroupFading);
+
+ //if new game then we fade out the welcome screen and start playing
+ lettersMovingState->addTransition(newAction, SIGNAL(triggered()), lettersFadingState);
+ lettersFadingState->addTransition(lettersFadingState, SIGNAL(animationFinished()), gameState);
+
+ //New Game is triggered then player start playing
+ gameState->addTransition(newAction, SIGNAL(triggered()), gameState);
+
+ //Wanna quit, then connect to CTRL+Q
+ gameState->addTransition(quitAction, SIGNAL(triggered()), final);
+ lettersMovingState->addTransition(quitAction, SIGNAL(triggered()), final);
+
+ //Welcome screen is the initial state
+ machine->setInitialState(lettersMovingState);
+
+ machine->start();
+
+ //We reach the final state, then we quit
+ connect(machine, SIGNAL(finished()), qApp, SLOT(quit()));
+}
+
+void GraphicsScene::addItem(Bomb *bomb)
+{
+ bombs.insert(bomb);
+ connect(bomb,SIGNAL(bombExecutionFinished()),this, SLOT(onBombExecutionFinished()));
+ QGraphicsScene::addItem(bomb);
+}
+
+void GraphicsScene::addItem(Torpedo *torpedo)
+{
+ torpedos.insert(torpedo);
+ connect(torpedo,SIGNAL(torpedoExecutionFinished()),this, SLOT(onTorpedoExecutionFinished()));
+ QGraphicsScene::addItem(torpedo);
+}
+
+void GraphicsScene::addItem(SubMarine *submarine)
+{
+ submarines.insert(submarine);
+ connect(submarine,SIGNAL(subMarineExecutionFinished()),this, SLOT(onSubMarineExecutionFinished()));
+ QGraphicsScene::addItem(submarine);
+}
+
+void GraphicsScene::addItem(QGraphicsItem *item)
+{
+ QGraphicsScene::addItem(item);
+}
+
+void GraphicsScene::onBombExecutionFinished()
+{
+ Bomb *bomb = qobject_cast<Bomb *>(sender());
+ bombs.remove(bomb);
+ bomb->deleteLater();
+ if (boat)
+ boat->setBombsLaunched(boat->bombsLaunched() - 1);
+}
+
+void GraphicsScene::onTorpedoExecutionFinished()
+{
+ Torpedo *torpedo = qobject_cast<Torpedo *>(sender());
+ torpedos.remove(torpedo);
+ torpedo->deleteLater();
+}
+
+void GraphicsScene::onSubMarineExecutionFinished()
+{
+ SubMarine *submarine = qobject_cast<SubMarine *>(sender());
+ submarines.remove(submarine);
+ if (submarines.count() == 0)
+ emit allSubMarineDestroyed(submarine->points());
+ else
+ emit subMarineDestroyed(submarine->points());
+ submarine->deleteLater();
+}
+
+void GraphicsScene::clearScene()
+{
+ foreach (SubMarine *sub, submarines) {
+ sub->destroy();
+ sub->deleteLater();
+ }
+
+ foreach (Torpedo *torpedo, torpedos) {
+ torpedo->destroy();
+ torpedo->deleteLater();
+ }
+
+ foreach (Bomb *bomb, bombs) {
+ bomb->destroy();
+ bomb->deleteLater();
+ }
+
+ submarines.clear();
+ bombs.clear();
+ torpedos.clear();
+
+ AnimationManager::self()->unregisterAllAnimations();
+
+ boat->stop();
+ boat->hide();
+ boat->setEnabled(true);
+}
diff --git a/examples/animation/sub-attaq/graphicsscene.h b/examples/animation/sub-attaq/graphicsscene.h
new file mode 100644
index 0000000000..e1220a5eb8
--- /dev/null
+++ b/examples/animation/sub-attaq/graphicsscene.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __GRAPHICSSCENE__H__
+#define __GRAPHICSSCENE__H__
+
+//Qt
+#include <QtGui/QGraphicsScene>
+#include <QtCore/QSet>
+#include <QtCore/QState>
+
+
+class Boat;
+class SubMarine;
+class Torpedo;
+class Bomb;
+class PixmapItem;
+class ProgressItem;
+class TextInformationItem;
+QT_BEGIN_NAMESPACE
+class QAction;
+QT_END_NAMESPACE
+
+class GraphicsScene : public QGraphicsScene
+{
+Q_OBJECT
+public:
+ enum Mode {
+ Big = 0,
+ Small
+ };
+
+ struct SubmarineDescription {
+ int type;
+ int points;
+ QString name;
+ };
+
+ struct LevelDescription {
+ int id;
+ QString name;
+ QList<QPair<int,int> > submarines;
+ };
+
+ GraphicsScene(int x, int y, int width, int height, Mode mode = Big);
+ qreal sealLevel() const;
+ void setupScene(QAction *newAction, QAction *quitAction);
+ void addItem(Bomb *bomb);
+ void addItem(Torpedo *torpedo);
+ void addItem(SubMarine *submarine);
+ void addItem(QGraphicsItem *item);
+ void clearScene();
+
+signals:
+ void subMarineDestroyed(int);
+ void allSubMarineDestroyed(int);
+
+private slots:
+ void onBombExecutionFinished();
+ void onTorpedoExecutionFinished();
+ void onSubMarineExecutionFinished();
+
+private:
+ Mode mode;
+ ProgressItem *progressItem;
+ TextInformationItem *textInformationItem;
+ Boat *boat;
+ QSet<SubMarine *> submarines;
+ QSet<Bomb *> bombs;
+ QSet<Torpedo *> torpedos;
+ QVector<SubmarineDescription> submarinesData;
+ QHash<int, LevelDescription> levelsData;
+
+ friend class PauseState;
+ friend class PlayState;
+ friend class LevelState;
+ friend class LostState;
+ friend class WinState;
+ friend class WinTransition;
+ friend class UpdateScoreTransition;
+};
+
+#endif //__GRAPHICSSCENE__H__
+
diff --git a/examples/animation/sub-attaq/main.cpp b/examples/animation/sub-attaq/main.cpp
new file mode 100644
index 0000000000..c8e534e7e7
--- /dev/null
+++ b/examples/animation/sub-attaq/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Q_INIT_RESOURCE(subattaq);
+
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
+
+ MainWindow w;
+ w.show();
+
+ return app.exec();
+}
diff --git a/examples/animation/sub-attaq/mainwindow.cpp b/examples/animation/sub-attaq/mainwindow.cpp
new file mode 100644
index 0000000000..81632a50a0
--- /dev/null
+++ b/examples/animation/sub-attaq/mainwindow.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "mainwindow.h"
+#include "graphicsscene.h"
+
+//Qt
+#include <QGraphicsView>
+
+#ifdef QT_NO_OPENGL
+ #include <QtGui/QMenuBar>
+ #include <QtGui/QLayout>
+ #include <QtGui/QApplication>
+#else
+ #include <QtOpenGL/QtOpenGL>
+#endif
+
+MainWindow::MainWindow() : QMainWindow(0)
+{
+ QMenu *file = menuBar()->addMenu(tr("&File"));
+
+ QAction *newAction = file->addAction(tr("New Game"));
+ newAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
+ QAction *quitAction = file->addAction(tr("Quit"));
+ quitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+
+ if (QApplication::arguments().contains("-fullscreen")) {
+ scene = new GraphicsScene(0, 0, 750, 400, GraphicsScene::Small);
+ setWindowState(Qt::WindowFullScreen);
+ } else {
+ scene = new GraphicsScene(0, 0, 880, 630);
+ layout()->setSizeConstraint(QLayout::SetFixedSize);
+ }
+
+ view = new QGraphicsView(scene, this);
+ view->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ scene->setupScene(newAction, quitAction);
+#ifndef QT_NO_OPENGL
+ view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
+#endif
+
+ setCentralWidget(view);
+}
diff --git a/examples/animation/sub-attaq/mainwindow.h b/examples/animation/sub-attaq/mainwindow.h
new file mode 100644
index 0000000000..933587a262
--- /dev/null
+++ b/examples/animation/sub-attaq/mainwindow.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __MAINWINDOW__H__
+#define __MAINWINDOW__H__
+
+//Qt
+#include <QtGui/QMainWindow>
+class GraphicsScene;
+QT_BEGIN_NAMESPACE
+class QGraphicsView;
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+Q_OBJECT
+public:
+ MainWindow();
+
+private:
+ GraphicsScene *scene;
+ QGraphicsView *view;
+};
+
+#endif //__MAINWINDOW__H__
diff --git a/examples/animation/sub-attaq/pics/big/background.png b/examples/animation/sub-attaq/pics/big/background.png
new file mode 100644
index 0000000000..9f581571fa
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/background.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/boat.png b/examples/animation/sub-attaq/pics/big/boat.png
new file mode 100644
index 0000000000..be82dff62a
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/boat.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/bomb.png b/examples/animation/sub-attaq/pics/big/bomb.png
new file mode 100644
index 0000000000..3af5f2f29c
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/bomb.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png
new file mode 100644
index 0000000000..c9fd8b0984
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png
new file mode 100644
index 0000000000..7528f2d2da
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png
new file mode 100644
index 0000000000..aae9c9c184
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png
new file mode 100644
index 0000000000..d697c1bae8
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png
new file mode 100644
index 0000000000..88ca5144b7
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png
new file mode 100644
index 0000000000..524f5890ee
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png
new file mode 100644
index 0000000000..2cca1e80fe
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png
new file mode 100644
index 0000000000..82100a8260
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/submarine.png b/examples/animation/sub-attaq/pics/big/submarine.png
new file mode 100644
index 0000000000..df435dc47d
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/submarine.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/surface.png b/examples/animation/sub-attaq/pics/big/surface.png
new file mode 100644
index 0000000000..4eba29e9cd
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/surface.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/big/torpedo.png b/examples/animation/sub-attaq/pics/big/torpedo.png
new file mode 100644
index 0000000000..f9c26873f1
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/big/torpedo.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/scalable/background-n810.svg b/examples/animation/sub-attaq/pics/scalable/background-n810.svg
new file mode 100644
index 0000000000..ece9f7aaf1
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/background-n810.svg
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ 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:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2588"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="background-n810.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata28">
+ <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="1141"
+ inkscape:window-width="1920"
+ 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"
+ showgrid="false"
+ inkscape:zoom="1.2399902"
+ inkscape:cx="375"
+ inkscape:cy="461.074"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2590">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective30" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.2388475,-0.1040669,0.3734391,-208.61982,418.216)" />
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.186038,-986.88716,67.776416)" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2561681,-151.5,-34.518664)" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-151.5,156.75229)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="206.64989"
+ x="-151.79456"
+ y="330.16019"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="1054.4708"
+ height="364.81519"
+ x="-152.23541"
+ y="533.48895"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -152.5,877.11847 C 120.5,865.81296 -202.86309,769.3663 109.5,871.29717 C 172.96247,892.00636 243.5,872.55334 297.5,871.29717 C 351.5,870.041 311.5,859.80335 358.5,876.13354 C 405.5,892.46372 553.5,861.09903 598.5,854.8182 C 643.5,848.53736 756.5,841.79698 795.5,853.10249 C 834.5,864.408 904.5,866.2725 904.5,866.2725 L 901.5,903.95754 L -154.5,902.70137 L -152.5,877.11847 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 902.20121,894.16261 C 632.01828,889.43035 756.73005,860.2801 614.20403,894.1311 C 596.58819,898.315 408.23621,883.21212 400.43291,894.1311 C 376.86263,927.11261 75.265447,868.1243 34.250926,886.79082 C 31.281885,888.14209 12.514878,884.22134 -12.264082,889.72008 C -48.555335,897.77353 -64.717178,885.62471 -103.31472,890.35697 C -141.91229,895.08922 -145.87102,891.93439 -145.87102,891.93439 L -152.79879,903.10131 L 892.3044,902.5755 L 902.20121,894.16261 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/background.svg b/examples/animation/sub-attaq/pics/scalable/background.svg
new file mode 100644
index 0000000000..0be268010e
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/background.svg
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ 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:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2588"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="background.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata28">
+ <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="1141"
+ inkscape:window-width="1920"
+ 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"
+ showgrid="false"
+ inkscape:zoom="0.93884027"
+ inkscape:cx="473.72605"
+ inkscape:cy="538.63678"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2590">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective30" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-208.61982,282.52272)" />
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-986.88716,-154.07447)" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,-151.5,-294.0167)" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-151.5,156.75229)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="291.32797"
+ x="-151.79456"
+ y="158.38464"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="1054.4708"
+ height="461.52972"
+ x="-152.23541"
+ y="435.10107"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -152.5,869.5896 C 120.5,855.15934 -202.86309,732.0556 109.5,862.15934 C 172.96247,888.59238 243.5,863.7627 297.5,862.15934 C 351.5,860.55598 311.5,847.48872 358.5,868.33244 C 405.5,889.17615 553.5,849.14252 598.5,841.12571 C 643.5,833.1089 756.5,824.50553 795.5,838.9358 C 834.5,853.36606 904.5,855.74589 904.5,855.74589 L 901.5,903.84677 L -154.5,902.24341 L -152.5,869.5896 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 902.20121,891.3446 C 632.01828,885.30439 756.73005,848.09724 614.20403,891.30439 C 596.58819,896.64468 408.23621,877.36748 400.43291,891.30439 C 376.86263,933.40172 75.265447,858.10952 34.250926,881.93531 C 31.281885,883.66006 12.514878,878.65564 -12.264082,885.67419 C -48.555335,895.95355 -64.717178,880.4469 -103.31472,886.48711 C -141.91229,892.52732 -145.87102,888.50052 -145.87102,888.50052 L -152.79879,902.75389 L 892.3044,902.08275 L 902.20121,891.3446 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/boat.svg b/examples/animation/sub-attaq/pics/scalable/boat.svg
new file mode 100644
index 0000000000..5298821ba8
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/boat.svg
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2584">
+ <defs
+ id="defs2666">
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3387"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-110.6791,190.19124)" />
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ id="stop3169"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3345"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3347"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3171"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="474.23065"
+ y1="229.92336"
+ x2="474.1944"
+ y2="218.27365"
+ id="linearGradient3416"
+ xlink:href="#linearGradient3167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-125.98032,185.95625)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573.5"
+ y1="244.2056"
+ x2="578.25"
+ y2="216.9556"
+ id="linearGradient3972"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-126.5541,188.56624)" />
+ <linearGradient
+ id="linearGradient3438">
+ <stop
+ id="stop3440"
+ style="stop-color:#939393;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3444"
+ style="stop-color:#d6d6d6;stop-opacity:1"
+ offset="0.12354442" />
+ <stop
+ id="stop3446"
+ style="stop-color:#dadada;stop-opacity:1"
+ offset="0.74055624" />
+ <stop
+ id="stop3442"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="660.29303"
+ y1="256.53284"
+ x2="444.79303"
+ y2="255.62085"
+ id="linearGradient3948"
+ xlink:href="#linearGradient3438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-126.5541,185.56624)" />
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3990"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-132.8041,190.19124)" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3994"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-88.054101,190.19124)" />
+ <linearGradient
+ id="linearGradient3428">
+ <stop
+ id="stop3430"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3432"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.18306103" />
+ <stop
+ id="stop3434"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.66368055" />
+ <stop
+ id="stop3436"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="592.92798"
+ y1="199.43727"
+ x2="557.05743"
+ y2="196.5448"
+ id="linearGradient3426"
+ xlink:href="#linearGradient3428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-102.5217,149.09845)" />
+ </defs>
+ <g
+ id="layer1">
+ <g
+ id="boat">
+ <path
+ d="M 296.669,434.15623 C 376.12538,436.50959 448.282,436.46711 542.42304,434.15623 C 542.42304,434.15623 544.22253,425.03531 542.42304,422.57953 C 432.90655,403.86953 296.669,418.12547 296.669,422.57953 L 296.669,434.15623 z"
+ id="path3469"
+ style="fill:#a9a9a9;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3.4975698;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="3.4280596"
+ height="29.611124"
+ x="647.59613"
+ y="173.91156"
+ transform="matrix(0.9327494,0.3605254,-0.3633626,0.9316478,0,0)"
+ id="rect3408"
+ style="opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="48.499989"
+ height="8.5"
+ x="318.48221"
+ y="405.82172"
+ transform="matrix(0.9999952,3.0887777e-3,-3.0887777e-3,0.9999952,0,0)"
+ id="rect3376"
+ style="opacity:1;fill:url(#linearGradient3416);fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 382.4459,430.66072 C 382.4459,430.66072 420.85999,388.74829 397.4459,385.66072 L 488.4459,397.66072 L 488.4459,432.66072 L 382.4459,430.66072 z"
+ id="path3952"
+ style="fill:url(#linearGradient3972);fill-opacity:1;fill-rule:evenodd;stroke:#323232;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 301.4459,429.66072 C 301.4459,429.66072 330.46329,468.66072 343.4459,468.66072 C 355.42851,471.91072 507.57644,473.70653 525.4459,465.91072 C 534.58031,461.59104 537.90602,455.58662 539.4459,429.66072 C 473.70193,439.43306 371.2651,439.78219 301.4459,429.66072 z"
+ id="path3938"
+ style="fill:url(#linearGradient3948);fill-opacity:1;fill-rule:evenodd;stroke:#545454;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 339.44863,416.12222 L 357.69854,416.17859 L 368.1622,427.96097 L 339.41234,427.87217 L 339.44863,416.12222 z"
+ id="rect3378"
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="411.19589"
+ y="404.28574"
+ id="rect3974"
+ style="opacity:1;fill:url(#linearGradient3990);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="455.94589"
+ y="404.28574"
+ id="rect3992"
+ style="opacity:1;fill:url(#linearGradient3994);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 295.6959,421.91072 C 360.77923,430.41072 446.61257,432.91072 541.9459,421.91072 C 541.9459,421.91072 543.74902,428.6076 541.9459,430.41072 C 432.20839,444.14823 295.6959,433.68104 295.6959,430.41072 L 295.6959,421.91072 z"
+ id="rect2558"
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="94.427879"
+ height="7.236649"
+ x="437.10614"
+ y="342.2645"
+ transform="matrix(0.9947793,0.1020501,-0.1079723,0.9941539,0,0)"
+ id="rect2569"
+ style="opacity:1;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.0365274;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="433.32089"
+ y="404.28574"
+ id="rect3385"
+ style="opacity:1;fill:url(#linearGradient3387);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 402.86916,380.21847 L 489.80407,388.85485 L 491.52271,394.54919 L 397.58781,384.91281 L 402.86916,380.21847 z"
+ id="rect3466"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.03650045;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="34.5"
+ height="14.5"
+ x="456.4783"
+ y="336.94293"
+ transform="matrix(0.997157,7.5351915e-2,-7.5351915e-2,0.997157,0,0)"
+ id="rect3418"
+ style="opacity:1;fill:url(#linearGradient3426);fill-opacity:1;fill-rule:nonzero;stroke:#494949;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ transform="matrix(0.9246214,0.3808874,-0.3808874,0.9246214,-13.252851,-40.129692)"
+ id="flag">
+ <rect
+ width="19.75"
+ height="27.75"
+ x="193.34448"
+ y="-709"
+ transform="matrix(0,1,-1,0,0,0)"
+ id="rect3389"
+ style="opacity:1;fill:#b20000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="27.25"
+ height="5.75"
+ x="681.5"
+ y="200.59448"
+ id="rect3393"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="5.75"
+ height="19.5"
+ x="691.25"
+ y="193.59448"
+ id="rect3395"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="27.75"
+ height="2.5"
+ x="681.5"
+ y="202.34448"
+ id="rect3397"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="3"
+ height="19.25"
+ x="692.5"
+ y="193.59448"
+ id="rect3399"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/bomb.svg b/examples/animation/sub-attaq/pics/scalable/bomb.svg
new file mode 100644
index 0000000000..294771a6dd
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/bomb.svg
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg3121">
+ <defs
+ id="defs3123">
+ <radialGradient
+ cx="-135.625"
+ cy="148.71948"
+ r="7.625"
+ fx="-135.625"
+ fy="148.71948"
+ id="radialGradient3439"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="-132.85063"
+ y1="173.6969"
+ x2="-145.3662"
+ y2="177.59828"
+ id="linearGradient3418"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.2134297,-0.5943658,0.6658882,-0.2391126,-274.53441,123.00067)" />
+ <linearGradient
+ x1="-141.85466"
+ y1="181.49153"
+ x2="-144.95044"
+ y2="175.90179"
+ id="linearGradient3414"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2134297,-0.5943658,-0.6658882,-0.2391126,-15.893355,122.67824)" />
+ <linearGradient
+ x1="-149.5"
+ y1="177.59448"
+ x2="-145.7928"
+ y2="180.05936"
+ id="linearGradient3410"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,0.7075182,-227.03781,54.321514)" />
+ <linearGradient
+ x1="-140.46242"
+ y1="177.40488"
+ x2="-147.04802"
+ y2="172.66473"
+ id="linearGradient3406"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,-0.7075182,-226.40365,274.91611)" />
+ <linearGradient
+ x1="-147.2406"
+ y1="180.95567"
+ x2="-140.01878"
+ y2="175.57777"
+ id="linearGradient3402"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,-0.7075182,-64.045217,275.07466)" />
+ <linearGradient
+ x1="-146.98956"
+ y1="174.00922"
+ x2="-142.60332"
+ y2="179.38712"
+ id="linearGradient3398"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,0.7075182,-62.683611,54.187362)" />
+ <linearGradient
+ id="linearGradient3366">
+ <stop
+ id="stop3368"
+ style="stop-color:#bcbcbc;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3370"
+ style="stop-color:#191b1c;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="-208.95004"
+ cy="173.10576"
+ r="31.667252"
+ fx="-208.95004"
+ fy="173.10576"
+ id="radialGradient3364"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g
+ id="layer1">
+ <g
+ transform="translate(419.4996,488.13454)"
+ id="mine">
+ <path
+ d="M -167.5843,186.54079 A 31.466251,31.466251 0 1 1 -230.5168,186.54079 A 31.466251,31.466251 0 1 1 -167.5843,186.54079 z"
+ transform="matrix(0.6341613,0,0,0.6341613,-18.521242,45.718192)"
+ id="path2586"
+ style="opacity:1;fill:url(#radialGradient3364);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -155.20193,175.4167 C -157.60085,176.6451 -156.78074,184.26068 -156.78074,184.26068 C -156.78074,184.26068 -148.33787,181.58301 -148.57092,178.60053 C -148.74283,176.40051 -153.23774,174.41092 -155.20193,175.4167 z"
+ id="path3382"
+ style="fill:url(#linearGradient3398);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -156.56354,153.84532 C -158.96246,152.61693 -158.14235,145.00135 -158.14235,145.00135 C -158.14235,145.00135 -149.69948,147.67902 -149.93253,150.66149 C -150.10444,152.86151 -154.59935,154.85111 -156.56354,153.84532 z"
+ id="path3400"
+ style="fill:url(#linearGradient3402);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -133.88532,153.68678 C -131.48641,152.45838 -132.30652,144.8428 -132.30652,144.8428 C -132.30652,144.8428 -140.74938,147.52047 -140.51633,150.50295 C -140.34442,152.70297 -135.84951,154.69256 -133.88532,153.68678 z"
+ id="path3404"
+ style="fill:url(#linearGradient3406);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -134.51948,175.55085 C -132.12057,176.77925 -132.94068,184.39483 -132.94068,184.39483 C -132.94068,184.39483 -141.38355,181.71716 -141.15049,178.73469 C -140.97858,176.53467 -136.48367,174.54507 -134.51948,175.55085 z"
+ id="path3408"
+ style="fill:url(#linearGradient3410);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -161.25709,168.78221 C -163.22395,170.62484 -170.11427,165.85236 -170.11427,165.85236 C -170.11427,165.85236 -164.7408,160.23808 -162.01257,161.46538 C -160.00011,162.37068 -159.64667,167.27352 -161.25709,168.78221 z"
+ id="path3412"
+ style="fill:url(#linearGradient3414);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -129.17068,169.10464 C -127.20382,170.94727 -120.3135,166.17478 -120.3135,166.17478 C -120.3135,166.17478 -125.68697,160.5605 -128.41519,161.7878 C -130.42766,162.69311 -130.7811,167.59595 -129.17068,169.10464 z"
+ id="path3416"
+ style="fill:url(#linearGradient3418);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -126,151.21948 A 6.625,6.625 0 1 1 -139.25,151.21948 A 6.625,6.625 0 1 1 -126,151.21948 z"
+ transform="matrix(0.6341613,0,0,0.6341613,-61.039517,68.324922)"
+ id="path3426"
+ style="opacity:1;fill:url(#radialGradient3439);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/sand.svg b/examples/animation/sub-attaq/pics/scalable/sand.svg
new file mode 100644
index 0000000000..8af11b7a66
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/sand.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2596">
+ <defs
+ id="defs2598">
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ id="stop3710"
+ style="stop-color:#202020;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3712"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient3794"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ id="stop3720"
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015"
+ offset="0" />
+ <stop
+ id="stop3722"
+ style="stop-color:#bcbcbc;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient3792"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient3790"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,-150.63569,-350.3846)" />
+ </defs>
+ <g
+ id="layer1">
+ <path
+ d="M -151.63569,813.2217 C 121.3643,798.79144 -201.99878,675.6877 110.3643,805.79144 C 173.82677,832.22448 244.3643,807.3948 298.3643,805.79144 C 352.3643,804.18808 312.3643,791.12082 359.3643,811.96454 C 406.3643,832.80825 554.3643,792.77462 599.3643,784.75781 C 644.3643,776.741 757.36426,768.13763 796.36426,782.5679 C 835.36426,796.99816 905.36426,799.37799 905.36426,799.37799 L 902.36426,847.47887 L -153.63569,845.87551 L -151.63569,813.2217 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 908.86426,836.95812 C 635.8643,830.91791 761.87636,793.71076 617.8643,836.91791 C 600.0648,842.2582 409.74894,822.981 401.8643,836.91791 C 378.04825,879.01524 73.306465,803.72304 31.864305,827.54883 C 28.864305,829.27358 9.9016246,824.26916 -15.135695,831.28771 C -51.805335,841.56707 -68.135695,826.06042 -107.1357,832.10063 C -146.1357,838.14084 -150.13569,834.11404 -150.13569,834.11404 L -157.13569,848.36741 L 898.86426,847.69627 L 908.86426,836.95812 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/see.svg b/examples/animation/sub-attaq/pics/scalable/see.svg
new file mode 100644
index 0000000000..0666691215
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/see.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2650">
+ <defs
+ id="defs2652">
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-996.17287,-279.00679)" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1054.4708"
+ height="461.52972"
+ x="-161.52115"
+ y="310.16876"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/sky.svg b/examples/animation/sub-attaq/pics/scalable/sky.svg
new file mode 100644
index 0000000000..1546c087a7
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/sky.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2721">
+ <defs
+ id="defs2723">
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-235.04839,425.12197)" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="291.32797"
+ x="-178.22313"
+ y="300.98392"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg b/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg
new file mode 100644
index 0000000000..b075179b46
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg
@@ -0,0 +1,1473 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ 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:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1052.3622"
+ height="744.09448"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="sub-attaq.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4">
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="radialGradient3439"
+ cx="-135.625"
+ cy="148.71948"
+ fx="-135.625"
+ fy="148.71948"
+ r="7.625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3418"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.2134297,-0.5943658,0.6658882,-0.2391126,-274.53441,123.00067)"
+ x1="-132.85063"
+ y1="173.6969"
+ x2="-145.3662"
+ y2="177.59828" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2134297,-0.5943658,-0.6658882,-0.2391126,-15.893355,122.67824)"
+ x1="-141.85466"
+ y1="181.49153"
+ x2="-144.95044"
+ y2="175.90179" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,0.7075182,-227.03781,54.321514)"
+ x1="-149.5"
+ y1="177.59448"
+ x2="-145.7928"
+ y2="180.05936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3406"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,-0.7075182,-226.40365,274.91611)"
+ x1="-140.46242"
+ y1="177.40488"
+ x2="-147.04802"
+ y2="172.66473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3402"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,-0.7075182,-64.045217,275.07466)"
+ x1="-147.2406"
+ y1="180.95567"
+ x2="-140.01878"
+ y2="175.57777" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3398"
+ x1="-146.98956"
+ y1="174.00922"
+ x2="-142.60332"
+ y2="179.38712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,0.7075182,-62.683611,54.187362)" />
+ <linearGradient
+ id="linearGradient3366">
+ <stop
+ id="stop3368"
+ offset="0"
+ style="stop-color:#bcbcbc;stop-opacity:1;" />
+ <stop
+ id="stop3370"
+ offset="1"
+ style="stop-color:#191b1c;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="radialGradient3364"
+ cx="-208.95004"
+ cy="173.10576"
+ fx="-208.95004"
+ fy="173.10576"
+ r="31.667252"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ style="stop-color:#19a2db;stop-opacity:0;"
+ offset="0"
+ id="stop5099" />
+ <stop
+ id="stop5109"
+ offset="0.30000001"
+ style="stop-color:#1379a7;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#0e5173;stop-opacity:1;"
+ offset="1"
+ id="stop5101" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3523"
+ inkscape:collect="always">
+ <stop
+ id="stop3525"
+ offset="0"
+ style="stop-color:#b9b9b9;stop-opacity:1" />
+ <stop
+ id="stop3527"
+ offset="1"
+ style="stop-color:#444444;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3438">
+ <stop
+ style="stop-color:#939393;stop-opacity:1;"
+ offset="0"
+ id="stop3440" />
+ <stop
+ id="stop3444"
+ offset="0.12354442"
+ style="stop-color:#d6d6d6;stop-opacity:1;" />
+ <stop
+ style="stop-color:#dadada;stop-opacity:1;"
+ offset="0.74055624"
+ id="stop3446" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3442" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3428">
+ <stop
+ id="stop3430"
+ offset="0"
+ style="stop-color:#464646;stop-opacity:1;" />
+ <stop
+ style="stop-color:#848788;stop-opacity:1;"
+ offset="0.18306103"
+ id="stop3432" />
+ <stop
+ id="stop3434"
+ offset="0.66368055"
+ style="stop-color:#9ca0a2;stop-opacity:1;" />
+ <stop
+ id="stop3436"
+ offset="1"
+ style="stop-color:#b5babd;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4034">
+ <stop
+ id="stop4036"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.49803922;"
+ offset="0.5"
+ id="stop4038" />
+ <stop
+ id="stop4040"
+ offset="0.63705367"
+ style="stop-color:#ffffff;stop-opacity:0.24705882;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.12156863;"
+ offset="0.79425853"
+ id="stop4042" />
+ <stop
+ id="stop4044"
+ offset="1"
+ style="stop-color:#a0a0a0;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4016">
+ <stop
+ style="stop-color:#283e6a;stop-opacity:1;"
+ offset="0"
+ id="stop4018" />
+ <stop
+ style="stop-color:#283e6a;stop-opacity:0;"
+ offset="1"
+ id="stop4020" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4004">
+ <stop
+ style="stop-color:#dbdbdb;stop-opacity:1;"
+ offset="0"
+ id="stop4010" />
+ <stop
+ style="stop-color:#c4c9cb;stop-opacity:1;"
+ offset="1"
+ id="stop4012" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3998">
+ <stop
+ id="stop4000"
+ offset="0"
+ style="stop-color:#adadad;stop-opacity:1;" />
+ <stop
+ id="stop4002"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3864">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3866" />
+ <stop
+ id="stop4028"
+ offset="0.5"
+ style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.24705882;"
+ offset="0.75"
+ id="stop4030" />
+ <stop
+ id="stop4032"
+ offset="0.875"
+ style="stop-color:#ffffff;stop-opacity:0.12156863;" />
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1;"
+ offset="1"
+ id="stop3868" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#ad8b00;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#ad8b00;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3748" />
+ <stop
+ style="stop-color:#0074b7;stop-opacity:1;"
+ offset="1"
+ id="stop3750" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015;"
+ offset="0"
+ id="stop3720" />
+ <stop
+ style="stop-color:#bcbcbc;stop-opacity:0;"
+ offset="1"
+ id="stop3722" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ style="stop-color:#202020;stop-opacity:1;"
+ offset="0"
+ id="stop3710" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3712" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3694" />
+ <stop
+ style="stop-color:#b6b6b6;stop-opacity:1;"
+ offset="1"
+ id="stop3696" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3656">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3658" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3660" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ style="stop-color:#3a8daf;stop-opacity:1;"
+ offset="0"
+ id="stop3626" />
+ <stop
+ id="stop3636"
+ offset="1"
+ style="stop-color:#252525;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3532">
+ <stop
+ id="stop3534"
+ offset="0"
+ style="stop-color:#545454;stop-opacity:1;" />
+ <stop
+ style="stop-color:#848788;stop-opacity:1;"
+ offset="0.44021741"
+ id="stop3536" />
+ <stop
+ id="stop3538"
+ offset="0.56799388"
+ style="stop-color:#9ca0a2;stop-opacity:1;" />
+ <stop
+ id="stop3540"
+ offset="1"
+ style="stop-color:#565d60;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3345">
+ <stop
+ id="stop3348"
+ offset="0"
+ style="stop-color:#898989;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9ea1a2;stop-opacity:1;"
+ offset="0.44021741"
+ id="stop3350" />
+ <stop
+ id="stop3352"
+ offset="0.56799388"
+ style="stop-color:#bbbdbf;stop-opacity:1;" />
+ <stop
+ id="stop3354"
+ offset="1"
+ style="stop-color:#f0f1f2;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3227">
+ <stop
+ style="stop-color:#444444;stop-opacity:1;"
+ offset="0"
+ id="stop3229" />
+ <stop
+ style="stop-color:#b0b0b0;stop-opacity:1;"
+ offset="1"
+ id="stop3232" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3435">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3437" />
+ <stop
+ style="stop-color:#c0c0c0;stop-opacity:0;"
+ offset="1"
+ id="stop3439" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3421">
+ <stop
+ style="stop-color:#444444;stop-opacity:1;"
+ offset="0"
+ id="stop3423" />
+ <stop
+ style="stop-color:#444444;stop-opacity:0;"
+ offset="1"
+ id="stop3425" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3293">
+ <stop
+ style="stop-color:#c4b434;stop-opacity:1;"
+ offset="0"
+ id="stop3295" />
+ <stop
+ style="stop-color:#9b5500;stop-opacity:1;"
+ offset="1"
+ id="stop3297" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3229">
+ <stop
+ style="stop-color:#125a7a;stop-opacity:1;"
+ offset="0"
+ id="stop3231" />
+ <stop
+ style="stop-color:#308fc0;stop-opacity:1;"
+ offset="1"
+ id="stop3233" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3219">
+ <stop
+ id="stop3221"
+ offset="0"
+ style="stop-color:#a55b00;stop-opacity:1;" />
+ <stop
+ id="stop3223"
+ offset="1"
+ style="stop-color:#f4e45e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3189">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3191" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3193" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ style="stop-color:#464646;stop-opacity:1;"
+ offset="0"
+ id="stop3169" />
+ <stop
+ id="stop3345"
+ offset="0.44021741"
+ style="stop-color:#848788;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9ca0a2;stop-opacity:1;"
+ offset="0.56799388"
+ id="stop3347" />
+ <stop
+ style="stop-color:#b5babd;stop-opacity:1;"
+ offset="1"
+ id="stop3171" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3167"
+ id="linearGradient3175"
+ x1="443.95602"
+ y1="315.31854"
+ x2="443.95602"
+ y2="247.85609"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4908502,0,0,0.4579593,350.98557,542.12189)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3253"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3255"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3321"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3323"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3331"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3333"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3343"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3292883,0,0,1.10796,1.5038593,-24.232315)"
+ x1="359.5589"
+ y1="258.84247"
+ x2="370.88239"
+ y2="258.84247" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3365"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3367"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3369"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3371"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3379"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3381"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3267302,0,0,1.1332782,-1.5786343,-29.194748)"
+ x1="371.79858"
+ y1="258.84247"
+ x2="364.49646"
+ y2="258.84247" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9807835,0,0,1.1280701,-361.45126,-28.553769)"
+ x1="371.79858"
+ y1="258.84247"
+ x2="364.49646"
+ y2="258.84247" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3421"
+ id="radialGradient3431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1862613,0,0,0.3638703,-186.86143,179.02055)"
+ cx="432.3343"
+ cy="233.80295"
+ fx="432.3343"
+ fy="233.80295"
+ r="59.056834" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3435"
+ id="radialGradient3441"
+ cx="290.5"
+ cy="244.34448"
+ fx="290.5"
+ fy="244.34448"
+ r="37.5"
+ gradientTransform="matrix(0.8202102,0.8202102,-0.7960458,0.7960458,246.73838,-189.686)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3345"
+ id="linearGradient3311"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.466978,0,0,0.4500435,352.00841,540.25044)"
+ x1="510.99884"
+ y1="161.99408"
+ x2="396.48914"
+ y2="161.99408" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3421"
+ id="radialGradient3339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4181493,0,0,0.1282619,386.09461,620.15777)"
+ cx="432.3343"
+ cy="233.80295"
+ fx="432.3343"
+ fy="233.80295"
+ r="59.056834" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3434"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3436"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3532"
+ id="linearGradient3520"
+ x1="525"
+ y1="371.09448"
+ x2="525"
+ y2="395.09448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5865192,0,0,0.2518015,339.73218,572.99479)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3624"
+ id="linearGradient3630"
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-835.38716,-310.82676)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3662"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3772"
+ gradientUnits="userSpaceOnUse"
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3718"
+ id="linearGradient3774"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)"
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3708"
+ id="linearGradient3776"
+ gradientUnits="userSpaceOnUse"
+ x1="518.26993"
+ y1="497.31477"
+ x2="533.02923"
+ y2="497.31477" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3790"
+ gradientUnits="userSpaceOnUse"
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3718"
+ id="linearGradient3792"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)"
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3708"
+ id="linearGradient3794"
+ gradientUnits="userSpaceOnUse"
+ x1="518.26993"
+ y1="497.31477"
+ x2="533.02923"
+ y2="497.31477" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3227"
+ id="linearGradient3812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1223608,0,0,0.3849769,-17.516054,565.40983)"
+ x1="543.5"
+ y1="205.19257"
+ x2="587.52001"
+ y2="205.19257" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="linearGradient3826"
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,0,-450.76899)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="radialGradient3874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.9674693,0.8647541,-0.8726553,1.0212484,-15.308759,-74.232772)"
+ cx="94.273849"
+ cy="89.893486"
+ fx="94.273849"
+ fy="89.893486"
+ r="74.397521" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="radialGradient3880"
+ cx="82.966125"
+ cy="-178.42453"
+ fx="82.966125"
+ fy="-178.42453"
+ r="526.79456"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-57.119818,125.77043)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3438"
+ id="linearGradient3948"
+ x1="660.29303"
+ y1="256.53284"
+ x2="444.79303"
+ y2="255.62085"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,32.526912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3972"
+ x1="573.5"
+ y1="244.2056"
+ x2="578.25"
+ y2="216.9556"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,35.526912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3990"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6.25,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3994"
+ gradientUnits="userSpaceOnUse"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientTransform="translate(38.5,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4016"
+ id="linearGradient4022"
+ x1="639"
+ y1="262.09448"
+ x2="667"
+ y2="262.09448"
+ gradientUnits="userSpaceOnUse" />
+ <inkscape:perspective
+ id="perspective2578"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3387"
+ gradientUnits="userSpaceOnUse"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientTransform="translate(15.875,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3167"
+ id="linearGradient3416"
+ x1="474.23065"
+ y1="229.92336"
+ x2="474.1944"
+ y2="218.27365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.1004684,32.526757)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3428"
+ id="linearGradient3426"
+ x1="592.92798"
+ y1="199.43727"
+ x2="557.05743"
+ y2="196.5448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.140805,-13.041887)" />
+ <filter
+ inkscape:collect="always"
+ id="filter3507">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="3.0523171"
+ id="feGaussianBlur3509" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3523"
+ id="linearGradient3521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-0.7291751,0,521.83983)"
+ x1="562.55634"
+ y1="285.89896"
+ x2="562.55634"
+ y2="244.09448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5097"
+ id="linearGradient5103"
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ gradientUnits="userSpaceOnUse"
+ spreadMethod="pad" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="radialGradient5107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.9674693,0.8647541,-0.8726553,1.0212484,-15.308759,-74.232772)"
+ cx="94.273849"
+ cy="89.893486"
+ fx="94.273849"
+ fy="89.893486"
+ r="74.397521" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.70710678"
+ inkscape:cx="532.91407"
+ inkscape:cy="457.84365"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1674"
+ inkscape:window-height="1000"
+ inkscape:window-x="2"
+ inkscape:window-y="14"
+ showguides="false" />
+ <metadata
+ id="metadata7">
+ <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>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3638"
+ width="1053.5891"
+ height="291.32797"
+ x="-0.29455566"
+ y="1.6323624" />
+ <path
+ style="fill:url(#radialGradient3874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3507)"
+ d="M 158.37853,75.817898 C 130.95894,49.483192 82.14552,74.615971 85.85382,95.15981 C 49.691853,94.8009 50.214842,139.36083 83.29101,132.16343 C 144.66465,163.16454 159.26268,129.80212 164.6863,136.51386 C 225.60448,157.97672 246.34362,130.65438 265.24417,127.0714 C 294.43981,137.91859 337.16986,121.78798 297.03636,102.77604 C 331.73096,64.597047 277.96882,60.229366 253.07028,70.400868 C 191.09597,33.610112 168.89234,63.292037 158.37853,75.817898 z"
+ id="path3872"
+ sodipodi:nodetypes="cccccccc"
+ transform="matrix(1.5062893,0,0,1.1720951,618.04001,132.36768)" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3622"
+ width="1054.4708"
+ height="461.52972"
+ x="-0.7354126"
+ y="278.34879" />
+ <path
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -0.99999999,712.83731 C 272,698.40705 -51.363087,575.30331 261,705.40705 C 324.46247,731.84009 395,707.01041 449,705.40705 C 503,703.80369 463,690.73643 510,711.58015 C 557,732.42386 705,692.39023 750,684.37342 C 795,676.35661 908,667.75324 947,682.18351 C 986,696.61377 1056,698.9936 1056,698.9936 L 1053,747.09448 L -3,745.49112 L -0.99999999,712.83731 z"
+ id="path3814"
+ sodipodi:nodetypes="cssssscccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3520);fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:0.56879884;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3512"
+ width="10.557344"
+ height="6.0432386"
+ x="642.3761"
+ y="666.43695" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path2455"
+ id="use3258"
+ transform="matrix(0.869168,0,0,-0.869168,81.98751,1246.5374)"
+ width="1052.3622"
+ height="744.09448" />
+ <path
+ style="fill:url(#linearGradient3812);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77744257;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 593.04822,651.68104 C 593.04822,651.68104 653.65569,615.49321 639.065,637.05192 C 624.47431,658.61061 624.47431,658.61061 624.47431,658.61061 L 593.04822,651.68104 z"
+ id="path2455" />
+ <path
+ style="fill:url(#linearGradient3175);fill-opacity:1;fill-rule:evenodd;stroke:#393939;stroke-width:1.90693891;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 485.26939,643.71814 C 443.15507,651.66437 458.5319,680.53556 502.21486,686.27814 C 551.68229,692.78115 568.45042,691.0115 605.34827,686.27814 C 657.60843,679.57406 657.68143,651.78445 605.34827,643.25553 C 553.98131,634.88408 516.10913,637.89923 485.26939,643.71814 z"
+ id="path2385"
+ sodipodi:nodetypes="cssss" />
+ <path
+ style="fill:url(#radialGradient3339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 542.18031,648.1112 C 548.56327,665.42741 608.42397,656.72745 586.93551,642.57104 C 586.93551,642.57104 543.33293,648.61096 542.18031,648.1112 z"
+ id="path3403"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="fill:url(#linearGradient3311);fill-opacity:1;fill-rule:evenodd;stroke:#2d2d2d;stroke-width:2.07042313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 537.39402,641.90906 C 537.39402,656.7605 583.62247,656.30589 583.62247,641.45445 L 583.62247,636.06071 C 583.62247,621.21003 537.39402,613.87461 537.39402,628.72529 L 537.39402,641.90906 z"
+ id="path3291"
+ sodipodi:nodetypes="cssss" />
+ <g
+ id="g3235"
+ transform="matrix(1.4016868,0,0,1.1319742,112.22001,-99.678822)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.227;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3433"
+ sodipodi:cx="303.5"
+ sodipodi:cy="263.09448"
+ sodipodi:rx="37.5"
+ sodipodi:ry="40"
+ d="M 341,263.09448 A 37.5,40 0 1 1 266,263.09448 A 37.5,40 0 1 1 341,263.09448 z"
+ transform="matrix(0.692163,0,1.4106583e-2,0.289185,275.31394,582.37251)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.06500006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3458"
+ sodipodi:cx="369.5"
+ sodipodi:cy="316.09448"
+ sodipodi:rx="27.5"
+ sodipodi:ry="7"
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0.5642633,0,0,0.5642633,348.03095,450.47113)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:4.23126984;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3510"
+ sodipodi:cx="369.5"
+ sodipodi:cy="316.09448"
+ sodipodi:rx="27.5"
+ sodipodi:ry="7"
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0,0.30778,-0.5642633,0,828.66499,563.5944)" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path3510"
+ id="use3544"
+ transform="translate(0.5000005,-17.23511)"
+ width="1052.3622"
+ height="744.09448" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:2.38492584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3584"
+ sodipodi:cx="237.5"
+ sodipodi:cy="366.09448"
+ sodipodi:rx="8.5"
+ sodipodi:ry="8"
+ d="M 246,366.09448 A 8.5,8 0 1 1 229,366.09448 A 8.5,8 0 1 1 246,366.09448 z"
+ transform="matrix(1.7798114,-4.2997512e-2,1.3318941e-2,0.5513151,196.65666,476.1443)" />
+ <path
+ style="fill:#a9a9a9;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3.49756980000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 423.2231,281.1169 C 502.67948,283.47026 574.8361,283.42778 668.97714,281.1169 C 668.97714,281.1169 670.77663,271.99598 668.97714,269.5402 C 559.46065,250.8302 423.2231,265.08614 423.2231,269.5402 L 423.2231,281.1169 z"
+ id="path3469"
+ sodipodi:nodetypes="cccsc" />
+ <rect
+ style="opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3408"
+ width="3.4280596"
+ height="29.611124"
+ x="709.89148"
+ y="-14.462622"
+ transform="matrix(0.9327494,0.3605254,-0.3633626,0.9316478,0,0)" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3416);fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3376"
+ width="48.499989"
+ height="8.5"
+ x="444.56302"
+ y="252.39224"
+ transform="matrix(0.9999952,3.0887776e-3,-3.0887776e-3,0.9999952,0,0)" />
+ <path
+ style="fill:url(#linearGradient3972);fill-opacity:1;fill-rule:evenodd;stroke:#323232;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 509,277.62139 C 509,277.62139 547.41409,235.70896 524,232.62139 L 615,244.62139 L 615,279.62139 L 509,277.62139 z"
+ id="path3952"
+ sodipodi:nodetypes="csccc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3662);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3654"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5187874,0,0,0.3968421,374.8524,387.30025)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3668);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3666"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5734968,0,0,0.4386917,316.52295,315.62837)" />
+ <path
+ transform="matrix(0.8598866,0,0,0.5637407,192.52282,220.77351)"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ sodipodi:ry="16.263456"
+ sodipodi:rx="12.727922"
+ sodipodi:cy="541.15485"
+ sodipodi:cx="656.19507"
+ id="path3670"
+ style="opacity:1;fill:url(#radialGradient3672);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.90000010000000020;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3676);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.90000010000000020;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3674"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.7435991,0,0,0.6264519,225.8301,127.83701)" />
+ <g
+ id="g3759"
+ transform="matrix(0.8830571,0,0,0.8830571,104.83144,103.2985)">
+ <path
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z"
+ sodipodi:ry="34.648232"
+ sodipodi:rx="7.7781744"
+ sodipodi:cy="469.73706"
+ sodipodi:cx="516.18793"
+ id="path3682"
+ style="opacity:1;fill:url(#linearGradient3772);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <g
+ id="g3754">
+ <rect
+ style="opacity:1;fill:url(#linearGradient3774);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3716"
+ width="33.58757"
+ height="59.927299"
+ x="498.86386"
+ y="497.84454" />
+ <path
+ style="fill:url(#linearGradient3776);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ id="path3704"
+ sodipodi:nodetypes="cscsc" />
+ <path
+ sodipodi:nodetypes="cscsc"
+ id="path3706"
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.8830571,0,0,0.8830571,192.45885,-66.370546)"
+ id="g3778">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#linearGradient3790);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3780"
+ sodipodi:cx="516.18793"
+ sodipodi:cy="469.73706"
+ sodipodi:rx="7.7781744"
+ sodipodi:ry="34.648232"
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z" />
+ <g
+ id="g3782">
+ <rect
+ y="497.84454"
+ x="498.86386"
+ height="59.927299"
+ width="33.58757"
+ id="rect3784"
+ style="opacity:1;fill:url(#linearGradient3792);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="cscsc"
+ id="path3786"
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ style="fill:url(#linearGradient3794);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ id="path3788"
+ sodipodi:nodetypes="cscsc" />
+ </g>
+ </g>
+ <path
+ transform="matrix(0.4292897,0,0,0.3283816,384.32775,481.20689)"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ sodipodi:ry="16.263456"
+ sodipodi:rx="12.727922"
+ sodipodi:cy="541.15485"
+ sodipodi:cx="656.19507"
+ id="path3802"
+ style="opacity:1;fill:url(#radialGradient3804);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3808);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3806"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5842998,0,0,0.4469553,299.7804,369.91514)" />
+ <path
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 1059.5,736.57373 C 786.5,730.53352 912.51207,693.32637 768.5,736.53352 C 750.7005,741.87381 560.38464,722.59661 552.5,736.53352 C 528.68395,778.63085 223.94216,703.33865 182.5,727.16444 C 179.5,728.88919 160.53732,723.88477 135.5,730.90332 C 98.830356,741.18268 82.5,725.67603 43.5,731.71624 C 4.5,737.75645 0.5,733.72965 0.5,733.72965 L -6.5,747.98302 L 1049.5,747.31188 L 1059.5,736.57373 z"
+ id="path3828"
+ sodipodi:nodetypes="cssssscccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient5103);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3448"
+ width="1053.5891"
+ height="67.882248"
+ x="-0.29455566"
+ y="274.57559" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path3519"
+ d="M 428,343.85222 C 428,343.85222 457.01739,315.41439 470,315.41439 C 481.98261,313.04457 634.13054,311.73511 652,317.41962 C 661.13441,320.56943 664.46012,324.9477 666,343.85222 C 600.25603,336.72647 497.8192,336.4719 428,343.85222 z"
+ style="opacity:0.43933058;fill:url(#linearGradient3521);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:url(#linearGradient3948);fill-opacity:1;fill-rule:evenodd;stroke:#545454;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 428,276.62139 C 428,276.62139 457.01739,315.62139 470,315.62139 C 481.98261,318.87139 634.13054,320.6672 652,312.87139 C 661.13441,308.55171 664.46012,302.54729 666,276.62139 C 600.25603,286.39373 497.8192,286.74286 428,276.62139 z"
+ id="path3938"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 466.00273,263.08289 L 484.25264,263.13926 L 494.7163,274.92164 L 465.96644,274.83284 L 466.00273,263.08289 z"
+ id="rect3378"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3990);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3974"
+ width="13.5"
+ height="17"
+ x="537.75"
+ y="251.2464"
+ inkscape:transform-center-x="30" />
+ <rect
+ inkscape:transform-center-x="30"
+ y="251.2464"
+ x="582.5"
+ height="17"
+ width="13.5"
+ id="rect3992"
+ style="opacity:1;fill:url(#linearGradient3994);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 422.25,268.87139 C 487.33333,277.37139 573.16667,279.87139 668.5,268.87139 C 668.5,268.87139 670.30312,275.56827 668.5,277.37139 C 558.76249,291.1089 422.25,280.64171 422.25,277.37139 L 422.25,268.87139 z"
+ id="rect2558"
+ sodipodi:nodetypes="cccsc" />
+ <rect
+ style="opacity:1;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.0365274;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect2569"
+ width="94.427879"
+ height="7.236649"
+ x="546.39832"
+ y="177.10637"
+ transform="matrix(0.9947793,0.1020501,-0.1079723,0.9941539,0,0)" />
+ <rect
+ inkscape:transform-center-x="30"
+ y="251.2464"
+ x="559.875"
+ height="17"
+ width="13.5"
+ id="rect3385"
+ style="opacity:1;fill:url(#linearGradient3387);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ id="g3401"
+ transform="matrix(0.9246214,0.3808874,-0.3808874,0.9246214,113.30125,-193.16902)"
+ inkscape:transform-center-x="17.590385"
+ inkscape:transform-center-y="-15.415449">
+ <rect
+ inkscape:transform-center-y="-43.888889"
+ transform="matrix(0,1,-1,0,0,0)"
+ style="opacity:1;fill:#b20000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3389"
+ width="19.75"
+ height="27.75"
+ x="193.34448"
+ y="-709" />
+ <rect
+ y="200.59448"
+ x="681.5"
+ height="5.75"
+ width="27.25"
+ id="rect3393"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="193.59448"
+ x="691.25"
+ height="19.5"
+ width="5.75"
+ id="rect3395"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="202.34448"
+ x="681.5"
+ height="2.5"
+ width="27.75"
+ id="rect3397"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="193.59448"
+ x="692.5"
+ height="19.25"
+ width="3"
+ id="rect3399"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <path
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.03650045;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 529.42326,227.17914 L 616.35817,235.81552 L 618.07681,241.50986 L 524.14191,231.87348 L 529.42326,227.17914 z"
+ id="rect3466"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3426);fill-opacity:1;fill-rule:nonzero;stroke:#494949;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3418"
+ width="34.5"
+ height="14.5"
+ x="571.14081"
+ y="174.8026"
+ transform="matrix(0.997157,7.5351915e-2,-7.5351915e-2,0.997157,0,0)"
+ inkscape:transform-center-x="-8"
+ inkscape:transform-center-y="2" />
+ <g
+ id="mine"
+ transform="translate(971.11461,237.62715)"
+ inkscape:label="#g3441">
+ <path
+ transform="matrix(0.6341613,0,0,0.6341613,-18.521242,45.718192)"
+ d="M -167.5843,186.54079 A 31.466251,31.466251 0 1 1 -230.5168,186.54079 A 31.466251,31.466251 0 1 1 -167.5843,186.54079 z"
+ sodipodi:ry="31.466251"
+ sodipodi:rx="31.466251"
+ sodipodi:cy="186.54079"
+ sodipodi:cx="-199.05055"
+ id="path2586"
+ style="opacity:1;fill:url(#radialGradient3364);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3382"
+ d="M -155.20193,175.4167 C -157.60085,176.6451 -156.78074,184.26068 -156.78074,184.26068 C -156.78074,184.26068 -148.33787,181.58301 -148.57092,178.60053 C -148.74283,176.40051 -153.23774,174.41092 -155.20193,175.4167 z"
+ style="fill:url(#linearGradient3398);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3400"
+ d="M -156.56354,153.84532 C -158.96246,152.61693 -158.14235,145.00135 -158.14235,145.00135 C -158.14235,145.00135 -149.69948,147.67902 -149.93253,150.66149 C -150.10444,152.86151 -154.59935,154.85111 -156.56354,153.84532 z"
+ style="fill:url(#linearGradient3402);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3404"
+ d="M -133.88532,153.68678 C -131.48641,152.45838 -132.30652,144.8428 -132.30652,144.8428 C -132.30652,144.8428 -140.74938,147.52047 -140.51633,150.50295 C -140.34442,152.70297 -135.84951,154.69256 -133.88532,153.68678 z"
+ style="fill:url(#linearGradient3406);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3408"
+ d="M -134.51948,175.55085 C -132.12057,176.77925 -132.94068,184.39483 -132.94068,184.39483 C -132.94068,184.39483 -141.38355,181.71716 -141.15049,178.73469 C -140.97858,176.53467 -136.48367,174.54507 -134.51948,175.55085 z"
+ style="fill:url(#linearGradient3410);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3412"
+ d="M -161.25709,168.78221 C -163.22395,170.62484 -170.11427,165.85236 -170.11427,165.85236 C -170.11427,165.85236 -164.7408,160.23808 -162.01257,161.46538 C -160.00011,162.37068 -159.64667,167.27352 -161.25709,168.78221 z"
+ style="fill:url(#linearGradient3414);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3416"
+ d="M -129.17068,169.10464 C -127.20382,170.94727 -120.3135,166.17478 -120.3135,166.17478 C -120.3135,166.17478 -125.68697,160.5605 -128.41519,161.7878 C -130.42766,162.69311 -130.7811,167.59595 -129.17068,169.10464 z"
+ style="fill:url(#linearGradient3418);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ transform="matrix(0.6341613,0,0,0.6341613,-61.039517,68.324922)"
+ d="M -126,151.21948 A 6.625,6.625 0 1 1 -139.25,151.21948 A 6.625,6.625 0 1 1 -126,151.21948 z"
+ sodipodi:ry="6.625"
+ sodipodi:rx="6.625"
+ sodipodi:cy="151.21948"
+ sodipodi:cx="-132.625"
+ id="path3426"
+ style="opacity:1;fill:url(#radialGradient3439);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/submarine.svg b/examples/animation/sub-attaq/pics/scalable/submarine.svg
new file mode 100644
index 0000000000..8a0ffddbca
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/submarine.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2594">
+ <defs
+ id="defs2596">
+ <linearGradient
+ id="linearGradient3345">
+ <stop
+ id="stop3348"
+ style="stop-color:#898989;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3350"
+ style="stop-color:#9ea1a2;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3352"
+ style="stop-color:#bbbdbf;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3354"
+ style="stop-color:#f0f1f2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="510.99884"
+ y1="161.99408"
+ x2="396.48914"
+ y2="161.99408"
+ id="linearGradient3311"
+ xlink:href="#linearGradient3345"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.466978,0,0,0.4500435,231.58508,159.95135)" />
+ <linearGradient
+ id="linearGradient3532">
+ <stop
+ id="stop3534"
+ style="stop-color:#545454;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3536"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3538"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3540"
+ style="stop-color:#565d60;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="525"
+ y1="371.09448"
+ x2="525"
+ y2="395.09448"
+ id="linearGradient3520"
+ xlink:href="#linearGradient3532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5865192,0,0,0.2518015,219.30885,192.6957)" />
+ <linearGradient
+ id="linearGradient3227">
+ <stop
+ id="stop3229"
+ style="stop-color:#444444;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3232"
+ style="stop-color:#b0b0b0;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="543.5"
+ y1="205.19257"
+ x2="587.52002"
+ y2="205.19257"
+ id="linearGradient3812"
+ xlink:href="#linearGradient3227"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1223608,0,0,0.3849769,-137.93938,185.11074)" />
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ id="stop3169"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3345"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3347"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3171"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="443.95602"
+ y1="315.31854"
+ x2="443.95602"
+ y2="247.85609"
+ id="linearGradient3175"
+ xlink:href="#linearGradient3167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4908502,0,0,0.4579593,230.56224,161.8228)" />
+ <linearGradient
+ id="linearGradient3421">
+ <stop
+ id="stop3423"
+ style="stop-color:#444444;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3425"
+ style="stop-color:#444444;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="432.33429"
+ cy="233.80295"
+ r="59.056835"
+ fx="432.33429"
+ fy="233.80295"
+ id="radialGradient3339"
+ xlink:href="#linearGradient3421"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4181493,0,0,0.1282619,265.67128,239.85868)" />
+ <linearGradient
+ id="linearGradient3435">
+ <stop
+ id="stop3437"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3439"
+ style="stop-color:#c0c0c0;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="290.5"
+ cy="244.34448"
+ r="37.5"
+ fx="290.5"
+ fy="244.34448"
+ id="radialGradient3441"
+ xlink:href="#linearGradient3435"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8202102,0.8202102,-0.7960458,0.7960458,246.73838,-189.686)" />
+ </defs>
+ <g
+ id="submarine">
+ <rect
+ width="10.557344"
+ height="6.0432386"
+ x="521.95276"
+ y="286.13785"
+ id="rect3512"
+ style="opacity:1;fill:url(#linearGradient3520);fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:0.56879884;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 472.62489,271.38195 C 472.62489,271.38195 533.23236,235.19412 518.64167,256.75283 C 504.05098,278.31152 504.05098,278.31152 504.05098,278.31152 L 472.62489,271.38195 z"
+ id="path2455"
+ style="fill:url(#linearGradient3812);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77744257;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 364.84606,263.41905 C 322.73174,271.36528 338.10857,300.23647 381.79153,305.97905 C 431.25896,312.48206 448.02709,310.71241 484.92494,305.97905 C 537.1851,299.27497 537.2581,271.48536 484.92494,262.95644 C 433.55798,254.58499 395.6858,257.60014 364.84606,263.41905 z"
+ id="path2385"
+ style="fill:url(#linearGradient3175);fill-opacity:1;fill-rule:evenodd;stroke:#393939;stroke-width:1.90693891;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 421.75698,267.81211 C 428.13994,285.12832 488.00064,276.42836 466.51218,262.27195 C 466.51218,262.27195 422.9096,268.31187 421.75698,267.81211 z"
+ id="path3403"
+ style="fill:url(#radialGradient3339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 416.97069,261.60997 C 416.97069,276.46141 463.19914,276.0068 463.19914,261.15536 L 463.19914,255.76162 C 463.19914,240.91094 416.97069,233.57552 416.97069,248.4262 L 416.97069,261.60997 z"
+ id="path3291"
+ style="fill:url(#linearGradient3311);fill-opacity:1;fill-rule:evenodd;stroke:#2d2d2d;stroke-width:2.07042313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 341,263.09448 A 37.5,40 0 1 1 266,263.09448 A 37.5,40 0 1 1 341,263.09448 z"
+ transform="matrix(0.692163,0,1.4106583e-2,0.289185,154.89061,202.07342)"
+ id="path3433"
+ style="opacity:1;fill:url(#radialGradient3441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.227;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0.5642633,0,0,0.5642633,227.60762,70.172035)"
+ id="path3458"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.06500006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0,0.30778,-0.5642633,0,708.24166,183.29531)"
+ id="path3510"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:4.23126984;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <use
+ transform="translate(0.5000044,-17.235115)"
+ id="use3544"
+ x="0"
+ y="0"
+ width="1052.3622"
+ height="744.09448"
+ xlink:href="#path3510" />
+ <path
+ d="M 246,366.09448 A 8.5,8 0 1 1 229,366.09448 A 8.5,8 0 1 1 246,366.09448 z"
+ transform="matrix(1.7798114,-4.2997512e-2,1.3318941e-2,0.5513151,76.233334,95.845205)"
+ id="path3584"
+ style="opacity:1;fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:2.38492584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/surface.svg b/examples/animation/sub-attaq/pics/scalable/surface.svg
new file mode 100644
index 0000000000..40ed239638
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/surface.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2685">
+ <defs
+ id="defs2687">
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-172.21428,209.55976)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="67.882248"
+ x="-172.50883"
+ y="484.13535"
+ id="rect3448"
+ style="opacity:1;fill:url(#linearGradient5103);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/scalable/torpedo.svg b/examples/animation/sub-attaq/pics/scalable/torpedo.svg
new file mode 100644
index 0000000000..48e429d2bf
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/scalable/torpedo.svg
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2584">
+ <defs
+ id="defs2586">
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ id="stop3710"
+ style="stop-color:#202020;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3712"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient3776"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ id="stop3720"
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015"
+ offset="0" />
+ <stop
+ id="stop3722"
+ style="stop-color:#bcbcbc;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient3774"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient3772"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient2403"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient2405"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient2407"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g
+ transform="translate(-128.69958,6.6568748)"
+ id="torpedo">
+ <g
+ transform="matrix(0.8830571,0,0,0.8830571,-119.78327,177.67947)"
+ id="g3525">
+ <path
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z"
+ id="path3682"
+ style="opacity:1;fill:url(#linearGradient2403);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ id="g3754">
+ <rect
+ width="33.58757"
+ height="59.927299"
+ x="498.86386"
+ y="497.84454"
+ id="rect3716"
+ style="opacity:1;fill:url(#linearGradient2405);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ id="path3704"
+ style="fill:url(#linearGradient2407);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ id="path3706"
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/examples/animation/sub-attaq/pics/small/background.png b/examples/animation/sub-attaq/pics/small/background.png
new file mode 100644
index 0000000000..5ad3db660a
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/background.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/small/boat.png b/examples/animation/sub-attaq/pics/small/boat.png
new file mode 100644
index 0000000000..114ccc310e
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/boat.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/small/bomb.png b/examples/animation/sub-attaq/pics/small/bomb.png
new file mode 100644
index 0000000000..3af5f2f29c
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/bomb.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/small/submarine.png b/examples/animation/sub-attaq/pics/small/submarine.png
new file mode 100644
index 0000000000..0c0c350600
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/submarine.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/small/surface.png b/examples/animation/sub-attaq/pics/small/surface.png
new file mode 100644
index 0000000000..06d0e47a5c
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/surface.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/small/torpedo.png b/examples/animation/sub-attaq/pics/small/torpedo.png
new file mode 100644
index 0000000000..f9c26873f1
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/small/torpedo.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a.png b/examples/animation/sub-attaq/pics/welcome/logo-a.png
new file mode 100644
index 0000000000..67dd76dac0
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-a.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a2.png b/examples/animation/sub-attaq/pics/welcome/logo-a2.png
new file mode 100644
index 0000000000..17668b07de
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-a2.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-b.png b/examples/animation/sub-attaq/pics/welcome/logo-b.png
new file mode 100644
index 0000000000..cf6c04560b
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-b.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-dash.png b/examples/animation/sub-attaq/pics/welcome/logo-dash.png
new file mode 100644
index 0000000000..219233ce6b
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-dash.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-excl.png b/examples/animation/sub-attaq/pics/welcome/logo-excl.png
new file mode 100644
index 0000000000..8dd0a2eb86
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-excl.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-q.png b/examples/animation/sub-attaq/pics/welcome/logo-q.png
new file mode 100644
index 0000000000..86e588d4d8
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-q.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-s.png b/examples/animation/sub-attaq/pics/welcome/logo-s.png
new file mode 100644
index 0000000000..7b6a36e93a
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-s.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t.png b/examples/animation/sub-attaq/pics/welcome/logo-t.png
new file mode 100644
index 0000000000..b2e3526bea
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-t.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t2.png b/examples/animation/sub-attaq/pics/welcome/logo-t2.png
new file mode 100644
index 0000000000..b11a77886e
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-t2.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pics/welcome/logo-u.png b/examples/animation/sub-attaq/pics/welcome/logo-u.png
new file mode 100644
index 0000000000..24eede887a
--- /dev/null
+++ b/examples/animation/sub-attaq/pics/welcome/logo-u.png
Binary files differ
diff --git a/examples/animation/sub-attaq/pixmapitem.cpp b/examples/animation/sub-attaq/pixmapitem.cpp
new file mode 100644
index 0000000000..be75bd1995
--- /dev/null
+++ b/examples/animation/sub-attaq/pixmapitem.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "pixmapitem.h"
+
+//Qt
+#include <QPainter>
+
+PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsObject(parent)
+{
+ if (mode == GraphicsScene::Big)
+ pix = ":/big/" + fileName;
+ else
+ pix = ":/small/" + fileName;
+}
+
+PixmapItem::PixmapItem(const QString &fileName, QGraphicsScene *scene) : QGraphicsObject(), pix(fileName)
+{
+ scene->addItem(this);
+}
+
+QSizeF PixmapItem::size() const
+{
+ return pix.size();
+}
+
+QRectF PixmapItem::boundingRect() const
+{
+ return QRectF(QPointF(0, 0), pix.size());
+}
+
+void PixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ painter->drawPixmap(0, 0, pix);
+}
+
+
diff --git a/examples/animation/sub-attaq/pixmapitem.h b/examples/animation/sub-attaq/pixmapitem.h
new file mode 100644
index 0000000000..0a94aab7eb
--- /dev/null
+++ b/examples/animation/sub-attaq/pixmapitem.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __PIXMAPITEM__H__
+#define __PIXMAPITEM__H__
+
+//Own
+#include "graphicsscene.h"
+
+//Qt
+#include <QtGui/QGraphicsObject>
+
+class PixmapItem : public QGraphicsObject
+{
+public:
+ PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0);
+ PixmapItem(const QString &fileName, QGraphicsScene *scene);
+ QSizeF size() const;
+ QRectF boundingRect() const;
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+private:
+ QPixmap pix;
+};
+
+#endif //__PIXMAPITEM__H__
diff --git a/examples/animation/sub-attaq/progressitem.cpp b/examples/animation/sub-attaq/progressitem.cpp
new file mode 100644
index 0000000000..426dedfbd4
--- /dev/null
+++ b/examples/animation/sub-attaq/progressitem.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "progressitem.h"
+#include "pixmapitem.h"
+
+ProgressItem::ProgressItem (QGraphicsItem * parent)
+ : QGraphicsTextItem(parent), currentLevel(1), currentScore(0)
+{
+ setFont(QFont("Comic Sans MS"));
+ setPos(parentItem()->boundingRect().topRight() - QPointF(180, -5));
+}
+
+void ProgressItem::setLevel(int level)
+{
+ currentLevel = level;
+ updateProgress();
+}
+
+void ProgressItem::setScore(int score)
+{
+ currentScore = score;
+ updateProgress();
+}
+
+void ProgressItem::updateProgress()
+{
+ setHtml(QString("Level : %1 Score : %2").arg(currentLevel).arg(currentScore));
+}
diff --git a/examples/animation/sub-attaq/progressitem.h b/examples/animation/sub-attaq/progressitem.h
new file mode 100644
index 0000000000..bcf708c512
--- /dev/null
+++ b/examples/animation/sub-attaq/progressitem.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROGRESSITEM_H
+#define PROGRESSITEM_H
+
+//Qt
+#include <QtGui/QGraphicsTextItem>
+
+class ProgressItem : public QGraphicsTextItem
+{
+public:
+ ProgressItem(QGraphicsItem * parent = 0);
+ void setLevel(int level);
+ void setScore(int score);
+
+private:
+ void updateProgress();
+ int currentLevel;
+ int currentScore;
+};
+
+#endif // PROGRESSITEM_H
diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp
new file mode 100644
index 0000000000..593c8dfe8d
--- /dev/null
+++ b/examples/animation/sub-attaq/qanimationstate.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanimationstate.h"
+
+#include <QtCore/qstate.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+\class QAnimationState
+
+\brief The QAnimationState class provides state that handle an animation and emit
+a signal when this animation is finished.
+
+\ingroup statemachine
+
+QAnimationState provides a state that handle an animation. It will start this animation
+when the state is entered and stop it when it is leaved. When the animation has finished the
+state emit animationFinished signal.
+QAnimationState is part of \l{The State Machine Framework}.
+
+\code
+QStateMachine machine;
+QAnimationState *s = new QAnimationState(machine->rootState());
+QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos");
+s->setAnimation(animation);
+QState *s2 = new QState(machine->rootState());
+s->addTransition(s, SIGNAL(animationFinished()), s2);
+machine.start();
+\endcode
+
+\sa QState, {The Animation Framework}
+*/
+
+
+#ifndef QT_NO_ANIMATION
+
+/*!
+ Constructs a new state with the given \a parent state.
+*/
+QAnimationState::QAnimationState(QState *parent)
+ : QState(parent), m_animation(0)
+{
+}
+
+/*!
+ Destroys the animation state.
+*/
+QAnimationState::~QAnimationState()
+{
+}
+
+/*!
+ Set an \a animation for this QAnimationState. If an animation was previously handle by this
+ state then it won't emit animationFinished for the old animation. The QAnimationState doesn't
+ take the ownership of the animation.
+*/
+void QAnimationState::setAnimation(QAbstractAnimation *animation)
+{
+ if (animation == m_animation)
+ return;
+
+ //Disconnect from the previous animation if exist
+ if(m_animation)
+ disconnect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished()));
+
+ m_animation = animation;
+
+ if (m_animation) {
+ //connect the new animation
+ connect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished()));
+ }
+}
+
+/*!
+ Returns the animation handle by this animation state, or 0 if there is no animation.
+*/
+QAbstractAnimation* QAnimationState::animation() const
+{
+ return m_animation;
+}
+
+/*!
+ \reimp
+*/
+void QAnimationState::onEntry(QEvent *)
+{
+ if (m_animation)
+ m_animation->start();
+}
+
+/*!
+ \reimp
+*/
+void QAnimationState::onExit(QEvent *)
+{
+ if (m_animation)
+ m_animation->stop();
+}
+
+/*!
+ \reimp
+*/
+bool QAnimationState::event(QEvent *e)
+{
+ return QState::event(e);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/examples/animation/sub-attaq/qanimationstate.h b/examples/animation/sub-attaq/qanimationstate.h
new file mode 100644
index 0000000000..aace3b502b
--- /dev/null
+++ b/examples/animation/sub-attaq/qanimationstate.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONSTATE_H
+#define QANIMATIONSTATE_H
+
+#ifndef QT_STATEMACHINE_SOLUTION
+# include <QtCore/qstate.h>
+# include <QtCore/qabstractanimation.h>
+#else
+# include "qstate.h"
+# include "qabstractanimation.h"
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ANIMATION
+
+class QAbstractAnimation;
+
+class QAnimationState : public QState
+{
+ Q_OBJECT
+public:
+ QAnimationState(QState *parent = 0);
+ ~QAnimationState();
+
+ void setAnimation(QAbstractAnimation *animation);
+ QAbstractAnimation* animation() const;
+
+signals:
+ void animationFinished();
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+ bool event(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QAnimationState)
+ QAbstractAnimation *m_animation;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QANIMATIONSTATE_H
diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp
new file mode 100644
index 0000000000..462e13b90e
--- /dev/null
+++ b/examples/animation/sub-attaq/states.cpp
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "states.h"
+#include "graphicsscene.h"
+#include "boat.h"
+#include "submarine.h"
+#include "torpedo.h"
+#include "animationmanager.h"
+#include "progressitem.h"
+#include "textinformationitem.h"
+
+//Qt
+#include <QtGui/QMessageBox>
+#include <QtGui/QGraphicsView>
+#include <QtCore/QStateMachine>
+#include <QtGui/QKeyEventTransition>
+#include <QtCore/QFinalState>
+
+PlayState::PlayState(GraphicsScene *scene, QState *parent)
+ : QState(parent),
+ scene(scene),
+ machine(0),
+ currentLevel(0),
+ score(0)
+{
+}
+
+PlayState::~PlayState()
+{
+ delete machine;
+}
+
+void PlayState::onEntry(QEvent *)
+{
+ //We are now playing?
+ if (machine) {
+ machine->stop();
+ //we hide the information
+ scene->textInformationItem->hide();
+ scene->clearScene();
+ currentLevel = 0;
+ score = 0;
+ delete machine;
+ }
+
+ machine = new QStateMachine;
+
+ //This state is when player is playing
+ LevelState *levelState = new LevelState(scene, this, machine);
+
+ //This state is when the player is actually playing but the game is not paused
+ QState *playingState = new QState(levelState);
+ levelState->setInitialState(playingState);
+
+ //This state is when the game is paused
+ PauseState *pauseState = new PauseState(scene, levelState);
+
+ //We have one view, it receive the key press event
+ QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
+ pressPplay->setTargetState(pauseState);
+ QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
+ pressPpause->setTargetState(playingState);
+
+ //Pause "P" is triggered, the player pause the game
+ playingState->addTransition(pressPplay);
+
+ //To get back playing when the game has been paused
+ pauseState->addTransition(pressPpause);
+
+ //This state is when player have lost
+ LostState *lostState = new LostState(scene, this, machine);
+
+ //This state is when player have won
+ WinState *winState = new WinState(scene, this, machine);
+
+ //The boat has been destroyed then the game is finished
+ levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState);
+
+ //This transition check if we won or not
+ WinTransition *winTransition = new WinTransition(scene, this, winState);
+
+ //The boat has been destroyed then the game is finished
+ levelState->addTransition(winTransition);
+
+ //This state is an animation when the score changed
+ UpdateScoreState *scoreState = new UpdateScoreState(this, levelState);
+
+ //This transition update the score when a submarine die
+ UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState);
+ scoreTransition->setTargetState(scoreState);
+
+ //The boat has been destroyed then the game is finished
+ playingState->addTransition(scoreTransition);
+
+ //We go back to play state
+ scoreState->addTransition(playingState);
+
+ //We start playing!!!
+ machine->setInitialState(levelState);
+
+ //Final state
+ QFinalState *final = new QFinalState(machine);
+
+ //This transition is triggered when the player press space after completing a level
+ CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space);
+ spaceTransition->setTargetState(levelState);
+ winState->addTransition(spaceTransition);
+
+ //We lost we should reach the final state
+ lostState->addTransition(lostState, SIGNAL(finished()), final);
+
+ machine->start();
+}
+
+LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+void LevelState::onEntry(QEvent *)
+{
+ initializeLevel();
+}
+
+void LevelState::initializeLevel()
+{
+ //we re-init the boat
+ scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height());
+ scene->boat->setCurrentSpeed(0);
+ scene->boat->setCurrentDirection(Boat::None);
+ scene->boat->setBombsLaunched(0);
+ scene->boat->show();
+ scene->setFocusItem(scene->boat, Qt::OtherFocusReason);
+ scene->boat->run();
+
+ scene->progressItem->setScore(game->score);
+ scene->progressItem->setLevel(game->currentLevel + 1);
+
+ GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel);
+
+ for (int i = 0; i < currentLevelDescription.submarines.size(); ++i ) {
+
+ QPair<int,int> subContent = currentLevelDescription.submarines.at(i);
+ GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first);
+
+ for (int j = 0; j < subContent.second; ++j ) {
+ SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points);
+ scene->addItem(sub);
+ int random = (qrand() % 15 + 1);
+ qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width();
+ qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height();
+ sub->setPos(x,y);
+ sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left);
+ sub->setCurrentSpeed(qrand() % 3 + 1);
+ }
+ }
+}
+
+/** Pause State */
+PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene)
+{
+}
+void PauseState::onEntry(QEvent *)
+{
+ AnimationManager::self()->pauseAll();
+ scene->boat->setEnabled(false);
+}
+void PauseState::onExit(QEvent *)
+{
+ AnimationManager::self()->resumeAll();
+ scene->boat->setEnabled(true);
+ scene->boat->setFocus();
+}
+
+/** Lost State */
+LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+
+void LostState::onEntry(QEvent *)
+{
+ //The message to display
+ QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
+
+ //We set the level back to 0
+ game->currentLevel = 0;
+
+ //We set the score back to 0
+ game->score = 0;
+
+ //We clear the scene
+ scene->clearScene();
+
+ //We inform the player
+ scene->textInformationItem->setMessage(message);
+ scene->textInformationItem->show();
+}
+
+void LostState::onExit(QEvent *)
+{
+ //we hide the information
+ scene->textInformationItem->hide();
+}
+
+/** Win State */
+WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+
+void WinState::onEntry(QEvent *)
+{
+ //We clear the scene
+ scene->clearScene();
+
+ QString message;
+ if (scene->levelsData.size() - 1 != game->currentLevel) {
+ message = QString("You win the level %1. Your score is %2.\nPress Space to continue.").arg(game->currentLevel+1).arg(game->score);
+ //We increment the level number
+ game->currentLevel++;
+ } else {
+ message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
+ //We set the level back to 0
+ game->currentLevel = 0;
+ //We set the score back to 0
+ game->score = 0;
+ }
+
+ //We inform the player
+ scene->textInformationItem->setMessage(message);
+ scene->textInformationItem->show();
+}
+
+void WinState::onExit(QEvent *)
+{
+ //we hide the information
+ scene->textInformationItem->hide();
+}
+
+/** UpdateScore State */
+UpdateScoreState::UpdateScoreState(PlayState *g, QState *parent) : QState(parent), game(g)
+{
+}
+
+/** Win transition */
+UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
+ : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int))),
+ game(game), scene(scene)
+{
+ setTargetState(target);
+}
+
+bool UpdateScoreTransition::eventTest(QEvent *event)
+{
+ if (!QSignalTransition::eventTest(event))
+ return false;
+ QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
+ game->score += se->arguments().at(0).toInt();
+ scene->progressItem->setScore(game->score);
+ return true;
+}
+
+/** Win transition */
+WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
+ : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int))),
+ game(game), scene(scene)
+{
+ setTargetState(target);
+}
+
+bool WinTransition::eventTest(QEvent *event)
+{
+ if (!QSignalTransition::eventTest(event))
+ return false;
+ QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
+ game->score += se->arguments().at(0).toInt();
+ scene->progressItem->setScore(game->score);
+ return true;
+}
+
+/** Space transition */
+CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key)
+ : QKeyEventTransition(widget, type, key),
+ game(game)
+{
+}
+
+bool CustomSpaceTransition::eventTest(QEvent *event)
+{
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (game->currentLevel != 0);
+}
diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h
new file mode 100644
index 0000000000..cda9603196
--- /dev/null
+++ b/examples/animation/sub-attaq/states.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STATES_H
+#define STATES_H
+
+//Qt
+#include <QtCore/QState>
+#include <QtCore/QSignalTransition>
+#include <QtCore/QPropertyAnimation>
+#include <QtGui/QKeyEventTransition>
+#include <QtCore/QSet>
+
+class GraphicsScene;
+class Boat;
+class SubMarine;
+QT_BEGIN_NAMESPACE
+class QStateMachine;
+QT_END_NAMESPACE
+
+class PlayState : public QState
+{
+public:
+ PlayState(GraphicsScene *scene, QState *parent = 0);
+ ~PlayState();
+
+ protected:
+ void onEntry(QEvent *);
+
+private :
+ GraphicsScene *scene;
+ QStateMachine *machine;
+ int currentLevel;
+ int score;
+ QState *parallelChild;
+
+ friend class UpdateScoreState;
+ friend class UpdateScoreTransition;
+ friend class WinTransition;
+ friend class CustomSpaceTransition;
+ friend class WinState;
+ friend class LostState;
+ friend class LevelState;
+};
+
+class LevelState : public QState
+{
+public:
+ LevelState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+protected:
+ void onEntry(QEvent *);
+private :
+ void initializeLevel();
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class PauseState : public QState
+{
+public:
+ PauseState(GraphicsScene *scene, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ Boat *boat;
+};
+
+class LostState : public QState
+{
+public:
+ LostState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class WinState : public QState
+{
+public:
+ WinState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class UpdateScoreState : public QState
+{
+public:
+ UpdateScoreState(PlayState *game, QState *parent);
+private:
+ QPropertyAnimation *scoreAnimation;
+ PlayState *game;
+};
+
+//These transtion is used to update the score
+class UpdateScoreTransition : public QSignalTransition
+{
+public:
+ UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState * game;
+ GraphicsScene *scene;
+};
+
+//These transtion test if we have won the game
+class WinTransition : public QSignalTransition
+{
+public:
+ WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState * game;
+ GraphicsScene *scene;
+};
+
+//These transtion is true if one level has been completed and the player want to continue
+ class CustomSpaceTransition : public QKeyEventTransition
+{
+public:
+ CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState *game;
+ int key;
+};
+
+#endif // STATES_H
diff --git a/examples/animation/sub-attaq/sub-attaq.pro b/examples/animation/sub-attaq/sub-attaq.pro
new file mode 100644
index 0000000000..5575f5e65f
--- /dev/null
+++ b/examples/animation/sub-attaq/sub-attaq.pro
@@ -0,0 +1,41 @@
+contains(QT_CONFIG, opengl):QT += opengl
+HEADERS += boat.h \
+ bomb.h \
+ mainwindow.h \
+ submarine.h \
+ torpedo.h \
+ pixmapitem.h \
+ graphicsscene.h \
+ animationmanager.h \
+ states.h \
+ boat_p.h \
+ submarine_p.h \
+ qanimationstate.h \
+ progressitem.h \
+ textinformationitem.h
+SOURCES += boat.cpp \
+ bomb.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ submarine.cpp \
+ torpedo.cpp \
+ pixmapitem.cpp \
+ graphicsscene.cpp \
+ animationmanager.cpp \
+ states.cpp \
+ qanimationstate.cpp \
+ progressitem.cpp \
+ textinformationitem.cpp
+RESOURCES += subattaq.qrc
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/sub-attaq
+sources.files = $$SOURCES \
+ $$HEADERS \
+ $$RESOURCES \
+ $$FORMS \
+ sub-attaq.pro \
+ pics
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/sub-attaq
+INSTALLS += target \
+ sources
diff --git a/examples/animation/sub-attaq/subattaq.qrc b/examples/animation/sub-attaq/subattaq.qrc
new file mode 100644
index 0000000000..80a3af11cc
--- /dev/null
+++ b/examples/animation/sub-attaq/subattaq.qrc
@@ -0,0 +1,39 @@
+<RCC>
+ <qresource prefix="/" >
+ <file alias="all" >pics/scalable/sub-attaq.svg</file>
+ <file alias="submarine" >pics/scalable/submarine.svg</file>
+ <file alias="boat" >pics/scalable/boat.svg</file>
+ <file alias="torpedo" >pics/scalable/torpedo.svg</file>
+ <file alias="logo-s" >pics/welcome/logo-s.png</file>
+ <file alias="logo-u" >pics/welcome/logo-u.png</file>
+ <file alias="logo-b" >pics/welcome/logo-b.png</file>
+ <file alias="logo-dash" >pics/welcome/logo-dash.png</file>
+ <file alias="logo-a" >pics/welcome/logo-a.png</file>
+ <file alias="logo-t" >pics/welcome/logo-t.png</file>
+ <file alias="logo-t2" >pics/welcome/logo-t2.png</file>
+ <file alias="logo-a2" >pics/welcome/logo-a2.png</file>
+ <file alias="logo-q" >pics/welcome/logo-q.png</file>
+ <file alias="logo-excl" >pics/welcome/logo-excl.png</file>
+ <file alias="big/background" >pics/big/background.png</file>
+ <file alias="big/boat" >pics/big/boat.png</file>
+ <file alias="big/bomb" >pics/big/bomb.png</file>
+ <file alias="big/submarine" >pics/big/submarine.png</file>
+ <file alias="big/surface" >pics/big/surface.png</file>
+ <file alias="big/torpedo" >pics/big/torpedo.png</file>
+ <file alias="small/background" >pics/small/background.png</file>
+ <file alias="small/boat" >pics/small/boat.png</file>
+ <file alias="small/bomb" >pics/small/bomb.png</file>
+ <file alias="small/submarine" >pics/small/submarine.png</file>
+ <file alias="small/surface" >pics/small/surface.png</file>
+ <file alias="small/torpedo" >pics/small/torpedo.png</file>
+ <file alias="big/explosion/boat/step1" >pics/big/explosion/boat/step1.png</file>
+ <file alias="big/explosion/boat/step2" >pics/big/explosion/boat/step2.png</file>
+ <file alias="big/explosion/boat/step3" >pics/big/explosion/boat/step3.png</file>
+ <file alias="big/explosion/boat/step4" >pics/big/explosion/boat/step4.png</file>
+ <file alias="big/explosion/submarine/step1" >pics/big/explosion/submarine/step1.png</file>
+ <file alias="big/explosion/submarine/step2" >pics/big/explosion/submarine/step2.png</file>
+ <file alias="big/explosion/submarine/step3" >pics/big/explosion/submarine/step3.png</file>
+ <file alias="big/explosion/submarine/step4" >pics/big/explosion/submarine/step4.png</file>
+ <file>data.xml</file>
+ </qresource>
+</RCC>
diff --git a/examples/animation/sub-attaq/submarine.cpp b/examples/animation/sub-attaq/submarine.cpp
new file mode 100644
index 0000000000..2c8a5a2884
--- /dev/null
+++ b/examples/animation/sub-attaq/submarine.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "submarine.h"
+#include "submarine_p.h"
+#include "torpedo.h"
+#include "pixmapitem.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+#include <QtCore/QSequentialAnimationGroup>
+
+static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub)
+{
+ QSequentialAnimationGroup *group = new QSequentialAnimationGroup(sub);
+ for (int i = 1; i <= 4; ++i) {
+ PixmapItem *step = new PixmapItem(QString::fromLatin1("explosion/submarine/step%1").arg(i), GraphicsScene::Big, sub);
+ step->setZValue(6);
+ step->setOpacity(0);
+ QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity", group);
+ anim->setDuration(100);
+ anim->setEndValue(1);
+ }
+ AnimationManager::self()->registerAnimation(group);
+ return group;
+}
+
+
+SubMarine::SubMarine(int type, const QString &name, int points) : PixmapItem(QString("submarine"), GraphicsScene::Big),
+ subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None)
+{
+ setZValue(5);
+ setTransformOriginPoint(boundingRect().center());
+
+ graphicsRotation = new QGraphicsRotation(this);
+ graphicsRotation->setAxis(Qt::YAxis);
+ graphicsRotation->setOrigin(QVector3D(size().width()/2, size().height()/2, 0));
+ QList<QGraphicsTransform *> r;
+ r.append(graphicsRotation);
+ setTransformations(r);
+
+ //We setup the state machine of the submarine
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the boat is moving/rotating
+ QState *moving = new QState(machine);
+
+ //This state is when the boat is moving from left to right
+ MovementState *movement = new MovementState(this, moving);
+
+ //This state is when the boat is moving from left to right
+ ReturnState *rotation = new ReturnState(this, moving);
+
+ //This is the initial state of the moving root state
+ moving->setInitialState(movement);
+
+ movement->addTransition(this, SIGNAL(subMarineStateChanged()), moving);
+
+ //This is the initial state of the machine
+ machine->setInitialState(moving);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ //If the moving animation is finished we move to the return state
+ movement->addTransition(movement, SIGNAL(animationFinished()), rotation);
+
+ //If the return animation is finished we move to the moving state
+ rotation->addTransition(rotation, SIGNAL(animationFinished()), movement);
+
+ //This state play the destroyed animation
+ QAnimationState *destroyedState = new QAnimationState(machine);
+ destroyedState->setAnimation(setupDestroyAnimation(this));
+
+ //Play a nice animation when the submarine is destroyed
+ moving->addTransition(this, SIGNAL(subMarineDestroyed()), destroyedState);
+
+ //Transition to final state when the destroyed animation is finished
+ destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the submarine is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(subMarineExecutionFinished()));
+
+ machine->start();
+}
+
+int SubMarine::points() const
+{
+ return subPoints;
+}
+
+void SubMarine::setCurrentDirection(SubMarine::Movement direction)
+{
+ if (this->direction == direction)
+ return;
+ if (direction == SubMarine::Right && this->direction == SubMarine::None) {
+ graphicsRotation->setAngle(180);
+ }
+ this->direction = direction;
+}
+
+enum SubMarine::Movement SubMarine::currentDirection() const
+{
+ return direction;
+}
+
+void SubMarine::setCurrentSpeed(int speed)
+{
+ if (speed < 0 || speed > 3) {
+ qWarning("SubMarine::setCurrentSpeed : The speed is invalid");
+ }
+ this->speed = speed;
+ emit subMarineStateChanged();
+}
+
+int SubMarine::currentSpeed() const
+{
+ return speed;
+}
+
+void SubMarine::launchTorpedo(int speed)
+{
+ Torpedo * torp = new Torpedo();
+ GraphicsScene *scene = static_cast<GraphicsScene *>(this->scene());
+ scene->addItem(torp);
+ torp->setPos(pos());
+ torp->setCurrentSpeed(speed);
+ torp->launch();
+}
+
+void SubMarine::destroy()
+{
+ emit subMarineDestroyed();
+}
+
+int SubMarine::type() const
+{
+ return Type;
+}
diff --git a/examples/animation/sub-attaq/submarine.h b/examples/animation/sub-attaq/submarine.h
new file mode 100644
index 0000000000..0d6087dc26
--- /dev/null
+++ b/examples/animation/sub-attaq/submarine.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __SUBMARINE__H__
+#define __SUBMARINE__H__
+
+//Qt
+#include <QtGui/QGraphicsTransform>
+
+#include "pixmapitem.h"
+
+class Torpedo;
+
+class SubMarine : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Movement {
+ None = 0,
+ Left,
+ Right
+ };
+ enum { Type = UserType + 1 };
+ SubMarine(int type, const QString &name, int points);
+
+ int points() const;
+
+ void setCurrentDirection(Movement direction);
+ enum Movement currentDirection() const;
+
+ void setCurrentSpeed(int speed);
+ int currentSpeed() const;
+
+ void launchTorpedo(int speed);
+ void destroy();
+
+ virtual int type() const;
+
+ QGraphicsRotation *rotation() const { return graphicsRotation; }
+
+signals:
+ void subMarineDestroyed();
+ void subMarineExecutionFinished();
+ void subMarineStateChanged();
+
+private:
+ int subType;
+ QString subName;
+ int subPoints;
+ int speed;
+ Movement direction;
+ QGraphicsRotation *graphicsRotation;
+};
+
+#endif //__SUBMARINE__H__
diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h
new file mode 100644
index 0000000000..f0b370d878
--- /dev/null
+++ b/examples/animation/sub-attaq/submarine_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SUBMARINE_P_H
+#define SUBMARINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+//Own
+#include "animationmanager.h"
+#include "submarine.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtGui/QGraphicsScene>
+
+//This state is describing when the boat is moving right
+class MovementState : public QAnimationState
+{
+Q_OBJECT
+public:
+ MovementState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent)
+ {
+ movementAnimation = new QPropertyAnimation(submarine, "pos");
+ connect(movementAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationMovementValueChanged(const QVariant &)));
+ setAnimation(movementAnimation);
+ AnimationManager::self()->registerAnimation(movementAnimation);
+ this->submarine = submarine;
+ }
+
+protected slots:
+ void onAnimationMovementValueChanged(const QVariant &)
+ {
+ if (qrand() % 200 + 1 == 3)
+ submarine->launchTorpedo(qrand() % 3 + 1);
+ }
+
+protected:
+ void onEntry(QEvent *e)
+ {
+ if (submarine->currentDirection() == SubMarine::Left) {
+ movementAnimation->setEndValue(QPointF(0,submarine->y()));
+ movementAnimation->setDuration(submarine->x()/submarine->currentSpeed()*12);
+ }
+ else /*if (submarine->currentDirection() == SubMarine::Right)*/ {
+ movementAnimation->setEndValue(QPointF(submarine->scene()->width()-submarine->size().width(),submarine->y()));
+ movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12);
+ }
+ QAnimationState::onEntry(e);
+ }
+
+private:
+ SubMarine *submarine;
+ QPropertyAnimation *movementAnimation;
+};
+
+//This state is describing when the boat is moving right
+class ReturnState : public QAnimationState
+{
+public:
+ ReturnState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent)
+ {
+ returnAnimation = new QPropertyAnimation(submarine->rotation(), "angle");
+ returnAnimation->setDuration(500);
+ AnimationManager::self()->registerAnimation(returnAnimation);
+ setAnimation(returnAnimation);
+ this->submarine = submarine;
+ }
+
+protected:
+ void onEntry(QEvent *e)
+ {
+ returnAnimation->stop();
+ returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.);
+ QAnimationState::onEntry(e);
+ }
+
+ void onExit(QEvent *e)
+ {
+ submarine->currentDirection() == SubMarine::Right ? submarine->setCurrentDirection(SubMarine::Left) : submarine->setCurrentDirection(SubMarine::Right);
+ QAnimationState::onExit(e);
+ }
+
+private:
+ SubMarine *submarine;
+ QPropertyAnimation *returnAnimation;
+};
+
+#endif // SUBMARINE_P_H
diff --git a/examples/animation/sub-attaq/textinformationitem.cpp b/examples/animation/sub-attaq/textinformationitem.cpp
new file mode 100644
index 0000000000..e2653361a1
--- /dev/null
+++ b/examples/animation/sub-attaq/textinformationitem.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "textinformationitem.h"
+#include "pixmapitem.h"
+
+TextInformationItem::TextInformationItem (QGraphicsItem * parent)
+ : QGraphicsTextItem(parent)
+{
+ setFont(QFont("Comic Sans MS", 15));
+}
+#include <QDebug>
+void TextInformationItem::setMessage(const QString& text)
+{
+ setHtml(text);
+ setPos(parentItem()->boundingRect().center().x() - boundingRect().size().width()/2 , parentItem()->boundingRect().center().y());
+}
diff --git a/examples/animation/sub-attaq/textinformationitem.h b/examples/animation/sub-attaq/textinformationitem.h
new file mode 100644
index 0000000000..4b5f71969f
--- /dev/null
+++ b/examples/animation/sub-attaq/textinformationitem.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTINFORMATIONITEM_H
+#define TEXTINFORMATIONITEM_H
+
+//Qt
+#include <QtGui/QGraphicsTextItem>
+
+class TextInformationItem : public QGraphicsTextItem
+{
+public:
+ TextInformationItem(QGraphicsItem * parent = 0);
+ void setMessage(const QString& text);
+};
+
+#endif // TEXTINFORMATIONITEM_H
diff --git a/examples/animation/sub-attaq/torpedo.cpp b/examples/animation/sub-attaq/torpedo.cpp
new file mode 100644
index 0000000000..8c9bacfa38
--- /dev/null
+++ b/examples/animation/sub-attaq/torpedo.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//Own
+#include "torpedo.h"
+#include "pixmapitem.h"
+#include "boat.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+
+Torpedo::Torpedo() : PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big),
+ currentSpeed(0)
+{
+ setZValue(2);
+}
+
+void Torpedo::launch()
+{
+ QPropertyAnimation *launchAnimation = new QPropertyAnimation(this, "pos");
+ AnimationManager::self()->registerAnimation(launchAnimation);
+ launchAnimation->setEndValue(QPointF(x(),qobject_cast<GraphicsScene *>(scene())->sealLevel() - 15));
+ launchAnimation->setEasingCurve(QEasingCurve::InQuad);
+ launchAnimation->setDuration(y()/currentSpeed*10);
+ connect(launchAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant)));
+ connect(this,SIGNAL(torpedoExploded()), launchAnimation, SLOT(stop()));
+
+ //We setup the state machine of the torpedo
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the launch animation is playing
+ QAnimationState *launched = new QAnimationState(machine);
+ launched->setAnimation(launchAnimation);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ machine->setInitialState(launched);
+
+ //### Add a nice animation when the torpedo is destroyed
+ launched->addTransition(this, SIGNAL(torpedoExploded()),final);
+
+ //If the animation is finished, then we move to the final state
+ launched->addTransition(launched, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(torpedoExecutionFinished()));
+
+ machine->start();
+}
+
+void Torpedo::setCurrentSpeed(int speed)
+{
+ if (speed < 0) {
+ qWarning("Torpedo::setCurrentSpeed : The speed is invalid");
+ return;
+ }
+ currentSpeed = speed;
+}
+
+void Torpedo::onAnimationLaunchValueChanged(const QVariant &)
+{
+ foreach (QGraphicsItem *item , collidingItems(Qt::IntersectsItemBoundingRect)) {
+ if (Boat *b = qgraphicsitem_cast<Boat*>(item))
+ b->destroy();
+ }
+}
+
+void Torpedo::destroy()
+{
+ emit torpedoExploded();
+}
diff --git a/examples/animation/sub-attaq/torpedo.h b/examples/animation/sub-attaq/torpedo.h
new file mode 100644
index 0000000000..a5ec24dabf
--- /dev/null
+++ b/examples/animation/sub-attaq/torpedo.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __TORPEDO__H__
+#define __TORPEDO__H__
+
+#include "pixmapitem.h"
+
+class Torpedo : public PixmapItem
+{
+Q_OBJECT
+public:
+ Torpedo();
+ void launch();
+ void setCurrentSpeed(int speed);
+ void destroy();
+
+signals:
+ void torpedoExploded();
+ void torpedoExecutionFinished();
+
+private slots:
+ void onAnimationLaunchValueChanged(const QVariant &);
+
+private:
+ int currentSpeed;
+};
+
+#endif //__TORPEDO__H__
diff --git a/examples/embedded/digiflip/digiflip.cpp b/examples/embedded/digiflip/digiflip.cpp
new file mode 100644
index 0000000000..895524355e
--- /dev/null
+++ b/examples/embedded/digiflip/digiflip.cpp
@@ -0,0 +1,425 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+
+class Digits: public QWidget
+{
+ Q_OBJECT
+
+public:
+
+ enum {
+ Slide,
+ Flip,
+ Rotate
+ };
+
+ Digits(QWidget *parent)
+ : QWidget(parent)
+ , m_number(0)
+ , m_transition(Slide)
+ {
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ connect(&m_animator, SIGNAL(frameChanged(int)), SLOT(update()));
+ m_animator.setFrameRange(0, 100);
+ m_animator.setDuration(600);
+ m_animator.setCurveShape(QTimeLine::EaseInOutCurve);
+ }
+
+ void setTransition(int tr) {
+ m_transition = tr;
+ }
+
+ int transition() const {
+ return m_transition;
+ }
+
+ void setNumber(int n) {
+ if (m_number != n) {
+ m_number = qBound(0, n, 99);
+ preparePixmap();
+ update();
+ }
+ }
+
+ void flipTo(int n) {
+ if (m_number != n) {
+ m_number = qBound(0, n, 99);
+ m_lastPixmap = m_pixmap;
+ preparePixmap();
+ m_animator.stop();
+ m_animator.start();
+ }
+ }
+
+protected:
+
+ void drawFrame(QPainter *p, const QRect &rect) {
+ p->setPen(Qt::NoPen);
+ QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
+ gradient.setColorAt(0.00, QColor(245, 245, 245));
+ gradient.setColorAt(0.49, QColor(192, 192, 192));
+ gradient.setColorAt(0.51, QColor(245, 245, 245));
+ gradient.setColorAt(1.00, QColor(192, 192, 192));
+ p->setBrush(gradient);
+ QRect r = rect;
+ p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
+ r.adjust(1, 4, -1, -4);
+ p->setPen(QColor(181, 181, 181));
+ p->setBrush(Qt::NoBrush);
+ p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
+ p->setPen(QColor(159, 159, 159));
+ int y = rect.top() + rect.height() / 2 - 1;
+ p->drawLine(rect.left(), y, rect.right(), y);
+ }
+
+ QPixmap drawDigits(int n, const QRect &rect) {
+
+ int scaleFactor = 2;
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ if (rect.height() > 240)
+ scaleFactor = 1;
+#endif
+
+ QString str = QString::number(n);
+ if (str.length() == 1)
+ str.prepend("0");
+
+ QFont font;
+ font.setFamily("Helvetica");
+ int fontHeight = scaleFactor * 0.55 * rect.height();
+ font.setPixelSize(fontHeight);
+ font.setBold(true);
+
+ QPixmap pixmap(rect.size() * scaleFactor);
+ pixmap.fill(Qt::transparent);
+
+ QLinearGradient gradient(QPoint(0, 0), QPoint(0, pixmap.height()));
+ gradient.setColorAt(0.00, QColor(128, 128, 128));
+ gradient.setColorAt(0.49, QColor(64, 64, 64));
+ gradient.setColorAt(0.51, QColor(128, 128, 128));
+ gradient.setColorAt(1.00, QColor(16, 16, 16));
+
+ QPainter p;
+ p.begin(&pixmap);
+ p.setFont(font);
+ QPen pen;
+ pen.setBrush(QBrush(gradient));
+ p.setPen(pen);
+ p.drawText(pixmap.rect(), Qt::AlignCenter, str);
+ p.end();
+
+ return pixmap.scaledToWidth(width(), Qt::SmoothTransformation);
+ }
+
+ void preparePixmap() {
+ m_pixmap = QPixmap(size());
+ m_pixmap.fill(Qt::transparent);
+ QPainter p;
+ p.begin(&m_pixmap);
+ p.drawPixmap(0, 0, drawDigits(m_number, rect()));
+ p.end();
+ }
+
+ void resizeEvent(QResizeEvent*) {
+ preparePixmap();
+ update();
+ }
+
+ void paintStatic() {
+ QPainter p(this);
+ p.fillRect(rect(), Qt::black);
+
+ int pad = width() / 10;
+ drawFrame(&p, rect().adjusted(pad, pad, -pad, -pad));
+ p.drawPixmap(0, 0, m_pixmap);
+ }
+
+ void paintSlide() {
+ QPainter p(this);
+ p.fillRect(rect(), Qt::black);
+
+ int pad = width() / 10;
+ QRect fr = rect().adjusted(pad, pad, -pad, -pad);
+ drawFrame(&p, fr);
+ p.setClipRect(fr);
+
+ int y = height() * m_animator.currentFrame() / 100;
+ p.drawPixmap(0, y, m_lastPixmap);
+ p.drawPixmap(0, y - height(), m_pixmap);
+ }
+
+ void paintFlip() {
+ QPainter p(this);
+#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_WINCE_WM)
+ p.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ p.setRenderHint(QPainter::Antialiasing, true);
+#endif
+ p.fillRect(rect(), Qt::black);
+
+ int hw = width() / 2;
+ int hh = height() / 2;
+
+ // behind is the new pixmap
+ int pad = width() / 10;
+ QRect fr = rect().adjusted(pad, pad, -pad, -pad);
+ drawFrame(&p, fr);
+ p.drawPixmap(0, 0, m_pixmap);
+
+ int index = m_animator.currentFrame();
+
+ if (index <= 50) {
+
+ // the top part of the old pixmap is flipping
+ int angle = -180 * index / 100;
+ QTransform transform;
+ transform.translate(hw, hh);
+ transform.rotate(angle, Qt::XAxis);
+ p.setTransform(transform);
+ drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
+ p.drawPixmap(-hw, -hh, m_lastPixmap);
+
+ // the bottom part is still the old pixmap
+ p.resetTransform();
+ p.setClipRect(0, hh, width(), hh);
+ drawFrame(&p, fr);
+ p.drawPixmap(0, 0, m_lastPixmap);
+ } else {
+
+ p.setClipRect(0, hh, width(), hh);
+
+ // the bottom part is still the old pixmap
+ drawFrame(&p, fr);
+ p.drawPixmap(0, 0, m_lastPixmap);
+
+ // the bottom part of the new pixmap is flipping
+ int angle = 180 - 180 * m_animator.currentFrame() / 100;
+ QTransform transform;
+ transform.translate(hw, hh);
+ transform.rotate(angle, Qt::XAxis);
+ p.setTransform(transform);
+ drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
+ p.drawPixmap(-hw, -hh, m_pixmap);
+
+ }
+
+ }
+
+ void paintRotate() {
+ QPainter p(this);
+
+ int pad = width() / 10;
+ QRect fr = rect().adjusted(pad, pad, -pad, -pad);
+ drawFrame(&p, fr);
+ p.setClipRect(fr);
+
+ int angle1 = -180 * m_animator.currentFrame() / 100;
+ int angle2 = 180 - 180 * m_animator.currentFrame() / 100;
+ int angle = (m_animator.currentFrame() <= 50) ? angle1 : angle2;
+ QPixmap pix = (m_animator.currentFrame() <= 50) ? m_lastPixmap : m_pixmap;
+
+ QTransform transform;
+ transform.translate(width() / 2, height() / 2);
+ transform.rotate(angle, Qt::XAxis);
+
+ p.setTransform(transform);
+ p.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ p.drawPixmap(-width() / 2, -height() / 2, pix);
+ }
+
+ void paintEvent(QPaintEvent *event) {
+ Q_UNUSED(event);
+ if (m_animator.state() == QTimeLine::Running) {
+ if (m_transition == Slide)
+ paintSlide();
+ if (m_transition == Flip)
+ paintFlip();
+ if (m_transition == Rotate)
+ paintRotate();
+ } else {
+ paintStatic();
+ }
+ }
+
+private:
+ int m_number;
+ int m_transition;
+ QPixmap m_pixmap;
+ QPixmap m_lastPixmap;
+ QTimeLine m_animator;
+};
+
+class DigiFlip : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ DigiFlip(QWidget *parent = 0)
+ : QMainWindow(parent)
+ {
+ m_hour = new Digits(this);
+ m_hour->show();
+ m_minute = new Digits(this);
+ m_minute->show();
+
+ QPalette pal = palette();
+ pal.setColor(QPalette::Window, Qt::black);
+ setPalette(pal);
+
+ m_ticker.start(1000, this);
+ QTime t = QTime::currentTime();
+ m_hour->setNumber(t.hour());
+ m_minute->setNumber(t.minute());
+ updateTime();
+
+ QAction *slideAction = new QAction("&Slide", this);
+ QAction *flipAction = new QAction("&Flip", this);
+ QAction *rotateAction = new QAction("&Rotate", this);
+ connect(slideAction, SIGNAL(triggered()), SLOT(chooseSlide()));
+ connect(flipAction, SIGNAL(triggered()), SLOT(chooseFlip()));
+ connect(rotateAction, SIGNAL(triggered()), SLOT(chooseRotate()));
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ menuBar()->addAction(slideAction);
+ menuBar()->addAction(flipAction);
+ menuBar()->addAction(rotateAction);
+#else
+ addAction(slideAction);
+ addAction(flipAction);
+ addAction(rotateAction);
+ setContextMenuPolicy(Qt::ActionsContextMenu);
+#endif
+ }
+
+ void updateTime() {
+ QTime t = QTime::currentTime();
+ m_hour->flipTo(t.hour());
+ m_minute->flipTo(t.minute());
+ QString str = t.toString("hh:mm:ss");
+ str.prepend(": ");
+ if (m_hour->transition() == Digits::Slide)
+ str.prepend("Slide");
+ if (m_hour->transition() == Digits::Flip)
+ str.prepend("Flip");
+ if (m_hour->transition() == Digits::Rotate)
+ str.prepend("Rotate");
+ setWindowTitle(str);
+ }
+
+ void switchTransition(int delta) {
+ int i = (m_hour->transition() + delta + 3) % 3;
+ m_hour->setTransition(i);
+ m_minute->setTransition(i);
+ updateTime();
+ }
+
+protected:
+ void resizeEvent(QResizeEvent*) {
+ int digitsWidth = width() / 2;
+ int digitsHeight = digitsWidth * 1.2;
+
+ int y = (height() - digitsHeight) / 3;
+
+ m_hour->resize(digitsWidth, digitsHeight);
+ m_hour->move(0, y);
+
+ m_minute->resize(digitsWidth, digitsHeight);
+ m_minute->move(width() / 2, y);
+ }
+
+ void timerEvent(QTimerEvent*) {
+ updateTime();
+ }
+
+ void keyPressEvent(QKeyEvent *event) {
+ if (event->key() == Qt::Key_Right) {
+ switchTransition(1);
+ event->accept();
+ }
+ if (event->key() == Qt::Key_Left) {
+ switchTransition(-1);
+ event->accept();
+ }
+ }
+
+private slots:
+ void chooseSlide() {
+ m_hour->setTransition(0);
+ m_minute->setTransition(0);
+ updateTime();
+ }
+
+ void chooseFlip() {
+ m_hour->setTransition(1);
+ m_minute->setTransition(1);
+ updateTime();
+ }
+
+ void chooseRotate() {
+ m_hour->setTransition(2);
+ m_minute->setTransition(2);
+ updateTime();
+ }
+
+private:
+ QBasicTimer m_ticker;
+ Digits *m_hour;
+ Digits *m_minute;
+};
+
+#include "digiflip.moc"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ DigiFlip time;
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ time.showMaximized();
+#else
+ time.resize(320, 240);
+ time.show();
+#endif
+
+ return app.exec();
+}
diff --git a/examples/embedded/digiflip/digiflip.pro b/examples/embedded/digiflip/digiflip.pro
new file mode 100644
index 0000000000..7fa06fa90a
--- /dev/null
+++ b/examples/embedded/digiflip/digiflip.pro
@@ -0,0 +1,11 @@
+SOURCES = digiflip.cpp
+
+symbian {
+ TARGET.UID3 = 0xA000CF72
+ CONFIG += qt_demo
+}
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/digiflip
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/digiflip
+INSTALLS += target sources
diff --git a/examples/embedded/embedded.pro b/examples/embedded/embedded.pro
new file mode 100644
index 0000000000..e9a448b1e3
--- /dev/null
+++ b/examples/embedded/embedded.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+SUBDIRS = styledemo raycasting flickable digiflip
+
+SUBDIRS += lightmaps
+SUBDIRS += flightinfo
+
+# install
+sources.files = README *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded
+INSTALLS += sources
+
+symbian: CONFIG += qt_demo
diff --git a/examples/embedded/flickable/flickable.cpp b/examples/embedded/flickable/flickable.cpp
new file mode 100644
index 0000000000..edcc1a7396
--- /dev/null
+++ b/examples/embedded/flickable/flickable.cpp
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "flickable.h"
+
+#include <QtCore>
+#include <QtGui>
+
+class FlickableTicker: QObject
+{
+public:
+ FlickableTicker(Flickable *scroller) {
+ m_scroller = scroller;
+ }
+
+ void start(int interval) {
+ if (!m_timer.isActive())
+ m_timer.start(interval, this);
+ }
+
+ void stop() {
+ m_timer.stop();
+ }
+
+protected:
+ void timerEvent(QTimerEvent *event) {
+ Q_UNUSED(event);
+ m_scroller->tick();
+ }
+
+private:
+ Flickable *m_scroller;
+ QBasicTimer m_timer;
+};
+
+class FlickablePrivate
+{
+public:
+ typedef enum {
+ Steady,
+ Pressed,
+ ManualScroll,
+ AutoScroll,
+ Stop
+ } State;
+
+ State state;
+ int threshold;
+ QPoint pressPos;
+ QPoint offset;
+ QPoint delta;
+ QPoint speed;
+ FlickableTicker *ticker;
+ QTime timeStamp;
+ QWidget *target;
+ QList<QEvent*> ignoreList;
+};
+
+Flickable::Flickable()
+{
+ d = new FlickablePrivate;
+ d->state = FlickablePrivate::Steady;
+ d->threshold = 10;
+ d->ticker = new FlickableTicker(this);
+ d->timeStamp = QTime::currentTime();
+ d->target = 0;
+}
+
+Flickable::~Flickable()
+{
+ delete d;
+}
+
+void Flickable::setThreshold(int th)
+{
+ if (th >= 0)
+ d->threshold = th;
+}
+
+int Flickable::threshold() const
+{
+ return d->threshold;
+}
+
+void Flickable::setAcceptMouseClick(QWidget *target)
+{
+ d->target = target;
+}
+
+static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64)
+{
+ int x = qBound(-max, speed.x(), max);
+ int y = qBound(-max, speed.y(), max);
+ x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a);
+ y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a);
+ return QPoint(x, y);
+}
+
+void Flickable::handleMousePress(QMouseEvent *event)
+{
+ event->ignore();
+
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ if (d->ignoreList.removeAll(event))
+ return;
+
+ switch (d->state) {
+
+ case FlickablePrivate::Steady:
+ event->accept();
+ d->state = FlickablePrivate::Pressed;
+ d->pressPos = event->pos();
+ break;
+
+ case FlickablePrivate::AutoScroll:
+ event->accept();
+ d->state = FlickablePrivate::Stop;
+ d->speed = QPoint(0, 0);
+ d->pressPos = event->pos();
+ d->offset = scrollOffset();
+ d->ticker->stop();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Flickable::handleMouseRelease(QMouseEvent *event)
+{
+ event->ignore();
+
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ if (d->ignoreList.removeAll(event))
+ return;
+
+ QPoint delta;
+
+ switch (d->state) {
+
+ case FlickablePrivate::Pressed:
+ event->accept();
+ d->state = FlickablePrivate::Steady;
+ if (d->target) {
+ QMouseEvent *event1 = new QMouseEvent(QEvent::MouseButtonPress,
+ d->pressPos, Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent *event2 = new QMouseEvent(*event);
+ d->ignoreList << event1;
+ d->ignoreList << event2;
+ QApplication::postEvent(d->target, event1);
+ QApplication::postEvent(d->target, event2);
+ }
+ break;
+
+ case FlickablePrivate::ManualScroll:
+ event->accept();
+ delta = event->pos() - d->pressPos;
+ if (d->timeStamp.elapsed() > 100) {
+ d->timeStamp = QTime::currentTime();
+ d->speed = delta - d->delta;
+ d->delta = delta;
+ }
+ d->offset = scrollOffset();
+ d->pressPos = event->pos();
+ if (d->speed == QPoint(0, 0)) {
+ d->state = FlickablePrivate::Steady;
+ } else {
+ d->speed /= 4;
+ d->state = FlickablePrivate::AutoScroll;
+ d->ticker->start(20);
+ }
+ break;
+
+ case FlickablePrivate::Stop:
+ event->accept();
+ d->state = FlickablePrivate::Steady;
+ d->offset = scrollOffset();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Flickable::handleMouseMove(QMouseEvent *event)
+{
+ event->ignore();
+
+ if (!(event->buttons() & Qt::LeftButton))
+ return;
+
+ if (d->ignoreList.removeAll(event))
+ return;
+
+ QPoint delta;
+
+ switch (d->state) {
+
+ case FlickablePrivate::Pressed:
+ case FlickablePrivate::Stop:
+ delta = event->pos() - d->pressPos;
+ if (delta.x() > d->threshold || delta.x() < -d->threshold ||
+ delta.y() > d->threshold || delta.y() < -d->threshold) {
+ d->timeStamp = QTime::currentTime();
+ d->state = FlickablePrivate::ManualScroll;
+ d->delta = QPoint(0, 0);
+ d->pressPos = event->pos();
+ event->accept();
+ }
+ break;
+
+ case FlickablePrivate::ManualScroll:
+ event->accept();
+ delta = event->pos() - d->pressPos;
+ setScrollOffset(d->offset - delta);
+ if (d->timeStamp.elapsed() > 100) {
+ d->timeStamp = QTime::currentTime();
+ d->speed = delta - d->delta;
+ d->delta = delta;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Flickable::tick()
+{
+ if (d->state == FlickablePrivate:: AutoScroll) {
+ d->speed = deaccelerate(d->speed);
+ setScrollOffset(d->offset - d->speed);
+ d->offset = scrollOffset();
+ if (d->speed == QPoint(0, 0)) {
+ d->state = FlickablePrivate::Steady;
+ d->ticker->stop();
+ }
+ } else {
+ d->ticker->stop();
+ }
+}
diff --git a/examples/embedded/flickable/flickable.h b/examples/embedded/flickable/flickable.h
new file mode 100644
index 0000000000..3195d3297c
--- /dev/null
+++ b/examples/embedded/flickable/flickable.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FLICKABLE_H
+#define FLICKABLE_H
+
+class QMouseEvent;
+class QPoint;
+class QWidget;
+
+class FlickableTicker;
+class FlickablePrivate;
+
+class Flickable
+{
+public:
+
+ Flickable();
+ virtual ~Flickable();
+
+ void setThreshold(int threshold);
+ int threshold() const;
+
+ void setAcceptMouseClick(QWidget *target);
+
+ void handleMousePress(QMouseEvent *event);
+ void handleMouseMove(QMouseEvent *event);
+ void handleMouseRelease(QMouseEvent *event);
+
+protected:
+ virtual QPoint scrollOffset() const = 0;
+ virtual void setScrollOffset(const QPoint &offset) = 0;
+
+private:
+ void tick();
+
+private:
+ FlickablePrivate *d;
+ friend class FlickableTicker;
+};
+
+#endif // FLICKABLE_H
diff --git a/examples/embedded/flickable/flickable.pro b/examples/embedded/flickable/flickable.pro
new file mode 100644
index 0000000000..6ee744bc63
--- /dev/null
+++ b/examples/embedded/flickable/flickable.pro
@@ -0,0 +1,12 @@
+SOURCES = flickable.cpp main.cpp
+HEADERS = flickable.h
+
+symbian {
+ TARGET.UID3 = 0xA000CF73
+ CONFIG += qt_demo
+}
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/flickable
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/flickable
+INSTALLS += target sources
diff --git a/examples/embedded/flickable/main.cpp b/examples/embedded/flickable/main.cpp
new file mode 100644
index 0000000000..3711a6dc57
--- /dev/null
+++ b/examples/embedded/flickable/main.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+
+#include "flickable.h"
+
+// Returns a list of two-word color names
+static QStringList colorPairs(int max)
+{
+ // capitalize the first letter
+ QStringList colors = QColor::colorNames();
+ colors.removeAll("transparent");
+ int num = colors.count();
+ for (int c = 0; c < num; ++c)
+ colors[c] = colors[c][0].toUpper() + colors[c].mid(1);
+
+ // combine two colors, e.g. "lime skyblue"
+ QStringList combinedColors;
+ for (int i = 0; i < num; ++i)
+ for (int j = 0; j < num; ++j)
+ combinedColors << QString("%1 %2").arg(colors[i]).arg(colors[j]);
+
+ // randomize it
+ colors.clear();
+ while (combinedColors.count()) {
+ int i = qrand() % combinedColors.count();
+ colors << combinedColors[i];
+ combinedColors.removeAt(i);
+ if (colors.count() == max)
+ break;
+ }
+
+ return colors;
+}
+
+class ColorList : public QWidget, public Flickable
+{
+ Q_OBJECT
+
+public:
+ ColorList(QWidget *parent = 0)
+ : QWidget(parent) {
+ m_offset = 0;
+ m_height = QFontMetrics(font()).height() + 5;
+ m_highlight = -1;
+ m_selected = -1;
+
+ QStringList colors = colorPairs(999);
+ for (int i = 0; i < colors.count(); ++i) {
+ QString c = colors[i];
+ QString str;
+ str.sprintf("%4d", i + 1);
+ m_colorNames << (str + " " + c);
+
+ QStringList duet = c.split(' ');
+ m_firstColor << duet[0];
+ m_secondColor << duet[1];
+ }
+
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+
+ setMouseTracking(true);
+ Flickable::setAcceptMouseClick(this);
+ }
+
+protected:
+ // reimplement from Flickable
+ virtual QPoint scrollOffset() const {
+ return QPoint(0, m_offset);
+ }
+
+ // reimplement from Flickable
+ virtual void setScrollOffset(const QPoint &offset) {
+ int yy = offset.y();
+ if (yy != m_offset) {
+ m_offset = qBound(0, yy, m_height * m_colorNames.count() - height());
+ update();
+ }
+ }
+
+protected:
+ void paintEvent(QPaintEvent *event) {
+ QPainter p(this);
+ p.fillRect(event->rect(), Qt::white);
+ int start = m_offset / m_height;
+ int y = start * m_height - m_offset;
+ if (m_offset <= 0) {
+ start = 0;
+ y = -m_offset;
+ }
+ int end = start + height() / m_height + 1;
+ if (end > m_colorNames.count() - 1)
+ end = m_colorNames.count() - 1;
+ for (int i = start; i <= end; ++i, y += m_height) {
+
+ p.setBrush(Qt::NoBrush);
+ p.setPen(Qt::black);
+ if (i == m_highlight) {
+ p.fillRect(0, y, width(), m_height, QColor(0, 64, 128));
+ p.setPen(Qt::white);
+ }
+ if (i == m_selected) {
+ p.fillRect(0, y, width(), m_height, QColor(0, 128, 240));
+ p.setPen(Qt::white);
+ }
+
+ p.drawText(m_height + 2, y, width(), m_height, Qt::AlignVCenter, m_colorNames[i]);
+
+ p.setPen(Qt::NoPen);
+ p.setBrush(m_firstColor[i]);
+ p.drawRect(1, y + 1, m_height - 2, m_height - 2);
+ p.setBrush(m_secondColor[i]);
+ p.drawRect(5, y + 5, m_height - 11, m_height - 11);
+ }
+ p.end();
+ }
+
+ void keyReleaseEvent(QKeyEvent *event) {
+ if (event->key() == Qt::Key_Down) {
+ m_offset += 20;
+ event->accept();
+ update();
+ return;
+ }
+ if (event->key() == Qt::Key_Up) {
+ m_offset -= 20;
+ event->accept();
+ update();
+ return;
+ }
+ }
+
+ void mousePressEvent(QMouseEvent *event) {
+ Flickable::handleMousePress(event);
+ if (event->isAccepted())
+ return;
+
+ if (event->button() == Qt::LeftButton) {
+ int y = event->pos().y() + m_offset;
+ int i = y / m_height;
+ if (i != m_highlight) {
+ m_highlight = i;
+ m_selected = -1;
+ update();
+ }
+ event->accept();
+ }
+ }
+
+ void mouseMoveEvent(QMouseEvent *event) {
+ Flickable::handleMouseMove(event);
+ }
+
+ void mouseReleaseEvent(QMouseEvent *event) {
+ Flickable::handleMouseRelease(event);
+ if (event->isAccepted())
+ return;
+
+ if (event->button() == Qt::LeftButton) {
+ m_selected = m_highlight;
+ event->accept();
+ update();
+ }
+ }
+
+private:
+ int m_offset;
+ int m_height;
+ int m_highlight;
+ int m_selected;
+ QStringList m_colorNames;
+ QList<QColor> m_firstColor;
+ QList<QColor> m_secondColor;
+};
+
+#include "main.moc"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ ColorList list;
+ list.setWindowTitle("Kinetic Scrolling");
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ list.showMaximized();
+#else
+ list.resize(320, 320);
+ list.show();
+#endif
+
+ return app.exec();
+}
diff --git a/examples/embedded/flightinfo/aircraft.png b/examples/embedded/flightinfo/aircraft.png
new file mode 100644
index 0000000000..2312bcc9f0
--- /dev/null
+++ b/examples/embedded/flightinfo/aircraft.png
Binary files differ
diff --git a/examples/embedded/flightinfo/flightinfo.cpp b/examples/embedded/flightinfo/flightinfo.cpp
new file mode 100644
index 0000000000..58e71c8376
--- /dev/null
+++ b/examples/embedded/flightinfo/flightinfo.cpp
@@ -0,0 +1,399 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+#include <QtNetwork>
+
+#include "ui_form.h"
+
+#define FLIGHTVIEW_URL "http://mobile.flightview.com/TrackByFlight.aspx"
+#define FLIGHTVIEW_RANDOM "http://mobile.flightview.com/TrackSampleFlight.aspx"
+
+// strips all invalid constructs that might trip QXmlStreamReader
+static QString sanitized(const QString &xml)
+{
+ QString data = xml;
+
+ // anything up to the html tag
+ int i = data.indexOf("<html");
+ if (i > 0)
+ data.remove(0, i - 1);
+
+ // everything inside the head tag
+ i = data.indexOf("<head");
+ if (i > 0)
+ data.remove(i, data.indexOf("</head>") - i + 7);
+
+ // invalid link for JavaScript code
+ while (true) {
+ i = data.indexOf("onclick=\"gotoUrl(");
+ if (i < 0)
+ break;
+ data.remove(i, data.indexOf('\"', i + 9) - i + 1);
+ }
+
+ // all inline frames
+ while (true) {
+ i = data.indexOf("<iframe");
+ if (i < 0)
+ break;
+ data.remove(i, data.indexOf("</iframe>") - i + 8);
+ }
+
+ // entities
+ data.remove("&nbsp;");
+ data.remove("&copy;");
+
+ return data;
+}
+
+class FlightInfo : public QMainWindow
+{
+ Q_OBJECT
+
+private:
+
+ Ui_Form ui;
+ QUrl m_url;
+ QDate m_searchDate;
+ QPixmap m_map;
+ QNetworkAccessManager m_manager;
+ QList<QNetworkReply *> mapReplies;
+
+public:
+
+ FlightInfo(QMainWindow *parent = 0): QMainWindow(parent) {
+
+ QWidget *w = new QWidget(this);
+ ui.setupUi(w);
+ setCentralWidget(w);
+
+ ui.searchBar->hide();
+ ui.infoBox->hide();
+ connect(ui.searchButton, SIGNAL(clicked()), SLOT(startSearch()));
+ connect(ui.flightEdit, SIGNAL(returnPressed()), SLOT(startSearch()));
+
+ setWindowTitle("Flight Info");
+
+ // Rendered from the public-domain vectorized aircraft
+ // http://openclipart.org/media/people/Jarno
+ m_map = QPixmap(":/aircraft.png");
+
+ QAction *searchTodayAction = new QAction("Today's Flight", this);
+ QAction *searchYesterdayAction = new QAction("Yesterday's Flight", this);
+ QAction *randomAction = new QAction("Random Flight", this);
+ connect(searchTodayAction, SIGNAL(triggered()), SLOT(today()));
+ connect(searchYesterdayAction, SIGNAL(triggered()), SLOT(yesterday()));
+ connect(randomAction, SIGNAL(triggered()), SLOT(randomFlight()));
+ connect(&m_manager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(handleNetworkData(QNetworkReply*)));
+#if defined(Q_OS_SYMBIAN)
+ menuBar()->addAction(searchTodayAction);
+ menuBar()->addAction(searchYesterdayAction);
+ menuBar()->addAction(randomAction);
+#else
+ addAction(searchTodayAction);
+ addAction(searchYesterdayAction);
+ addAction(randomAction);
+ setContextMenuPolicy(Qt::ActionsContextMenu);
+#endif
+ }
+
+private slots:
+
+ void handleNetworkData(QNetworkReply *networkReply) {
+ if (!networkReply->error()) {
+ if (!mapReplies.contains(networkReply)) {
+ // Assume UTF-8 encoded
+ QByteArray data = networkReply->readAll();
+ QString xml = QString::fromUtf8(data);
+ digest(xml);
+ } else {
+ mapReplies.removeOne(networkReply);
+ m_map.loadFromData(networkReply->readAll());
+ update();
+ }
+ }
+ networkReply->deleteLater();
+ }
+
+ void today() {
+ QDateTime timestamp = QDateTime::currentDateTime();
+ m_searchDate = timestamp.date();
+ searchFlight();
+ }
+
+ void yesterday() {
+ QDateTime timestamp = QDateTime::currentDateTime();
+ timestamp = timestamp.addDays(-1);
+ m_searchDate = timestamp.date();
+ searchFlight();
+ }
+
+ void searchFlight() {
+ ui.searchBar->show();
+ ui.infoBox->hide();
+ ui.flightStatus->hide();
+ ui.flightName->setText("Enter flight number");
+ ui.flightEdit->setFocus();
+#ifdef QT_KEYPAD_NAVIGATION
+ ui.flightEdit->setEditFocus(true);
+#endif
+ m_map = QPixmap();
+ update();
+ }
+
+ void startSearch() {
+ ui.searchBar->hide();
+ QString flight = ui.flightEdit->text().simplified();
+ if (!flight.isEmpty())
+ request(flight, m_searchDate);
+ }
+
+ void randomFlight() {
+ request(QString(), QDate::currentDate());
+ }
+
+public slots:
+
+ void request(const QString &flightCode, const QDate &date) {
+
+ setWindowTitle("Loading...");
+
+ QString code = flightCode.simplified();
+ QString airlineCode = code.left(2).toUpper();
+ QString flightNumber = code.mid(2, code.length());
+
+ ui.flightName->setText("Searching for " + code);
+
+ m_url = QUrl(FLIGHTVIEW_URL);
+ m_url.addEncodedQueryItem("view", "detail");
+ m_url.addEncodedQueryItem("al", QUrl::toPercentEncoding(airlineCode));
+ m_url.addEncodedQueryItem("fn", QUrl::toPercentEncoding(flightNumber));
+ m_url.addEncodedQueryItem("dpdat", QUrl::toPercentEncoding(date.toString("yyyyMMdd")));
+
+ if (code.isEmpty()) {
+ // random flight as sample
+ m_url = QUrl(FLIGHTVIEW_RANDOM);
+ ui.flightName->setText("Getting a random flight...");
+ }
+
+ m_manager.get(QNetworkRequest(m_url));
+ }
+
+
+private:
+
+ void digest(const QString &content) {
+
+ setWindowTitle("Flight Info");
+ QString data = sanitized(content);
+
+ // do we only get the flight list?
+ // we grab the first leg in the flight list
+ // then fetch another URL for the real flight info
+ int i = data.indexOf("a href=\"?view=detail");
+ if (i > 0) {
+ QString href = data.mid(i, data.indexOf('\"', i + 8) - i + 1);
+ QRegExp regex("dpap=([A-Za-z0-9]+)");
+ regex.indexIn(href);
+ QString airport = regex.cap(1);
+ m_url.addEncodedQueryItem("dpap", QUrl::toPercentEncoding(airport));
+ m_manager.get(QNetworkRequest(m_url));
+ return;
+ }
+
+ QXmlStreamReader xml(data);
+ bool inFlightName = false;
+ bool inFlightStatus = false;
+ bool inFlightMap = false;
+ bool inFieldName = false;
+ bool inFieldValue = false;
+
+ QString flightName;
+ QString flightStatus;
+ QStringList fieldNames;
+ QStringList fieldValues;
+
+ while (!xml.atEnd()) {
+ xml.readNext();
+
+ if (xml.tokenType() == QXmlStreamReader::StartElement) {
+ QStringRef className = xml.attributes().value("class");
+ inFlightName |= xml.name() == "h1";
+ inFlightStatus |= className == "FlightDetailHeaderStatus";
+ inFlightMap |= className == "flightMap";
+ if (xml.name() == "td" && !className.isEmpty()) {
+ QString cn = className.toString();
+ if (cn.contains("fieldTitle")) {
+ inFieldName = true;
+ fieldNames += QString();
+ fieldValues += QString();
+ }
+ if (cn.contains("fieldValue"))
+ inFieldValue = true;
+ }
+ if (xml.name() == "img" && inFlightMap) {
+ QString src = xml.attributes().value("src").toString();
+ src.prepend("http://mobile.flightview.com/");
+ QUrl url = QUrl::fromPercentEncoding(src.toAscii());
+ mapReplies.append(m_manager.get(QNetworkRequest(url)));
+ }
+ }
+
+ if (xml.tokenType() == QXmlStreamReader::EndElement) {
+ inFlightName &= xml.name() != "h1";
+ inFlightStatus &= xml.name() != "div";
+ inFlightMap &= xml.name() != "div";
+ inFieldName &= xml.name() != "td";
+ inFieldValue &= xml.name() != "td";
+ }
+
+ if (xml.tokenType() == QXmlStreamReader::Characters) {
+ if (inFlightName)
+ flightName += xml.text();
+ if (inFlightStatus)
+ flightStatus += xml.text();
+ if (inFieldName)
+ fieldNames.last() += xml.text();
+ if (inFieldValue)
+ fieldValues.last() += xml.text();
+ }
+ }
+
+ if (fieldNames.isEmpty()) {
+ QString code = ui.flightEdit->text().simplified().left(10);
+ QString msg = QString("Flight %1 is not found").arg(code);
+ ui.flightName->setText(msg);
+ return;
+ }
+
+ ui.flightName->setText(flightName);
+ flightStatus.remove("Status: ");
+ ui.flightStatus->setText(flightStatus);
+ ui.flightStatus->show();
+
+ QStringList whiteList;
+ whiteList << "Departure";
+ whiteList << "Arrival";
+ whiteList << "Scheduled";
+ whiteList << "Takeoff";
+ whiteList << "Estimated";
+ whiteList << "Term-Gate";
+
+ QString text;
+ text = QString("<table width=%1>").arg(width() - 25);
+ for (int i = 0; i < fieldNames.count(); i++) {
+ QString fn = fieldNames[i].simplified();
+ if (fn.endsWith(':'))
+ fn = fn.left(fn.length() - 1);
+ if (!whiteList.contains(fn))
+ continue;
+
+ QString fv = fieldValues[i].simplified();
+ bool special = false;
+ special |= fn.startsWith("Departure");
+ special |= fn.startsWith("Arrival");
+ text += "<tr>";
+ if (special) {
+ text += "<td align=center colspan=2>";
+ text += "<b><font size=+1>" + fv + "</font></b>";
+ text += "</td>";
+ } else {
+ text += "<td align=right>";
+ text += fn;
+ text += " : ";
+ text += "&nbsp;";
+ text += "</td>";
+ text += "<td>";
+ text += fv;
+ text += "</td>";
+ }
+ text += "</tr>";
+ }
+ text += "</table>";
+ ui.detailedInfo->setText(text);
+ ui.infoBox->show();
+ }
+
+ void resizeEvent(QResizeEvent *event) {
+ Q_UNUSED(event);
+ ui.detailedInfo->setMaximumWidth(width() - 25);
+ }
+
+ void paintEvent(QPaintEvent *event) {
+ QMainWindow::paintEvent(event);
+ QPainter p(this);
+ p.fillRect(rect(), QColor(131, 171, 210));
+ if (!m_map.isNull()) {
+ int x = (width() - m_map.width()) / 2;
+ int space = ui.infoBox->pos().y();
+ if (!ui.infoBox->isVisible())
+ space = height();
+ int top = ui.titleBox->height();
+ int y = qMax(top, (space - m_map.height()) / 2);
+ p.drawPixmap(x, y, m_map);
+ }
+ p.end();
+ }
+
+};
+
+
+#include "flightinfo.moc"
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(flightinfo);
+
+ QApplication app(argc, argv);
+
+ FlightInfo w;
+#if defined(Q_OS_SYMBIAN)
+ w.showMaximized();
+#else
+ w.resize(360, 504);
+ w.show();
+#endif
+
+ return app.exec();
+}
diff --git a/examples/embedded/flightinfo/flightinfo.pro b/examples/embedded/flightinfo/flightinfo.pro
new file mode 100644
index 0000000000..a33423f543
--- /dev/null
+++ b/examples/embedded/flightinfo/flightinfo.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = flightinfo
+SOURCES = flightinfo.cpp
+FORMS += form.ui
+RESOURCES = flightinfo.qrc
+QT += network
+
+symbian {
+ TARGET.UID3 = 0xA000CF74
+ CONFIG += qt_demo
+ TARGET.CAPABILITY = NetworkServices
+}
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/flightinfo
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/flightinfo
+INSTALLS += target sources
diff --git a/examples/embedded/flightinfo/flightinfo.qrc b/examples/embedded/flightinfo/flightinfo.qrc
new file mode 100644
index 0000000000..babea7e0cb
--- /dev/null
+++ b/examples/embedded/flightinfo/flightinfo.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>aircraft.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/embedded/flightinfo/form.ui b/examples/embedded/flightinfo/form.ui
new file mode 100644
index 0000000000..3a24c758a6
--- /dev/null
+++ b/examples/embedded/flightinfo/form.ui
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>220</width>
+ <height>171</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="titleBox">
+ <property name="styleSheet">
+ <string>QFrame {
+background-color: #45629a;
+}
+
+QLabel {
+color: white;
+}</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="flightName">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Powered by FlightView</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="flightStatus">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="styleSheet">
+ <string>background-color: white;
+color: #45629a;</string>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <property name="text">
+ <string>Ready</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="margin">
+ <number>4</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="searchBar">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="margin">
+ <number>5</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="flightEdit">
+ <property name="styleSheet">
+ <string>color: black;
+border: 1px solid black;
+background: white;
+selection-background-color: lightgray;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="searchButton">
+ <property name="styleSheet">
+ <string>color: rgb(255, 255, 255);
+background-color: rgb(85, 85, 255);
+padding: 2px;
+border: 2px solid rgb(0, 0, 127);</string>
+ </property>
+ <property name="text">
+ <string>Search</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>58</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QFrame" name="infoBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string>QFrame { border: 2px solid white;
+border-radius: 10px;
+margin: 5px;
+background-color: rgba(69, 98, 154, 192); }</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="detailedInfo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string>color: white;
+border: none;
+background-color: none;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/embedded/lightmaps/lightmaps.cpp b/examples/embedded/lightmaps/lightmaps.cpp
new file mode 100644
index 0000000000..d672530e19
--- /dev/null
+++ b/examples/embedded/lightmaps/lightmaps.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+#include <QtNetwork>
+
+#include <math.h>
+
+#include "lightmaps.h"
+#include "slippymap.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+// how long (milliseconds) the user need to hold (after a tap on the screen)
+// before triggering the magnifying glass feature
+// 701, a prime number, is the sum of 229, 233, 239
+// (all three are also prime numbers, consecutive!)
+#define HOLD_TIME 701
+
+// maximum size of the magnifier
+// Hint: see above to find why I picked this one :)
+#define MAX_MAGNIFIER 229
+
+LightMaps::LightMaps(QWidget *parent)
+ : QWidget(parent), pressed(false), snapped(false), zoomed(false),
+ invert(false)
+{
+ m_normalMap = new SlippyMap(this);
+ m_largeMap = new SlippyMap(this);
+ connect(m_normalMap, SIGNAL(updated(QRect)), SLOT(updateMap(QRect)));
+ connect(m_largeMap, SIGNAL(updated(QRect)), SLOT(update()));
+}
+
+void LightMaps::setCenter(qreal lat, qreal lng)
+{
+ m_normalMap->latitude = lat;
+ m_normalMap->longitude = lng;
+ m_normalMap->invalidate();
+ m_largeMap->latitude = lat;
+ m_largeMap->longitude = lng;
+ m_largeMap->invalidate();
+}
+
+void LightMaps::toggleNightMode()
+{
+ invert = !invert;
+ update();
+}
+
+void LightMaps::updateMap(const QRect &r)
+{
+ update(r);
+}
+
+void LightMaps::activateZoom()
+{
+ zoomed = true;
+ tapTimer.stop();
+ m_largeMap->zoom = m_normalMap->zoom + 1;
+ m_largeMap->width = m_normalMap->width * 2;
+ m_largeMap->height = m_normalMap->height * 2;
+ m_largeMap->latitude = m_normalMap->latitude;
+ m_largeMap->longitude = m_normalMap->longitude;
+ m_largeMap->invalidate();
+ update();
+}
+
+void LightMaps::resizeEvent(QResizeEvent *)
+{
+ m_normalMap->width = width();
+ m_normalMap->height = height();
+ m_normalMap->invalidate();
+ m_largeMap->width = m_normalMap->width * 2;
+ m_largeMap->height = m_normalMap->height * 2;
+ m_largeMap->invalidate();
+}
+
+void LightMaps::paintEvent(QPaintEvent *event)
+{
+ QPainter p;
+ p.begin(this);
+ m_normalMap->render(&p, event->rect());
+ p.setPen(Qt::black);
+#if defined(Q_OS_SYMBIAN)
+ QFont font = p.font();
+ font.setPixelSize(13);
+ p.setFont(font);
+#endif
+ p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap,
+ "Map data CCBYSA 2009 OpenStreetMap.org contributors");
+ p.end();
+
+ if (zoomed) {
+ int dim = qMin(width(), height());
+ int magnifierSize = qMin(MAX_MAGNIFIER, dim * 2 / 3);
+ int radius = magnifierSize / 2;
+ int ring = radius - 15;
+ QSize box = QSize(magnifierSize, magnifierSize);
+
+ // reupdate our mask
+ if (maskPixmap.size() != box) {
+ maskPixmap = QPixmap(box);
+ maskPixmap.fill(Qt::transparent);
+
+ QRadialGradient g;
+ g.setCenter(radius, radius);
+ g.setFocalPoint(radius, radius);
+ g.setRadius(radius);
+ g.setColorAt(1.0, QColor(255, 255, 255, 0));
+ g.setColorAt(0.5, QColor(128, 128, 128, 255));
+
+ QPainter mask(&maskPixmap);
+ mask.setRenderHint(QPainter::Antialiasing);
+ mask.setCompositionMode(QPainter::CompositionMode_Source);
+ mask.setBrush(g);
+ mask.setPen(Qt::NoPen);
+ mask.drawRect(maskPixmap.rect());
+ mask.setBrush(QColor(Qt::transparent));
+ mask.drawEllipse(g.center(), ring, ring);
+ mask.end();
+ }
+
+ QPoint center = dragPos - QPoint(0, radius);
+ center = center + QPoint(0, radius / 2);
+ QPoint corner = center - QPoint(radius, radius);
+
+ QPoint xy = center * 2 - QPoint(radius, radius);
+
+ // only set the dimension to the magnified portion
+ if (zoomPixmap.size() != box) {
+ zoomPixmap = QPixmap(box);
+ zoomPixmap.fill(Qt::lightGray);
+ }
+ if (true) {
+ QPainter p(&zoomPixmap);
+ p.translate(-xy);
+ m_largeMap->render(&p, QRect(xy, box));
+ p.end();
+ }
+
+ QPainterPath clipPath;
+ clipPath.addEllipse(center, ring, ring);
+
+ QPainter p(this);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setClipPath(clipPath);
+ p.drawPixmap(corner, zoomPixmap);
+ p.setClipping(false);
+ p.drawPixmap(corner, maskPixmap);
+ p.setPen(Qt::gray);
+ p.drawPath(clipPath);
+ }
+ if (invert) {
+ QPainter p(this);
+ p.setCompositionMode(QPainter::CompositionMode_Difference);
+ p.fillRect(event->rect(), Qt::white);
+ p.end();
+ }
+}
+
+void LightMaps::timerEvent(QTimerEvent *)
+{
+ if (!zoomed)
+ activateZoom();
+ update();
+}
+
+void LightMaps::mousePressEvent(QMouseEvent *event)
+{
+ if (event->buttons() != Qt::LeftButton)
+ return;
+ pressed = snapped = true;
+ pressPos = dragPos = event->pos();
+ tapTimer.stop();
+ tapTimer.start(HOLD_TIME, this);
+}
+
+void LightMaps::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!event->buttons())
+ return;
+ if (!zoomed) {
+ if (!pressed || !snapped) {
+ QPoint delta = event->pos() - pressPos;
+ pressPos = event->pos();
+ m_normalMap->pan(delta);
+ return;
+ } else {
+ const int threshold = 10;
+ QPoint delta = event->pos() - pressPos;
+ if (snapped) {
+ snapped &= delta.x() < threshold;
+ snapped &= delta.y() < threshold;
+ snapped &= delta.x() > -threshold;
+ snapped &= delta.y() > -threshold;
+ }
+ if (!snapped)
+ tapTimer.stop();
+ }
+ } else {
+ dragPos = event->pos();
+ update();
+ }
+}
+
+void LightMaps::mouseReleaseEvent(QMouseEvent *)
+{
+ zoomed = false;
+ update();
+}
+
+void LightMaps::keyPressEvent(QKeyEvent *event)
+{
+ if (!zoomed) {
+ if (event->key() == Qt::Key_Left)
+ m_normalMap->pan(QPoint(20, 0));
+ if (event->key() == Qt::Key_Right)
+ m_normalMap->pan(QPoint(-20, 0));
+ if (event->key() == Qt::Key_Up)
+ m_normalMap->pan(QPoint(0, 20));
+ if (event->key() == Qt::Key_Down)
+ m_normalMap->pan(QPoint(0, -20));
+ if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) {
+ dragPos = QPoint(width() / 2, height() / 2);
+ activateZoom();
+ }
+ } else {
+ if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) {
+ zoomed = false;
+ update();
+ }
+ QPoint delta(0, 0);
+ if (event->key() == Qt::Key_Left)
+ delta = QPoint(-15, 0);
+ if (event->key() == Qt::Key_Right)
+ delta = QPoint(15, 0);
+ if (event->key() == Qt::Key_Up)
+ delta = QPoint(0, -15);
+ if (event->key() == Qt::Key_Down)
+ delta = QPoint(0, 15);
+ if (delta != QPoint(0, 0)) {
+ dragPos += delta;
+ update();
+ }
+ }
+}
diff --git a/examples/embedded/lightmaps/lightmaps.h b/examples/embedded/lightmaps/lightmaps.h
new file mode 100644
index 0000000000..45b5c188a2
--- /dev/null
+++ b/examples/embedded/lightmaps/lightmaps.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIGHTMAPS_H
+#define LIGHTMAPS_H
+
+#include <QBasicTimer>
+#include <QWidget>
+
+class SlippyMap;
+
+class LightMaps: public QWidget
+{
+ Q_OBJECT
+
+public:
+ LightMaps(QWidget *parent = 0);
+ void setCenter(qreal lat, qreal lng);
+
+public slots:
+ void toggleNightMode();
+
+protected:
+ void activateZoom();
+ void resizeEvent(QResizeEvent *);
+ void paintEvent(QPaintEvent *event);
+ void timerEvent(QTimerEvent *);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *);
+ void keyPressEvent(QKeyEvent *event);
+
+private slots:
+ void updateMap(const QRect &r);
+
+private:
+ SlippyMap *m_normalMap;
+ SlippyMap *m_largeMap;
+ bool pressed;
+ bool snapped;
+ QPoint pressPos;
+ QPoint dragPos;
+ QBasicTimer tapTimer;
+ bool zoomed;
+ QPixmap zoomPixmap;
+ QPixmap maskPixmap;
+ bool invert;
+};
+
+#endif \ No newline at end of file
diff --git a/examples/embedded/lightmaps/lightmaps.pro b/examples/embedded/lightmaps/lightmaps.pro
new file mode 100644
index 0000000000..2751c3a647
--- /dev/null
+++ b/examples/embedded/lightmaps/lightmaps.pro
@@ -0,0 +1,21 @@
+TEMPLATE = app
+HEADERS = lightmaps.h \
+ mapzoom.h \
+ slippymap.h
+SOURCES = lightmaps.cpp \
+ main.cpp \
+ mapzoom.cpp \
+ slippymap.cpp
+QT += network
+
+symbian {
+ TARGET.UID3 = 0xA000CF75
+ CONFIG += qt_demo
+ TARGET.CAPABILITY = NetworkServices
+ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
+}
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/lightmaps
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/lightmaps
+INSTALLS += target sources
diff --git a/examples/embedded/lightmaps/main.cpp b/examples/embedded/lightmaps/main.cpp
new file mode 100644
index 0000000000..85f74e638e
--- /dev/null
+++ b/examples/embedded/lightmaps/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "mapzoom.h"
+
+int main(int argc, char **argv)
+{
+#if defined(Q_WS_X11)
+ QApplication::setGraphicsSystem("raster");
+#endif
+
+ QApplication app(argc, argv);
+ app.setApplicationName("LightMaps");
+
+ MapZoom w;
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ w.showMaximized();
+#else
+ w.resize(600, 450);
+ w.show();
+#endif
+
+ return app.exec();
+}
diff --git a/examples/embedded/lightmaps/mapzoom.cpp b/examples/embedded/lightmaps/mapzoom.cpp
new file mode 100644
index 0000000000..d01457e3f4
--- /dev/null
+++ b/examples/embedded/lightmaps/mapzoom.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtNetwork>
+#include "lightmaps.h"
+#include "mapzoom.h"
+
+MapZoom::MapZoom()
+ : QMainWindow(0)
+{
+ map = new LightMaps(this);
+ setCentralWidget(map);
+ map->setFocus();
+
+ QAction *osloAction = new QAction(tr("&Oslo"), this);
+ QAction *berlinAction = new QAction(tr("&Berlin"), this);
+ QAction *jakartaAction = new QAction(tr("&Jakarta"), this);
+ QAction *nightModeAction = new QAction(tr("Night Mode"), this);
+ nightModeAction->setCheckable(true);
+ nightModeAction->setChecked(false);
+ QAction *osmAction = new QAction(tr("About OpenStreetMap"), this);
+ connect(osloAction, SIGNAL(triggered()), SLOT(chooseOslo()));
+ connect(berlinAction, SIGNAL(triggered()), SLOT(chooseBerlin()));
+ connect(jakartaAction, SIGNAL(triggered()), SLOT(chooseJakarta()));
+ connect(nightModeAction, SIGNAL(triggered()), map, SLOT(toggleNightMode()));
+ connect(osmAction, SIGNAL(triggered()), SLOT(aboutOsm()));
+
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ menuBar()->addAction(osloAction);
+ menuBar()->addAction(berlinAction);
+ menuBar()->addAction(jakartaAction);
+ menuBar()->addAction(nightModeAction);
+ menuBar()->addAction(osmAction);
+#else
+ QMenu *menu = menuBar()->addMenu(tr("&Options"));
+ menu->addAction(osloAction);
+ menu->addAction(berlinAction);
+ menu->addAction(jakartaAction);
+ menu->addSeparator();
+ menu->addAction(nightModeAction);
+ menu->addAction(osmAction);
+#endif
+
+ QNetworkConfigurationManager manager;
+ if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
+ // Get saved network configuration
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QtNetwork"));
+ const QString id =
+ settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
+ settings.endGroup();
+
+ // If the saved network configuration is not currently discovered use the system
+ // default
+ QNetworkConfiguration config = manager.configurationFromIdentifier(id);
+ if ((config.state() & QNetworkConfiguration::Discovered) !=
+ QNetworkConfiguration::Discovered) {
+ config = manager.defaultConfiguration();
+ }
+
+ networkSession = new QNetworkSession(config, this);
+ connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
+
+ networkSession->open();
+ } else {
+ networkSession = 0;
+ }
+
+ setWindowTitle(tr("Light Maps"));
+}
+
+void MapZoom::sessionOpened()
+{
+ // Save the used configuration
+ QNetworkConfiguration config = networkSession->configuration();
+ QString id;
+ if (config.type() == QNetworkConfiguration::UserChoice) {
+ id = networkSession->sessionProperty(
+ QLatin1String("UserChoiceConfiguration")).toString();
+ } else {
+ id = config.identifier();
+ }
+
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QtNetwork"));
+ settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
+ settings.endGroup();
+}
+
+void MapZoom::chooseOslo()
+{
+ map->setCenter(59.9138204, 10.7387413);
+}
+
+void MapZoom::chooseBerlin()
+{
+ map->setCenter(52.52958999943302, 13.383053541183472);
+}
+
+void MapZoom::chooseJakarta()
+{
+ map->setCenter(-6.211544, 106.845172);
+}
+
+void MapZoom::aboutOsm()
+{
+ QDesktopServices::openUrl(QUrl("http://www.openstreetmap.org"));
+}
diff --git a/examples/embedded/lightmaps/mapzoom.h b/examples/embedded/lightmaps/mapzoom.h
new file mode 100644
index 0000000000..ac70a23316
--- /dev/null
+++ b/examples/embedded/lightmaps/mapzoom.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAPZOOM_H
+#define MAPZOOM_H
+
+#include <QMainWindow>
+
+class QNetworkSession;
+class LightMaps;
+
+class MapZoom : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MapZoom();
+
+private slots:
+ void sessionOpened();
+ void chooseOslo();
+ void chooseBerlin();
+ void chooseJakarta();
+ void aboutOsm();
+
+private:
+ LightMaps *map;
+ QNetworkSession *networkSession;
+};
+
+#endif \ No newline at end of file
diff --git a/examples/embedded/lightmaps/slippymap.cpp b/examples/embedded/lightmaps/slippymap.cpp
new file mode 100644
index 0000000000..8c71f2946a
--- /dev/null
+++ b/examples/embedded/lightmaps/slippymap.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <math.h>
+
+#include <QtGui>
+#include <QtNetwork>
+#include "slippymap.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+uint qHash(const QPoint& p)
+{
+ return p.x() * 17 ^ p.y();
+}
+
+// tile size in pixels
+const int tdim = 256;
+
+QPointF tileForCoordinate(qreal lat, qreal lng, int zoom)
+{
+ qreal zn = static_cast<qreal>(1 << zoom);
+ qreal tx = (lng + 180.0) / 360.0;
+ qreal ty = (1.0 - log(tan(lat * M_PI / 180.0) +
+ 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0;
+ return QPointF(tx * zn, ty * zn);
+}
+
+qreal longitudeFromTile(qreal tx, int zoom)
+{
+ qreal zn = static_cast<qreal>(1 << zoom);
+ qreal lat = tx / zn * 360.0 - 180.0;
+ return lat;
+}
+
+qreal latitudeFromTile(qreal ty, int zoom)
+{
+ qreal zn = static_cast<qreal>(1 << zoom);
+ qreal n = M_PI - 2 * M_PI * ty / zn;
+ qreal lng = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
+ return lng;
+}
+
+
+SlippyMap::SlippyMap(QObject *parent)
+ : QObject(parent), width(400), height(300), zoom(15),
+ latitude(59.9138204), longitude(10.7387413)
+{
+ m_emptyTile = QPixmap(tdim, tdim);
+ m_emptyTile.fill(Qt::lightGray);
+
+ QNetworkDiskCache *cache = new QNetworkDiskCache;
+ cache->setCacheDirectory(QDesktopServices::storageLocation
+ (QDesktopServices::CacheLocation));
+ m_manager.setCache(cache);
+ connect(&m_manager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(handleNetworkData(QNetworkReply*)));
+}
+
+void SlippyMap::invalidate()
+{
+ if (width <= 0 || height <= 0)
+ return;
+
+ QPointF ct = tileForCoordinate(latitude, longitude, zoom);
+ qreal tx = ct.x();
+ qreal ty = ct.y();
+
+ // top-left corner of the center tile
+ int xp = width / 2 - (tx - floor(tx)) * tdim;
+ int yp = height / 2 - (ty - floor(ty)) * tdim;
+
+ // first tile vertical and horizontal
+ int xa = (xp + tdim - 1) / tdim;
+ int ya = (yp + tdim - 1) / tdim;
+ int xs = static_cast<int>(tx) - xa;
+ int ys = static_cast<int>(ty) - ya;
+
+ // offset for top-left tile
+ m_offset = QPoint(xp - xa * tdim, yp - ya * tdim);
+
+ // last tile vertical and horizontal
+ int xe = static_cast<int>(tx) + (width - xp - 1) / tdim;
+ int ye = static_cast<int>(ty) + (height - yp - 1) / tdim;
+
+ // build a rect
+ m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1);
+
+ if (m_url.isEmpty())
+ download();
+
+ emit updated(QRect(0, 0, width, height));
+}
+
+void SlippyMap::render(QPainter *p, const QRect &rect)
+{
+ for (int x = 0; x <= m_tilesRect.width(); ++x)
+ for (int y = 0; y <= m_tilesRect.height(); ++y) {
+ QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top());
+ QRect box = tileRect(tp);
+ if (rect.intersects(box)) {
+ if (m_tilePixmaps.contains(tp))
+ p->drawPixmap(box, m_tilePixmaps.value(tp));
+ else
+ p->drawPixmap(box, m_emptyTile);
+ }
+ }
+}
+
+void SlippyMap::pan(const QPoint &delta)
+{
+ QPointF dx = QPointF(delta) / qreal(tdim);
+ QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx;
+ latitude = latitudeFromTile(center.y(), zoom);
+ longitude = longitudeFromTile(center.x(), zoom);
+ invalidate();
+}
+
+void SlippyMap::handleNetworkData(QNetworkReply *reply)
+{
+ QImage img;
+ QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint();
+ QUrl url = reply->url();
+ if (!reply->error())
+ if (!img.load(reply, 0))
+ img = QImage();
+ reply->deleteLater();
+ m_tilePixmaps[tp] = QPixmap::fromImage(img);
+ if (img.isNull())
+ m_tilePixmaps[tp] = m_emptyTile;
+ emit updated(tileRect(tp));
+
+ // purge unused spaces
+ QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2);
+ foreach(QPoint tp, m_tilePixmaps.keys())
+ if (!bound.contains(tp))
+ m_tilePixmaps.remove(tp);
+
+ download();
+}
+
+void SlippyMap::download()
+{
+ QPoint grab(0, 0);
+ for (int x = 0; x <= m_tilesRect.width(); ++x)
+ for (int y = 0; y <= m_tilesRect.height(); ++y) {
+ QPoint tp = m_tilesRect.topLeft() + QPoint(x, y);
+ if (!m_tilePixmaps.contains(tp)) {
+ grab = tp;
+ break;
+ }
+ }
+ if (grab == QPoint(0, 0)) {
+ m_url = QUrl();
+ return;
+ }
+
+ QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
+ m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y()));
+ QNetworkRequest request;
+ request.setUrl(m_url);
+ request.setRawHeader("User-Agent", "Nokia (Qt) Graphics Dojo 1.0");
+ request.setAttribute(QNetworkRequest::User, QVariant(grab));
+ m_manager.get(request);
+}
+
+QRect SlippyMap::tileRect(const QPoint &tp)
+{
+ QPoint t = tp - m_tilesRect.topLeft();
+ int x = t.x() * tdim + m_offset.x();
+ int y = t.y() * tdim + m_offset.y();
+ return QRect(x, y, tdim, tdim);
+}
diff --git a/examples/embedded/lightmaps/slippymap.h b/examples/embedded/lightmaps/slippymap.h
new file mode 100644
index 0000000000..64ba5c3e59
--- /dev/null
+++ b/examples/embedded/lightmaps/slippymap.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SLIPPYMAP_H
+#define SLIPPYMAP_H
+
+#include <QNetworkAccessManager>
+#include <QPixmap>
+#include <QUrl>
+
+class QNetworkReply;
+class QPainter;
+
+class SlippyMap: public QObject
+{
+ Q_OBJECT
+
+public:
+ SlippyMap(QObject *parent = 0);
+ void invalidate();
+ void render(QPainter *p, const QRect &rect);
+ void pan(const QPoint &delta);
+
+ int width;
+ int height;
+ int zoom;
+ qreal latitude;
+ qreal longitude;
+
+signals:
+ void updated(const QRect &rect);
+
+private slots:
+ void handleNetworkData(QNetworkReply *reply);
+ void download();
+
+protected:
+ QRect tileRect(const QPoint &tp);
+
+private:
+ QPoint m_offset;
+ QRect m_tilesRect;
+ QPixmap m_emptyTile;
+ QHash<QPoint, QPixmap> m_tilePixmaps;
+ QNetworkAccessManager m_manager;
+ QUrl m_url;
+};
+
+#endif \ No newline at end of file
diff --git a/examples/embedded/raycasting/raycasting.cpp b/examples/embedded/raycasting/raycasting.cpp
new file mode 100644
index 0000000000..d404044a9a
--- /dev/null
+++ b/examples/embedded/raycasting/raycasting.cpp
@@ -0,0 +1,391 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtGui>
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define WORLD_SIZE 8
+int world_map[WORLD_SIZE][WORLD_SIZE] = {
+ { 1, 1, 1, 1, 6, 1, 1, 1 },
+ { 1, 0, 0, 1, 0, 0, 0, 7 },
+ { 1, 1, 0, 1, 0, 1, 1, 1 },
+ { 6, 0, 0, 0, 0, 0, 0, 3 },
+ { 1, 8, 8, 0, 8, 0, 8, 1 },
+ { 2, 2, 0, 0, 8, 8, 7, 1 },
+ { 3, 0, 0, 0, 0, 0, 0, 5 },
+ { 2, 2, 2, 2, 7, 4, 4, 4 },
+};
+
+#define TEXTURE_SIZE 64
+#define TEXTURE_BLOCK (TEXTURE_SIZE * TEXTURE_SIZE)
+
+class Raycasting: public QWidget
+{
+public:
+ Raycasting(QWidget *parent = 0)
+ : QWidget(parent)
+ , angle(0.5)
+ , playerPos(1.5, 1.5)
+ , angleDelta(0)
+ , moveDelta(0)
+ , touchDevice(false) {
+
+ // http://www.areyep.com/RIPandMCS-TextureLibrary.html
+ textureImg.load(":/textures.png");
+ textureImg = textureImg.convertToFormat(QImage::Format_ARGB32);
+ Q_ASSERT(textureImg.width() == TEXTURE_SIZE * 2);
+ Q_ASSERT(textureImg.bytesPerLine() == 4 * TEXTURE_SIZE * 2);
+ textureCount = textureImg.height() / TEXTURE_SIZE;
+
+ watch.start();
+ ticker.start(25, this);
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setMouseTracking(false);
+ }
+
+ void updatePlayer() {
+ int interval = qBound(20, watch.elapsed(), 250);
+ watch.start();
+ angle += angleDelta * interval / 1000;
+ qreal step = moveDelta * interval / 1000;
+ qreal dx = cos(angle) * step;
+ qreal dy = sin(angle) * step;
+ QPointF pos = playerPos + 3 * QPointF(dx, dy);
+ int xi = static_cast<int>(pos.x());
+ int yi = static_cast<int>(pos.y());
+ if (world_map[yi][xi] == 0)
+ playerPos = playerPos + QPointF(dx, dy);
+ }
+
+ void showFps() {
+ static QTime frameTick;
+ static int totalFrame = 0;
+ if (!(totalFrame & 31)) {
+ int elapsed = frameTick.elapsed();
+ frameTick.start();
+ int fps = 32 * 1000 / (1 + elapsed);
+ setWindowTitle(QString("Raycasting (%1 FPS)").arg(fps));
+ }
+ totalFrame++;
+ }
+
+ void render() {
+
+ // setup the screen surface
+ if (buffer.size() != bufferSize)
+ buffer = QImage(bufferSize, QImage::Format_ARGB32);
+ int bufw = buffer.width();
+ int bufh = buffer.height();
+ if (bufw <= 0 || bufh <= 0)
+ return;
+
+ // we intentionally cheat here, to avoid detach
+ const uchar *ptr = buffer.bits();
+ QRgb *start = (QRgb*)(ptr);
+ QRgb stride = buffer.bytesPerLine() / 4;
+ QRgb *finish = start + stride * bufh;
+
+ // prepare the texture pointer
+ const uchar *src = textureImg.bits();
+ const QRgb *texsrc = reinterpret_cast<const QRgb*>(src);
+
+ // cast all rays here
+ qreal sina = sin(angle);
+ qreal cosa = cos(angle);
+ qreal u = cosa - sina;
+ qreal v = sina + cosa;
+ qreal du = 2 * sina / bufw;
+ qreal dv = -2 * cosa / bufw;
+
+ for (int ray = 0; ray < bufw; ++ray, u += du, v += dv) {
+ // every time this ray advances 'u' units in x direction,
+ // it also advanced 'v' units in y direction
+ qreal uu = (u < 0) ? -u : u;
+ qreal vv = (v < 0) ? -v : v;
+ qreal duu = 1 / uu;
+ qreal dvv = 1 / vv;
+ int stepx = (u < 0) ? -1 : 1;
+ int stepy = (v < 0) ? -1 : 1;
+
+ // the cell in the map that we need to check
+ qreal px = playerPos.x();
+ qreal py = playerPos.y();
+ int mapx = static_cast<int>(px);
+ int mapy = static_cast<int>(py);
+
+ // the position and texture for the hit
+ int texture = 0;
+ qreal hitdist = 0.1;
+ qreal texofs = 0;
+ bool dark = false;
+
+ // first hit at constant x and constant y lines
+ qreal distx = (u > 0) ? (mapx + 1 - px) * duu : (px - mapx) * duu;
+ qreal disty = (v > 0) ? (mapy + 1 - py) * dvv : (py - mapy) * dvv;
+
+ // loop until we hit something
+ while (texture <= 0) {
+ if (distx > disty) {
+ // shorter distance to a hit in constant y line
+ hitdist = disty;
+ disty += dvv;
+ mapy += stepy;
+ texture = world_map[mapy][mapx];
+ if (texture > 0) {
+ dark = true;
+ if (stepy > 0) {
+ qreal ofs = px + u * (mapy - py) / v;
+ texofs = ofs - floor(ofs);
+ } else {
+ qreal ofs = px + u * (mapy + 1 - py) / v;
+ texofs = ofs - floor(ofs);
+ }
+ }
+ } else {
+ // shorter distance to a hit in constant x line
+ hitdist = distx;
+ distx += duu;
+ mapx += stepx;
+ texture = world_map[mapy][mapx];
+ if (texture > 0) {
+ if (stepx > 0) {
+ qreal ofs = py + v * (mapx - px) / u;
+ texofs = ofs - floor(ofs);
+ } else {
+ qreal ofs = py + v * (mapx + 1 - px) / u;
+ texofs = ceil(ofs) - ofs;
+ }
+ }
+ }
+ }
+
+ // get the texture, note that the texture image
+ // has two textures horizontally, "normal" vs "dark"
+ int col = static_cast<int>(texofs * TEXTURE_SIZE);
+ col = qBound(0, col, TEXTURE_SIZE - 1);
+ texture = (texture - 1) % textureCount;
+ const QRgb *tex = texsrc + TEXTURE_BLOCK * texture * 2 +
+ (TEXTURE_SIZE * 2 * col);
+ if (dark)
+ tex += TEXTURE_SIZE;
+
+ // start from the texture center (horizontally)
+ int h = static_cast<int>(bufw / hitdist / 2);
+ int dy = (TEXTURE_SIZE << 12) / h;
+ int p1 = ((TEXTURE_SIZE / 2) << 12) - dy;
+ int p2 = p1 + dy;
+
+ // start from the screen center (vertically)
+ // y1 will go up (decrease), y2 will go down (increase)
+ int y1 = bufh / 2;
+ int y2 = y1 + 1;
+ QRgb *pixel1 = start + y1 * stride + ray;
+ QRgb *pixel2 = pixel1 + stride;
+
+ // map the texture to the sliver
+ while (y1 >= 0 && y2 < bufh && p1 >= 0) {
+ *pixel1 = tex[p1 >> 12];
+ *pixel2 = tex[p2 >> 12];
+ p1 -= dy;
+ p2 += dy;
+ --y1;
+ ++y2;
+ pixel1 -= stride;
+ pixel2 += stride;
+ }
+
+ // ceiling and floor
+ for (; pixel1 > start; pixel1 -= stride)
+ *pixel1 = qRgb(0, 0, 0);
+ for (; pixel2 < finish; pixel2 += stride)
+ *pixel2 = qRgb(96, 96, 96);
+ }
+
+ update(QRect(QPoint(0, 0), bufferSize));
+ }
+
+protected:
+
+ void resizeEvent(QResizeEvent*) {
+#if defined(Q_OS_WINCE_WM)
+ touchDevice = true;
+#elif defined(Q_OS_SYMBIAN)
+ // FIXME: use HAL
+ if (width() > 480 || height() > 480)
+ touchDevice = true;
+#else
+ touchDevice = false;
+#endif
+ if (touchDevice) {
+ if (width() < height()) {
+ trackPad = QRect(0, height() / 2, width(), height() / 2);
+ centerPad = QPoint(width() / 2, height() * 3 / 4);
+ bufferSize = QSize(width(), height() / 2);
+ } else {
+ trackPad = QRect(width() / 2, 0, width() / 2, height());
+ centerPad = QPoint(width() * 3 / 4, height() / 2);
+ bufferSize = QSize(width() / 2, height());
+ }
+ } else {
+ trackPad = QRect();
+ bufferSize = size();
+ }
+ update();
+ }
+
+ void timerEvent(QTimerEvent*) {
+ updatePlayer();
+ render();
+ showFps();
+ }
+
+ void paintEvent(QPaintEvent *event) {
+ QPainter p(this);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+
+ p.drawImage(event->rect(), buffer, event->rect());
+
+ if (touchDevice && event->rect().intersects(trackPad)) {
+ p.fillRect(trackPad, Qt::white);
+ p.setPen(QPen(QColor(224, 224, 224), 6));
+ int rad = qMin(trackPad.width(), trackPad.height()) * 0.3;
+ p.drawEllipse(centerPad, rad, rad);
+
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::gray);
+
+ QPolygon poly;
+ poly << QPoint(-30, 0);
+ poly << QPoint(0, -40);
+ poly << QPoint(30, 0);
+
+ p.translate(centerPad);
+ for (int i = 0; i < 4; ++i) {
+ p.rotate(90);
+ p.translate(0, 20 - rad);
+ p.drawPolygon(poly);
+ p.translate(0, rad - 20);
+ }
+ }
+
+ p.end();
+ }
+
+ void keyPressEvent(QKeyEvent *event) {
+ event->accept();
+ if (event->key() == Qt::Key_Left)
+ angleDelta = 1.3 * M_PI;
+ if (event->key() == Qt::Key_Right)
+ angleDelta = -1.3 * M_PI;
+ if (event->key() == Qt::Key_Up)
+ moveDelta = 2.5;
+ if (event->key() == Qt::Key_Down)
+ moveDelta = -2.5;
+ }
+
+ void keyReleaseEvent(QKeyEvent *event) {
+ event->accept();
+ if (event->key() == Qt::Key_Left)
+ angleDelta = (angleDelta > 0) ? 0 : angleDelta;
+ if (event->key() == Qt::Key_Right)
+ angleDelta = (angleDelta < 0) ? 0 : angleDelta;
+ if (event->key() == Qt::Key_Up)
+ moveDelta = (moveDelta > 0) ? 0 : moveDelta;
+ if (event->key() == Qt::Key_Down)
+ moveDelta = (moveDelta < 0) ? 0 : moveDelta;
+ }
+
+ void mousePressEvent(QMouseEvent *event) {
+ qreal dx = centerPad.x() - event->pos().x();
+ qreal dy = centerPad.y() - event->pos().y();
+ angleDelta = dx * 2 * M_PI / width();
+ moveDelta = dy * 10 / height();
+ }
+
+ void mouseMoveEvent(QMouseEvent *event) {
+ qreal dx = centerPad.x() - event->pos().x();
+ qreal dy = centerPad.y() - event->pos().y();
+ angleDelta = dx * 2 * M_PI / width();
+ moveDelta = dy * 10 / height();
+ }
+
+ void mouseReleaseEvent(QMouseEvent*) {
+ angleDelta = 0;
+ moveDelta = 0;
+ }
+
+private:
+ QTime watch;
+ QBasicTimer ticker;
+ QImage buffer;
+ qreal angle;
+ QPointF playerPos;
+ qreal angleDelta;
+ qreal moveDelta;
+ QImage textureImg;
+ int textureCount;
+ bool touchDevice;
+ QRect trackPad;
+ QPoint centerPad;
+ QSize bufferSize;
+};
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ Raycasting w;
+ w.setWindowTitle("Raycasting");
+#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM)
+ w.showMaximized();
+#else
+ w.resize(640, 480);
+ w.show();
+#endif
+
+ return app.exec();
+}
diff --git a/examples/embedded/raycasting/raycasting.pro b/examples/embedded/raycasting/raycasting.pro
new file mode 100644
index 0000000000..a4bb1826b9
--- /dev/null
+++ b/examples/embedded/raycasting/raycasting.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+SOURCES = raycasting.cpp
+RESOURCES += raycasting.qrc
+
+symbian {
+ TARGET.UID3 = 0xA000CF76
+ CONFIG += qt_demo
+}
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/raycasting
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/raycasting
+INSTALLS += target sources
diff --git a/examples/embedded/raycasting/raycasting.qrc b/examples/embedded/raycasting/raycasting.qrc
new file mode 100644
index 0000000000..974a06093c
--- /dev/null
+++ b/examples/embedded/raycasting/raycasting.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>textures.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/embedded/raycasting/textures.png b/examples/embedded/raycasting/textures.png
new file mode 100644
index 0000000000..2eb1ba7ff6
--- /dev/null
+++ b/examples/embedded/raycasting/textures.png
Binary files differ
diff --git a/examples/embedded/styledemo/files/add.png b/examples/embedded/styledemo/files/add.png
new file mode 100755
index 0000000000..fc5c16d4c8
--- /dev/null
+++ b/examples/embedded/styledemo/files/add.png
Binary files differ
diff --git a/examples/embedded/styledemo/files/application.qss b/examples/embedded/styledemo/files/application.qss
new file mode 100644
index 0000000000..432fe6bc76
--- /dev/null
+++ b/examples/embedded/styledemo/files/application.qss
@@ -0,0 +1,125 @@
+QWidget#StyleWidget
+{
+ background-color: none;
+ background-image: url(icons:nature_1.jpg);
+}
+
+QLabel, QAbstractButton
+{
+ font: bold;
+ color: beige;
+}
+
+QAbstractButton
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(173,216,230,60%), stop:1 rgba(0,0,139,60%) );
+ border-color: black;
+ border-style: solid;
+ border-width: 3px;
+ border-radius: 6px;
+}
+
+QAbstractButton:pressed, QAbstractButton:checked
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
+}
+
+QSpinBox {
+ padding-left: 24px;
+ padding-right: 24px;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 5;
+ border-width: 3;
+}
+
+QSpinBox::up-button
+{
+ subcontrol-origin: padding;
+ subcontrol-position: right; /* position at the top right corner */
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+
+}
+
+QSpinBox::up-arrow
+{
+ image: url(icons:add.png);
+ width: 18px;
+ height: 18px;
+}
+
+
+QSpinBox::down-button
+{
+ subcontrol-origin: border;
+ subcontrol-position: left;
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+}
+
+QSpinBox::down-arrow
+{
+ image: url(icons:remove.png);
+ width: 18px;
+ height: 18px;
+}
+
+
+QScrollBar:horizontal
+{
+ border: 1px solid black;
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
+ height: 15px;
+ margin: 0px 20px 0 20px;
+}
+
+QScrollBar::handle:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ min-width: 20px;
+}
+
+QScrollBar::add-line:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ width: 20px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ width: 20px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal
+{
+ border: none;
+ width: 16px;
+ height: 16px;
+}
+
+QScrollBar:left-arrow:horizontal
+{
+ image: url(icons:add.png)
+}
+
+QScrollBar::right-arrow:horizontal
+{
+ image: url(icons:remove.png)
+}
+
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+ background: none;
+}
+
diff --git a/examples/embedded/styledemo/files/blue.qss b/examples/embedded/styledemo/files/blue.qss
new file mode 100644
index 0000000000..ac8671b5e4
--- /dev/null
+++ b/examples/embedded/styledemo/files/blue.qss
@@ -0,0 +1,38 @@
+*
+{
+ color: beige;
+}
+
+QLabel, QAbstractButton
+{
+ font: bold;
+ color: yellow;
+}
+
+QFrame
+{
+ background-color: rgba(96,96,255,60%);
+ border-color: rgb(32,32,196);
+ border-width: 3px;
+ border-style: solid;
+ border-radius: 5;
+ padding: 3px;
+}
+
+QAbstractButton
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
+ stop:0 lightblue, stop:0.5 darkblue);
+ border-width: 3px;
+ border-color: darkblue;
+ border-style: solid;
+ border-radius: 5;
+ padding: 3px;
+}
+
+QAbstractButton:pressed
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
+ stop:0.5 darkblue, stop:1 lightblue);
+ border-color: beige;
+}
diff --git a/examples/embedded/styledemo/files/khaki.qss b/examples/embedded/styledemo/files/khaki.qss
new file mode 100644
index 0000000000..b0d4a0fa6f
--- /dev/null
+++ b/examples/embedded/styledemo/files/khaki.qss
@@ -0,0 +1,99 @@
+
+QWidget#StartScreen, QWidget#MainWidget {
+ border: none;
+}
+
+QWidget#StartScreen, .QFrame {
+ background-color: beige;
+}
+
+QPushButton, QToolButton {
+ background-color: palegoldenrod;
+ border-width: 2px;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 5;
+ padding: 3px;
+ /* min-width: 96px; */
+ /* min-height: 48px; */
+}
+
+QPushButton:hover, QToolButton:hover {
+ background-color: khaki;
+}
+
+QPushButton:pressed, QToolButton:pressed {
+ padding-left: 5px;
+ padding-top: 5px;
+ background-color: #d0d67c;
+}
+
+QLabel, QAbstractButton {
+ font: italic "Times New Roman";
+}
+
+QFrame, QLabel#title {
+ border-width: 2px;
+ padding: 1px;
+ border-style: solid;
+ border-color: darkkhaki;
+ border-radius: 5px;
+}
+
+QFrame:focus {
+ border-width: 3px;
+ padding: 0px;
+}
+
+
+QLabel {
+ border: none;
+ padding: 0;
+ background: none;
+}
+
+QLabel#title {
+ font: 32px bold;
+}
+
+QSpinBox {
+ padding-left: 24px;
+ padding-right: 24px;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 5;
+ border-width: 3;
+}
+
+QSpinBox::up-button
+{
+ subcontrol-origin: padding;
+ subcontrol-position: right; /* position at the top right corner */
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+ border-image: url(:/files/spindownpng) 1;
+}
+
+QSpinBox::up-arrow {
+ image: url(:/files/add.png);
+ width: 12px;
+ height: 12px;
+ }
+
+
+QSpinBox::down-button
+{
+ subcontrol-origin: border;
+ subcontrol-position: left;
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+ border-image: url(:/files/spindownpng) 1;
+}
+
+QSpinBox::down-arrow {
+ image: url(:/files/remove.png);
+ width: 12px;
+ height: 12px;
+ }
diff --git a/examples/embedded/styledemo/files/nature_1.jpg b/examples/embedded/styledemo/files/nature_1.jpg
new file mode 100644
index 0000000000..3a04edb96a
--- /dev/null
+++ b/examples/embedded/styledemo/files/nature_1.jpg
Binary files differ
diff --git a/examples/embedded/styledemo/files/nostyle.qss b/examples/embedded/styledemo/files/nostyle.qss
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/examples/embedded/styledemo/files/nostyle.qss
diff --git a/examples/embedded/styledemo/files/remove.png b/examples/embedded/styledemo/files/remove.png
new file mode 100755
index 0000000000..a0ab1fa21a
--- /dev/null
+++ b/examples/embedded/styledemo/files/remove.png
Binary files differ
diff --git a/examples/embedded/styledemo/files/transparent.qss b/examples/embedded/styledemo/files/transparent.qss
new file mode 100644
index 0000000000..b38eb366f4
--- /dev/null
+++ b/examples/embedded/styledemo/files/transparent.qss
@@ -0,0 +1,139 @@
+QWidget#StyleWidget
+{
+ background-color: none;
+ background-image: url(:/files/nature_1.jpg);
+}
+
+QLabel, QAbstractButton
+{
+ color: beige;
+}
+
+QFrame, QLabel#title {
+ border-width: 2px;
+ padding: 1px;
+ border-style: solid;
+ border-color: black;
+ border-radius: 5px;
+}
+
+QFrame:focus {
+ border-width: 3px;
+ padding: 0px;
+}
+
+
+
+QAbstractButton
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(173,216,230,60%), stop:1 rgba(0,0,139,60%) );
+ border-color: black;
+ border-style: solid;
+ border-width: 3px;
+ border-radius: 6px;
+}
+
+QAbstractButton:pressed, QAbstractButton:checked
+{
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
+}
+
+QSpinBox {
+ padding-left: 24px;
+ padding-right: 24px;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 5;
+ border-width: 3;
+}
+
+QSpinBox::up-button
+{
+ subcontrol-origin: padding;
+ subcontrol-position: right; /* position at the top right corner */
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+
+}
+
+QSpinBox::up-arrow
+{
+ image: url(:/files/add.png);
+ width: 18px;
+ height: 18px;
+}
+
+
+QSpinBox::down-button
+{
+ subcontrol-origin: border;
+ subcontrol-position: left;
+ width: 24px;
+ height: 24px;
+ border-width: 3px;
+}
+
+QSpinBox::down-arrow
+{
+ image: url(:/files/remove.png);
+ width: 18px;
+ height: 18px;
+}
+
+
+QScrollBar:horizontal
+{
+ border: 1px solid black;
+ background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
+ height: 15px;
+ margin: 0px 20px 0 20px;
+}
+
+QScrollBar::handle:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ min-width: 20px;
+}
+
+QScrollBar::add-line:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ width: 20px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:horizontal
+{
+ border: 1px solid black;
+ background: rgba(0,0,139,60%);
+ width: 20px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal
+{
+ border: none;
+ width: 16px;
+ height: 16px;
+}
+
+QScrollBar:left-arrow:horizontal
+{
+ image: url(:/files/add.png)
+}
+
+QScrollBar::right-arrow:horizontal
+{
+ image: url(:/files/remove.png)
+}
+
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+ background: none;
+}
+
diff --git a/examples/embedded/styledemo/main.cpp b/examples/embedded/styledemo/main.cpp
new file mode 100644
index 0000000000..7a484b0365
--- /dev/null
+++ b/examples/embedded/styledemo/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QApplication>
+
+#include "stylewidget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Q_INIT_RESOURCE(styledemo);
+
+ app.setApplicationName("style");
+ app.setOrganizationName("Nokia");
+ app.setOrganizationDomain("com.nokia.qt");
+
+ StyleWidget widget;
+ widget.showFullScreen();
+
+ return app.exec();
+}
+
diff --git a/examples/embedded/styledemo/styledemo.pro b/examples/embedded/styledemo/styledemo.pro
new file mode 100644
index 0000000000..60700dd1df
--- /dev/null
+++ b/examples/embedded/styledemo/styledemo.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+
+# Input
+HEADERS += stylewidget.h
+FORMS += stylewidget.ui
+SOURCES += main.cpp stylewidget.cpp
+RESOURCES += styledemo.qrc
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/styledemo
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro *.html
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded/styledemo
+INSTALLS += target sources
+
+symbian {
+ TARGET.UID3 = 0xA000A63F
+ CONFIG += qt_demo
+}
diff --git a/examples/embedded/styledemo/styledemo.qrc b/examples/embedded/styledemo/styledemo.qrc
new file mode 100644
index 0000000000..96237d4203
--- /dev/null
+++ b/examples/embedded/styledemo/styledemo.qrc
@@ -0,0 +1,13 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>files/add.png</file>
+ <file>files/blue.qss</file>
+ <file>files/khaki.qss</file>
+ <file>files/nostyle.qss</file>
+ <file>files/transparent.qss</file>
+ <file>files/application.qss</file>
+ <file>files/nature_1.jpg</file>
+ <file>files/remove.png</file>
+</qresource>
+</RCC>
+
diff --git a/examples/embedded/styledemo/stylewidget.cpp b/examples/embedded/styledemo/stylewidget.cpp
new file mode 100644
index 0000000000..7bac8a84d7
--- /dev/null
+++ b/examples/embedded/styledemo/stylewidget.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QApplication>
+#include <QString>
+#include <QFile>
+
+#include "stylewidget.h"
+
+
+
+StyleWidget::StyleWidget(QWidget *parent)
+ : QFrame(parent)
+{
+ m_ui.setupUi(this);
+}
+
+
+void StyleWidget::on_close_clicked()
+{
+ close();
+}
+
+void StyleWidget::on_blueStyle_clicked()
+{
+ QFile styleSheet(":/files/blue.qss");
+
+ if (!styleSheet.open(QIODevice::ReadOnly)) {
+ qWarning("Unable to open :/files/blue.qss");
+ return;
+ }
+
+ qApp->setStyleSheet(styleSheet.readAll());
+}
+
+void StyleWidget::on_khakiStyle_clicked()
+{
+ QFile styleSheet(":/files/khaki.qss");
+
+ if (!styleSheet.open(QIODevice::ReadOnly)) {
+ qWarning("Unable to open :/files/khaki.qss");
+ return;
+ }
+
+ qApp->setStyleSheet(styleSheet.readAll());
+}
+
+
+void StyleWidget::on_noStyle_clicked()
+{
+ QFile styleSheet(":/files/nostyle.qss");
+
+ if (!styleSheet.open(QIODevice::ReadOnly)) {
+ qWarning("Unable to open :/files/nostyle.qss");
+ return;
+ }
+
+ qApp->setStyleSheet(styleSheet.readAll());
+}
+
+
+void StyleWidget::on_transparentStyle_clicked()
+{
+ QFile styleSheet(":/files/transparent.qss");
+
+ if (!styleSheet.open(QIODevice::ReadOnly)) {
+ qWarning("Unable to open :/files/transparent.qss");
+ return;
+ }
+
+ qApp->setStyleSheet(styleSheet.readAll());
+}
+
+
+
diff --git a/examples/embedded/styledemo/stylewidget.h b/examples/embedded/styledemo/stylewidget.h
new file mode 100644
index 0000000000..11fa5348de
--- /dev/null
+++ b/examples/embedded/styledemo/stylewidget.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef STYLEWIDGET_H
+#define STYLEWIDGET_H
+
+#include <QFrame>
+
+#include "ui_stylewidget.h"
+
+class StyleWidget : public QFrame
+{
+ Q_OBJECT
+public:
+ StyleWidget(QWidget *parent = 0);
+
+private:
+ Ui_StyleWidget m_ui;
+
+private slots:
+ void on_close_clicked();
+ void on_blueStyle_clicked();
+ void on_khakiStyle_clicked();
+ void on_noStyle_clicked();
+ void on_transparentStyle_clicked();
+};
+
+#endif
diff --git a/examples/embedded/styledemo/stylewidget.ui b/examples/embedded/styledemo/stylewidget.ui
new file mode 100644
index 0000000000..767f44aead
--- /dev/null
+++ b/examples/embedded/styledemo/stylewidget.ui
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StyleWidget</class>
+ <widget class="QWidget" name="StyleWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>184</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Styles</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QPushButton" name="transparentStyle">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Transp.</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="blueStyle">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Blue</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="khakiStyle">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Khaki</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="noStyle">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>None</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Value:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBox">
+ <property name="focusPolicy">
+ <enum>Qt::WheelFocus</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="keyboardTracking">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <widget class="QScrollBar" name="horizontalScrollBar">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QScrollBar" name="horizontalScrollBar_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QPushButton" name="pushButton_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Show</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QPushButton" name="pushButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Enable</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="0">
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="6" column="1">
+ <widget class="QPushButton" name="close">
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="StyleDemo.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>horizontalScrollBar</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>horizontalScrollBar_2</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>84</x>
+ <y>147</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>166</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>horizontalScrollBar_2</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>horizontalScrollBar</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>166</x>
+ <y>147</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>84</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pushButton</sender>
+ <signal>clicked(bool)</signal>
+ <receiver>horizontalScrollBar_2</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>166</x>
+ <y>175</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>166</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pushButton_2</sender>
+ <signal>clicked(bool)</signal>
+ <receiver>horizontalScrollBar</receiver>
+ <slot>setVisible(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>84</x>
+ <y>175</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>84</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>spinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>horizontalScrollBar_2</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>166</x>
+ <y>115</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>166</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>horizontalScrollBar_2</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>spinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>132</x>
+ <y>132</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>135</x>
+ <y>110</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/graphicsview/boxes/3rdparty/fbm.c b/examples/graphicsview/boxes/3rdparty/fbm.c
new file mode 100644
index 0000000000..98eb87a33b
--- /dev/null
+++ b/examples/graphicsview/boxes/3rdparty/fbm.c
@@ -0,0 +1,207 @@
+/*****************************************************************
+
+ Implementation of the fractional Brownian motion algorithm. These
+ functions were originally the work of F. Kenton Musgrave.
+ For documentation of the different functions please refer to the
+ book:
+ "Texturing and modeling: a procedural approach"
+ by David S. Ebert et. al.
+
+******************************************************************/
+
+#if defined (_MSC_VER)
+#include <qglobal.h>
+#endif
+
+#include <time.h>
+#include <stdlib.h>
+#include "fbm.h"
+
+#if defined(Q_CC_MSVC)
+#pragma warning(disable:4244)
+#endif
+
+/* Definitions used by the noise2() functions */
+
+//#define B 0x100
+//#define BM 0xff
+#define B 0x20
+#define BM 0x1f
+
+#define N 0x1000
+#define NP 12 /* 2^N */
+#define NM 0xfff
+
+static int p[B + B + 2];
+static float g3[B + B + 2][3];
+static float g2[B + B + 2][2];
+static float g1[B + B + 2];
+static int start = 1;
+
+static void init(void);
+
+#define s_curve(t) ( t * t * (3. - 2. * t) )
+
+#define lerp(t, a, b) ( a + t * (b - a) )
+
+#define setup(i,b0,b1,r0,r1)\
+ t = vec[i] + N;\
+ b0 = ((int)t) & BM;\
+ b1 = (b0+1) & BM;\
+ r0 = t - (int)t;\
+ r1 = r0 - 1.;
+#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
+
+/* Fractional Brownian Motion function */
+
+double fBm( Vector point, double H, double lacunarity, double octaves,
+ int init )
+{
+
+ double value, frequency, remainder;
+ int i;
+ static double exponent_array[10];
+ float vec[3];
+
+ /* precompute and store spectral weights */
+ if ( init ) {
+ start = 1;
+ srand( time(0) );
+ /* seize required memory for exponent_array */
+ frequency = 1.0;
+ for (i=0; i<=octaves; i++) {
+ /* compute weight for each frequency */
+ exponent_array[i] = pow( frequency, -H );
+ frequency *= lacunarity;
+ }
+ }
+
+ value = 0.0; /* initialize vars to proper values */
+ frequency = 1.0;
+ vec[0]=point.x;
+ vec[1]=point.y;
+ vec[2]=point.z;
+
+
+ /* inner loop of spectral construction */
+ for (i=0; i<octaves; i++) {
+ /* value += noise3( vec ) * exponent_array[i];*/
+ value += noise3( vec ) * exponent_array[i];
+ vec[0] *= lacunarity;
+ vec[1] *= lacunarity;
+ vec[2] *= lacunarity;
+ } /* for */
+
+ remainder = octaves - (int)octaves;
+ if ( remainder ) /* add in ``octaves'' remainder */
+ /* ``i'' and spatial freq. are preset in loop above */
+ value += remainder * noise3( vec ) * exponent_array[i];
+
+ return( value );
+
+} /* fBm() */
+
+
+float noise3(float vec[3])
+{
+ int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+ float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
+ register int i, j;
+
+ if (start) {
+ start = 0;
+ init();
+ }
+
+ setup(0, bx0,bx1, rx0,rx1);
+ setup(1, by0,by1, ry0,ry1);
+ setup(2, bz0,bz1, rz0,rz1);
+
+ i = p[ bx0 ];
+ j = p[ bx1 ];
+
+ b00 = p[ i + by0 ];
+ b10 = p[ j + by0 ];
+ b01 = p[ i + by1 ];
+ b11 = p[ j + by1 ];
+
+ t = s_curve(rx0);
+ sy = s_curve(ry0);
+ sz = s_curve(rz0);
+
+
+ q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
+ q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
+ a = lerp(t, u, v);
+
+ q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
+ q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
+ b = lerp(t, u, v);
+
+ c = lerp(sy, a, b);
+
+ q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
+ q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
+ a = lerp(t, u, v);
+
+ q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
+ q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
+ b = lerp(t, u, v);
+
+ d = lerp(sy, a, b);
+
+ return lerp(sz, c, d);
+}
+
+static void normalize2(float v[2])
+{
+ float s;
+
+ s = sqrt(v[0] * v[0] + v[1] * v[1]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+}
+
+static void normalize3(float v[3])
+{
+ float s;
+
+ s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ v[0] = v[0] / s;
+ v[1] = v[1] / s;
+ v[2] = v[2] / s;
+}
+
+static void init(void)
+{
+ int i, j, k;
+
+ for (i = 0 ; i < B ; i++) {
+ p[i] = i;
+
+ g1[i] = (float)((rand() % (B + B)) - B) / B;
+
+ for (j = 0 ; j < 2 ; j++)
+ g2[i][j] = (float)((rand() % (B + B)) - B) / B;
+ normalize2(g2[i]);
+
+ for (j = 0 ; j < 3 ; j++)
+ g3[i][j] = (float)((rand() % (B + B)) - B) / B;
+ normalize3(g3[i]);
+ }
+
+ while (--i) {
+ k = p[i];
+ p[i] = p[j = rand() % B];
+ p[j] = k;
+ }
+
+ for (i = 0 ; i < B + 2 ; i++) {
+ p[B + i] = p[i];
+ g1[B + i] = g1[i];
+ for (j = 0 ; j < 2 ; j++)
+ g2[B + i][j] = g2[i][j];
+ for (j = 0 ; j < 3 ; j++)
+ g3[B + i][j] = g3[i][j];
+ }
+}
diff --git a/examples/graphicsview/boxes/3rdparty/fbm.h b/examples/graphicsview/boxes/3rdparty/fbm.h
new file mode 100644
index 0000000000..b8a4a99ae4
--- /dev/null
+++ b/examples/graphicsview/boxes/3rdparty/fbm.h
@@ -0,0 +1,40 @@
+/*****************************************************************
+
+ Prototypes for the fractional Brownian motion algorithm. These
+ functions were originally the work of F. Kenton Musgrave. For
+ documentation of the different functions please refer to the book:
+ "Texturing and modeling: a procedural approach"
+ by David S. Ebert et. al.
+
+******************************************************************/
+
+#ifndef _fbm_h
+#define _fbm_h
+
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define TRUE 1
+//#define FALSE 0
+
+typedef struct {
+ double x;
+ double y;
+ double z;
+} Vector;
+
+float noise3(float vec[]);
+double fBm( Vector point, double H, double lacunarity, double octaves,
+ int init );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
diff --git a/examples/graphicsview/boxes/basic.fsh b/examples/graphicsview/boxes/basic.fsh
new file mode 100644
index 0000000000..faf3601606
--- /dev/null
+++ b/examples/graphicsview/boxes/basic.fsh
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform vec4 basicColor;
+
+void main()
+{
+ vec3 N = normalize(normal);
+ // assume directional light
+
+ gl_MaterialParameters M = gl_FrontMaterial;
+
+ float NdotL = dot(N, lightDirection.xyz);
+ float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);
+
+ vec3 absN = abs(gl_TexCoord[1].xyz);
+ vec3 texCoord;
+ if (absN.x > absN.y && absN.x > absN.z)
+ texCoord = gl_TexCoord[1].yzx;
+ else if (absN.y > absN.z)
+ texCoord = gl_TexCoord[1].zxy;
+ else
+ texCoord = gl_TexCoord[1].xyz;
+ texCoord.y *= -sign(texCoord.z);
+ texCoord += 0.5;
+
+ vec4 texColor = texture2D(tex, texCoord.xy);
+ vec4 unlitColor = gl_Color * mix(basicColor, vec4(texColor.xyz, 1.0), texColor.w);
+ gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+}
diff --git a/examples/graphicsview/boxes/basic.vsh b/examples/graphicsview/boxes/basic.vsh
new file mode 100644
index 0000000000..31acc4224a
--- /dev/null
+++ b/examples/graphicsview/boxes/basic.vsh
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform mat4 view;
+
+void main()
+{
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_Vertex;
+ specular = gl_LightSource[0].specular;
+ ambient = gl_LightSource[0].ambient;
+ diffuse = gl_LightSource[0].diffuse;
+ lightDirection = view * gl_LightSource[0].position;
+
+ normal = gl_NormalMatrix * gl_Normal;
+ position = (gl_ModelViewMatrix * gl_Vertex).xyz;
+
+ gl_FrontColor = gl_Color;
+ gl_Position = ftransform();
+}
diff --git a/examples/graphicsview/boxes/boxes.pro b/examples/graphicsview/boxes/boxes.pro
new file mode 100644
index 0000000000..d599a3a0ac
--- /dev/null
+++ b/examples/graphicsview/boxes/boxes.pro
@@ -0,0 +1,49 @@
+######################################################################
+# Automatically generated by qmake (2.01a) ma 3. nov 17:33:30 2008
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+HEADERS += 3rdparty/fbm.h \
+ glbuffers.h \
+ glextensions.h \
+ gltrianglemesh.h \
+ qtbox.h \
+ roundedbox.h \
+ scene.h \
+ trackball.h
+SOURCES += 3rdparty/fbm.c \
+ glbuffers.cpp \
+ glextensions.cpp \
+ main.cpp \
+ qtbox.cpp \
+ roundedbox.cpp \
+ scene.cpp \
+ trackball.cpp
+
+RESOURCES += boxes.qrc
+
+QT += opengl
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/boxes
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html *.jpg *.png *.fsh *.vsh *.par
+sources.files -= 3rdparty/fbm.h 3rdparty/fbm.c
+sources.files += 3rdparty
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/boxes
+INSTALLS += target sources
+
+wince*: {
+ DEPLOYMENT_PLUGIN += qjpeg
+}
+
+win32-msvc* {
+ QMAKE_CXXFLAGS -= -Zm200
+ QMAKE_CFLAGS -= -Zm200
+ QMAKE_CXXFLAGS += -Zm500
+ QMAKE_CFLAGS += -Zm500
+}
diff --git a/examples/graphicsview/boxes/boxes.qrc b/examples/graphicsview/boxes/boxes.qrc
new file mode 100644
index 0000000000..d27506dc5a
--- /dev/null
+++ b/examples/graphicsview/boxes/boxes.qrc
@@ -0,0 +1,25 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/boxes">
+ <file>cubemap_negx.jpg</file>
+ <file>cubemap_negy.jpg</file>
+ <file>cubemap_negz.jpg</file>
+ <file>cubemap_posx.jpg</file>
+ <file>cubemap_posy.jpg</file>
+ <file>cubemap_posz.jpg</file>
+ <file>square.jpg</file>
+ <file>basic.vsh</file>
+ <file>basic.fsh</file>
+ <file>dotted.fsh</file>
+ <file>fresnel.fsh</file>
+ <file>glass.fsh</file>
+ <file>granite.fsh</file>
+ <file>marble.fsh</file>
+ <file>reflection.fsh</file>
+ <file>refraction.fsh</file>
+ <file>wood.fsh</file>
+ <file>parameters.par</file>
+ <file>qt-logo.png</file>
+ <file>smiley.png</file>
+ <file>qt-logo.jpg</file>
+</qresource>
+</RCC>
diff --git a/examples/graphicsview/boxes/cubemap_negx.jpg b/examples/graphicsview/boxes/cubemap_negx.jpg
new file mode 100644
index 0000000000..07c282eab9
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_negx.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/cubemap_negy.jpg b/examples/graphicsview/boxes/cubemap_negy.jpg
new file mode 100644
index 0000000000..46cd2f9cf3
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_negy.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/cubemap_negz.jpg b/examples/graphicsview/boxes/cubemap_negz.jpg
new file mode 100644
index 0000000000..40c01ddff3
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_negz.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/cubemap_posx.jpg b/examples/graphicsview/boxes/cubemap_posx.jpg
new file mode 100644
index 0000000000..0b42e8a1b1
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_posx.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/cubemap_posy.jpg b/examples/graphicsview/boxes/cubemap_posy.jpg
new file mode 100644
index 0000000000..2aca9b1e98
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_posy.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/cubemap_posz.jpg b/examples/graphicsview/boxes/cubemap_posz.jpg
new file mode 100644
index 0000000000..2e49173848
--- /dev/null
+++ b/examples/graphicsview/boxes/cubemap_posz.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/dotted.fsh b/examples/graphicsview/boxes/dotted.fsh
new file mode 100644
index 0000000000..a9f1bcbefb
--- /dev/null
+++ b/examples/graphicsview/boxes/dotted.fsh
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+
+void main()
+{
+ vec3 N = normalize(normal);
+
+ gl_MaterialParameters M = gl_FrontMaterial;
+
+ // assume directional light
+ float NdotL = dot(N, lightDirection.xyz);
+ float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);
+
+ float r1 = length(fract(7.0 * gl_TexCoord[1].xyz) - 0.5);
+ float r2 = length(fract(5.0 * gl_TexCoord[1].xyz + 0.2) - 0.5);
+ float r3 = length(fract(11.0 * gl_TexCoord[1].xyz + 0.7) - 0.5);
+ vec4 rs = vec4(r1, r2, r3, 0.0);
+
+ vec4 unlitColor = gl_Color * (0.8 - clamp(10.0 * (0.4 - rs), 0.0, 0.2));
+ unlitColor.w = 1.0;
+ gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+}
diff --git a/examples/graphicsview/boxes/fresnel.fsh b/examples/graphicsview/boxes/fresnel.fsh
new file mode 100644
index 0000000000..462f9674f4
--- /dev/null
+++ b/examples/graphicsview/boxes/fresnel.fsh
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform samplerCube env;
+uniform mat4 view;
+uniform vec4 basicColor;
+
+void main()
+{
+ vec3 N = normalize(normal);
+ // assume directional light
+
+ gl_MaterialParameters M = gl_FrontMaterial;
+
+ float NdotL = dot(N, lightDirection.xyz);
+ float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);
+
+ vec3 absN = abs(gl_TexCoord[1].xyz);
+ vec3 texCoord;
+ if (absN.x > absN.y && absN.x > absN.z)
+ texCoord = gl_TexCoord[1].yzx;
+ else if (absN.y > absN.z)
+ texCoord = gl_TexCoord[1].zxy;
+ else
+ texCoord = gl_TexCoord[1].xyz;
+ texCoord.y *= -sign(texCoord.z);
+ texCoord += 0.5;
+
+ vec4 texColor = texture2D(tex, texCoord.xy);
+ vec4 unlitColor = gl_Color * mix(basicColor, vec4(texColor.xyz, 1.0), texColor.w);
+ vec4 litColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+
+ vec3 R = 2.0 * dot(-position, N) * N + position;
+ vec4 reflectedColor = textureCube(env, R * mat3(view[0].xyz, view[1].xyz, view[2].xyz));
+ gl_FragColor = mix(litColor, reflectedColor, 0.2 + 0.8 * pow(1.0 + dot(N, normalize(position)), 2.0));
+}
diff --git a/examples/graphicsview/boxes/glass.fsh b/examples/graphicsview/boxes/glass.fsh
new file mode 100644
index 0000000000..aeac2c2fed
--- /dev/null
+++ b/examples/graphicsview/boxes/glass.fsh
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform samplerCube env;
+uniform mat4 view;
+
+// Some arbitrary values
+// Arrays don't work here on glsl < 120, apparently.
+//const float coeffs[6] = float[6](1.0/4.0, 1.0/4.1, 1.0/4.2, 1.0/4.3, 1.0/4.4, 1.0/4.5);
+float coeffs(int i)
+{
+ return 1.0 / (3.0 + 0.1 * float(i));
+}
+
+void main()
+{
+ vec3 N = normalize(normal);
+ vec3 I = -normalize(position);
+ mat3 V = mat3(view[0].xyz, view[1].xyz, view[2].xyz);
+ float IdotN = dot(I, N);
+ float scales[6];
+ vec3 C[6];
+ for (int i = 0; i < 6; ++i) {
+ scales[i] = (IdotN - sqrt(1.0 - coeffs(i) + coeffs(i) * (IdotN * IdotN)));
+ C[i] = textureCube(env, (-I + coeffs(i) * N) * V).xyz;
+ }
+ vec4 refractedColor = 0.25 * vec4(C[5].x + 2.0*C[0].x + C[1].x, C[1].y + 2.0*C[2].y + C[3].y,
+ C[3].z + 2.0*C[4].z + C[5].z, 4.0);
+
+ vec3 R = 2.0 * dot(-position, N) * N + position;
+ vec4 reflectedColor = textureCube(env, R * V);
+
+ gl_FragColor = mix(refractedColor, reflectedColor, 0.4 + 0.6 * pow(1.0 - IdotN, 2.0));
+}
diff --git a/examples/graphicsview/boxes/glbuffers.cpp b/examples/graphicsview/boxes/glbuffers.cpp
new file mode 100644
index 0000000000..e12132b4cd
--- /dev/null
+++ b/examples/graphicsview/boxes/glbuffers.cpp
@@ -0,0 +1,402 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "glbuffers.h"
+#include <QtGui/qmatrix4x4.h>
+
+
+void qgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
+{
+ const GLdouble ymax = zNear * tan(fovy * M_PI / 360.0);
+ const GLdouble ymin = -ymax;
+ const GLdouble xmin = ymin * aspect;
+ const GLdouble xmax = ymax * aspect;
+ glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+//============================================================================//
+// GLTexture //
+//============================================================================//
+
+GLTexture::GLTexture() : m_texture(0), m_failed(false)
+{
+ glGenTextures(1, &m_texture);
+}
+
+GLTexture::~GLTexture()
+{
+ glDeleteTextures(1, &m_texture);
+}
+
+//============================================================================//
+// GLTexture2D //
+//============================================================================//
+
+GLTexture2D::GLTexture2D(int width, int height)
+{
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, 0);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+
+GLTexture2D::GLTexture2D(const QString& fileName, int width, int height)
+{
+ // TODO: Add error handling.
+ QImage image(fileName);
+
+ if (image.isNull()) {
+ m_failed = true;
+ return;
+ }
+
+ image = image.convertToFormat(QImage::Format_ARGB32);
+
+ //qDebug() << "Image size:" << image.width() << "x" << image.height();
+ if (width <= 0)
+ width = image.width();
+ if (height <= 0)
+ height = image.height();
+ if (width != image.width() || height != image.height())
+ image = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ // Works on x86, so probably works on all little-endian systems.
+ // Does it work on big-endian systems?
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, image.width(), image.height(), 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void GLTexture2D::load(int width, int height, QRgb *data)
+{
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void GLTexture2D::bind()
+{
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glEnable(GL_TEXTURE_2D);
+}
+
+void GLTexture2D::unbind()
+{
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+}
+
+
+//============================================================================//
+// GLTexture3D //
+//============================================================================//
+
+GLTexture3D::GLTexture3D(int width, int height, int depth)
+{
+ GLBUFFERS_ASSERT_OPENGL("GLTexture3D::GLTexture3D", glTexImage3D, return)
+
+ glBindTexture(GL_TEXTURE_3D, m_texture);
+ glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, 0);
+
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_3D, 0);
+}
+
+void GLTexture3D::load(int width, int height, int depth, QRgb *data)
+{
+ GLBUFFERS_ASSERT_OPENGL("GLTexture3D::load", glTexImage3D, return)
+
+ glBindTexture(GL_TEXTURE_3D, m_texture);
+ glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, data);
+ glBindTexture(GL_TEXTURE_3D, 0);
+}
+
+void GLTexture3D::bind()
+{
+ glBindTexture(GL_TEXTURE_3D, m_texture);
+ glEnable(GL_TEXTURE_3D);
+}
+
+void GLTexture3D::unbind()
+{
+ glBindTexture(GL_TEXTURE_3D, 0);
+ glDisable(GL_TEXTURE_3D);
+}
+
+//============================================================================//
+// GLTextureCube //
+//============================================================================//
+
+GLTextureCube::GLTextureCube(int size)
+{
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
+
+ for (int i = 0; i < 6; ++i)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 4, size, size, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, 0);
+
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+GLTextureCube::GLTextureCube(const QStringList& fileNames, int size)
+{
+ // TODO: Add error handling.
+
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
+
+ int index = 0;
+ foreach (QString file, fileNames) {
+ QImage image(file);
+ if (image.isNull()) {
+ m_failed = true;
+ break;
+ }
+
+ image = image.convertToFormat(QImage::Format_ARGB32);
+
+ //qDebug() << "Image size:" << image.width() << "x" << image.height();
+ if (size <= 0)
+ size = image.width();
+ if (size != image.width() || size != image.height())
+ image = image.scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+
+ // Works on x86, so probably works on all little-endian systems.
+ // Does it work on big-endian systems?
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, image.width(), image.height(), 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
+
+ if (++index == 6)
+ break;
+ }
+
+ // Clear remaining faces.
+ while (index < 6) {
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, size, size, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, 0);
+ ++index;
+ }
+
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+void GLTextureCube::load(int size, int face, QRgb *data)
+{
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, 4, size, size, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, data);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+void GLTextureCube::bind()
+{
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
+ glEnable(GL_TEXTURE_CUBE_MAP);
+}
+
+void GLTextureCube::unbind()
+{
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ glDisable(GL_TEXTURE_CUBE_MAP);
+}
+
+//============================================================================//
+// GLFrameBufferObject //
+//============================================================================//
+
+GLFrameBufferObject::GLFrameBufferObject(int width, int height)
+ : m_fbo(0)
+ , m_depthBuffer(0)
+ , m_width(width)
+ , m_height(height)
+ , m_failed(false)
+{
+ GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::GLFrameBufferObject",
+ glGenFramebuffersEXT && glGenRenderbuffersEXT && glBindRenderbufferEXT && glRenderbufferStorageEXT, return)
+
+ // TODO: share depth buffers of same size
+ glGenFramebuffersEXT(1, &m_fbo);
+ //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ glGenRenderbuffersEXT(1, &m_depthBuffer);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height);
+ //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
+ //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+}
+
+GLFrameBufferObject::~GLFrameBufferObject()
+{
+ GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::~GLFrameBufferObject",
+ glDeleteFramebuffersEXT && glDeleteRenderbuffersEXT, return)
+
+ glDeleteFramebuffersEXT(1, &m_fbo);
+ glDeleteRenderbuffersEXT(1, &m_depthBuffer);
+}
+
+void GLFrameBufferObject::setAsRenderTarget(bool state)
+{
+ GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::setAsRenderTarget", glBindFramebufferEXT, return)
+
+ if (state) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ glPushAttrib(GL_VIEWPORT_BIT);
+ glViewport(0, 0, m_width, m_height);
+ } else {
+ glPopAttrib();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+}
+
+bool GLFrameBufferObject::isComplete()
+{
+ GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::isComplete", glCheckFramebufferStatusEXT, return false)
+
+ return GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+}
+
+//============================================================================//
+// GLRenderTargetCube //
+//============================================================================//
+
+GLRenderTargetCube::GLRenderTargetCube(int size)
+ : GLTextureCube(size)
+ , m_fbo(size, size)
+{
+}
+
+void GLRenderTargetCube::begin(int face)
+{
+ GLBUFFERS_ASSERT_OPENGL("GLRenderTargetCube::begin",
+ glFramebufferTexture2DEXT && glFramebufferRenderbufferEXT, return)
+
+ m_fbo.setAsRenderTarget(true);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_texture, 0);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_fbo.m_depthBuffer);
+}
+
+void GLRenderTargetCube::end()
+{
+ m_fbo.setAsRenderTarget(false);
+}
+
+void GLRenderTargetCube::getViewMatrix(QMatrix4x4& mat, int face)
+{
+ if (face < 0 || face >= 6) {
+ qWarning("GLRenderTargetCube::getViewMatrix: 'face' must be in the range [0, 6). (face == %d)", face);
+ return;
+ }
+
+ static int perm[6][3] = {
+ {2, 1, 0},
+ {2, 1, 0},
+ {0, 2, 1},
+ {0, 2, 1},
+ {0, 1, 2},
+ {0, 1, 2},
+ };
+
+ static float signs[6][3] = {
+ {-1.0f, -1.0f, -1.0f},
+ {+1.0f, -1.0f, +1.0f},
+ {+1.0f, +1.0f, -1.0f},
+ {+1.0f, -1.0f, +1.0f},
+ {+1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, +1.0f},
+ };
+
+ mat.fill(0.0f);
+ for (int i = 0; i < 3; ++i)
+ mat(i, perm[face][i]) = signs[face][i];
+ mat(3, 3) = 1.0f;
+}
+
+void GLRenderTargetCube::getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ)
+{
+ static const QMatrix4x4 reference(
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f);
+
+ mat = reference;
+ mat(2, 2) = (nearZ+farZ)/(nearZ-farZ);
+ mat(2, 3) = 2.0f*nearZ*farZ/(nearZ-farZ);
+}
diff --git a/examples/graphicsview/boxes/glbuffers.h b/examples/graphicsview/boxes/glbuffers.h
new file mode 100644
index 0000000000..6b18d3f128
--- /dev/null
+++ b/examples/graphicsview/boxes/glbuffers.h
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLBUFFERS_H
+#define GLBUFFERS_H
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include <QtGui>
+#include <QtOpenGL>
+
+#define BUFFER_OFFSET(i) ((char*)0 + (i))
+#define SIZE_OF_MEMBER(cls, member) sizeof(static_cast<cls *>(0)->member)
+
+#define GLBUFFERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \
+if (m_failed || !(assertion)) { \
+ if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \
+ m_failed = true; \
+ returnStatement; \
+}
+
+void qgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
+
+QT_BEGIN_NAMESPACE
+class QMatrix4x4;
+QT_END_NAMESPACE
+
+class GLTexture
+{
+public:
+ GLTexture();
+ virtual ~GLTexture();
+ virtual void bind() = 0;
+ virtual void unbind() = 0;
+ virtual bool failed() const {return m_failed;}
+protected:
+ GLuint m_texture;
+ bool m_failed;
+};
+
+class GLFrameBufferObject
+{
+public:
+ friend class GLRenderTargetCube;
+ // friend class GLRenderTarget2D;
+
+ GLFrameBufferObject(int width, int height);
+ virtual ~GLFrameBufferObject();
+ bool isComplete();
+ virtual bool failed() const {return m_failed;}
+protected:
+ void setAsRenderTarget(bool state = true);
+ GLuint m_fbo;
+ GLuint m_depthBuffer;
+ int m_width, m_height;
+ bool m_failed;
+};
+
+class GLTexture2D : public GLTexture
+{
+public:
+ GLTexture2D(int width, int height);
+ GLTexture2D(const QString& fileName, int width = 0, int height = 0);
+ void load(int width, int height, QRgb *data);
+ virtual void bind();
+ virtual void unbind();
+};
+
+class GLTexture3D : public GLTexture
+{
+public:
+ GLTexture3D(int width, int height, int depth);
+ // TODO: Implement function below
+ //GLTexture3D(const QString& fileName, int width = 0, int height = 0);
+ void load(int width, int height, int depth, QRgb *data);
+ virtual void bind();
+ virtual void unbind();
+};
+
+class GLTextureCube : public GLTexture
+{
+public:
+ GLTextureCube(int size);
+ GLTextureCube(const QStringList& fileNames, int size = 0);
+ void load(int size, int face, QRgb *data);
+ virtual void bind();
+ virtual void unbind();
+};
+
+// TODO: Define and implement class below
+//class GLRenderTarget2D : public GLTexture2D
+
+class GLRenderTargetCube : public GLTextureCube
+{
+public:
+ GLRenderTargetCube(int size);
+ // begin rendering to one of the cube's faces. 0 <= face < 6
+ void begin(int face);
+ // end rendering
+ void end();
+ virtual bool failed() {return m_failed || m_fbo.failed();}
+
+ static void getViewMatrix(QMatrix4x4& mat, int face);
+ static void getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ);
+private:
+ GLFrameBufferObject m_fbo;
+};
+
+struct VertexDescription
+{
+ enum
+ {
+ Null = 0, // Terminates a VertexDescription array
+ Position,
+ TexCoord,
+ Normal,
+ Color,
+ };
+ int field; // Position, TexCoord, Normal, Color
+ int type; // GL_FLOAT, GL_UNSIGNED_BYTE
+ int count; // number of elements
+ int offset; // field's offset into vertex struct
+ int index; // 0 (unused at the moment)
+};
+
+// Implementation of interleaved buffers.
+// 'T' is a struct which must include a null-terminated static array
+// 'VertexDescription* description'.
+// Example:
+/*
+struct Vertex
+{
+ GLfloat position[3];
+ GLfloat texCoord[2];
+ GLfloat normal[3];
+ GLbyte color[4];
+ static VertexDescription description[];
+};
+
+VertexDescription Vertex::description[] = {
+ {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(Vertex, position) / sizeof(GLfloat), offsetof(Vertex, position), 0},
+ {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(Vertex, texCoord) / sizeof(GLfloat), offsetof(Vertex, texCoord), 0},
+ {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(Vertex, normal) / sizeof(GLfloat), offsetof(Vertex, normal), 0},
+ {VertexDescription::Color, GL_BYTE, SIZE_OF_MEMBER(Vertex, color) / sizeof(GLbyte), offsetof(Vertex, color), 0},
+ {VertexDescription::Null, 0, 0, 0, 0},
+};
+*/
+template<class T>
+class GLVertexBuffer
+{
+public:
+ GLVertexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
+ : m_length(0)
+ , m_mode(mode)
+ , m_buffer(0)
+ , m_failed(false)
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
+
+ glGenBuffers(1, &m_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
+ glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
+ }
+
+ ~GLVertexBuffer()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::~GLVertexBuffer", glDeleteBuffers, return)
+
+ glDeleteBuffers(1, &m_buffer);
+ }
+
+ void bind()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::bind", glBindBuffer, return)
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
+ for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
+ switch (desc->field) {
+ case VertexDescription::Position:
+ glVertexPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ break;
+ case VertexDescription::TexCoord:
+ glTexCoordPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ case VertexDescription::Normal:
+ glNormalPointer(desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
+ glEnableClientState(GL_NORMAL_ARRAY);
+ break;
+ case VertexDescription::Color:
+ glColorPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
+ glEnableClientState(GL_COLOR_ARRAY);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void unbind()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unbind", glBindBuffer, return)
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
+ switch (desc->field) {
+ case VertexDescription::Position:
+ glDisableClientState(GL_VERTEX_ARRAY);
+ break;
+ case VertexDescription::TexCoord:
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ case VertexDescription::Normal:
+ glDisableClientState(GL_NORMAL_ARRAY);
+ break;
+ case VertexDescription::Color:
+ glDisableClientState(GL_COLOR_ARRAY);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ int length() const {return m_length;}
+
+ T *lock()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
+ //glBufferData(GL_ARRAY_BUFFER, m_length, NULL, m_mode);
+ GLvoid* buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
+ m_failed = (buffer == 0);
+ return reinterpret_cast<T *>(buffer);
+ }
+
+ void unlock()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ }
+
+ bool failed()
+ {
+ return m_failed;
+ }
+
+private:
+ int m_length, m_mode;
+ GLuint m_buffer;
+ bool m_failed;
+};
+
+template<class T>
+class GLIndexBuffer
+{
+public:
+ GLIndexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
+ : m_length(0)
+ , m_mode(mode)
+ , m_buffer(0)
+ , m_failed(false)
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::GLIndexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
+
+ glGenBuffers(1, &m_buffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
+ }
+
+ ~GLIndexBuffer()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::~GLIndexBuffer", glDeleteBuffers, return)
+
+ glDeleteBuffers(1, &m_buffer);
+ }
+
+ void bind()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::bind", glBindBuffer, return)
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
+ }
+
+ void unbind()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unbind", glBindBuffer, return)
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+
+ int length() const {return m_length;}
+
+ T *lock()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
+ GLvoid* buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE);
+ m_failed = (buffer == 0);
+ return reinterpret_cast<T *>(buffer);
+ }
+
+ void unlock()
+ {
+ GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+ }
+
+ bool failed()
+ {
+ return m_failed;
+ }
+
+private:
+ int m_length, m_mode;
+ GLuint m_buffer;
+ bool m_failed;
+};
+
+#endif
diff --git a/examples/graphicsview/boxes/glextensions.cpp b/examples/graphicsview/boxes/glextensions.cpp
new file mode 100644
index 0000000000..b712efe38b
--- /dev/null
+++ b/examples/graphicsview/boxes/glextensions.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "glextensions.h"
+
+#define RESOLVE_GL_FUNC(f) ok &= bool((f = (_gl##f) context->getProcAddress(QLatin1String("gl" #f))));
+
+bool GLExtensionFunctions::resolve(const QGLContext *context)
+{
+ bool ok = true;
+
+ RESOLVE_GL_FUNC(GenFramebuffersEXT)
+ RESOLVE_GL_FUNC(GenRenderbuffersEXT)
+ RESOLVE_GL_FUNC(BindRenderbufferEXT)
+ RESOLVE_GL_FUNC(RenderbufferStorageEXT)
+ RESOLVE_GL_FUNC(DeleteFramebuffersEXT)
+ RESOLVE_GL_FUNC(DeleteRenderbuffersEXT)
+ RESOLVE_GL_FUNC(BindFramebufferEXT)
+ RESOLVE_GL_FUNC(FramebufferTexture2DEXT)
+ RESOLVE_GL_FUNC(FramebufferRenderbufferEXT)
+ RESOLVE_GL_FUNC(CheckFramebufferStatusEXT)
+
+ RESOLVE_GL_FUNC(ActiveTexture)
+ RESOLVE_GL_FUNC(TexImage3D)
+
+ RESOLVE_GL_FUNC(GenBuffers)
+ RESOLVE_GL_FUNC(BindBuffer)
+ RESOLVE_GL_FUNC(BufferData)
+ RESOLVE_GL_FUNC(DeleteBuffers)
+ RESOLVE_GL_FUNC(MapBuffer)
+ RESOLVE_GL_FUNC(UnmapBuffer)
+
+ return ok;
+}
+
+bool GLExtensionFunctions::fboSupported() {
+ return GenFramebuffersEXT
+ && GenRenderbuffersEXT
+ && BindRenderbufferEXT
+ && RenderbufferStorageEXT
+ && DeleteFramebuffersEXT
+ && DeleteRenderbuffersEXT
+ && BindFramebufferEXT
+ && FramebufferTexture2DEXT
+ && FramebufferRenderbufferEXT
+ && CheckFramebufferStatusEXT;
+}
+
+bool GLExtensionFunctions::openGL15Supported() {
+ return ActiveTexture
+ && TexImage3D
+ && GenBuffers
+ && BindBuffer
+ && BufferData
+ && DeleteBuffers
+ && MapBuffer
+ && UnmapBuffer;
+}
+
+#undef RESOLVE_GL_FUNC
diff --git a/examples/graphicsview/boxes/glextensions.h b/examples/graphicsview/boxes/glextensions.h
new file mode 100644
index 0000000000..54de548cd7
--- /dev/null
+++ b/examples/graphicsview/boxes/glextensions.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLEXTENSIONS_H
+#define GLEXTENSIONS_H
+
+#include <QtOpenGL>
+
+/*
+Functions resolved:
+
+glGenFramebuffersEXT
+glGenRenderbuffersEXT
+glBindRenderbufferEXT
+glRenderbufferStorageEXT
+glDeleteFramebuffersEXT
+glDeleteRenderbuffersEXT
+glBindFramebufferEXT
+glFramebufferTexture2DEXT
+glFramebufferRenderbufferEXT
+glCheckFramebufferStatusEXT
+
+glActiveTexture
+glTexImage3D
+
+glGenBuffers
+glBindBuffer
+glBufferData
+glDeleteBuffers
+glMapBuffer
+glUnmapBuffer
+*/
+
+#ifndef Q_WS_MAC
+# ifndef APIENTRYP
+# ifdef APIENTRY
+# define APIENTRYP APIENTRY *
+# else
+# define APIENTRY
+# define APIENTRYP *
+# endif
+# endif
+#else
+# define APIENTRY
+# define APIENTRYP *
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_BGRA 0x80E1
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_READ_WRITE 0x88BA
+#define GL_STATIC_DRAW 0x88E4
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#endif
+
+typedef void (APIENTRY *_glGenFramebuffersEXT) (GLsizei, GLuint *);
+typedef void (APIENTRY *_glGenRenderbuffersEXT) (GLsizei, GLuint *);
+typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum, GLuint);
+typedef void (APIENTRY *_glRenderbufferStorageEXT) (GLenum, GLenum, GLsizei, GLsizei);
+typedef void (APIENTRY *_glDeleteFramebuffersEXT) (GLsizei, const GLuint*);
+typedef void (APIENTRY *_glDeleteRenderbuffersEXT) (GLsizei, const GLuint*);
+typedef void (APIENTRY *_glBindFramebufferEXT) (GLenum, GLuint);
+typedef void (APIENTRY *_glFramebufferTexture2DEXT) (GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (APIENTRY *_glFramebufferRenderbufferEXT) (GLenum, GLenum, GLenum, GLuint);
+typedef GLenum (APIENTRY *_glCheckFramebufferStatusEXT) (GLenum);
+
+typedef void (APIENTRY *_glActiveTexture) (GLenum);
+typedef void (APIENTRY *_glTexImage3D) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+
+typedef void (APIENTRY *_glGenBuffers) (GLsizei, GLuint *);
+typedef void (APIENTRY *_glBindBuffer) (GLenum, GLuint);
+typedef void (APIENTRY *_glBufferData) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum);
+typedef void (APIENTRY *_glDeleteBuffers) (GLsizei, const GLuint *);
+typedef void *(APIENTRY *_glMapBuffer) (GLenum, GLenum);
+typedef GLboolean (APIENTRY *_glUnmapBuffer) (GLenum);
+
+struct GLExtensionFunctions
+{
+ bool resolve(const QGLContext *context);
+
+ bool fboSupported();
+ bool openGL15Supported(); // the rest: multi-texture, 3D-texture, vertex buffer objects
+
+ _glGenFramebuffersEXT GenFramebuffersEXT;
+ _glGenRenderbuffersEXT GenRenderbuffersEXT;
+ _glBindRenderbufferEXT BindRenderbufferEXT;
+ _glRenderbufferStorageEXT RenderbufferStorageEXT;
+ _glDeleteFramebuffersEXT DeleteFramebuffersEXT;
+ _glDeleteRenderbuffersEXT DeleteRenderbuffersEXT;
+ _glBindFramebufferEXT BindFramebufferEXT;
+ _glFramebufferTexture2DEXT FramebufferTexture2DEXT;
+ _glFramebufferRenderbufferEXT FramebufferRenderbufferEXT;
+ _glCheckFramebufferStatusEXT CheckFramebufferStatusEXT;
+
+ _glActiveTexture ActiveTexture;
+ _glTexImage3D TexImage3D;
+
+ _glGenBuffers GenBuffers;
+ _glBindBuffer BindBuffer;
+ _glBufferData BufferData;
+ _glDeleteBuffers DeleteBuffers;
+ _glMapBuffer MapBuffer;
+ _glUnmapBuffer UnmapBuffer;
+};
+
+inline GLExtensionFunctions &getGLExtensionFunctions()
+{
+ static GLExtensionFunctions funcs;
+ return funcs;
+}
+
+#define glGenFramebuffersEXT getGLExtensionFunctions().GenFramebuffersEXT
+#define glGenRenderbuffersEXT getGLExtensionFunctions().GenRenderbuffersEXT
+#define glBindRenderbufferEXT getGLExtensionFunctions().BindRenderbufferEXT
+#define glRenderbufferStorageEXT getGLExtensionFunctions().RenderbufferStorageEXT
+#define glDeleteFramebuffersEXT getGLExtensionFunctions().DeleteFramebuffersEXT
+#define glDeleteRenderbuffersEXT getGLExtensionFunctions().DeleteRenderbuffersEXT
+#define glBindFramebufferEXT getGLExtensionFunctions().BindFramebufferEXT
+#define glFramebufferTexture2DEXT getGLExtensionFunctions().FramebufferTexture2DEXT
+#define glFramebufferRenderbufferEXT getGLExtensionFunctions().FramebufferRenderbufferEXT
+#define glCheckFramebufferStatusEXT getGLExtensionFunctions().CheckFramebufferStatusEXT
+
+#define glActiveTexture getGLExtensionFunctions().ActiveTexture
+#define glTexImage3D getGLExtensionFunctions().TexImage3D
+
+#define glGenBuffers getGLExtensionFunctions().GenBuffers
+#define glBindBuffer getGLExtensionFunctions().BindBuffer
+#define glBufferData getGLExtensionFunctions().BufferData
+#define glDeleteBuffers getGLExtensionFunctions().DeleteBuffers
+#define glMapBuffer getGLExtensionFunctions().MapBuffer
+#define glUnmapBuffer getGLExtensionFunctions().UnmapBuffer
+
+#endif
diff --git a/examples/graphicsview/boxes/gltrianglemesh.h b/examples/graphicsview/boxes/gltrianglemesh.h
new file mode 100644
index 0000000000..ecf6531d85
--- /dev/null
+++ b/examples/graphicsview/boxes/gltrianglemesh.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLTRIANGLEMESH_H
+#define GLTRIANGLEMESH_H
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include <QtGui>
+#include <QtOpenGL>
+
+#include "glbuffers.h"
+
+template<class TVertex, class TIndex>
+class GLTriangleMesh
+{
+public:
+ GLTriangleMesh(int vertexCount, int indexCount) : m_vb(vertexCount), m_ib(indexCount)
+ {
+ }
+
+ virtual ~GLTriangleMesh()
+ {
+ }
+
+ virtual void draw()
+ {
+ if (failed())
+ return;
+
+ int type = GL_UNSIGNED_INT;
+ if (sizeof(TIndex) == sizeof(char)) type = GL_UNSIGNED_BYTE;
+ if (sizeof(TIndex) == sizeof(short)) type = GL_UNSIGNED_SHORT;
+
+ m_vb.bind();
+ m_ib.bind();
+ glDrawElements(GL_TRIANGLES, m_ib.length(), type, BUFFER_OFFSET(0));
+ m_vb.unbind();
+ m_ib.unbind();
+ }
+
+ bool failed()
+ {
+ return m_vb.failed() || m_ib.failed();
+ }
+protected:
+ GLVertexBuffer<TVertex> m_vb;
+ GLIndexBuffer<TIndex> m_ib;
+};
+
+
+#endif
diff --git a/examples/graphicsview/boxes/granite.fsh b/examples/graphicsview/boxes/granite.fsh
new file mode 100644
index 0000000000..abaeeb97bc
--- /dev/null
+++ b/examples/graphicsview/boxes/granite.fsh
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform sampler3D noise;
+
+//const vec4 graniteColors[3] = {vec4(0.0, 0.0, 0.0, 1), vec4(0.30, 0.15, 0.10, 1), vec4(0.80, 0.70, 0.75, 1)};
+uniform vec4 graniteColors[3];
+
+float steep(float x)
+{
+ return clamp(5.0 * x - 2.0, 0.0, 1.0);
+}
+
+void main()
+{
+ vec2 turbulence = vec2(0, 0);
+ float scale = 1.0;
+ for (int i = 0; i < 4; ++i) {
+ turbulence += scale * (texture3D(noise, gl_TexCoord[1].xyz / scale).xy - 0.5);
+ scale *= 0.5;
+ }
+
+ vec3 N = normalize(normal);
+ // assume directional light
+
+ gl_MaterialParameters M = gl_FrontMaterial;
+
+ float NdotL = dot(N, lightDirection.xyz);
+ float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);
+
+ vec4 unlitColor = mix(graniteColors[1], mix(graniteColors[0], graniteColors[2], steep(0.5 + turbulence.y)), 4.0 * abs(turbulence.x));
+ gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+}
diff --git a/examples/graphicsview/boxes/main.cpp b/examples/graphicsview/boxes/main.cpp
new file mode 100644
index 0000000000..483170801f
--- /dev/null
+++ b/examples/graphicsview/boxes/main.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include "scene.h"
+
+#include <QtGui>
+#include <QGLWidget>
+
+class GraphicsView : public QGraphicsView
+{
+public:
+ GraphicsView()
+ {
+ setWindowTitle(tr("Boxes"));
+ setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+ //setRenderHints(QPainter::SmoothPixmapTransform);
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *event) {
+ if (scene())
+ scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
+ QGraphicsView::resizeEvent(event);
+ }
+};
+
+inline bool matchString(const char *extensionString, const char *subString)
+{
+ int subStringLength = strlen(subString);
+ return (strncmp(extensionString, subString, subStringLength) == 0)
+ && ((extensionString[subStringLength] == ' ') || (extensionString[subStringLength] == '\0'));
+}
+
+bool necessaryExtensionsSupported()
+{
+ const char *extensionString = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ const char *p = extensionString;
+
+ const int GL_EXT_FBO = 1;
+ const int GL_ARB_VS = 2;
+ const int GL_ARB_FS = 4;
+ const int GL_ARB_SO = 8;
+ int extensions = 0;
+
+ while (*p) {
+ if (matchString(p, "GL_EXT_framebuffer_object"))
+ extensions |= GL_EXT_FBO;
+ else if (matchString(p, "GL_ARB_vertex_shader"))
+ extensions |= GL_ARB_VS;
+ else if (matchString(p, "GL_ARB_fragment_shader"))
+ extensions |= GL_ARB_FS;
+ else if (matchString(p, "GL_ARB_shader_objects"))
+ extensions |= GL_ARB_SO;
+ while ((*p != ' ') && (*p != '\0'))
+ ++p;
+ if (*p == ' ')
+ ++p;
+ }
+ return (extensions == 15);
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_5) == 0) {
+ QMessageBox::critical(0, "OpenGL features missing",
+ "OpenGL version 1.5 or higher is required to run this demo.\n"
+ "The program will now exit.");
+ return -1;
+ }
+
+ int maxTextureSize = 1024;
+ QGLWidget *widget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
+ widget->makeCurrent();
+
+ if (!necessaryExtensionsSupported()) {
+ QMessageBox::critical(0, "OpenGL features missing",
+ "The OpenGL extensions required to run this demo are missing.\n"
+ "The program will now exit.");
+ delete widget;
+ return -2;
+ }
+
+ // Check if all the necessary functions are resolved.
+ if (!getGLExtensionFunctions().resolve(widget->context())) {
+ QMessageBox::critical(0, "OpenGL features missing",
+ "Failed to resolve OpenGL functions required to run this demo.\n"
+ "The program will now exit.");
+ delete widget;
+ return -3;
+ }
+
+ // TODO: Make conditional for final release
+ QMessageBox::information(0, "For your information",
+ "This demo can be GPU and CPU intensive and may\n"
+ "work poorly or not at all on your system.");
+
+ widget->makeCurrent(); // The current context must be set before calling Scene's constructor
+ Scene scene(1024, 768, maxTextureSize);
+ GraphicsView view;
+ view.setViewport(widget);
+ view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+ view.setScene(&scene);
+ view.show();
+
+ return app.exec();
+}
+
diff --git a/examples/graphicsview/boxes/marble.fsh b/examples/graphicsview/boxes/marble.fsh
new file mode 100644
index 0000000000..170ec3abef
--- /dev/null
+++ b/examples/graphicsview/boxes/marble.fsh
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform sampler3D noise;
+
+//const vec4 marbleColors[2] = {vec4(0.9, 0.9, 0.9, 1), vec4(0.6, 0.5, 0.5, 1)};
+uniform vec4 marbleColors[2];
+
+void main()
+{
+ float turbulence = 0.0;
+ float scale = 1.0;
+ for (int i = 0; i < 4; ++i) {
+ turbulence += scale * (texture3D(noise, 0.125 * gl_TexCoord[1].xyz / scale).x - 0.5);
+ scale *= 0.5;
+ }
+
+ vec3 N = normalize(normal);
+ // assume directional light
+
+ gl_MaterialParameters M = gl_FrontMaterial;
+
+ float NdotL = dot(N, lightDirection.xyz);
+ float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);
+
+ vec4 unlitColor = mix(marbleColors[0], marbleColors[1], exp(-4.0 * abs(turbulence)));
+ gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+}
diff --git a/examples/graphicsview/boxes/parameters.par b/examples/graphicsview/boxes/parameters.par
new file mode 100644
index 0000000000..50e20739b9
--- /dev/null
+++ b/examples/graphicsview/boxes/parameters.par
@@ -0,0 +1,5 @@
+color basicColor ff0e3d0e
+color woodColors ff5e3d33 ffcc9966
+float woodTubulence 0.1
+color graniteColors ff000000 ff4d261a ffccb3bf
+color marbleColors ffe6e6e6 ff998080
diff --git a/examples/graphicsview/boxes/qt-logo.jpg b/examples/graphicsview/boxes/qt-logo.jpg
new file mode 100644
index 0000000000..4014b4659c
--- /dev/null
+++ b/examples/graphicsview/boxes/qt-logo.jpg
Binary files differ
diff --git a/examples/graphicsview/boxes/qt-logo.png b/examples/graphicsview/boxes/qt-logo.png
new file mode 100644
index 0000000000..7d3e97eb36
--- /dev/null
+++ b/examples/graphicsview/boxes/qt-logo.png
Binary files differ
diff --git a/examples/graphicsview/boxes/qtbox.cpp b/examples/graphicsview/boxes/qtbox.cpp
new file mode 100644
index 0000000000..d24116578c
--- /dev/null
+++ b/examples/graphicsview/boxes/qtbox.cpp
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbox.h"
+
+const qreal ROTATE_SPEED_X = 30.0 / 1000.0;
+const qreal ROTATE_SPEED_Y = 20.0 / 1000.0;
+const qreal ROTATE_SPEED_Z = 40.0 / 1000.0;
+const int MAX_ITEM_SIZE = 512;
+const int MIN_ITEM_SIZE = 16;
+
+//============================================================================//
+// ItemBase //
+//============================================================================//
+
+ItemBase::ItemBase(int size, int x, int y) : m_size(size), m_isResizing(false)
+{
+ setFlag(QGraphicsItem::ItemIsMovable, true);
+ setFlag(QGraphicsItem::ItemIsSelectable, true);
+ setFlag(QGraphicsItem::ItemIsFocusable, true);
+ setAcceptHoverEvents(true);
+ setPos(x, y);
+ m_startTime = QTime::currentTime();
+}
+
+ItemBase::~ItemBase()
+{
+}
+
+QRectF ItemBase::boundingRect() const
+{
+ return QRectF(-m_size / 2, -m_size / 2, m_size, m_size);
+}
+
+void ItemBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
+{
+ if (option->state & QStyle::State_Selected) {
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ if (option->state & QStyle::State_HasFocus)
+ painter->setPen(Qt::yellow);
+ else
+ painter->setPen(Qt::white);
+ painter->drawRect(boundingRect());
+
+ painter->drawLine(m_size / 2 - 9, m_size / 2, m_size / 2, m_size / 2 - 9);
+ painter->drawLine(m_size / 2 - 6, m_size / 2, m_size / 2, m_size / 2 - 6);
+ painter->drawLine(m_size / 2 - 3, m_size / 2, m_size / 2, m_size / 2 - 3);
+
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ }
+}
+
+void ItemBase::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+ if (!isSelected() && scene()) {
+ scene()->clearSelection();
+ setSelected(true);
+ }
+
+ QMenu menu;
+ QAction *delAction = menu.addAction("Delete");
+ QAction *newAction = menu.addAction("New");
+ QAction *growAction = menu.addAction("Grow");
+ QAction *shrinkAction = menu.addAction("Shrink");
+
+ QAction *selectedAction = menu.exec(event->screenPos());
+
+ if (selectedAction == delAction)
+ deleteSelectedItems(scene());
+ else if (selectedAction == newAction)
+ duplicateSelectedItems(scene());
+ else if (selectedAction == growAction)
+ growSelectedItems(scene());
+ else if (selectedAction == shrinkAction)
+ shrinkSelectedItems(scene());
+}
+
+void ItemBase::duplicateSelectedItems(QGraphicsScene *scene)
+{
+ if (!scene)
+ return;
+
+ QList<QGraphicsItem *> selected;
+ selected = scene->selectedItems();
+
+ foreach (QGraphicsItem *item, selected) {
+ ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item);
+ if (itemBase)
+ scene->addItem(itemBase->createNew(itemBase->m_size, itemBase->pos().x() + itemBase->m_size, itemBase->pos().y()));
+ }
+}
+
+void ItemBase::deleteSelectedItems(QGraphicsScene *scene)
+{
+ if (!scene)
+ return;
+
+ QList<QGraphicsItem *> selected;
+ selected = scene->selectedItems();
+
+ foreach (QGraphicsItem *item, selected) {
+ ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item);
+ if (itemBase)
+ delete itemBase;
+ }
+}
+
+void ItemBase::growSelectedItems(QGraphicsScene *scene)
+{
+ if (!scene)
+ return;
+
+ QList<QGraphicsItem *> selected;
+ selected = scene->selectedItems();
+
+ foreach (QGraphicsItem *item, selected) {
+ ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item);
+ if (itemBase) {
+ itemBase->prepareGeometryChange();
+ itemBase->m_size *= 2;
+ if (itemBase->m_size > MAX_ITEM_SIZE)
+ itemBase->m_size = MAX_ITEM_SIZE;
+ }
+ }
+}
+
+void ItemBase::shrinkSelectedItems(QGraphicsScene *scene)
+{
+ if (!scene)
+ return;
+
+ QList<QGraphicsItem *> selected;
+ selected = scene->selectedItems();
+
+ foreach (QGraphicsItem *item, selected) {
+ ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item);
+ if (itemBase) {
+ itemBase->prepareGeometryChange();
+ itemBase->m_size /= 2;
+ if (itemBase->m_size < MIN_ITEM_SIZE)
+ itemBase->m_size = MIN_ITEM_SIZE;
+ }
+ }
+}
+
+void ItemBase::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_isResizing) {
+ int dx = int(2.0 * event->pos().x());
+ int dy = int(2.0 * event->pos().y());
+ prepareGeometryChange();
+ m_size = (dx > dy ? dx : dy);
+ if (m_size < MIN_ITEM_SIZE)
+ m_size = MIN_ITEM_SIZE;
+ else if (m_size > MAX_ITEM_SIZE)
+ m_size = MAX_ITEM_SIZE;
+ } else {
+ QGraphicsItem::mouseMoveEvent(event);
+ }
+}
+
+void ItemBase::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ if (m_isResizing || (isInResizeArea(event->pos()) && isSelected()))
+ setCursor(Qt::SizeFDiagCursor);
+ else
+ setCursor(Qt::ArrowCursor);
+ QGraphicsItem::hoverMoveEvent(event);
+}
+
+void ItemBase::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ static qreal z = 0.0;
+ setZValue(z += 1.0);
+ if (event->button() == Qt::LeftButton && isInResizeArea(event->pos())) {
+ m_isResizing = true;
+ } else {
+ QGraphicsItem::mousePressEvent(event);
+ }
+}
+
+void ItemBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton && m_isResizing) {
+ m_isResizing = false;
+ } else {
+ QGraphicsItem::mouseReleaseEvent(event);
+ }
+}
+
+void ItemBase::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Delete:
+ deleteSelectedItems(scene());
+ break;
+ case Qt::Key_Insert:
+ duplicateSelectedItems(scene());
+ break;
+ case Qt::Key_Plus:
+ growSelectedItems(scene());
+ break;
+ case Qt::Key_Minus:
+ shrinkSelectedItems(scene());
+ break;
+ default:
+ QGraphicsItem::keyPressEvent(event);
+ break;
+ }
+}
+
+void ItemBase::wheelEvent(QGraphicsSceneWheelEvent *event)
+{
+ prepareGeometryChange();
+ m_size = int(m_size * exp(-event->delta() / 600.0));
+ if (m_size > MAX_ITEM_SIZE)
+ m_size = MAX_ITEM_SIZE;
+ else if (m_size < MIN_ITEM_SIZE)
+ m_size = MIN_ITEM_SIZE;
+}
+
+int ItemBase::type() const
+{
+ return Type;
+}
+
+
+bool ItemBase::isInResizeArea(const QPointF &pos)
+{
+ return (-pos.y() < pos.x() - m_size + 9);
+}
+
+//============================================================================//
+// QtBox //
+//============================================================================//
+
+QtBox::QtBox(int size, int x, int y) : ItemBase(size, x, y), m_texture(0)
+{
+ for (int i = 0; i < 8; ++i) {
+ m_vertices[i].setX(i & 1 ? 0.5f : -0.5f);
+ m_vertices[i].setY(i & 2 ? 0.5f : -0.5f);
+ m_vertices[i].setZ(i & 4 ? 0.5f : -0.5f);
+ }
+ for (int i = 0; i < 4; ++i) {
+ m_texCoords[i].setX(i & 1 ? 1.0f : 0.0f);
+ m_texCoords[i].setY(i & 2 ? 1.0f : 0.0f);
+ }
+ m_normals[0] = QVector3D(-1.0f, 0.0f, 0.0f);
+ m_normals[1] = QVector3D(1.0f, 0.0f, 0.0f);
+ m_normals[2] = QVector3D(0.0f, -1.0f, 0.0f);
+ m_normals[3] = QVector3D(0.0f, 1.0f, 0.0f);
+ m_normals[4] = QVector3D(0.0f, 0.0f, -1.0f);
+ m_normals[5] = QVector3D(0.0f, 0.0f, 1.0f);
+}
+
+QtBox::~QtBox()
+{
+ if (m_texture)
+ delete m_texture;
+}
+
+ItemBase *QtBox::createNew(int size, int x, int y)
+{
+ return new QtBox(size, x, y);
+}
+
+void QtBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ QRectF rect = boundingRect().translated(pos());
+ float width = float(painter->device()->width());
+ float height = float(painter->device()->height());
+
+ float left = 2.0f * float(rect.left()) / width - 1.0f;
+ float right = 2.0f * float(rect.right()) / width - 1.0f;
+ float top = 1.0f - 2.0f * float(rect.top()) / height;
+ float bottom = 1.0f - 2.0f * float(rect.bottom()) / height;
+ float moveToRectMatrix[] = {
+ 0.5f * (right - left), 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.5f * (bottom - top), 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.5f * (right + left), 0.5f * (bottom + top), 0.0f, 1.0f
+ };
+
+ painter->beginNativePainting();
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadMatrixf(moveToRectMatrix);
+ qgluPerspective(60.0, 1.0, 0.01, 10.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ //glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_NORMALIZE);
+
+ if(m_texture == 0)
+ m_texture = new GLTexture2D(":/res/boxes/qt-logo.jpg", 64, 64);
+ m_texture->bind();
+ glEnable(GL_TEXTURE_2D);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ float lightColour[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ float lightDir[] = {0.0f, 0.0f, 1.0f, 0.0f};
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColour);
+ glLightfv(GL_LIGHT0, GL_POSITION, lightDir);
+ glEnable(GL_LIGHT0);
+
+ glTranslatef(0.0f, 0.0f, -1.5f);
+ glRotatef(ROTATE_SPEED_X * m_startTime.msecsTo(QTime::currentTime()), 1.0f, 0.0f, 0.0f);
+ glRotatef(ROTATE_SPEED_Y * m_startTime.msecsTo(QTime::currentTime()), 0.0f, 1.0f, 0.0f);
+ glRotatef(ROTATE_SPEED_Z * m_startTime.msecsTo(QTime::currentTime()), 0.0f, 0.0f, 1.0f);
+ int dt = m_startTime.msecsTo(QTime::currentTime());
+ if (dt < 500)
+ glScalef(dt / 500.0f, dt / 500.0f, dt / 500.0f);
+
+ for (int dir = 0; dir < 3; ++dir) {
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 0]));
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i]));
+ glVertex3fv(reinterpret_cast<float *>(&m_vertices[(i << ((dir + 2) % 3)) | (j << ((dir + 1) % 3))]));
+ }
+ }
+ glEnd();
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 1]));
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i]));
+ glVertex3fv(reinterpret_cast<float *>(&m_vertices[(1 << dir) | (i << ((dir + 1) % 3)) | (j << ((dir + 2) % 3))]));
+ }
+ }
+ glEnd();
+ }
+ m_texture->unbind();
+
+ //glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHT0);
+ glDisable(GL_NORMALIZE);
+
+ glPopMatrix();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ painter->endNativePainting();
+
+ ItemBase::paint(painter, option, widget);
+}
+
+//============================================================================//
+// CircleItem //
+//============================================================================//
+
+CircleItem::CircleItem(int size, int x, int y) : ItemBase(size, x, y)
+{
+ m_color = QColor::fromHsv(rand() % 360, 255, 255);
+}
+
+void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ int dt = m_startTime.msecsTo(QTime::currentTime());
+
+ qreal r0 = 0.5 * m_size * (1.0 - exp(-0.001 * ((dt + 3800) % 4000)));
+ qreal r1 = 0.5 * m_size * (1.0 - exp(-0.001 * ((dt + 0) % 4000)));
+ qreal r2 = 0.5 * m_size * (1.0 - exp(-0.001 * ((dt + 1800) % 4000)));
+ qreal r3 = 0.5 * m_size * (1.0 - exp(-0.001 * ((dt + 2000) % 4000)));
+
+ if (r0 > r1)
+ r0 = 0.0;
+ if (r2 > r3)
+ r2 = 0.0;
+
+ QPainterPath path;
+ path.moveTo(r1, 0.0);
+ path.arcTo(-r1, -r1, 2 * r1, 2 * r1, 0.0, 360.0);
+ path.lineTo(r0, 0.0);
+ path.arcTo(-r0, -r0, 2 * r0, 2 * r0, 0.0, -360.0);
+ path.closeSubpath();
+ path.moveTo(r3, 0.0);
+ path.arcTo(-r3, -r3, 2 * r3, 2 * r3, 0.0, 360.0);
+ path.lineTo(r0, 0.0);
+ path.arcTo(-r2, -r2, 2 * r2, 2 * r2, 0.0, -360.0);
+ path.closeSubpath();
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->setBrush(QBrush(m_color));
+ painter->setPen(Qt::NoPen);
+ painter->drawPath(path);
+ painter->setBrush(Qt::NoBrush);
+ painter->setPen(Qt::SolidLine);
+ painter->setRenderHint(QPainter::Antialiasing, false);
+
+ ItemBase::paint(painter, option, widget);
+}
+
+ItemBase *CircleItem::createNew(int size, int x, int y)
+{
+ return new CircleItem(size, x, y);
+}
+
+//============================================================================//
+// SquareItem //
+//============================================================================//
+
+SquareItem::SquareItem(int size, int x, int y) : ItemBase(size, x, y)
+{
+ m_image = QPixmap(":/res/boxes/square.jpg");
+}
+
+void SquareItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ int dt = m_startTime.msecsTo(QTime::currentTime());
+ QTransform oldTransform = painter->worldTransform();
+ int dtMod = dt % 2000;
+ qreal amp = 0.002 * (dtMod < 1000 ? dtMod : 2000 - dtMod) - 1.0;
+
+ qreal scale = 0.6 + 0.2 * amp * amp;
+ painter->setWorldTransform(QTransform().rotate(15.0 * amp).scale(scale, scale), true);
+
+ painter->drawPixmap(-m_size / 2, -m_size / 2, m_size, m_size, m_image);
+
+ painter->setWorldTransform(oldTransform, false);
+ ItemBase::paint(painter, option, widget);
+}
+
+ItemBase *SquareItem::createNew(int size, int x, int y)
+{
+ return new SquareItem(size, x, y);
+}
diff --git a/examples/graphicsview/boxes/qtbox.h b/examples/graphicsview/boxes/qtbox.h
new file mode 100644
index 0000000000..56b86a55bb
--- /dev/null
+++ b/examples/graphicsview/boxes/qtbox.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBOX_H
+#define QTBOX_H
+
+#include <QtGui>
+
+#include <QtGui/qvector3d.h>
+#include "glbuffers.h"
+
+class ItemBase : public QGraphicsItem
+{
+public:
+ enum { Type = UserType + 1 };
+
+ ItemBase(int size, int x, int y);
+ virtual ~ItemBase();
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+protected:
+ virtual ItemBase *createNew(int size, int x, int y) = 0;
+ virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
+ virtual int type() const;
+ bool isInResizeArea(const QPointF &pos);
+
+ static void duplicateSelectedItems(QGraphicsScene *scene);
+ static void deleteSelectedItems(QGraphicsScene *scene);
+ static void growSelectedItems(QGraphicsScene *scene);
+ static void shrinkSelectedItems(QGraphicsScene *scene);
+
+ int m_size;
+ QTime m_startTime;
+ bool m_isResizing;
+};
+
+class QtBox : public ItemBase
+{
+public:
+ QtBox(int size, int x, int y);
+ virtual ~QtBox();
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+protected:
+ virtual ItemBase *createNew(int size, int x, int y);
+private:
+ QVector3D m_vertices[8];
+ QVector3D m_texCoords[4];
+ QVector3D m_normals[6];
+ GLTexture *m_texture;
+};
+
+class CircleItem : public ItemBase
+{
+public:
+ CircleItem(int size, int x, int y);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+protected:
+ virtual ItemBase *createNew(int size, int x, int y);
+
+ QColor m_color;
+};
+
+class SquareItem : public ItemBase
+{
+public:
+ SquareItem(int size, int x, int y);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+protected:
+ virtual ItemBase *createNew(int size, int x, int y);
+
+ QPixmap m_image;
+};
+
+#endif
diff --git a/examples/graphicsview/boxes/reflection.fsh b/examples/graphicsview/boxes/reflection.fsh
new file mode 100644
index 0000000000..576c522bbb
--- /dev/null
+++ b/examples/graphicsview/boxes/reflection.fsh
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform samplerCube env;
+uniform mat4 view;
+
+void main()
+{
+ vec3 N = normalize(normal);
+ vec3 R = 2.0 * dot(-position, N) * N + position;
+ gl_FragColor = textureCube(env, R * mat3(view[0].xyz, view[1].xyz, view[2].xyz));
+}
diff --git a/examples/graphicsview/boxes/refraction.fsh b/examples/graphicsview/boxes/refraction.fsh
new file mode 100644
index 0000000000..10ab38a54c
--- /dev/null
+++ b/examples/graphicsview/boxes/refraction.fsh
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform samplerCube env;
+uniform mat4 view;
+
+// Arrays don't work here on glsl < 120, apparently.
+//const float coeffs[6] = float[6](1.0/2.0, 1.0/2.1, 1.0/2.2, 1.0/2.3, 1.0/2.4, 1.0/2.5);
+float coeffs(int i)
+{
+ return 1.0 / (2.0 + 0.1 * float(i));
+}
+
+void main()
+{
+ vec3 N = normalize(normal);
+ vec3 I = -normalize(position);
+ float IdotN = dot(I, N);
+ float scales[6];
+ vec3 C[6];
+ for (int i = 0; i < 6; ++i) {
+ scales[i] = (IdotN - sqrt(1.0 - coeffs(i) + coeffs(i) * (IdotN * IdotN)));
+ C[i] = textureCube(env, (-I + coeffs(i) * N) * mat3(view[0].xyz, view[1].xyz, view[2].xyz)).xyz;
+ }
+
+ gl_FragColor = 0.25 * vec4(C[5].x + 2.0*C[0].x + C[1].x, C[1].y + 2.0*C[2].y + C[3].y,
+ C[3].z + 2.0*C[4].z + C[5].z, 4.0);
+}
diff --git a/examples/graphicsview/boxes/roundedbox.cpp b/examples/graphicsview/boxes/roundedbox.cpp
new file mode 100644
index 0000000000..5058043707
--- /dev/null
+++ b/examples/graphicsview/boxes/roundedbox.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "roundedbox.h"
+
+//============================================================================//
+// P3T2N3Vertex //
+//============================================================================//
+
+VertexDescription P3T2N3Vertex::description[] = {
+ {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, position) / sizeof(float), 0, 0},
+ {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, texCoord) / sizeof(float), sizeof(QVector3D), 0},
+ {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, normal) / sizeof(float), sizeof(QVector3D) + sizeof(QVector2D), 0},
+
+ {VertexDescription::Null, 0, 0, 0, 0},
+};
+
+//============================================================================//
+// GLRoundedBox //
+//============================================================================//
+
+float lerp(float a, float b, float t)
+{
+ return a * (1.0f - t) + b * t;
+}
+
+GLRoundedBox::GLRoundedBox(float r, float scale, int n)
+ : GLTriangleMesh<P3T2N3Vertex, unsigned short>((n+2)*(n+3)*4, (n+1)*(n+1)*24+36+72*(n+1))
+{
+ int vidx = 0, iidx = 0;
+ int vertexCountPerCorner = (n + 2) * (n + 3) / 2;
+
+ P3T2N3Vertex *vp = m_vb.lock();
+ unsigned short *ip = m_ib.lock();
+
+ if (!vp || !ip) {
+ qWarning("GLRoundedBox::GLRoundedBox: Failed to lock vertex buffer and/or index buffer.");
+ m_ib.unlock();
+ m_vb.unlock();
+ return;
+ }
+
+ for (int corner = 0; corner < 8; ++corner) {
+ QVector3D centre(corner & 1 ? 1.0f : -1.0f,
+ corner & 2 ? 1.0f : -1.0f,
+ corner & 4 ? 1.0f : -1.0f);
+ int winding = (corner & 1) ^ ((corner >> 1) & 1) ^ (corner >> 2);
+ int offsX = ((corner ^ 1) - corner) * vertexCountPerCorner;
+ int offsY = ((corner ^ 2) - corner) * vertexCountPerCorner;
+ int offsZ = ((corner ^ 4) - corner) * vertexCountPerCorner;
+
+ // Face polygons
+ if (winding) {
+ ip[iidx++] = vidx;
+ ip[iidx++] = vidx + offsX;
+ ip[iidx++] = vidx + offsY;
+
+ ip[iidx++] = vidx + vertexCountPerCorner - n - 2;
+ ip[iidx++] = vidx + vertexCountPerCorner - n - 2 + offsY;
+ ip[iidx++] = vidx + vertexCountPerCorner - n - 2 + offsZ;
+
+ ip[iidx++] = vidx + vertexCountPerCorner - 1;
+ ip[iidx++] = vidx + vertexCountPerCorner - 1 + offsZ;
+ ip[iidx++] = vidx + vertexCountPerCorner - 1 + offsX;
+ }
+
+ for (int i = 0; i < n + 2; ++i) {
+
+ // Edge polygons
+ if (winding && i < n + 1) {
+ ip[iidx++] = vidx + i + 1;
+ ip[iidx++] = vidx;
+ ip[iidx++] = vidx + offsY + i + 1;
+ ip[iidx++] = vidx + offsY;
+ ip[iidx++] = vidx + offsY + i + 1;
+ ip[iidx++] = vidx;
+
+ ip[iidx++] = vidx + i;
+ ip[iidx++] = vidx + 2 * i + 2;
+ ip[iidx++] = vidx + i + offsX;
+ ip[iidx++] = vidx + 2 * i + offsX + 2;
+ ip[iidx++] = vidx + i + offsX;
+ ip[iidx++] = vidx + 2 * i + 2;
+
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i;
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i;
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i + offsZ;
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i + offsZ;
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i + offsZ;
+ ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i;
+ }
+
+ for (int j = 0; j <= i; ++j) {
+ QVector3D normal = QVector3D(i - j, j, n + 1 - i).normalized();
+ QVector3D offset(0.5f - r, 0.5f - r, 0.5f - r);
+ QVector3D pos = centre * (offset + r * normal);
+
+ vp[vidx].position = scale * pos;
+ vp[vidx].normal = centre * normal;
+ vp[vidx].texCoord = QVector2D(pos.x() + 0.5f, pos.y() + 0.5f);
+
+ // Corner polygons
+ if (i < n + 1) {
+ ip[iidx++] = vidx;
+ ip[iidx++] = vidx + i + 2 - winding;
+ ip[iidx++] = vidx + i + 1 + winding;
+ }
+ if (i < n) {
+ ip[iidx++] = vidx + i + 1 + winding;
+ ip[iidx++] = vidx + i + 2 - winding;
+ ip[iidx++] = vidx + 2 * i + 4;
+ }
+
+ ++vidx;
+ }
+ }
+
+ }
+
+ m_ib.unlock();
+ m_vb.unlock();
+}
+
diff --git a/examples/graphicsview/boxes/roundedbox.h b/examples/graphicsview/boxes/roundedbox.h
new file mode 100644
index 0000000000..54dda82000
--- /dev/null
+++ b/examples/graphicsview/boxes/roundedbox.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ROUNDEDBOX_H
+#define ROUNDEDBOX_H
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include <QtGui>
+#include <QtOpenGL>
+
+#include "gltrianglemesh.h"
+#include <QtGui/qvector3d.h>
+#include <QtGui/qvector2d.h>
+#include "glbuffers.h"
+
+struct P3T2N3Vertex
+{
+ QVector3D position;
+ QVector2D texCoord;
+ QVector3D normal;
+ static VertexDescription description[];
+};
+
+class GLRoundedBox : public GLTriangleMesh<P3T2N3Vertex, unsigned short>
+{
+public:
+ // 0 < r < 0.5, 0 <= n <= 125
+ GLRoundedBox(float r = 0.25f, float scale = 1.0f, int n = 10);
+};
+
+
+#endif
diff --git a/examples/graphicsview/boxes/scene.cpp b/examples/graphicsview/boxes/scene.cpp
new file mode 100644
index 0000000000..39cd0fcafd
--- /dev/null
+++ b/examples/graphicsview/boxes/scene.cpp
@@ -0,0 +1,1085 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include "scene.h"
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qvector3d.h>
+
+#include "3rdparty/fbm.h"
+
+void checkGLErrors(const QString& prefix)
+{
+ switch (glGetError()) {
+ case GL_NO_ERROR:
+ //qDebug() << prefix << tr("No error.");
+ break;
+ case GL_INVALID_ENUM:
+ qDebug() << prefix << QObject::tr("Invalid enum.");
+ break;
+ case GL_INVALID_VALUE:
+ qDebug() << prefix << QObject::tr("Invalid value.");
+ break;
+ case GL_INVALID_OPERATION:
+ qDebug() << prefix << QObject::tr("Invalid operation.");
+ break;
+ case GL_STACK_OVERFLOW:
+ qDebug() << prefix << QObject::tr("Stack overflow.");
+ break;
+ case GL_STACK_UNDERFLOW:
+ qDebug() << prefix << QObject::tr("Stack underflow.");
+ break;
+ case GL_OUT_OF_MEMORY:
+ qDebug() << prefix << QObject::tr("Out of memory.");
+ break;
+ default:
+ qDebug() << prefix << QObject::tr("Unknown error.");
+ break;
+ }
+}
+
+//============================================================================//
+// ColorEdit //
+//============================================================================//
+
+ColorEdit::ColorEdit(QRgb initialColor, int id)
+ : m_color(initialColor), m_id(id)
+{
+ QHBoxLayout *layout = new QHBoxLayout;
+ setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+
+ m_lineEdit = new QLineEdit(QString::number(m_color, 16));
+ layout->addWidget(m_lineEdit);
+
+ m_button = new QFrame;
+ QPalette palette = m_button->palette();
+ palette.setColor(QPalette::Window, QColor(m_color));
+ m_button->setPalette(palette);
+ m_button->setAutoFillBackground(true);
+ m_button->setMinimumSize(32, 0);
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ m_button->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ layout->addWidget(m_button);
+
+ connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(editDone()));
+}
+
+void ColorEdit::editDone()
+{
+ bool ok;
+ QRgb newColor = m_lineEdit->text().toUInt(&ok, 16);
+ if (ok)
+ setColor(newColor);
+}
+
+void ColorEdit::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ QColor color(m_color);
+ QColorDialog dialog(color, 0);
+ dialog.setOption(QColorDialog::ShowAlphaChannel, true);
+// The ifdef block is a workaround for the beta, TODO: remove when bug 238525 is fixed
+#ifdef Q_WS_MAC
+ dialog.setOption(QColorDialog::DontUseNativeDialog, true);
+#endif
+ dialog.move(280, 120);
+ if (dialog.exec() == QDialog::Rejected)
+ return;
+ QRgb newColor = dialog.selectedColor().rgba();
+ if (newColor == m_color)
+ return;
+ setColor(newColor);
+ }
+}
+
+void ColorEdit::setColor(QRgb color)
+{
+ m_color = color;
+ m_lineEdit->setText(QString::number(m_color, 16)); // "Clean up" text
+ QPalette palette = m_button->palette();
+ palette.setColor(QPalette::Window, QColor(m_color));
+ m_button->setPalette(palette);
+ emit colorChanged(m_color, m_id);
+}
+
+//============================================================================//
+// FloatEdit //
+//============================================================================//
+
+FloatEdit::FloatEdit(float initialValue, int id)
+ : m_value(initialValue), m_id(id)
+{
+ QHBoxLayout *layout = new QHBoxLayout;
+ setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+
+ m_lineEdit = new QLineEdit(QString::number(m_value));
+ layout->addWidget(m_lineEdit);
+
+ connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(editDone()));
+}
+
+void FloatEdit::editDone()
+{
+ bool ok;
+ float newValue = m_lineEdit->text().toFloat(&ok);
+ if (ok) {
+ m_value = newValue;
+ m_lineEdit->setText(QString::number(m_value)); // "Clean up" text
+ emit valueChanged(m_value, m_id);
+ }
+}
+
+//============================================================================//
+// TwoSidedGraphicsWidget //
+//============================================================================//
+
+TwoSidedGraphicsWidget::TwoSidedGraphicsWidget(QGraphicsScene *scene)
+ : QObject(scene)
+ , m_current(0)
+ , m_angle(0)
+ , m_delta(0)
+{
+ for (int i = 0; i < 2; ++i)
+ m_proxyWidgets[i] = 0;
+}
+
+void TwoSidedGraphicsWidget::setWidget(int index, QWidget *widget)
+{
+ if (index < 0 || index >= 2)
+ {
+ qWarning("TwoSidedGraphicsWidget::setWidget: Index out of bounds, index == %d", index);
+ return;
+ }
+
+ GraphicsWidget *proxy = new GraphicsWidget;
+ proxy->setWidget(widget);
+
+ if (m_proxyWidgets[index])
+ delete m_proxyWidgets[index];
+ m_proxyWidgets[index] = proxy;
+
+ proxy->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+ proxy->setZValue(1e30); // Make sure the dialog is drawn on top of all other (OpenGL) items
+
+ if (index != m_current)
+ proxy->setVisible(false);
+
+ qobject_cast<QGraphicsScene *>(parent())->addItem(proxy);
+}
+
+QWidget *TwoSidedGraphicsWidget::widget(int index)
+{
+ if (index < 0 || index >= 2)
+ {
+ qWarning("TwoSidedGraphicsWidget::widget: Index out of bounds, index == %d", index);
+ return 0;
+ }
+ return m_proxyWidgets[index]->widget();
+}
+
+void TwoSidedGraphicsWidget::flip()
+{
+ m_delta = (m_current == 0 ? 9 : -9);
+ animateFlip();
+}
+
+void TwoSidedGraphicsWidget::animateFlip()
+{
+ m_angle += m_delta;
+ if (m_angle == 90) {
+ int old = m_current;
+ m_current ^= 1;
+ m_proxyWidgets[old]->setVisible(false);
+ m_proxyWidgets[m_current]->setVisible(true);
+ m_proxyWidgets[m_current]->setGeometry(m_proxyWidgets[old]->geometry());
+ }
+
+ QRectF r = m_proxyWidgets[m_current]->boundingRect();
+ m_proxyWidgets[m_current]->setTransform(QTransform()
+ .translate(r.width() / 2, r.height() / 2)
+ .rotate(m_angle - 180 * m_current, Qt::YAxis)
+ .translate(-r.width() / 2, -r.height() / 2));
+
+ if ((m_current == 0 && m_angle > 0) || (m_current == 1 && m_angle < 180))
+ QTimer::singleShot(25, this, SLOT(animateFlip()));
+}
+
+QVariant GraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemPositionChange && scene()) {
+ QRectF rect = boundingRect();
+ QPointF pos = value.toPointF();
+ QRectF sceneRect = scene()->sceneRect();
+ if (pos.x() + rect.left() < sceneRect.left())
+ pos.setX(sceneRect.left() - rect.left());
+ else if (pos.x() + rect.right() >= sceneRect.right())
+ pos.setX(sceneRect.right() - rect.right());
+ if (pos.y() + rect.top() < sceneRect.top())
+ pos.setY(sceneRect.top() - rect.top());
+ else if (pos.y() + rect.bottom() >= sceneRect.bottom())
+ pos.setY(sceneRect.bottom() - rect.bottom());
+ return pos;
+ }
+ return QGraphicsProxyWidget::itemChange(change, value);
+}
+
+void GraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ setCacheMode(QGraphicsItem::NoCache);
+ setCacheMode(QGraphicsItem::ItemCoordinateCache);
+ QGraphicsProxyWidget::resizeEvent(event);
+}
+
+void GraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ QGraphicsProxyWidget::paint(painter, option, widget);
+ //painter->setRenderHint(QPainter::Antialiasing, true);
+}
+
+//============================================================================//
+// RenderOptionsDialog //
+//============================================================================//
+
+RenderOptionsDialog::RenderOptionsDialog()
+ : QDialog(0, Qt::CustomizeWindowHint | Qt::WindowTitleHint)
+{
+ setWindowOpacity(0.75);
+ setWindowTitle(tr("Options (double click to flip)"));
+ QGridLayout *layout = new QGridLayout;
+ setLayout(layout);
+ layout->setColumnStretch(1, 1);
+
+ int row = 0;
+
+ QCheckBox *check = new QCheckBox(tr("Dynamic cube map"));
+ check->setCheckState(Qt::Unchecked);
+ // Dynamic cube maps are only enabled when multi-texturing and render to texture are available.
+ check->setEnabled(glActiveTexture && glGenFramebuffersEXT);
+ connect(check, SIGNAL(stateChanged(int)), this, SIGNAL(dynamicCubemapToggled(int)));
+ layout->addWidget(check, 0, 0, 1, 2);
+ ++row;
+
+ QPalette palette;
+
+ // Load all .par files
+ // .par files have a simple syntax for specifying user adjustable uniform variables.
+ QSet<QByteArray> uniforms;
+ QList<QString> filter = QStringList("*.par");
+ QList<QFileInfo> files = QDir(":/res/boxes/").entryInfoList(filter, QDir::Files | QDir::Readable);
+
+ foreach (QFileInfo fileInfo, files) {
+ QFile file(fileInfo.absoluteFilePath());
+ if (file.open(QIODevice::ReadOnly)) {
+ while (!file.atEnd()) {
+ QList<QByteArray> tokens = file.readLine().simplified().split(' ');
+ QList<QByteArray>::const_iterator it = tokens.begin();
+ if (it == tokens.end())
+ continue;
+ QByteArray type = *it;
+ if (++it == tokens.end())
+ continue;
+ QByteArray name = *it;
+ bool singleElement = (tokens.size() == 3); // type, name and one value
+ char counter[10] = "000000000";
+ int counterPos = 8; // position of last digit
+ while (++it != tokens.end()) {
+ m_parameterNames << name;
+ if (!singleElement) {
+ m_parameterNames.back() += "[";
+ m_parameterNames.back() += counter + counterPos;
+ m_parameterNames.back() += "]";
+ int j = 8; // position of last digit
+ ++counter[j];
+ while (j > 0 && counter[j] > '9') {
+ counter[j] = '0';
+ ++counter[--j];
+ }
+ if (j < counterPos)
+ counterPos = j;
+ }
+
+ if (type == "color") {
+ layout->addWidget(new QLabel(m_parameterNames.back()));
+ bool ok;
+ ColorEdit *colorEdit = new ColorEdit(it->toUInt(&ok, 16), m_parameterNames.size() - 1);
+ m_parameterEdits << colorEdit;
+ layout->addWidget(colorEdit);
+ connect(colorEdit, SIGNAL(colorChanged(QRgb,int)), this, SLOT(setColorParameter(QRgb,int)));
+ ++row;
+ } else if (type == "float") {
+ layout->addWidget(new QLabel(m_parameterNames.back()));
+ bool ok;
+ FloatEdit *floatEdit = new FloatEdit(it->toFloat(&ok), m_parameterNames.size() - 1);
+ m_parameterEdits << floatEdit;
+ layout->addWidget(floatEdit);
+ connect(floatEdit, SIGNAL(valueChanged(float,int)), this, SLOT(setFloatParameter(float,int)));
+ ++row;
+ }
+ }
+ }
+ file.close();
+ }
+ }
+
+ layout->addWidget(new QLabel(tr("Texture:")));
+ m_textureCombo = new QComboBox;
+ connect(m_textureCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(textureChanged(int)));
+ layout->addWidget(m_textureCombo);
+ ++row;
+
+ layout->addWidget(new QLabel(tr("Shader:")));
+ m_shaderCombo = new QComboBox;
+ connect(m_shaderCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(shaderChanged(int)));
+ layout->addWidget(m_shaderCombo);
+ ++row;
+
+ layout->setRowStretch(row, 1);
+}
+
+int RenderOptionsDialog::addTexture(const QString &name)
+{
+ m_textureCombo->addItem(name);
+ return m_textureCombo->count() - 1;
+}
+
+int RenderOptionsDialog::addShader(const QString &name)
+{
+ m_shaderCombo->addItem(name);
+ return m_shaderCombo->count() - 1;
+}
+
+void RenderOptionsDialog::emitParameterChanged()
+{
+ foreach (ParameterEdit *edit, m_parameterEdits)
+ edit->emitChange();
+}
+
+void RenderOptionsDialog::setColorParameter(QRgb color, int id)
+{
+ emit colorParameterChanged(m_parameterNames[id], color);
+}
+
+void RenderOptionsDialog::setFloatParameter(float value, int id)
+{
+ emit floatParameterChanged(m_parameterNames[id], value);
+}
+
+void RenderOptionsDialog::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton)
+ emit doubleClicked();
+}
+
+//============================================================================//
+// ItemDialog //
+//============================================================================//
+
+ItemDialog::ItemDialog()
+ : QDialog(0, Qt::CustomizeWindowHint | Qt::WindowTitleHint)
+{
+ setWindowTitle(tr("Items (double click to flip)"));
+ setWindowOpacity(0.75);
+ resize(160, 100);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ setLayout(layout);
+ QPushButton *button;
+
+ button = new QPushButton(tr("Add Qt box"));
+ layout->addWidget(button);
+ connect(button, SIGNAL(clicked()), this, SLOT(triggerNewQtBox()));
+
+ button = new QPushButton(tr("Add circle"));
+ layout->addWidget(button);
+ connect(button, SIGNAL(clicked()), this, SLOT(triggerNewCircleItem()));
+
+ button = new QPushButton(tr("Add square"));
+ layout->addWidget(button);
+ connect(button, SIGNAL(clicked()), this, SLOT(triggerNewSquareItem()));
+
+ layout->addStretch(1);
+}
+
+void ItemDialog::triggerNewQtBox()
+{
+ emit newItemTriggered(QtBoxItem);
+}
+
+void ItemDialog::triggerNewCircleItem()
+{
+ emit newItemTriggered(CircleItem);
+}
+
+void ItemDialog::triggerNewSquareItem()
+{
+ emit newItemTriggered(SquareItem);
+}
+
+void ItemDialog::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton)
+ emit doubleClicked();
+}
+
+//============================================================================//
+// Scene //
+//============================================================================//
+
+const static char environmentShaderText[] =
+ "uniform samplerCube env;"
+ "void main() {"
+ "gl_FragColor = textureCube(env, gl_TexCoord[1].xyz);"
+ "}";
+
+Scene::Scene(int width, int height, int maxTextureSize)
+ : m_distExp(600)
+ , m_frame(0)
+ , m_maxTextureSize(maxTextureSize)
+ , m_currentShader(0)
+ , m_currentTexture(0)
+ , m_dynamicCubemap(false)
+ , m_updateAllCubemaps(true)
+ , m_box(0)
+ , m_vertexShader(0)
+ , m_environmentShader(0)
+ , m_environmentProgram(0)
+{
+ setSceneRect(0, 0, width, height);
+
+ m_trackBalls[0] = TrackBall(0.05f, QVector3D(0, 1, 0), TrackBall::Sphere);
+ m_trackBalls[1] = TrackBall(0.005f, QVector3D(0, 0, 1), TrackBall::Sphere);
+ m_trackBalls[2] = TrackBall(0.0f, QVector3D(0, 1, 0), TrackBall::Plane);
+
+ m_renderOptions = new RenderOptionsDialog;
+ m_renderOptions->move(20, 120);
+ m_renderOptions->resize(m_renderOptions->sizeHint());
+
+ connect(m_renderOptions, SIGNAL(dynamicCubemapToggled(int)), this, SLOT(toggleDynamicCubemap(int)));
+ connect(m_renderOptions, SIGNAL(colorParameterChanged(QString,QRgb)), this, SLOT(setColorParameter(QString,QRgb)));
+ connect(m_renderOptions, SIGNAL(floatParameterChanged(QString,float)), this, SLOT(setFloatParameter(QString,float)));
+ connect(m_renderOptions, SIGNAL(textureChanged(int)), this, SLOT(setTexture(int)));
+ connect(m_renderOptions, SIGNAL(shaderChanged(int)), this, SLOT(setShader(int)));
+
+ m_itemDialog = new ItemDialog;
+ connect(m_itemDialog, SIGNAL(newItemTriggered(ItemDialog::ItemType)), this, SLOT(newItem(ItemDialog::ItemType)));
+
+ TwoSidedGraphicsWidget *twoSided = new TwoSidedGraphicsWidget(this);
+ twoSided->setWidget(0, m_renderOptions);
+ twoSided->setWidget(1, m_itemDialog);
+
+ connect(m_renderOptions, SIGNAL(doubleClicked()), twoSided, SLOT(flip()));
+ connect(m_itemDialog, SIGNAL(doubleClicked()), twoSided, SLOT(flip()));
+
+ addItem(new QtBox(64, width - 64, height - 64));
+ addItem(new QtBox(64, width - 64, 64));
+ addItem(new QtBox(64, 64, height - 64));
+ addItem(new QtBox(64, 64, 64));
+
+ initGL();
+
+ m_timer = new QTimer(this);
+ m_timer->setInterval(20);
+ connect(m_timer, SIGNAL(timeout()), this, SLOT(update()));
+ m_timer->start();
+
+ m_time.start();
+}
+
+Scene::~Scene()
+{
+ if (m_box)
+ delete m_box;
+ foreach (GLTexture *texture, m_textures)
+ if (texture) delete texture;
+ if (m_mainCubemap)
+ delete m_mainCubemap;
+ foreach (QGLShaderProgram *program, m_programs)
+ if (program) delete program;
+ if (m_vertexShader)
+ delete m_vertexShader;
+ foreach (QGLShader *shader, m_fragmentShaders)
+ if (shader) delete shader;
+ foreach (GLRenderTargetCube *rt, m_cubemaps)
+ if (rt) delete rt;
+ if (m_environmentShader)
+ delete m_environmentShader;
+ if (m_environmentProgram)
+ delete m_environmentProgram;
+}
+
+void Scene::initGL()
+{
+ m_box = new GLRoundedBox(0.25f, 1.0f, 10);
+
+ m_vertexShader = new QGLShader(QGLShader::Vertex);
+ m_vertexShader->compileSourceFile(QLatin1String(":/res/boxes/basic.vsh"));
+
+ QStringList list;
+ list << ":/res/boxes/cubemap_posx.jpg" << ":/res/boxes/cubemap_negx.jpg" << ":/res/boxes/cubemap_posy.jpg"
+ << ":/res/boxes/cubemap_negy.jpg" << ":/res/boxes/cubemap_posz.jpg" << ":/res/boxes/cubemap_negz.jpg";
+ m_environment = new GLTextureCube(list, qMin(1024, m_maxTextureSize));
+ m_environmentShader = new QGLShader(QGLShader::Fragment);
+ m_environmentShader->compileSourceCode(environmentShaderText);
+ m_environmentProgram = new QGLShaderProgram;
+ m_environmentProgram->addShader(m_vertexShader);
+ m_environmentProgram->addShader(m_environmentShader);
+ m_environmentProgram->link();
+
+ const int NOISE_SIZE = 128; // for a different size, B and BM in fbm.c must also be changed
+ m_noise = new GLTexture3D(NOISE_SIZE, NOISE_SIZE, NOISE_SIZE);
+ QRgb *data = new QRgb[NOISE_SIZE * NOISE_SIZE * NOISE_SIZE];
+ memset(data, 0, NOISE_SIZE * NOISE_SIZE * NOISE_SIZE * sizeof(QRgb));
+ QRgb *p = data;
+ float pos[3];
+ for (int k = 0; k < NOISE_SIZE; ++k) {
+ pos[2] = k * (0x20 / (float)NOISE_SIZE);
+ for (int j = 0; j < NOISE_SIZE; ++j) {
+ for (int i = 0; i < NOISE_SIZE; ++i) {
+ for (int byte = 0; byte < 4; ++byte) {
+ pos[0] = (i + (byte & 1) * 16) * (0x20 / (float)NOISE_SIZE);
+ pos[1] = (j + (byte & 2) * 8) * (0x20 / (float)NOISE_SIZE);
+ *p |= (int)(128.0f * (noise3(pos) + 1.0f)) << (byte * 8);
+ }
+ ++p;
+ }
+ }
+ }
+ m_noise->load(NOISE_SIZE, NOISE_SIZE, NOISE_SIZE, data);
+ delete[] data;
+
+ m_mainCubemap = new GLRenderTargetCube(512);
+
+ QStringList filter;
+ QList<QFileInfo> files;
+
+ // Load all .png files as textures
+ m_currentTexture = 0;
+ filter = QStringList("*.png");
+ files = QDir(":/res/boxes/").entryInfoList(filter, QDir::Files | QDir::Readable);
+
+ foreach (QFileInfo file, files) {
+ GLTexture *texture = new GLTexture2D(file.absoluteFilePath(), qMin(256, m_maxTextureSize), qMin(256, m_maxTextureSize));
+ if (texture->failed()) {
+ delete texture;
+ continue;
+ }
+ m_textures << texture;
+ m_renderOptions->addTexture(file.baseName());
+ }
+
+ if (m_textures.size() == 0)
+ m_textures << new GLTexture2D(qMin(64, m_maxTextureSize), qMin(64, m_maxTextureSize));
+
+ // Load all .fsh files as fragment shaders
+ m_currentShader = 0;
+ filter = QStringList("*.fsh");
+ files = QDir(":/res/boxes/").entryInfoList(filter, QDir::Files | QDir::Readable);
+ foreach (QFileInfo file, files) {
+ QGLShaderProgram *program = new QGLShaderProgram;
+ QGLShader* shader = new QGLShader(QGLShader::Fragment);
+ shader->compileSourceFile(file.absoluteFilePath());
+ // The program does not take ownership over the shaders, so store them in a vector so they can be deleted afterwards.
+ program->addShader(m_vertexShader);
+ program->addShader(shader);
+ if (!program->link()) {
+ qWarning("Failed to compile and link shader program");
+ qWarning("Vertex shader log:");
+ qWarning() << m_vertexShader->log();
+ qWarning() << "Fragment shader log ( file =" << file.absoluteFilePath() << "):";
+ qWarning() << shader->log();
+ qWarning("Shader program log:");
+ qWarning() << program->log();
+
+ delete shader;
+ delete program;
+ continue;
+ }
+
+ m_fragmentShaders << shader;
+ m_programs << program;
+ m_renderOptions->addShader(file.baseName());
+
+ program->bind();
+ m_cubemaps << ((program->uniformLocation("env") != -1) ? new GLRenderTargetCube(qMin(256, m_maxTextureSize)) : 0);
+ program->release();
+ }
+
+ if (m_programs.size() == 0)
+ m_programs << new QGLShaderProgram;
+
+ m_renderOptions->emitParameterChanged();
+}
+
+static void loadMatrix(const QMatrix4x4& m)
+{
+ // static to prevent glLoadMatrixf to fail on certain drivers
+ static GLfloat mat[16];
+ const qreal *data = m.constData();
+ for (int index = 0; index < 16; ++index)
+ mat[index] = data[index];
+ glLoadMatrixf(mat);
+}
+
+static void multMatrix(const QMatrix4x4& m)
+{
+ // static to prevent glMultMatrixf to fail on certain drivers
+ static GLfloat mat[16];
+ const qreal *data = m.constData();
+ for (int index = 0; index < 16; ++index)
+ mat[index] = data[index];
+ glMultMatrixf(mat);
+}
+
+// If one of the boxes should not be rendered, set excludeBox to its index.
+// If the main box should not be rendered, set excludeBox to -1.
+void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox)
+{
+ QMatrix4x4 invView = view.inverted();
+
+ // If multi-texturing is supported, use three saplers.
+ if (glActiveTexture) {
+ glActiveTexture(GL_TEXTURE0);
+ m_textures[m_currentTexture]->bind();
+ glActiveTexture(GL_TEXTURE2);
+ m_noise->bind();
+ glActiveTexture(GL_TEXTURE1);
+ } else {
+ m_textures[m_currentTexture]->bind();
+ }
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_CULL_FACE);
+
+ QMatrix4x4 viewRotation(view);
+ viewRotation(3, 0) = viewRotation(3, 1) = viewRotation(3, 2) = 0.0f;
+ viewRotation(0, 3) = viewRotation(1, 3) = viewRotation(2, 3) = 0.0f;
+ viewRotation(3, 3) = 1.0f;
+ loadMatrix(viewRotation);
+ glScalef(20.0f, 20.0f, 20.0f);
+
+ // Don't render the environment if the environment texture can't be set for the correct sampler.
+ if (glActiveTexture) {
+ m_environment->bind();
+ m_environmentProgram->bind();
+ m_environmentProgram->setUniformValue("tex", GLint(0));
+ m_environmentProgram->setUniformValue("env", GLint(1));
+ m_environmentProgram->setUniformValue("noise", GLint(2));
+ m_box->draw();
+ m_environmentProgram->release();
+ m_environment->unbind();
+ }
+
+ loadMatrix(view);
+
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+
+ for (int i = 0; i < m_programs.size(); ++i) {
+ if (i == excludeBox)
+ continue;
+
+ glPushMatrix();
+ QMatrix4x4 m;
+ m.rotate(m_trackBalls[1].rotation());
+ multMatrix(m);
+
+ glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f);
+ glTranslatef(2.0f, 0.0f, 0.0f);
+ glScalef(0.3f, 0.6f, 0.6f);
+
+ if (glActiveTexture) {
+ if (m_dynamicCubemap && m_cubemaps[i])
+ m_cubemaps[i]->bind();
+ else
+ m_environment->bind();
+ }
+ m_programs[i]->bind();
+ m_programs[i]->setUniformValue("tex", GLint(0));
+ m_programs[i]->setUniformValue("env", GLint(1));
+ m_programs[i]->setUniformValue("noise", GLint(2));
+ m_programs[i]->setUniformValue("view", view);
+ m_programs[i]->setUniformValue("invView", invView);
+ m_box->draw();
+ m_programs[i]->release();
+
+ if (glActiveTexture) {
+ if (m_dynamicCubemap && m_cubemaps[i])
+ m_cubemaps[i]->unbind();
+ else
+ m_environment->unbind();
+ }
+ glPopMatrix();
+ }
+
+ if (-1 != excludeBox) {
+ QMatrix4x4 m;
+ m.rotate(m_trackBalls[0].rotation());
+ multMatrix(m);
+
+ if (glActiveTexture) {
+ if (m_dynamicCubemap)
+ m_mainCubemap->bind();
+ else
+ m_environment->bind();
+ }
+
+ m_programs[m_currentShader]->bind();
+ m_programs[m_currentShader]->setUniformValue("tex", GLint(0));
+ m_programs[m_currentShader]->setUniformValue("env", GLint(1));
+ m_programs[m_currentShader]->setUniformValue("noise", GLint(2));
+ m_programs[m_currentShader]->setUniformValue("view", view);
+ m_programs[m_currentShader]->setUniformValue("invView", invView);
+ m_box->draw();
+ m_programs[m_currentShader]->release();
+
+ if (glActiveTexture) {
+ if (m_dynamicCubemap)
+ m_mainCubemap->unbind();
+ else
+ m_environment->unbind();
+ }
+ }
+
+ if (glActiveTexture) {
+ glActiveTexture(GL_TEXTURE2);
+ m_noise->unbind();
+ glActiveTexture(GL_TEXTURE0);
+ }
+ m_textures[m_currentTexture]->unbind();
+}
+
+void Scene::setStates()
+{
+ //glClearColor(0.25f, 0.25f, 0.5f, 1.0f);
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ //glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_NORMALIZE);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ setLights();
+
+ float materialSpecular[] = {0.5f, 0.5f, 0.5f, 1.0f};
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0f);
+}
+
+void Scene::setLights()
+{
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ //float lightColour[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ float lightDir[] = {0.0f, 0.0f, 1.0f, 0.0f};
+ //glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColour);
+ //glLightfv(GL_LIGHT0, GL_SPECULAR, lightColour);
+ glLightfv(GL_LIGHT0, GL_POSITION, lightDir);
+ glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0f);
+ glEnable(GL_LIGHT0);
+}
+
+void Scene::defaultStates()
+{
+ //glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_LIGHTING);
+ //glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHT0);
+ glDisable(GL_NORMALIZE);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0.0f);
+ float defaultMaterialSpecular[] = {0.0f, 0.0f, 0.0f, 1.0f};
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defaultMaterialSpecular);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
+}
+
+void Scene::renderCubemaps()
+{
+ // To speed things up, only update the cubemaps for the small cubes every N frames.
+ const int N = (m_updateAllCubemaps ? 1 : 3);
+
+ QMatrix4x4 mat;
+ GLRenderTargetCube::getProjectionMatrix(mat, 0.1f, 100.0f);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ loadMatrix(mat);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ QVector3D center;
+
+ for (int i = m_frame % N; i < m_cubemaps.size(); i += N) {
+ if (0 == m_cubemaps[i])
+ continue;
+
+ float angle = 2.0f * PI * i / m_cubemaps.size();
+
+ center = m_trackBalls[1].rotation().rotatedVector(QVector3D(cos(angle), sin(angle), 0.0f));
+
+ for (int face = 0; face < 6; ++face) {
+ m_cubemaps[i]->begin(face);
+
+ GLRenderTargetCube::getViewMatrix(mat, face);
+ QVector4D v = QVector4D(-center.x(), -center.y(), -center.z(), 1.0);
+ mat.setColumn(3, mat * v);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ renderBoxes(mat, i);
+
+ m_cubemaps[i]->end();
+ }
+ }
+
+ for (int face = 0; face < 6; ++face) {
+ m_mainCubemap->begin(face);
+ GLRenderTargetCube::getViewMatrix(mat, face);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ renderBoxes(mat, -1);
+
+ m_mainCubemap->end();
+ }
+
+ glPopMatrix();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ m_updateAllCubemaps = false;
+}
+
+void Scene::drawBackground(QPainter *painter, const QRectF &)
+{
+ float width = float(painter->device()->width());
+ float height = float(painter->device()->height());
+
+ painter->beginNativePainting();
+ setStates();
+
+ if (m_dynamicCubemap)
+ renderCubemaps();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ qgluPerspective(60.0, width / height, 0.01, 15.0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ QMatrix4x4 view;
+ view.rotate(m_trackBalls[2].rotation());
+ view(2, 3) -= 2.0f * exp(m_distExp / 1200.0f);
+ renderBoxes(view);
+
+ defaultStates();
+ ++m_frame;
+
+ painter->endNativePainting();
+}
+
+QPointF Scene::pixelPosToViewPos(const QPointF& p)
+{
+ return QPointF(2.0 * float(p.x()) / width() - 1.0,
+ 1.0 - 2.0 * float(p.y()) / height());
+}
+
+void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsScene::mouseMoveEvent(event);
+ if (event->isAccepted())
+ return;
+
+ if (event->buttons() & Qt::LeftButton) {
+ m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ } else {
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ }
+
+ if (event->buttons() & Qt::RightButton) {
+ m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ } else {
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ }
+
+ if (event->buttons() & Qt::MidButton) {
+ m_trackBalls[2].move(pixelPosToViewPos(event->scenePos()), QQuaternion());
+ event->accept();
+ } else {
+ m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion());
+ }
+}
+
+void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsScene::mousePressEvent(event);
+ if (event->isAccepted())
+ return;
+
+ if (event->buttons() & Qt::LeftButton) {
+ m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ }
+
+ if (event->buttons() & Qt::RightButton) {
+ m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ }
+
+ if (event->buttons() & Qt::MidButton) {
+ m_trackBalls[2].push(pixelPosToViewPos(event->scenePos()), QQuaternion());
+ event->accept();
+ }
+}
+
+void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsScene::mouseReleaseEvent(event);
+ if (event->isAccepted())
+ return;
+
+ if (event->button() == Qt::LeftButton) {
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ }
+
+ if (event->button() == Qt::RightButton) {
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ event->accept();
+ }
+
+ if (event->button() == Qt::MidButton) {
+ m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion());
+ event->accept();
+ }
+}
+
+void Scene::wheelEvent(QGraphicsSceneWheelEvent * event)
+{
+ QGraphicsScene::wheelEvent(event);
+ if (!event->isAccepted()) {
+ m_distExp += event->delta();
+ if (m_distExp < -8 * 120)
+ m_distExp = -8 * 120;
+ if (m_distExp > 10 * 120)
+ m_distExp = 10 * 120;
+ event->accept();
+ }
+}
+
+void Scene::setShader(int index)
+{
+ if (index >= 0 && index < m_fragmentShaders.size())
+ m_currentShader = index;
+}
+
+void Scene::setTexture(int index)
+{
+ if (index >= 0 && index < m_textures.size())
+ m_currentTexture = index;
+}
+
+void Scene::toggleDynamicCubemap(int state)
+{
+ if ((m_dynamicCubemap = (state == Qt::Checked)))
+ m_updateAllCubemaps = true;
+}
+
+void Scene::setColorParameter(const QString &name, QRgb color)
+{
+ // set the color in all programs
+ foreach (QGLShaderProgram *program, m_programs) {
+ program->bind();
+ program->setUniformValue(program->uniformLocation(name), QColor(color));
+ program->release();
+ }
+}
+
+void Scene::setFloatParameter(const QString &name, float value)
+{
+ // set the color in all programs
+ foreach (QGLShaderProgram *program, m_programs) {
+ program->bind();
+ program->setUniformValue(program->uniformLocation(name), value);
+ program->release();
+ }
+}
+
+void Scene::newItem(ItemDialog::ItemType type)
+{
+ QSize size = sceneRect().size().toSize();
+ switch (type) {
+ case ItemDialog::QtBoxItem:
+ addItem(new QtBox(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32));
+ break;
+ case ItemDialog::CircleItem:
+ addItem(new CircleItem(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32));
+ break;
+ case ItemDialog::SquareItem:
+ addItem(new SquareItem(64, rand() % (size.width() - 64) + 32, rand() % (size.height() - 64) + 32));
+ break;
+ default:
+ break;
+ }
+}
diff --git a/examples/graphicsview/boxes/scene.h b/examples/graphicsview/boxes/scene.h
new file mode 100644
index 0000000000..96ee908d58
--- /dev/null
+++ b/examples/graphicsview/boxes/scene.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_H
+#define SCENE_H
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include &