summaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /demos
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'demos')
-rw-r--r--demos/README39
-rw-r--r--demos/affine/affine.pro25
-rw-r--r--demos/affine/affine.qrc7
-rw-r--r--demos/affine/bg1.jpgbin0 -> 23771 bytes
-rw-r--r--demos/affine/main.cpp65
-rw-r--r--demos/affine/xform.cpp902
-rw-r--r--demos/affine/xform.h141
-rw-r--r--demos/affine/xform.html23
-rw-r--r--demos/books/bookdelegate.cpp126
-rw-r--r--demos/books/bookdelegate.h73
-rw-r--r--demos/books/books.pro23
-rw-r--r--demos/books/books.qrc5
-rw-r--r--demos/books/bookwindow.cpp121
-rw-r--r--demos/books/bookwindow.h64
-rw-r--r--demos/books/bookwindow.ui149
-rw-r--r--demos/books/images/star.pngbin0 -> 782 bytes
-rw-r--r--demos/books/initdb.h125
-rw-r--r--demos/books/main.cpp56
-rw-r--r--demos/boxes/3rdparty/fbm.c207
-rw-r--r--demos/boxes/3rdparty/fbm.h40
-rw-r--r--demos/boxes/basic.fsh73
-rw-r--r--demos/boxes/basic.vsh61
-rw-r--r--demos/boxes/boxes.pro49
-rw-r--r--demos/boxes/boxes.qrc25
-rw-r--r--demos/boxes/cubemap_negx.jpgbin0 -> 41060 bytes
-rw-r--r--demos/boxes/cubemap_negy.jpgbin0 -> 15520 bytes
-rw-r--r--demos/boxes/cubemap_negz.jpgbin0 -> 68911 bytes
-rw-r--r--demos/boxes/cubemap_posx.jpgbin0 -> 74915 bytes
-rw-r--r--demos/boxes/cubemap_posy.jpgbin0 -> 24193 bytes
-rw-r--r--demos/boxes/cubemap_posz.jpgbin0 -> 57881 bytes
-rw-r--r--demos/boxes/dotted.fsh66
-rw-r--r--demos/boxes/fresnel.fsh79
-rw-r--r--demos/boxes/glass.fsh76
-rw-r--r--demos/boxes/glbuffers.cpp402
-rw-r--r--demos/boxes/glbuffers.h366
-rw-r--r--demos/boxes/glextensions.cpp98
-rw-r--r--demos/boxes/glextensions.h202
-rw-r--r--demos/boxes/gltrianglemesh.h91
-rw-r--r--demos/boxes/granite.fsh76
-rw-r--r--demos/boxes/main.cpp150
-rw-r--r--demos/boxes/marble.fsh71
-rw-r--r--demos/boxes/parameters.par5
-rw-r--r--demos/boxes/qt-logo.jpgbin0 -> 40886 bytes
-rw-r--r--demos/boxes/qt-logo.pngbin0 -> 13923 bytes
-rw-r--r--demos/boxes/qtbox.cpp480
-rw-r--r--demos/boxes/qtbox.h118
-rw-r--r--demos/boxes/reflection.fsh54
-rw-r--r--demos/boxes/refraction.fsh70
-rw-r--r--demos/boxes/roundedbox.cpp161
-rw-r--r--demos/boxes/roundedbox.h72
-rw-r--r--demos/boxes/scene.cpp1085
-rw-r--r--demos/boxes/scene.h245
-rw-r--r--demos/boxes/smiley.pngbin0 -> 14508 bytes
-rw-r--r--demos/boxes/square.jpgbin0 -> 14542 bytes
-rw-r--r--demos/boxes/trackball.cpp160
-rw-r--r--demos/boxes/trackball.h79
-rw-r--r--demos/boxes/wood.fsh70
-rw-r--r--demos/chip/chip.cpp183
-rw-r--r--demos/chip/chip.h68
-rw-r--r--demos/chip/chip.pro20
-rw-r--r--demos/chip/fileprint.pngbin0 -> 1456 bytes
-rw-r--r--demos/chip/images.qrc10
-rw-r--r--demos/chip/main.cpp57
-rw-r--r--demos/chip/mainwindow.cpp109
-rw-r--r--demos/chip/mainwindow.h68
-rw-r--r--demos/chip/qt4logo.pngbin0 -> 48333 bytes
-rw-r--r--demos/chip/rotateleft.pngbin0 -> 1754 bytes
-rw-r--r--demos/chip/rotateright.pngbin0 -> 1732 bytes
-rw-r--r--demos/chip/view.cpp276
-rw-r--r--demos/chip/view.h104
-rw-r--r--demos/chip/zoomin.pngbin0 -> 1622 bytes
-rw-r--r--demos/chip/zoomout.pngbin0 -> 1601 bytes
-rw-r--r--demos/composition/composition.cpp544
-rw-r--r--demos/composition/composition.h193
-rw-r--r--demos/composition/composition.html23
-rw-r--r--demos/composition/composition.pro29
-rw-r--r--demos/composition/composition.qrc8
-rw-r--r--demos/composition/flower.jpgbin0 -> 49616 bytes
-rw-r--r--demos/composition/flower_alpha.jpgbin0 -> 67326 bytes
-rw-r--r--demos/composition/main.cpp68
-rw-r--r--demos/deform/deform.pro24
-rw-r--r--demos/deform/deform.qrc6
-rw-r--r--demos/deform/main.cpp72
-rw-r--r--demos/deform/pathdeform.cpp647
-rw-r--r--demos/deform/pathdeform.h153
-rw-r--r--demos/deform/pathdeform.html24
-rw-r--r--demos/demos.pro116
-rw-r--r--demos/embedded/digiflip/digiflip.cpp425
-rw-r--r--demos/embedded/digiflip/digiflip.pro11
-rw-r--r--demos/embedded/embedded.pro32
-rw-r--r--demos/embedded/flickable/flickable.cpp284
-rw-r--r--demos/embedded/flickable/flickable.h80
-rw-r--r--demos/embedded/flickable/flickable.pro12
-rw-r--r--demos/embedded/flickable/main.cpp233
-rw-r--r--demos/embedded/flightinfo/aircraft.pngbin0 -> 20200 bytes
-rw-r--r--demos/embedded/flightinfo/flightinfo.cpp399
-rw-r--r--demos/embedded/flightinfo/flightinfo.pro17
-rw-r--r--demos/embedded/flightinfo/flightinfo.qrc5
-rw-r--r--demos/embedded/flightinfo/form.ui226
-rw-r--r--demos/embedded/lightmaps/lightmaps.cpp287
-rw-r--r--demos/embedded/lightmaps/lightmaps.h88
-rw-r--r--demos/embedded/lightmaps/lightmaps.pro21
-rw-r--r--demos/embedded/lightmaps/main.cpp63
-rw-r--r--demos/embedded/lightmaps/mapzoom.cpp147
-rw-r--r--demos/embedded/lightmaps/mapzoom.h69
-rw-r--r--demos/embedded/lightmaps/slippymap.cpp213
-rw-r--r--demos/embedded/lightmaps/slippymap.h87
-rw-r--r--demos/embedded/raycasting/raycasting.cpp391
-rw-r--r--demos/embedded/raycasting/raycasting.pro13
-rw-r--r--demos/embedded/raycasting/raycasting.qrc5
-rw-r--r--demos/embedded/raycasting/textures.pngbin0 -> 17669 bytes
-rwxr-xr-xdemos/embedded/styledemo/files/add.pngbin0 -> 1474 bytes
-rw-r--r--demos/embedded/styledemo/files/application.qss125
-rw-r--r--demos/embedded/styledemo/files/blue.qss38
-rw-r--r--demos/embedded/styledemo/files/khaki.qss99
-rw-r--r--demos/embedded/styledemo/files/nature_1.jpgbin0 -> 167443 bytes
-rw-r--r--demos/embedded/styledemo/files/nostyle.qss0
-rwxr-xr-xdemos/embedded/styledemo/files/remove.pngbin0 -> 865 bytes
-rw-r--r--demos/embedded/styledemo/files/transparent.qss139
-rw-r--r--demos/embedded/styledemo/main.cpp59
-rw-r--r--demos/embedded/styledemo/styledemo.pro17
-rw-r--r--demos/embedded/styledemo/styledemo.qrc13
-rw-r--r--demos/embedded/styledemo/stylewidget.cpp112
-rw-r--r--demos/embedded/styledemo/stylewidget.h65
-rw-r--r--demos/embedded/styledemo/stylewidget.ui417
-rw-r--r--demos/embeddeddialogs/No-Ones-Laughing-3.jpgbin0 -> 30730 bytes
-rw-r--r--demos/embeddeddialogs/customproxy.cpp167
-rw-r--r--demos/embeddeddialogs/customproxy.h76
-rw-r--r--demos/embeddeddialogs/embeddeddialog.cpp106
-rw-r--r--demos/embeddeddialogs/embeddeddialog.h66
-rw-r--r--demos/embeddeddialogs/embeddeddialog.ui87
-rw-r--r--demos/embeddeddialogs/embeddeddialogs.pro19
-rw-r--r--demos/embeddeddialogs/embeddeddialogs.qrc5
-rw-r--r--demos/embeddeddialogs/main.cpp83
-rw-r--r--demos/gradients/gradients.cpp516
-rw-r--r--demos/gradients/gradients.h170
-rw-r--r--demos/gradients/gradients.html31
-rw-r--r--demos/gradients/gradients.pro20
-rw-r--r--demos/gradients/gradients.qrc6
-rw-r--r--demos/gradients/main.cpp63
-rw-r--r--demos/interview/README2
-rw-r--r--demos/interview/images/folder.pngbin0 -> 3910 bytes
-rw-r--r--demos/interview/images/interview.pngbin0 -> 174 bytes
-rw-r--r--demos/interview/images/services.pngbin0 -> 3749 bytes
-rw-r--r--demos/interview/interview.pro19
-rw-r--r--demos/interview/interview.qrc7
-rw-r--r--demos/interview/main.cpp95
-rw-r--r--demos/interview/model.cpp147
-rw-r--r--demos/interview/model.h90
-rw-r--r--demos/macmainwindow/macmainwindow.h137
-rw-r--r--demos/macmainwindow/macmainwindow.mm347
-rw-r--r--demos/macmainwindow/macmainwindow.pro23
-rw-r--r--demos/macmainwindow/main.cpp66
-rw-r--r--demos/mainwindow/colorswatch.cpp746
-rw-r--r--demos/mainwindow/colorswatch.h136
-rw-r--r--demos/mainwindow/main.cpp164
-rw-r--r--demos/mainwindow/mainwindow.cpp514
-rw-r--r--demos/mainwindow/mainwindow.h90
-rw-r--r--demos/mainwindow/mainwindow.pro17
-rw-r--r--demos/mainwindow/mainwindow.qrc8
-rw-r--r--demos/mainwindow/qt.pngbin0 -> 2037 bytes
-rw-r--r--demos/mainwindow/titlebarCenter.pngbin0 -> 146 bytes
-rw-r--r--demos/mainwindow/titlebarLeft.pngbin0 -> 5148 bytes
-rw-r--r--demos/mainwindow/titlebarRight.pngbin0 -> 2704 bytes
-rw-r--r--demos/mainwindow/toolbar.cpp383
-rw-r--r--demos/mainwindow/toolbar.h118
-rw-r--r--demos/pathstroke/main.cpp71
-rw-r--r--demos/pathstroke/pathstroke.cpp686
-rw-r--r--demos/pathstroke/pathstroke.h171
-rw-r--r--demos/pathstroke/pathstroke.html20
-rw-r--r--demos/pathstroke/pathstroke.pro24
-rw-r--r--demos/pathstroke/pathstroke.qrc6
-rw-r--r--demos/shared/arthurstyle.cpp452
-rw-r--r--demos/shared/arthurstyle.h79
-rw-r--r--demos/shared/arthurwidgets.cpp371
-rw-r--r--demos/shared/arthurwidgets.h137
-rw-r--r--demos/shared/hoverpoints.cpp415
-rw-r--r--demos/shared/hoverpoints.h162
-rw-r--r--demos/shared/images/bg_pattern.pngbin0 -> 104 bytes
-rw-r--r--demos/shared/images/button_normal_cap_left.pngbin0 -> 654 bytes
-rw-r--r--demos/shared/images/button_normal_cap_right.pngbin0 -> 674 bytes
-rw-r--r--demos/shared/images/button_normal_stretch.pngbin0 -> 185 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_left.pngbin0 -> 710 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_right.pngbin0 -> 785 bytes
-rw-r--r--demos/shared/images/button_pressed_stretch.pngbin0 -> 217 bytes
-rw-r--r--demos/shared/images/curve_thing_edit-6.pngbin0 -> 58097 bytes
-rw-r--r--demos/shared/images/frame_bottom.pngbin0 -> 166 bytes
-rw-r--r--demos/shared/images/frame_bottomleft.pngbin0 -> 602 bytes
-rw-r--r--demos/shared/images/frame_bottomright.pngbin0 -> 553 bytes
-rw-r--r--demos/shared/images/frame_left.pngbin0 -> 182 bytes
-rw-r--r--demos/shared/images/frame_right.pngbin0 -> 175 bytes
-rw-r--r--demos/shared/images/frame_top.pngbin0 -> 188 bytes
-rw-r--r--demos/shared/images/frame_topleft.pngbin0 -> 801 bytes
-rw-r--r--demos/shared/images/frame_topright.pngbin0 -> 851 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_left.pngbin0 -> 397 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_right.pngbin0 -> 383 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_stretch.pngbin0 -> 141 bytes
-rw-r--r--demos/shared/images/groupframe_left_stretch.pngbin0 -> 132 bytes
-rw-r--r--demos/shared/images/groupframe_right_stretch.pngbin0 -> 113 bytes
-rw-r--r--demos/shared/images/groupframe_top_stretch.pngbin0 -> 115 bytes
-rw-r--r--demos/shared/images/groupframe_topleft.pngbin0 -> 412 bytes
-rw-r--r--demos/shared/images/groupframe_topright.pngbin0 -> 449 bytes
-rw-r--r--demos/shared/images/line_dash_dot.pngbin0 -> 151 bytes
-rw-r--r--demos/shared/images/line_dash_dot_dot.pngbin0 -> 155 bytes
-rw-r--r--demos/shared/images/line_dashed.pngbin0 -> 121 bytes
-rw-r--r--demos/shared/images/line_dotted.pngbin0 -> 116 bytes
-rw-r--r--demos/shared/images/line_solid.pngbin0 -> 110 bytes
-rw-r--r--demos/shared/images/radiobutton-off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton-on.pngbin0 -> 474 bytes
-rw-r--r--demos/shared/images/radiobutton_off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton_on.pngbin0 -> 499 bytes
-rw-r--r--demos/shared/images/slider_bar.pngbin0 -> 748 bytes
-rw-r--r--demos/shared/images/slider_thumb_off.pngbin0 -> 823 bytes
-rw-r--r--demos/shared/images/slider_thumb_on.pngbin0 -> 798 bytes
-rw-r--r--demos/shared/images/title_cap_left.pngbin0 -> 179 bytes
-rw-r--r--demos/shared/images/title_cap_right.pngbin0 -> 184 bytes
-rw-r--r--demos/shared/images/title_stretch.pngbin0 -> 106 bytes
-rw-r--r--demos/shared/shared.pri21
-rw-r--r--demos/shared/shared.pro38
-rw-r--r--demos/shared/shared.qrc39
-rw-r--r--demos/spreadsheet/images/interview.pngbin0 -> 174 bytes
-rw-r--r--demos/spreadsheet/main.cpp55
-rw-r--r--demos/spreadsheet/printview.cpp59
-rw-r--r--demos/spreadsheet/printview.h60
-rw-r--r--demos/spreadsheet/spreadsheet.cpp633
-rw-r--r--demos/spreadsheet/spreadsheet.h124
-rw-r--r--demos/spreadsheet/spreadsheet.pro34
-rw-r--r--demos/spreadsheet/spreadsheet.qrc5
-rw-r--r--demos/spreadsheet/spreadsheetdelegate.cpp114
-rw-r--r--demos/spreadsheet/spreadsheetdelegate.h65
-rw-r--r--demos/spreadsheet/spreadsheetitem.cpp167
-rw-r--r--demos/spreadsheet/spreadsheetitem.h73
-rw-r--r--demos/sqlbrowser/browser.cpp247
-rw-r--r--demos/sqlbrowser/browser.h99
-rw-r--r--demos/sqlbrowser/browserwidget.ui199
-rw-r--r--demos/sqlbrowser/connectionwidget.cpp165
-rw-r--r--demos/sqlbrowser/connectionwidget.h79
-rw-r--r--demos/sqlbrowser/main.cpp91
-rw-r--r--demos/sqlbrowser/qsqlconnectiondialog.cpp115
-rw-r--r--demos/sqlbrowser/qsqlconnectiondialog.h74
-rw-r--r--demos/sqlbrowser/qsqlconnectiondialog.ui224
-rw-r--r--demos/sqlbrowser/sqlbrowser.pro25
-rw-r--r--demos/sub-attaq/animationmanager.cpp98
-rw-r--r--demos/sub-attaq/animationmanager.h73
-rw-r--r--demos/sub-attaq/boat.cpp272
-rw-r--r--demos/sub-attaq/boat.h95
-rw-r--r--demos/sub-attaq/boat_p.h232
-rw-r--r--demos/sub-attaq/bomb.cpp118
-rw-r--r--demos/sub-attaq/bomb.h67
-rw-r--r--demos/sub-attaq/data.xml39
-rw-r--r--demos/sub-attaq/graphicsscene.cpp282
-rw-r--r--demos/sub-attaq/graphicsscene.h122
-rw-r--r--demos/sub-attaq/main.cpp57
-rw-r--r--demos/sub-attaq/mainwindow.cpp82
-rw-r--r--demos/sub-attaq/mainwindow.h63
-rw-r--r--demos/sub-attaq/pics/big/background.pngbin0 -> 48858 bytes
-rw-r--r--demos/sub-attaq/pics/big/boat.pngbin0 -> 5198 bytes
-rw-r--r--demos/sub-attaq/pics/big/bomb.pngbin0 -> 760 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/boat/step1.pngbin0 -> 5760 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/boat/step2.pngbin0 -> 9976 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/boat/step3.pngbin0 -> 12411 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/boat/step4.pngbin0 -> 15438 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/submarine/step1.pngbin0 -> 3354 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/submarine/step2.pngbin0 -> 6205 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/submarine/step3.pngbin0 -> 6678 bytes
-rw-r--r--demos/sub-attaq/pics/big/explosion/submarine/step4.pngbin0 -> 6666 bytes
-rw-r--r--demos/sub-attaq/pics/big/submarine.pngbin0 -> 3202 bytes
-rw-r--r--demos/sub-attaq/pics/big/surface.pngbin0 -> 575 bytes
-rw-r--r--demos/sub-attaq/pics/big/torpedo.pngbin0 -> 951 bytes
-rw-r--r--demos/sub-attaq/pics/scalable/background-n810.svg171
-rw-r--r--demos/sub-attaq/pics/scalable/background.svg171
-rw-r--r--demos/sub-attaq/pics/scalable/boat.svg279
-rw-r--r--demos/sub-attaq/pics/scalable/bomb.svg138
-rw-r--r--demos/sub-attaq/pics/scalable/sand.svg103
-rw-r--r--demos/sub-attaq/pics/scalable/see.svg44
-rw-r--r--demos/sub-attaq/pics/scalable/sky.svg45
-rw-r--r--demos/sub-attaq/pics/scalable/sub-attaq.svg1473
-rw-r--r--demos/sub-attaq/pics/scalable/submarine.svg214
-rw-r--r--demos/sub-attaq/pics/scalable/surface.svg49
-rw-r--r--demos/sub-attaq/pics/scalable/torpedo.svg127
-rw-r--r--demos/sub-attaq/pics/small/background.pngbin0 -> 34634 bytes
-rw-r--r--demos/sub-attaq/pics/small/boat.pngbin0 -> 2394 bytes
-rw-r--r--demos/sub-attaq/pics/small/bomb.pngbin0 -> 760 bytes
-rw-r--r--demos/sub-attaq/pics/small/submarine.pngbin0 -> 1338 bytes
-rw-r--r--demos/sub-attaq/pics/small/surface.pngbin0 -> 502 bytes
-rw-r--r--demos/sub-attaq/pics/small/torpedo.pngbin0 -> 951 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-a.pngbin0 -> 5972 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-a2.pngbin0 -> 5969 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-b.pngbin0 -> 6869 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-dash.pngbin0 -> 2255 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-excl.pngbin0 -> 2740 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-q.pngbin0 -> 7016 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-s.pngbin0 -> 5817 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-t.pngbin0 -> 3717 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-t2.pngbin0 -> 3688 bytes
-rw-r--r--demos/sub-attaq/pics/welcome/logo-u.pngbin0 -> 5374 bytes
-rw-r--r--demos/sub-attaq/pixmapitem.cpp76
-rw-r--r--demos/sub-attaq/pixmapitem.h63
-rw-r--r--demos/sub-attaq/progressitem.cpp67
-rw-r--r--demos/sub-attaq/progressitem.h61
-rw-r--r--demos/sub-attaq/qanimationstate.cpp150
-rw-r--r--demos/sub-attaq/qanimationstate.h92
-rw-r--r--demos/sub-attaq/states.cpp330
-rw-r--r--demos/sub-attaq/states.h180
-rw-r--r--demos/sub-attaq/sub-attaq.pro41
-rw-r--r--demos/sub-attaq/subattaq.qrc39
-rw-r--r--demos/sub-attaq/submarine.cpp182
-rw-r--r--demos/sub-attaq/submarine.h93
-rw-r--r--demos/sub-attaq/submarine_p.h137
-rw-r--r--demos/sub-attaq/textinformationitem.cpp54
-rw-r--r--demos/sub-attaq/textinformationitem.h55
-rw-r--r--demos/sub-attaq/torpedo.cpp114
-rw-r--r--demos/sub-attaq/torpedo.h67
-rw-r--r--demos/symbianpkgrules.pri19
-rw-r--r--demos/textedit/example.html79
-rw-r--r--demos/textedit/images/logo32.pngbin0 -> 1410 bytes
-rw-r--r--demos/textedit/images/mac/editcopy.pngbin0 -> 1468 bytes
-rw-r--r--demos/textedit/images/mac/editcut.pngbin0 -> 1512 bytes
-rw-r--r--demos/textedit/images/mac/editpaste.pngbin0 -> 1906 bytes
-rw-r--r--demos/textedit/images/mac/editredo.pngbin0 -> 1752 bytes
-rw-r--r--demos/textedit/images/mac/editundo.pngbin0 -> 1746 bytes
-rw-r--r--demos/textedit/images/mac/exportpdf.pngbin0 -> 1215 bytes
-rw-r--r--demos/textedit/images/mac/filenew.pngbin0 -> 1172 bytes
-rw-r--r--demos/textedit/images/mac/fileopen.pngbin0 -> 2168 bytes
-rw-r--r--demos/textedit/images/mac/fileprint.pngbin0 -> 2087 bytes
-rw-r--r--demos/textedit/images/mac/filesave.pngbin0 -> 1206 bytes
-rw-r--r--demos/textedit/images/mac/textbold.pngbin0 -> 1611 bytes
-rw-r--r--demos/textedit/images/mac/textcenter.pngbin0 -> 1404 bytes
-rw-r--r--demos/textedit/images/mac/textitalic.pngbin0 -> 1164 bytes
-rw-r--r--demos/textedit/images/mac/textjustify.pngbin0 -> 1257 bytes
-rw-r--r--demos/textedit/images/mac/textleft.pngbin0 -> 1235 bytes
-rw-r--r--demos/textedit/images/mac/textright.pngbin0 -> 1406 bytes
-rw-r--r--demos/textedit/images/mac/textunder.pngbin0 -> 1183 bytes
-rw-r--r--demos/textedit/images/mac/zoomin.pngbin0 -> 1696 bytes
-rw-r--r--demos/textedit/images/mac/zoomout.pngbin0 -> 1662 bytes
-rw-r--r--demos/textedit/images/win/editcopy.pngbin0 -> 1325 bytes
-rw-r--r--demos/textedit/images/win/editcut.pngbin0 -> 1896 bytes
-rw-r--r--demos/textedit/images/win/editpaste.pngbin0 -> 1482 bytes
-rw-r--r--demos/textedit/images/win/editredo.pngbin0 -> 1787 bytes
-rw-r--r--demos/textedit/images/win/editundo.pngbin0 -> 1768 bytes
-rw-r--r--demos/textedit/images/win/exportpdf.pngbin0 -> 1059 bytes
-rw-r--r--demos/textedit/images/win/filenew.pngbin0 -> 768 bytes
-rw-r--r--demos/textedit/images/win/fileopen.pngbin0 -> 1662 bytes
-rw-r--r--demos/textedit/images/win/fileprint.pngbin0 -> 1456 bytes
-rw-r--r--demos/textedit/images/win/filesave.pngbin0 -> 1205 bytes
-rw-r--r--demos/textedit/images/win/textbold.pngbin0 -> 1134 bytes
-rw-r--r--demos/textedit/images/win/textcenter.pngbin0 -> 627 bytes
-rw-r--r--demos/textedit/images/win/textitalic.pngbin0 -> 829 bytes
-rw-r--r--demos/textedit/images/win/textjustify.pngbin0 -> 695 bytes
-rw-r--r--demos/textedit/images/win/textleft.pngbin0 -> 673 bytes
-rw-r--r--demos/textedit/images/win/textright.pngbin0 -> 677 bytes
-rw-r--r--demos/textedit/images/win/textunder.pngbin0 -> 971 bytes
-rw-r--r--demos/textedit/images/win/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--demos/textedit/images/win/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--demos/textedit/main.cpp54
-rw-r--r--demos/textedit/textedit.cpp734
-rw-r--r--demos/textedit/textedit.h129
-rw-r--r--demos/textedit/textedit.pro22
-rw-r--r--demos/textedit/textedit.qdoc45
-rw-r--r--demos/textedit/textedit.qrc44
-rw-r--r--demos/undo/commands.cpp180
-rw-r--r--demos/undo/commands.h112
-rw-r--r--demos/undo/document.cpp445
-rw-r--r--demos/undo/document.h125
-rw-r--r--demos/undo/icons/background.pngbin0 -> 93 bytes
-rw-r--r--demos/undo/icons/blue.pngbin0 -> 1659 bytes
-rw-r--r--demos/undo/icons/circle.pngbin0 -> 1359 bytes
-rw-r--r--demos/undo/icons/exit.pngbin0 -> 1731 bytes
-rw-r--r--demos/undo/icons/fileclose.pngbin0 -> 1121 bytes
-rw-r--r--demos/undo/icons/filenew.pngbin0 -> 1266 bytes
-rw-r--r--demos/undo/icons/fileopen.pngbin0 -> 1771 bytes
-rw-r--r--demos/undo/icons/filesave.pngbin0 -> 1022 bytes
-rw-r--r--demos/undo/icons/green.pngbin0 -> 1766 bytes
-rw-r--r--demos/undo/icons/ok.pngbin0 -> 979 bytes
-rw-r--r--demos/undo/icons/rectangle.pngbin0 -> 690 bytes
-rw-r--r--demos/undo/icons/red.pngbin0 -> 1653 bytes
-rw-r--r--demos/undo/icons/redo.pngbin0 -> 985 bytes
-rw-r--r--demos/undo/icons/remove.pngbin0 -> 1833 bytes
-rw-r--r--demos/undo/icons/triangle.pngbin0 -> 850 bytes
-rw-r--r--demos/undo/icons/undo.pngbin0 -> 962 bytes
-rw-r--r--demos/undo/main.cpp56
-rw-r--r--demos/undo/mainwindow.cpp446
-rw-r--r--demos/undo/mainwindow.h87
-rw-r--r--demos/undo/mainwindow.ui322
-rw-r--r--demos/undo/undo.pro18
-rw-r--r--demos/undo/undo.qrc20
386 files changed, 32744 insertions, 0 deletions
diff --git a/demos/README b/demos/README
new file mode 100644
index 0000000000..b1619908e2
--- /dev/null
+++ b/demos/README
@@ -0,0 +1,39 @@
+These demonstrations are intended to highlight Qt's capabilities in different
+application areas, and provide examples that are more advanced than those in
+the examples directory.
+
+Beginners to Qt may wish to try out the Qt tutorial and some of the examples
+before examining the demonstrations in detail.
+
+
+The example launcher can be used to explore the different categories
+available. It provides an overview of each example, lets you view the
+documentation in Qt Assistant, and is able to launch examples.
+
+
+Finding the Qt Examples and Demos launcher
+==========================================
+
+On Windows:
+
+The launcher can be accessed via the Windows Start menu. Select the menu
+entry entitled "Qt Examples and Demos" entry in the submenu containing
+the Qt tools.
+
+On Mac OS X:
+
+For the binary distribution, the qtdemo executable is installed in the
+/Developer/Applications/Qt directory. For the source distribution, it is
+installed alongside the other Qt tools on the path specified when Qt is
+configured.
+
+On Unix/Linux:
+
+The qtdemo executable is installed alongside the other Qt tools on the path
+specified when Qt is configured.
+
+On all platforms:
+
+The source code for the launcher can be found in the demos/qtdemo directory
+in the Qt package. This example is built at the same time as the Qt libraries,
+tools, examples, and demonstrations.
diff --git a/demos/affine/affine.pro b/demos/affine/affine.pro
new file mode 100644
index 0000000000..4f869987b9
--- /dev/null
+++ b/demos/affine/affine.pro
@@ -0,0 +1,25 @@
+SOURCES += main.cpp xform.cpp
+HEADERS += xform.h
+
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += affine.qrc
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/affine
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html *.jpg
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/affine
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+wince*: {
+ DEPLOYMENT_PLUGIN += qjpeg
+}
diff --git a/demos/affine/affine.qrc b/demos/affine/affine.qrc
new file mode 100644
index 0000000000..d8a7ae40cb
--- /dev/null
+++ b/demos/affine/affine.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/affine">
+ <file>xform.cpp</file>
+ <file>xform.html</file>
+ <file>bg1.jpg</file>
+</qresource>
+</RCC>
diff --git a/demos/affine/bg1.jpg b/demos/affine/bg1.jpg
new file mode 100644
index 0000000000..dfc7cee6ad
--- /dev/null
+++ b/demos/affine/bg1.jpg
Binary files differ
diff --git a/demos/affine/main.cpp b/demos/affine/main.cpp
new file mode 100644
index 0000000000..92b7fab81d
--- /dev/null
+++ b/demos/affine/main.cpp
@@ -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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xform.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(affine);
+
+ QApplication app(argc, argv);
+
+ XFormWidget xformWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ xformWidget.setStyle(arthurStyle);
+
+ QList<QWidget *> widgets = xformWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets) {
+ w->setStyle(arthurStyle);
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+
+ xformWidget.show();
+
+ return app.exec();
+}
diff --git a/demos/affine/xform.cpp b/demos/affine/xform.cpp
new file mode 100644
index 0000000000..724b640664
--- /dev/null
+++ b/demos/affine/xform.cpp
@@ -0,0 +1,902 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xform.h"
+#include "hoverpoints.h"
+
+#include <QLayout>
+#include <QPainter>
+#include <QPainterPath>
+
+const int alpha = 155;
+
+XFormView::XFormView(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ setAttribute(Qt::WA_MouseTracking);
+ m_type = VectorType;
+ m_rotation = 0.0;
+ m_scale = 1.0;
+ m_shear = 0.0;
+
+ m_pixmap = QPixmap(":res/affine/bg1.jpg");
+ pts = new HoverPoints(this, HoverPoints::CircleShape);
+ pts->setConnectionType(HoverPoints::LineConnection);
+ pts->setEditable(false);
+ pts->setPointSize(QSize(15, 15));
+ pts->setShapeBrush(QBrush(QColor(151, 0, 0, alpha)));
+ pts->setShapePen(QPen(QColor(255, 100, 50, alpha)));
+ pts->setConnectionPen(QPen(QColor(151, 0, 0, 50)));
+ pts->setBoundingRect(QRectF(0, 0, 500, 500));
+ ctrlPoints << QPointF(250, 250) << QPointF(350, 250);
+ pts->setPoints(ctrlPoints);
+ connect(pts, SIGNAL(pointsChanged(QPolygonF)),
+ this, SLOT(updateCtrlPoints(QPolygonF)));
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+
+XFormView::XFormType XFormView::type() const
+{
+ return m_type;
+}
+
+QPixmap XFormView::pixmap() const
+{
+ return m_pixmap;
+}
+
+QString XFormView::text() const
+{
+ return m_text;
+}
+
+void XFormView::setText(const QString &t)
+{
+ m_text = t;
+ update();
+}
+
+void XFormView::setPixmap(const QPixmap &p)
+{
+ m_pixmap = p;
+ update();
+}
+
+void XFormView::setType(XFormType t)
+{
+ m_type = t;
+ update();
+}
+
+void XFormView::mousePressEvent(QMouseEvent *)
+{
+ setDescriptionEnabled(false);
+}
+
+void XFormView::resizeEvent(QResizeEvent *e)
+{
+ pts->setBoundingRect(rect());
+ ArthurFrame::resizeEvent(e);
+}
+
+void XFormView::paint(QPainter *p)
+{
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ switch (m_type) {
+ case VectorType:
+ drawVectorType(p);
+ break;
+ case PixmapType:
+ drawPixmapType(p);
+ break;
+ case TextType:
+ drawTextType(p);
+ break;
+ }
+ p->restore();
+}
+
+void XFormView::updateCtrlPoints(const QPolygonF &points)
+{
+ QPointF trans = points.at(0) - ctrlPoints.at(0);
+
+ if (qAbs(points.at(0).x() - points.at(1).x()) < 10
+ && qAbs(points.at(0).y() - points.at(1).y()) < 10)
+ pts->setPoints(ctrlPoints);
+ if (!trans.isNull()) {
+ ctrlPoints[0] = points.at(0);
+ ctrlPoints[1] += trans;
+ pts->setPoints(ctrlPoints);
+ }
+ ctrlPoints = points;
+
+ QLineF line(ctrlPoints.at(0), ctrlPoints.at(1));
+ m_rotation = line.angle(QLineF(0, 0, 1, 0));
+ if (line.dy() < 0)
+ m_rotation = 360 - m_rotation;
+
+ if (trans.isNull())
+ emit rotationChanged(int(m_rotation*10));
+}
+
+void XFormView::setVectorType()
+{
+ m_type = VectorType;
+ update();
+}
+
+void XFormView::setPixmapType()
+{
+ m_type = PixmapType;
+ update();
+}
+
+void XFormView::setTextType()
+{
+ m_type = TextType;
+ update();
+}
+
+void XFormView::setAnimation(bool animate)
+{
+ timer.stop();
+ if (animate)
+ timer.start(25, this);
+}
+
+void XFormView::changeRotation(int r)
+{
+ setRotation(qreal(r) / 10);
+}
+
+void XFormView::changeScale(int s)
+{
+ setScale(qreal(s) / 1000);
+}
+
+void XFormView::changeShear(int s)
+{
+ setShear(qreal(s) / 1000);
+}
+
+void XFormView::setShear(qreal s)
+{
+ m_shear = s;
+ update();
+}
+
+void XFormView::setScale(qreal s)
+{
+ m_scale = s;
+ update();
+}
+
+void XFormView::setRotation(qreal r)
+{
+ qreal old_rot = m_rotation;
+ m_rotation = r;
+
+ QPointF center(pts->points().at(0));
+ QMatrix m;
+ m.translate(center.x(), center.y());
+ m.rotate(m_rotation - old_rot);
+ m.translate(-center.x(), -center.y());
+ pts->setPoints(pts->points() * m);
+
+ update();
+}
+
+void XFormView::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == timer.timerId()) {
+ QPointF center(pts->points().at(0));
+ QMatrix m;
+ m.translate(center.x(), center.y());
+ m.rotate(0.2);
+ m.translate(-center.x(), -center.y());
+ pts->setPoints(pts->points() * m);
+
+ setUpdatesEnabled(false);
+ static qreal scale_inc = 0.003;
+ static qreal shear_inc = -0.001;
+ emit scaleChanged(int((m_scale + scale_inc) * 1000));
+ emit shearChanged(int((m_shear + shear_inc) * 1000));
+ if (m_scale >= 4.0 || m_scale <= 0.1)
+ scale_inc = -scale_inc;
+ if (m_shear >= 1.0 || m_shear <= -1.0)
+ shear_inc = -shear_inc;
+ setUpdatesEnabled(true);
+
+ pts->firePointChange();
+ }
+}
+
+void XFormView::wheelEvent(QWheelEvent *e)
+{
+ m_scale += e->delta() / qreal(600);
+ m_scale = qMax(qreal(0.1), qMin(qreal(4), m_scale));
+ emit scaleChanged(int(m_scale*1000));
+}
+
+void XFormView::reset()
+{
+ emit rotationChanged(0);
+ emit scaleChanged(1000);
+ emit shearChanged(0);
+ ctrlPoints = QPolygonF();
+ ctrlPoints << QPointF(250, 250) << QPointF(350, 250);
+ pts->setPoints(ctrlPoints);
+ pts->firePointChange();
+}
+
+void XFormView::drawPixmapType(QPainter *painter)
+{
+ QPointF center(m_pixmap.width() / qreal(2), m_pixmap.height() / qreal(2));
+ painter->translate(ctrlPoints.at(0) - center);
+
+ painter->translate(center);
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center);
+
+ painter->drawPixmap(QPointF(0, 0), m_pixmap);
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(QRectF(0, 0, m_pixmap.width(), m_pixmap.height()).adjusted(-2, -2, 2, 2));
+}
+
+void XFormView::drawTextType(QPainter *painter)
+{
+ QPainterPath path;
+ QFont f("times new roman,utopia");
+ f.setStyleStrategy(QFont::ForceOutline);
+ f.setPointSize(72);
+ f.setStyleHint(QFont::Times);
+ path.addText(0, 0, f, m_text);
+
+ QFontMetrics fm(f);
+ QRectF br(fm.boundingRect(m_text));
+ QPointF center(br.center());
+ painter->translate(ctrlPoints.at(0) - center);
+
+ painter->translate(center);
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center);
+
+ painter->fillPath(path, Qt::black);
+
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(br.adjusted(-1, -1, 1, 1));
+}
+
+void XFormView::drawVectorType(QPainter *painter)
+{
+ QPainterPath path;
+ painter->translate(ctrlPoints.at(0) - QPointF(250,250));
+
+ painter->scale(0.77, 0.77);
+ painter->translate(98.9154 + 30 , -217.691 - 20);
+
+ QRect br(-55, 275, 500, 590);
+ QPoint center = br.center();
+ painter->translate(center.x(), center.y());
+ painter->rotate(m_rotation);
+ painter->scale(m_scale, m_scale);
+ painter->shear(0, m_shear);
+ painter->translate(-center.x(), -center.y());
+
+ painter->setPen(Qt::NoPen);
+ path.moveTo(120, 470);
+ path.lineTo(60+245, 470);
+ path.lineTo(60+245, 470+350);
+ path.lineTo(60, 470+350);
+ path.lineTo(60, 470+80);
+
+ painter->setBrush(Qt::white);
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor( 193, 193, 191, 255));
+ path.moveTo(329.336, 727.552);
+ path.cubicTo(QPointF(315.224, 726.328), QPointF(304.136, 715.816), QPointF(303.128, 694.936));
+ path.cubicTo(QPointF(306.368, 639.496), QPointF(309.608, 582.112), QPointF(271.232, 545.104));
+ path.cubicTo(QPointF(265.256, 499.024), QPointF(244.016, 482.104), QPointF(234.008, 452.512));
+ path.lineTo(218.24, 441.208);
+ path.lineTo(237.104, 411.688);
+ path.lineTo(245.168, 411.904);
+ path.lineTo(323.936, 571.168);
+ path.lineTo(340.424, 651.448);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(136.232, 439.696);
+ path.cubicTo(QPointF(133.856, 455.248), QPointF(132.56, 470.512), QPointF(134.792, 485.272));
+ path.cubicTo(QPointF(118.376, 507.592), QPointF(105.92, 530.128), QPointF(104.48, 553.312));
+ path.cubicTo(QPointF(92.024, 586.504), QPointF(62.432, 614.584), QPointF(67.544, 680.104));
+ path.cubicTo(QPointF(84.176, 697.456), QPointF(107.432, 713.584), QPointF(127.376, 730.36));
+ path.cubicTo(QPointF(152.432, 751.312), QPointF(137.528, 778.96), QPointF(102.248, 772.408));
+ path.cubicTo(QPointF(94.4, 763.768), QPointF(76.616, 709.624), QPointF(42.92, 676.288));
+ path.lineTo(49.544, 632.584);
+ path.lineTo(81.368, 547.408);
+ path.lineTo(120.968, 484.048);
+ path.lineTo(125.36, 456.688);
+ path.lineTo(119.816, 386.776);
+ path.lineTo(124.424, 361.216);
+ path.lineTo(136.232, 439.696);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(115.64, 341.416);
+ path.cubicTo(QPointF(116.576, 336.376), QPointF(117.8, 331.624), QPointF(119.312, 327.16));
+ path.lineTo(121.688, 342.784);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(120.968, 500.464);
+ path.cubicTo(QPointF(108.368, 523.792), QPointF(103.976, 546.256), QPointF(132.92, 550.216));
+ path.cubicTo(QPointF(117.008, 553.888), QPointF(97.208, 568.648), QPointF(77.192, 593.488));
+ path.lineTo(77.624, 543.016);
+ path.lineTo(101.456, 503.272);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(-33.256, 818.488);
+ path.cubicTo(QPointF(10.52, 838.144), QPointF(41.408, 837.064), QPointF(69.272, 850.96));
+ path.cubicTo(QPointF(91.304, 862.552), QPointF(113.552, 861.184), QPointF(126.944, 847.144));
+ path.cubicTo(QPointF(138.32, 832.456), QPointF(146.744, 831.736), QPointF(163.52, 830.224));
+ path.cubicTo(QPointF(190.952, 828.568), QPointF(217.736, 828.28), QPointF(241.928, 830.8));
+ path.lineTo(269.576, 833.032);
+ path.cubicTo(QPointF(269.072, 864.064), QPointF(328.04, 867.88), QPointF(345.392, 844.336));
+ path.cubicTo(QPointF(366.344, 819.424), QPointF(395.144, 808.264), QPointF(419.84, 790.192));
+ path.lineTo(289.304, 725.536);
+ path.cubicTo(QPointF(255.824, 806.464), QPointF(131.048, 827.632), QPointF(113.768, 763.264));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(286.424, 711.568);
+ path.cubicTo(QPointF(273.824, 711.496), QPointF(260.936, 715.6), QPointF(261.944, 732.16));
+ path.lineTo(266.192, 776.44);
+ path.lineTo(304.424, 756.64);
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(-37.36, 821.224);
+ path.cubicTo(QPointF(7.136, 840.88), QPointF(38.6, 839.728), QPointF(66.968, 853.696));
+ path.cubicTo(QPointF(89.36, 865.216), QPointF(111.968, 863.92), QPointF(125.648, 849.808));
+ path.cubicTo(QPointF(137.24, 835.192), QPointF(145.808, 834.472), QPointF(162.872, 832.96));
+ path.cubicTo(QPointF(190.736, 831.232), QPointF(218.024, 831.016), QPointF(242.648, 833.464));
+ path.lineTo(270.728, 835.768);
+ path.cubicTo(QPointF(270.224, 866.8), QPointF(330.272, 870.544), QPointF(347.912, 847));
+ path.cubicTo(QPointF(369.224, 822.088), QPointF(398.528, 811), QPointF(423.656, 792.856));
+ path.lineTo(290.816, 728.272);
+ path.cubicTo(QPointF(256.76, 809.128), QPointF(129.824, 830.296), QPointF(112.256, 766));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(382.328, 691.984);
+ path.cubicTo(QPointF(403.64, 698.968), QPointF(389.888, 720.28), QPointF(400.76, 732.52));
+ path.cubicTo(QPointF(405.44, 742.888), QPointF(415.304, 752.032), QPointF(431.792, 760.528));
+ path.cubicTo(QPointF(459.368, 774.424), QPointF(426.248, 799.336), QPointF(392.768, 812.08));
+ path.cubicTo(QPointF(351.944, 825.616), QPointF(344.024, 862.912), QPointF(299.312, 851.896));
+ path.cubicTo(QPointF(283.112, 846.496), QPointF(278.36, 831.808), QPointF(278.864, 809.128));
+ path.cubicTo(QPointF(284.264, 762.76), QPointF(277.784, 730.432), QPointF(278.792, 698.824));
+ path.cubicTo(QPointF(278.72, 686.152), QPointF(283.544, 684.64), QPointF(307.232, 687.952));
+ path.cubicTo(QPointF(310.04, 726.328), QPointF(352.376, 727.336), QPointF(382.328, 691.984));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(339.632, 826.624);
+ path.cubicTo(QPointF(371.6, 814.312), QPointF(403.856, 798.112), QPointF(429.848, 782.128));
+ path.cubicTo(QPointF(437.84, 777.448), QPointF(438.92, 765.928), QPointF(427.688, 762.328));
+ path.cubicTo(QPointF(403.352, 748.504), QPointF(390.104, 731.224), QPointF(392.912, 708.76));
+ path.cubicTo(QPointF(393.344, 700.912), QPointF(383.696, 692.56), QPointF(381.104, 700.048));
+ path.cubicTo(QPointF(359.864, 771.472), QPointF(291.32, 767.656), QPointF(300.752, 696.952));
+ path.cubicTo(QPointF(301.256, 694.864), QPointF(301.76, 692.776), QPointF(302.264, 690.76));
+ path.cubicTo(QPointF(289.952, 688.24), QPointF(285.2, 690.976), QPointF(285.776, 700.408));
+ path.lineTo(295.28, 806.608);
+ path.cubicTo(QPointF(297.656, 830.8), QPointF(317.312, 836.128), QPointF(339.632, 826.624));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(354.464, 537.544);
+ path.cubicTo(QPointF(379.16, 569.8), QPointF(404.432, 651.088), QPointF(384.416, 691.552));
+ path.cubicTo(QPointF(360.944, 737.776), QPointF(307.808, 743.248), QPointF(305.504, 695.8));
+ path.cubicTo(QPointF(308.816, 639.64), QPointF(311.984, 581.536), QPointF(273.68, 544.096));
+ path.cubicTo(QPointF(267.704, 497.368), QPointF(246.392, 480.232), QPointF(236.384, 450.28));
+ path.lineTo(203.12, 426.088);
+ path.lineTo(133.568, 435.088);
+ path.cubicTo(QPointF(130.76, 452.152), QPointF(129.104, 468.784), QPointF(131.552, 484.912));
+ path.cubicTo(QPointF(115.064, 507.376), QPointF(102.608, 530.056), QPointF(101.168, 553.312));
+ path.cubicTo(QPointF(88.712, 586.648), QPointF(59.12, 614.944), QPointF(64.232, 680.752));
+ path.cubicTo(QPointF(80.864, 698.248), QPointF(104.12, 714.448), QPointF(124.064, 731.296));
+ path.cubicTo(QPointF(149.12, 752.392), QPointF(135.512, 776.296), QPointF(100.232, 769.672));
+ path.cubicTo(QPointF(78.848, 746.056), QPointF(56.744, 722.872), QPointF(35.288, 699.328));
+ path.cubicTo(QPointF(12.392, 683.056), QPointF(3.896, 662.176), QPointF(27.368, 630.496));
+ path.cubicTo(QPointF(43.424, 609.04), QPointF(47.96, 562.456), QPointF(62, 543.664));
+ path.cubicTo(QPointF(74.312, 525.16), QPointF(92.24, 508.6), QPointF(105.272, 490.096));
+ path.cubicTo(QPointF(112.184, 477.928), QPointF(114.344, 468.568), QPointF(113.264, 454.456));
+ path.lineTo(110.312, 369.136);
+ path.cubicTo(QPointF(108.368, 307.216), QPointF(142.424, 274.24), QPointF(189.8, 275.248));
+ path.cubicTo(QPointF(243.512, 275.752), QPointF(287.576, 312.472), QPointF(288.152, 378.28));
+ path.cubicTo(QPointF(292.688, 410.32), QPointF(283.256, 428.68), QPointF(308.672, 474.472));
+ path.cubicTo(QPointF(334.52, 522.712), QPointF(338.552, 520.12), QPointF(354.464, 537.544));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(261.296, 503.632);
+ path.lineTo(263.528, 512.2);
+ path.cubicTo(QPointF(257.696, 501.688), QPointF(250.712, 483.616), QPointF(241.928, 475.696));
+ path.cubicTo(QPointF(239.264, 473.536), QPointF(235.808, 473.608), QPointF(233.72, 475.624));
+ path.cubicTo(QPointF(222.056, 486.928), QPointF(193.112, 510.112), QPointF(169.928, 507.088));
+ path.cubicTo(QPointF(152.072, 505.288), QPointF(134.648, 493.264), QPointF(130.832, 480.232));
+ path.cubicTo(QPointF(128.816, 470.872), QPointF(129.752, 463.168), QPointF(130.976, 455.32));
+ path.lineTo(240.704, 453.52);
+ path.cubicTo(QPointF(238.472, 463.168), QPointF(253.088, 487), QPointF(261.296, 503.632));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(143.144, 363.232);
+ path.cubicTo(QPointF(154.088, 363.232), QPointF(163.88, 376.84), QPointF(163.808, 395.632));
+ path.cubicTo(QPointF(163.736, 408.232), QPointF(155.528, 411.472), QPointF(149.336, 417.016));
+ path.cubicTo(QPointF(146.6, 419.536), QPointF(145.952, 433.144), QPointF(142.568, 433.144));
+ path.cubicTo(QPointF(131.696, 433.144), QPointF(123.488, 413.776), QPointF(123.488, 395.632));
+ path.cubicTo(QPointF(123.488, 377.56), QPointF(132.272, 363.232), QPointF(143.144, 363.232));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(144.368, 375.04);
+ path.cubicTo(QPointF(154.088, 375.04), QPointF(160.856, 379.936), QPointF(161.648, 391.312));
+ path.cubicTo(QPointF(162.224, 399.16), QPointF(160.136, 411.76), QPointF(154.664, 414.424));
+ path.cubicTo(QPointF(152.144, 415.648), QPointF(143.432, 426.664), QPointF(140.408, 426.52));
+ path.cubicTo(QPointF(128.096, 425.944), QPointF(125, 402.112), QPointF(125.936, 390.736));
+ path.cubicTo(QPointF(126.8, 379.36), QPointF(134.72, 375.04), QPointF(144.368, 375.04));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(141.848, 382.672);
+ path.cubicTo(QPointF(148.544, 382.096), QPointF(154.736, 389.728), QPointF(155.6, 399.664));
+ path.cubicTo(QPointF(156.464, 409.6), QPointF(151.64, 418.24), QPointF(144.944, 418.816));
+ path.cubicTo(QPointF(138.248, 419.392), QPointF(132.056, 411.76), QPointF(131.192, 401.752));
+ path.cubicTo(QPointF(130.328, 391.816), QPointF(135.152, 383.248), QPointF(141.848, 382.672));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(151.064, 397.288);
+ path.cubicTo(QPointF(151.424, 399.088), QPointF(149.408, 400.024), QPointF(148.832, 398.224));
+ path.cubicTo(QPointF(148.256, 395.992), QPointF(146.888, 393.328), QPointF(145.088, 391.168));
+ path.cubicTo(QPointF(143.936, 389.872), QPointF(145.088, 388.432), QPointF(146.528, 389.44));
+ path.cubicTo(QPointF(149.048, 391.528), QPointF(150.488, 394.12), QPointF(151.064, 397.288));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(216.944, 360.712);
+ path.cubicTo(QPointF(232.712, 360.712), QPointF(245.6, 377.416), QPointF(245.6, 397.792));
+ path.cubicTo(QPointF(245.6, 418.24), QPointF(232.712, 434.872), QPointF(216.944, 434.872));
+ path.cubicTo(QPointF(201.176, 434.872), QPointF(188.432, 418.24), QPointF(188.432, 397.792));
+ path.cubicTo(QPointF(188.432, 377.416), QPointF(201.176, 360.712), QPointF(216.944, 360.712));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(224.792, 374.968);
+ path.cubicTo(QPointF(235.664, 378.856), QPointF(241.928, 387.424), QPointF(242.72, 396.568));
+ path.cubicTo(QPointF(243.656, 407.08), QPointF(239.408, 418.96), QPointF(230.264, 425.944));
+ path.cubicTo(QPointF(227.672, 427.888), QPointF(197.72, 416.08), QPointF(195.992, 411.616));
+ path.cubicTo(QPointF(193.4, 405.208), QPointF(191.816, 392.896), QPointF(193.76, 385.624));
+ path.cubicTo(QPointF(194.552, 382.744), QPointF(197.216, 378.568), QPointF(201.176, 376.336));
+ path.cubicTo(QPointF(207.44, 372.808), QPointF(216.656, 372.088), QPointF(224.792, 374.968));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(0, 0, 0, 255));
+ path.moveTo(216.872, 380.944);
+ path.cubicTo(QPointF(225.584, 380.944), QPointF(232.712, 389.296), QPointF(232.712, 399.448));
+ path.cubicTo(QPointF(232.712, 409.672), QPointF(225.584, 418.024), QPointF(216.872, 418.024));
+ path.cubicTo(QPointF(208.16, 418.024), QPointF(201.032, 409.672), QPointF(201.032, 399.448));
+ path.cubicTo(QPointF(201.032, 389.296), QPointF(208.16, 380.944), QPointF(216.872, 380.944));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(227.096, 392.392);
+ path.cubicTo(QPointF(228.104, 394.048), QPointF(226.448, 395.776), QPointF(225.224, 394.12));
+ path.cubicTo(QPointF(223.784, 392.104), QPointF(221.408, 389.944), QPointF(218.888, 388.432));
+ path.cubicTo(QPointF(217.232, 387.568), QPointF(217.808, 385.624), QPointF(219.68, 386.2));
+ path.cubicTo(QPointF(222.92, 387.28), QPointF(225.368, 389.368), QPointF(227.096, 392.392));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(164.96, 404.488);
+ path.cubicTo(QPointF(172.376, 402.328), QPointF(184.112, 403.048), QPointF(192.248, 404.632));
+ path.cubicTo(QPointF(200.384, 406.792), QPointF(222.056, 418.24), QPointF(245.024, 430.696));
+ path.cubicTo(QPointF(247.976, 432.208), QPointF(248.84, 437.104), QPointF(245.024, 438.688));
+ path.cubicTo(QPointF(239.12, 439.12), QPointF(249.272, 453.664), QPointF(238.904, 458.848));
+ path.cubicTo(QPointF(223.352, 462.88), QPointF(198.44, 485.992), QPointF(186.128, 487.864));
+ path.cubicTo(QPointF(179.288, 489.376), QPointF(172.232, 489.592), QPointF(164.6, 487.864));
+ path.cubicTo(QPointF(140.552, 482.968), QPointF(134.216, 455.608), QPointF(122.912, 450.064));
+ path.cubicTo(QPointF(119.816, 446.824), QPointF(121.4, 441.208), QPointF(122.408, 440.056));
+ path.cubicTo(QPointF(123.632, 434.224), QPointF(149.696, 406.216), QPointF(164.96, 404.488));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(185.408, 405.856);
+ path.cubicTo(QPointF(198.44, 407.296), QPointF(226.088, 423.928), QPointF(239.408, 430.624));
+ path.cubicTo(QPointF(242.72, 432.424), QPointF(242.504, 437.824), QPointF(239.552, 438.688));
+ path.cubicTo(QPointF(236.384, 440.488), QPointF(235.448, 438.256), QPointF(232.928, 437.896));
+ path.cubicTo(QPointF(228.896, 435.736), QPointF(222.272, 440.92), QPointF(217.016, 444.88));
+ path.cubicTo(QPointF(186.704, 467.776), QPointF(180.656, 465.256), QPointF(156.176, 462.664));
+ path.cubicTo(QPointF(147.68, 460.576), QPointF(142.136, 457.984), QPointF(139.688, 455.968));
+ path.cubicTo(QPointF(141.488, 445.888), QPointF(160.496, 407.656), QPointF(166.76, 406.792));
+ path.cubicTo(QPointF(168.344, 404.704), QPointF(179.936, 404.632), QPointF(185.408, 405.856));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(190.664, 412.048);
+ path.lineTo(193.76, 413.416);
+ path.cubicTo(QPointF(196.064, 414.712), QPointF(193.256, 418.168), QPointF(190.736, 417.088));
+ path.lineTo(186.2, 415.504);
+ path.cubicTo(QPointF(183.536, 413.272), QPointF(186.704, 410.104), QPointF(190.664, 412.048));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(268.568, 452.368);
+ path.cubicTo(QPointF(273.032, 454.384), QPointF(279.224, 457.192), QPointF(282.536, 460.144));
+ path.cubicTo(QPointF(285.488, 464.104), QPointF(286.784, 468.064), QPointF(286.424, 472.024));
+ path.cubicTo(QPointF(285.776, 474.544), QPointF(284.12, 476.344), QPointF(281.24, 477.424));
+ path.cubicTo(QPointF(277.856, 478.216), QPointF(273.68, 477.424), QPointF(271.376, 474.112));
+ path.cubicTo(QPointF(269.864, 471.448), QPointF(265.256, 462.16), QPointF(263.96, 460.576));
+ path.cubicTo(QPointF(262.232, 457.12), QPointF(261.944, 454.456), QPointF(262.88, 452.368));
+ path.cubicTo(QPointF(264.032, 451.288), QPointF(266.048, 451), QPointF(268.568, 452.368));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(255, 255, 255, 255));
+ path.moveTo(273.752, 461.584);
+ path.cubicTo(QPointF(275.48, 462.376), QPointF(277.928, 463.456), QPointF(279.224, 464.68));
+ path.cubicTo(QPointF(280.376, 466.264), QPointF(280.88, 467.776), QPointF(280.736, 469.36));
+ path.cubicTo(QPointF(280.52, 470.296), QPointF(279.8, 471.016), QPointF(278.72, 471.448));
+ path.cubicTo(QPointF(277.352, 471.808), QPointF(275.768, 471.448), QPointF(274.832, 470.152));
+ path.cubicTo(QPointF(274.256, 469.144), QPointF(272.456, 465.472), QPointF(271.952, 464.824));
+ path.cubicTo(QPointF(271.232, 463.456), QPointF(271.088, 462.448), QPointF(271.448, 461.584));
+ path.cubicTo(QPointF(271.952, 461.152), QPointF(272.744, 461.08), QPointF(273.752, 461.584));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(238.616, 358.552);
+ path.cubicTo(QPointF(239.048, 359.2), QPointF(238.976, 359.776), QPointF(238.4, 360.28));
+ path.cubicTo(QPointF(237.896, 360.784), QPointF(237.176, 360.712), QPointF(236.24, 360.208));
+ path.lineTo(231.632, 356.248);
+ path.cubicTo(QPointF(231.056, 355.744), QPointF(230.912, 354.952), QPointF(231.272, 354.088));
+ path.cubicTo(QPointF(232.28, 353.44), QPointF(233.144, 353.44), QPointF(233.936, 354.088));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(235.592, 305.992);
+ path.cubicTo(QPointF(239.624, 308.224), QPointF(240.848, 313.912), QPointF(238.184, 318.592));
+ path.cubicTo(QPointF(235.592, 323.2), QPointF(230.12, 325.144), QPointF(226.016, 322.84));
+ path.cubicTo(QPointF(221.984, 320.536), QPointF(220.76, 314.92), QPointF(223.424, 310.24));
+ path.cubicTo(QPointF(226.016, 305.56), QPointF(231.488, 303.688), QPointF(235.592, 305.992));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(374.912, 680.536);
+ path.cubicTo(QPointF(378.296, 683.128), QPointF(373.256, 687.376), QPointF(371.024, 686.296));
+ path.cubicTo(QPointF(369.152, 685.648), QPointF(367.784, 683.488), QPointF(366.92, 682.408));
+ path.cubicTo(QPointF(366.128, 681.184), QPointF(366.2, 679.168), QPointF(366.92, 678.448));
+ path.cubicTo(QPointF(367.712, 677.44), QPointF(369.728, 677.656), QPointF(371.024, 678.52));
+ path.cubicTo(QPointF(372.32, 679.168), QPointF(373.616, 679.888), QPointF(374.912, 680.536));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(297.44, 551.512);
+ path.cubicTo(QPointF(338.984, 572.896), QPointF(350, 611.56), QPointF(332.072, 664.192));
+ path.cubicTo(QPointF(330.992, 666.64), QPointF(334.16, 668.368), QPointF(335.24, 666.064));
+ path.cubicTo(QPointF(354.824, 610.336), QPointF(341.432, 571.312), QPointF(299.024, 548.56));
+ path.cubicTo(QPointF(296.864, 547.552), QPointF(295.28, 550.432), QPointF(297.44, 551.512));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(72.008, 569.512);
+ path.cubicTo(QPointF(38.312, 627.256), QPointF(38.096, 662.68), QPointF(62.504, 681.328));
+ path.cubicTo(QPointF(63.728, 682.264), QPointF(64.448, 680.032), QPointF(63.296, 679.168));
+ path.cubicTo(QPointF(36.296, 655.48), QPointF(48.896, 615.52), QPointF(74.168, 570.88));
+ path.cubicTo(QPointF(74.888, 569.584), QPointF(72.512, 568.432), QPointF(72.008, 569.512));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(289.376, 586.864);
+ path.cubicTo(QPointF(289.232, 589.168), QPointF(288.368, 589.528), QPointF(286.424, 587.368));
+ path.cubicTo(QPointF(279.8, 575.848), QPointF(235.088, 551.44), QPointF(213.344, 548.704));
+ path.cubicTo(QPointF(209.24, 547.264), QPointF(209.456, 545.392), QPointF(213.488, 544.816));
+ path.cubicTo(QPointF(229.184, 544.816), QPointF(241.28, 537.904), QPointF(254.96, 537.904));
+ path.cubicTo(QPointF(258.704, 538.048), QPointF(262.304, 539.488), QPointF(264.392, 541.648));
+ path.cubicTo(QPointF(269.504, 544.96), QPointF(288.08, 570.592), QPointF(289.376, 586.864));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(180.152, 546.832);
+ path.cubicTo(QPointF(180.872, 550.792), QPointF(163.808, 545.68), QPointF(164.744, 556.696));
+ path.cubicTo(QPointF(165.032, 559.72), QPointF(160.496, 561.376), QPointF(160.64, 556.696));
+ path.cubicTo(QPointF(160.64, 548.272), QPointF(161.072, 548.416), QPointF(152.72, 546.832));
+ path.cubicTo(QPointF(151.208, 546.76), QPointF(151.352, 544.528), QPointF(152.72, 544.816));
+ path.lineTo(152.72, 544.816);
+ path.cubicTo(QPointF(158.696, 546.472), QPointF(166.76, 542.872), QPointF(166.4, 538.84));
+ path.cubicTo(QPointF(166.256, 537.472), QPointF(168.56, 537.688), QPointF(168.488, 538.84));
+ path.cubicTo(QPointF(167.984, 545.248), QPointF(181.664, 542.152), QPointF(180.152, 546.832));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(193, 193, 191, 255));
+ path.moveTo(151.568, 705.376);
+ path.cubicTo(QPointF(151.64, 708.328), QPointF(148.76, 707.68), QPointF(148.544, 705.592));
+ path.cubicTo(QPointF(140.192, 680.536), QPointF(143.72, 618.832), QPointF(151.856, 598.96));
+ path.cubicTo(QPointF(152.432, 596.08), QPointF(156.248, 596.944), QPointF(155.744, 598.96));
+ path.cubicTo(QPointF(147.104, 635.464), QPointF(147.248, 673.048), QPointF(151.568, 705.376));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(183, 114, 0, 255));
+ path.moveTo(51.704, 684.424);
+ path.cubicTo(QPointF(75.68, 707.824), QPointF(91.376, 743.248), QPointF(114.632, 775.288));
+ path.cubicTo(QPointF(148.472, 816.04), QPointF(121.472, 858.304), QPointF(66.464, 845.56));
+ path.cubicTo(QPointF(38.888, 835.192), QPointF(-0.784, 836.344), QPointF(-32.68, 825.832));
+ path.cubicTo(QPointF(-55.072, 820.36), QPointF(-55.864, 809.272), QPointF(-44.416, 787.6));
+ path.cubicTo(QPointF(-40.384, 773.776), QPointF(-40.024, 751.312), QPointF(-43.768, 732.592));
+ path.cubicTo(QPointF(-45.784, 718.408), QPointF(-39.232, 710.488), QPointF(-24.112, 708.832));
+ path.lineTo(-24.112, 708.832);
+ path.cubicTo(QPointF(-11.296, 708.688), QPointF(6.56, 713.872), QPointF(16.28, 686.44));
+ path.cubicTo(QPointF(23.552, 673.336), QPointF(40.976, 672.976), QPointF(51.704, 684.424));
+ path.closeSubpath();
+ painter->drawPath(path);
+ path = QPainterPath();
+
+ painter->setBrush(QColor(242, 183, 0, 255));
+ path.moveTo(24.632, 699.04);
+ path.cubicTo(QPointF(23.84, 680.968), QPointF(39.32, 677.296), QPointF(49.688, 688.312));
+ path.cubicTo(QPointF(68.192, 710.992), QPointF(85.112, 736.048), QPointF(100.376, 764.992));
+ path.cubicTo(QPointF(124.712, 804.16), QPointF(104.624, 842.68), QPointF(67.904, 828.064));
+ path.cubicTo(QPointF(49.688, 817.84), QPointF(6.128, 813.304), QPointF(-17.344, 809.128));
+ path.cubicTo(QPointF(-33.04, 807.832), QPointF(-35.128, 797.608), QPointF(-29.152, 791.848));
+ path.cubicTo(QPointF(-20.944, 782.416), QPointF(-20.08, 759.808), QPointF(-27.856, 740.512));
+ path.cubicTo(QPointF(-35.56, 728.56), QPointF(-21.088, 715.384), QPointF(-9.712, 720.856));
+ path.cubicTo(QPointF(0.8, 727.048), QPointF(25.64, 713.08), QPointF(24.632, 699.04));
+ path.closeSubpath();
+ painter->drawPath(path);
+
+ painter->setPen(QPen(QColor(255, 0, 0, alpha), 0.25, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(br.adjusted(-1, -1, 1, 1));
+}
+
+
+XFormWidget::XFormWidget(QWidget *parent)
+ : QWidget(parent), textEditor(new QLineEdit)
+{
+ setWindowTitle(tr("Affine Transformations"));
+
+ view = new XFormView(this);
+ view->setMinimumSize(200, 200);
+
+ QGroupBox *mainGroup = new QGroupBox(this);
+ mainGroup->setFixedWidth(180);
+ mainGroup->setTitle(tr("Affine Transformations"));
+
+ QGroupBox *rotateGroup = new QGroupBox(mainGroup);
+ rotateGroup->setTitle(tr("Rotate"));
+ QSlider *rotateSlider = new QSlider(Qt::Horizontal, rotateGroup);
+ rotateSlider->setRange(0, 3600);
+ rotateSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *scaleGroup = new QGroupBox(mainGroup);
+ scaleGroup->setTitle(tr("Scale"));
+ QSlider *scaleSlider = new QSlider(Qt::Horizontal, scaleGroup);
+ scaleSlider->setRange(1, 4000);
+ scaleSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *shearGroup = new QGroupBox(mainGroup);
+ shearGroup->setTitle(tr("Shear"));
+ QSlider *shearSlider = new QSlider(Qt::Horizontal, shearGroup);
+ shearSlider->setRange(-990, 990);
+ shearSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *typeGroup = new QGroupBox(mainGroup);
+ typeGroup->setTitle(tr("Type"));
+ QRadioButton *vectorType = new QRadioButton(typeGroup);
+ QRadioButton *pixmapType = new QRadioButton(typeGroup);
+ QRadioButton *textType= new QRadioButton(typeGroup);
+ vectorType->setText(tr("Vector Image"));
+ pixmapType->setText(tr("Pixmap"));
+ textType->setText(tr("Text"));
+
+ QPushButton *resetButton = new QPushButton(mainGroup);
+ resetButton->setText(tr("Reset Transform"));
+
+ QPushButton *animateButton = new QPushButton(mainGroup);
+ animateButton->setText(tr("Animate"));
+ animateButton->setCheckable(true);
+
+ QPushButton *showSourceButton = new QPushButton(mainGroup);
+ showSourceButton->setText(tr("Show Source"));
+#ifdef QT_OPENGL_SUPPORT
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(view->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+ QHBoxLayout *viewLayout = new QHBoxLayout(this);
+ viewLayout->addWidget(view);
+ viewLayout->addWidget(mainGroup);
+
+ QVBoxLayout *rotateGroupLayout = new QVBoxLayout(rotateGroup);
+ rotateGroupLayout->addWidget(rotateSlider);
+
+ QVBoxLayout *scaleGroupLayout = new QVBoxLayout(scaleGroup);
+ scaleGroupLayout->addWidget(scaleSlider);
+
+ QVBoxLayout *shearGroupLayout = new QVBoxLayout(shearGroup);
+ shearGroupLayout->addWidget(shearSlider);
+
+ QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
+ typeGroupLayout->addWidget(vectorType);
+ typeGroupLayout->addWidget(pixmapType);
+ typeGroupLayout->addWidget(textType);
+ typeGroupLayout->addSpacing(4);
+ typeGroupLayout->addWidget(textEditor);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(rotateGroup);
+ mainGroupLayout->addWidget(scaleGroup);
+ mainGroupLayout->addWidget(shearGroup);
+ mainGroupLayout->addWidget(typeGroup);
+ mainGroupLayout->addStretch(1);
+ mainGroupLayout->addWidget(resetButton);
+ mainGroupLayout->addWidget(animateButton);
+ mainGroupLayout->addWidget(showSourceButton);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(whatsThisButton);
+
+ connect(rotateSlider, SIGNAL(valueChanged(int)), view, SLOT(changeRotation(int)));
+ connect(shearSlider, SIGNAL(valueChanged(int)), view, SLOT(changeShear(int)));
+ connect(scaleSlider, SIGNAL(valueChanged(int)), view, SLOT(changeScale(int)));
+
+ connect(vectorType, SIGNAL(clicked()), view, SLOT(setVectorType()));
+ connect(pixmapType, SIGNAL(clicked()), view, SLOT(setPixmapType()));
+ connect(textType, SIGNAL(clicked()), view, SLOT(setTextType()));
+ connect(textType, SIGNAL(toggled(bool)), textEditor, SLOT(setEnabled(bool)));
+ connect(textEditor, SIGNAL(textChanged(QString)), view, SLOT(setText(QString)));
+
+ connect(view, SIGNAL(rotationChanged(int)), rotateSlider, SLOT(setValue(int)));
+ connect(view, SIGNAL(scaleChanged(int)), scaleSlider, SLOT(setValue(int)));
+ connect(view, SIGNAL(shearChanged(int)), shearSlider, SLOT(setValue(int)));
+
+ connect(resetButton, SIGNAL(clicked()), view, SLOT(reset()));
+ connect(animateButton, SIGNAL(clicked(bool)), view, SLOT(setAnimation(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
+ connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
+#endif
+ view->loadSourceFile(":res/affine/xform.cpp");
+ view->loadDescription(":res/affine/xform.html");
+
+ // defaults
+ view->reset();
+ vectorType->setChecked(true);
+ textEditor->setText("Qt Affine Transformation Demo");
+ textEditor->setEnabled(false);
+
+ animateButton->animateClick();
+}
diff --git a/demos/affine/xform.h b/demos/affine/xform.h
new file mode 100644
index 0000000000..80e672b0e4
--- /dev/null
+++ b/demos/affine/xform.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XFORM_H
+#define XFORM_H
+
+#include "arthurwidgets.h"
+
+#include <QBasicTimer>
+#include <QPolygonF>
+
+class HoverPoints;
+QT_FORWARD_DECLARE_CLASS(QLineEdit)
+
+class XFormView : public ArthurFrame
+{
+public:
+ Q_OBJECT
+
+ Q_PROPERTY(XFormType type READ type WRITE setType)
+ Q_PROPERTY(bool animation READ animation WRITE setAnimation)
+ Q_PROPERTY(qreal shear READ shear WRITE setShear)
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
+ Q_PROPERTY(qreal scale READ scale WRITE setScale)
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
+ Q_ENUMS(XFormType)
+
+public:
+ enum XFormType { VectorType, PixmapType, TextType };
+
+ XFormView(QWidget *parent);
+ void paint(QPainter *);
+ void drawVectorType(QPainter *painter);
+ void drawPixmapType(QPainter *painter);
+ void drawTextType(QPainter *painter);
+ QSize sizeHint() const { return QSize(500, 500); }
+
+ void mousePressEvent(QMouseEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ HoverPoints *hoverPoints() { return pts; }
+
+ bool animation() const { return timer.isActive(); }
+ qreal shear() const { return m_shear; }
+ qreal scale() const { return m_scale; }
+ qreal rotation() const { return m_rotation; }
+ void setShear(qreal s);
+ void setScale(qreal s);
+ void setRotation(qreal r);
+
+ XFormType type() const;
+ QPixmap pixmap() const;
+ QString text() const;
+
+public slots:
+ void setAnimation(bool animate);
+ void updateCtrlPoints(const QPolygonF &);
+ void changeRotation(int rotation);
+ void changeScale(int scale);
+ void changeShear(int shear);
+
+ void setText(const QString &);
+ void setPixmap(const QPixmap &);
+ void setType(XFormType t);
+
+ void setVectorType();
+ void setPixmapType();
+ void setTextType();
+ void reset();
+
+signals:
+ void rotationChanged(int rotation);
+ void scaleChanged(int scale);
+ void shearChanged(int shear);
+
+protected:
+ void timerEvent(QTimerEvent *e);
+ void wheelEvent(QWheelEvent *);
+
+private:
+ QPolygonF ctrlPoints;
+ HoverPoints *pts;
+ qreal m_rotation;
+ qreal m_scale;
+ qreal m_shear;
+ XFormType m_type;
+ QPixmap m_pixmap;
+ QString m_text;
+ QBasicTimer timer;
+};
+
+class XFormWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ XFormWidget(QWidget *parent);
+
+private:
+ XFormView *view;
+ QLineEdit *textEditor;
+};
+
+#endif // XFORM_H
diff --git a/demos/affine/xform.html b/demos/affine/xform.html
new file mode 100644
index 0000000000..17325ac2a0
--- /dev/null
+++ b/demos/affine/xform.html
@@ -0,0 +1,23 @@
+<html>
+<center>
+<h2>Affine Transformations</h2>
+</center>
+
+<p>In this demo we demonstrate Qt's ability to perform affine transformations
+on painting operations.</p>
+
+<p>Transformations can be performed on any kind of graphics drawn using
+QPainter. The transformations used to display the vector graphics, images,
+and text can be adjusted in the following ways:</p>
+
+<ul>
+ <li>Dragging the red circle in the centre of each drawing moves it to a new
+ position.</li>
+ <li>Dragging the displaced red circle causes the current drawing to be
+ rotated about the central circle. Rotation can also be controlled with
+ the <b>Rotate</b> slider.</li>
+ <li>Scaling is controlled with the <b>Scale</b> slider.</li>
+ <li>Each drawing can be sheared with the <b>Shear</b> slider.</li>
+</ul>
+
+</html>
diff --git a/demos/books/bookdelegate.cpp b/demos/books/bookdelegate.cpp
new file mode 100644
index 0000000000..eb5d95b7b5
--- /dev/null
+++ b/demos/books/bookdelegate.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookdelegate.h"
+
+#include <QtGui>
+
+BookDelegate::BookDelegate(QObject *parent)
+ : QSqlRelationalDelegate(parent), star(QPixmap(":images/star.png"))
+{
+}
+
+void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 5) {
+ QStyleOptionViewItemV3 opt = option;
+ opt.rect.adjust(0, 0, -1, -1); // since we draw the grid ourselves
+ QSqlRelationalDelegate::paint(painter, opt, index);
+ } else {
+ const QAbstractItemModel *model = index.model();
+ QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ?
+ (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled;
+
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight));
+
+ int rating = model->data(index, Qt::DisplayRole).toInt();
+ int width = star.width();
+ int height = star.height();
+ int x = option.rect.x();
+ int y = option.rect.y() + (option.rect.height() / 2) - (height / 2);
+ for (int i = 0; i < rating; ++i) {
+ painter->drawPixmap(x, y, star);
+ x += width;
+ }
+ drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)); // since we draw the grid ourselves
+ }
+
+ QPen pen = painter->pen();
+ painter->setPen(option.palette.color(QPalette::Mid));
+ painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
+ painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
+ painter->setPen(pen);
+}
+
+QSize BookDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() == 5)
+ return QSize(5 * star.width(), star.height()) + QSize(1, 1);
+
+ return QSqlRelationalDelegate::sizeHint(option, index) + QSize(1, 1); // since we draw the grid ourselves
+}
+
+bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index)
+{
+ if (index.column() != 5)
+ return QSqlRelationalDelegate::editorEvent(event, model, option, index);
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ int stars = qBound(0, int(0.7 + qreal(mouseEvent->pos().x()
+ - option.rect.x()) / star.width()), 5);
+ model->setData(index, QVariant(stars));
+ return false; //so that the selection can change
+ }
+
+ return true;
+}
+
+QWidget *BookDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 4)
+ return QSqlRelationalDelegate::createEditor(parent, option, index);
+
+ // for editing the year, return a spinbox with a range from -1000 to 2100.
+ QSpinBox *sb = new QSpinBox(parent);
+ sb->setFrame(false);
+ sb->setMaximum(2100);
+ sb->setMinimum(-1000);
+
+ return sb;
+}
+
diff --git a/demos/books/bookdelegate.h b/demos/books/bookdelegate.h
new file mode 100644
index 0000000000..bb1d824804
--- /dev/null
+++ b/demos/books/bookdelegate.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 demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOOKDELEGATE_H
+#define BOOKDELEGATE_H
+
+#include <QModelIndex>
+#include <QPixmap>
+#include <QSize>
+#include <QSqlRelationalDelegate>
+
+QT_FORWARD_DECLARE_CLASS(QPainter)
+
+class BookDelegate : public QSqlRelationalDelegate
+{
+public:
+ BookDelegate(QObject *parent);
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+private:
+ QPixmap star;
+};
+
+#endif
diff --git a/demos/books/books.pro b/demos/books/books.pro
new file mode 100644
index 0000000000..ad4009035c
--- /dev/null
+++ b/demos/books/books.pro
@@ -0,0 +1,23 @@
+TEMPLATE = app
+INCLUDEPATH += .
+
+HEADERS = bookdelegate.h bookwindow.h initdb.h
+RESOURCES = books.qrc
+SOURCES = bookdelegate.cpp main.cpp bookwindow.cpp
+FORMS = bookwindow.ui
+
+QT += sql
+
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/books
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro images
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/books
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+wince*: {
+ CONFIG(debug, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*d4.dll
+ CONFIG(release, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*[^d]4.dll
+ sqlPlugins.path = sqldrivers
+ DEPLOYMENT += sqlPlugins
+}
diff --git a/demos/books/books.qrc b/demos/books/books.qrc
new file mode 100644
index 0000000000..342638ecb0
--- /dev/null
+++ b/demos/books/books.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>images/star.png</file>
+</qresource>
+</RCC>
diff --git a/demos/books/bookwindow.cpp b/demos/books/bookwindow.cpp
new file mode 100644
index 0000000000..23e64c2b48
--- /dev/null
+++ b/demos/books/bookwindow.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookwindow.h"
+#include "bookdelegate.h"
+#include "initdb.h"
+
+#include <QtSql>
+
+BookWindow::BookWindow()
+{
+ ui.setupUi(this);
+
+ if (!QSqlDatabase::drivers().contains("QSQLITE"))
+ QMessageBox::critical(this, "Unable to load database", "This demo needs the SQLITE driver");
+
+ // initialize the database
+ QSqlError err = initDb();
+ if (err.type() != QSqlError::NoError) {
+ showError(err);
+ return;
+ }
+
+ // Create the data model
+ model = new QSqlRelationalTableModel(ui.bookTable);
+ model->setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model->setTable("books");
+
+ // Remember the indexes of the columns
+ authorIdx = model->fieldIndex("author");
+ genreIdx = model->fieldIndex("genre");
+
+ // Set the relations to the other database tables
+ model->setRelation(authorIdx, QSqlRelation("authors", "id", "name"));
+ model->setRelation(genreIdx, QSqlRelation("genres", "id", "name"));
+
+ // Set the localized header captions
+ model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name"));
+ model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre"));
+ model->setHeaderData(model->fieldIndex("title"), Qt::Horizontal, tr("Title"));
+ model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year"));
+ model->setHeaderData(model->fieldIndex("rating"), Qt::Horizontal, tr("Rating"));
+
+ // Populate the model
+ if (!model->select()) {
+ showError(model->lastError());
+ return;
+ }
+
+ // Set the model and hide the ID column
+ ui.bookTable->setModel(model);
+ ui.bookTable->setItemDelegate(new BookDelegate(ui.bookTable));
+ ui.bookTable->setColumnHidden(model->fieldIndex("id"), true);
+ ui.bookTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // Initialize the Author combo box
+ ui.authorEdit->setModel(model->relationModel(authorIdx));
+ ui.authorEdit->setModelColumn(model->relationModel(authorIdx)->fieldIndex("name"));
+
+ ui.genreEdit->setModel(model->relationModel(genreIdx));
+ ui.genreEdit->setModelColumn(model->relationModel(genreIdx)->fieldIndex("name"));
+
+ QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
+ mapper->setModel(model);
+ mapper->setItemDelegate(new BookDelegate(this));
+ mapper->addMapping(ui.titleEdit, model->fieldIndex("title"));
+ mapper->addMapping(ui.yearEdit, model->fieldIndex("year"));
+ mapper->addMapping(ui.authorEdit, authorIdx);
+ mapper->addMapping(ui.genreEdit, genreIdx);
+ mapper->addMapping(ui.ratingEdit, model->fieldIndex("rating"));
+
+ connect(ui.bookTable->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
+ mapper, SLOT(setCurrentModelIndex(QModelIndex)));
+
+ ui.bookTable->setCurrentIndex(model->index(0, 0));
+}
+
+void BookWindow::showError(const QSqlError &err)
+{
+ QMessageBox::critical(this, "Unable to initialize Database",
+ "Error initializing database: " + err.text());
+}
+
diff --git a/demos/books/bookwindow.h b/demos/books/bookwindow.h
new file mode 100644
index 0000000000..96545d7e8b
--- /dev/null
+++ b/demos/books/bookwindow.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOOKWINDOW_H
+#define BOOKWINDOW_H
+
+#include <QtGui>
+#include <QtSql>
+
+#include "ui_bookwindow.h"
+
+
+class BookWindow: public QMainWindow
+{
+ Q_OBJECT
+public:
+ BookWindow();
+
+private:
+ void showError(const QSqlError &err);
+ Ui::BookWindow ui;
+ QSqlRelationalTableModel *model;
+ int authorIdx, genreIdx;
+};
+
+#endif
diff --git a/demos/books/bookwindow.ui b/demos/books/bookwindow.ui
new file mode 100644
index 0000000000..659d324564
--- /dev/null
+++ b/demos/books/bookwindow.ui
@@ -0,0 +1,149 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>BookWindow</class>
+ <widget class="QMainWindow" name="BookWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>601</width>
+ <height>420</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Books</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Books</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTableView" name="bookTable" >
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Details</string>
+ </property>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>&lt;b>Title:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="titleEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2_2_2_2" >
+ <property name="text" >
+ <string>&lt;b>Author: &lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="authorEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>&lt;b>Genre:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="genreEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>&lt;b>Year:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="yearEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="prefix" >
+ <string/>
+ </property>
+ <property name="maximum" >
+ <number>2100</number>
+ </property>
+ <property name="minimum" >
+ <number>-1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&lt;b>Rating:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSpinBox" name="ratingEdit" >
+ <property name="maximum" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <tabstops>
+ <tabstop>bookTable</tabstop>
+ <tabstop>titleEdit</tabstop>
+ <tabstop>authorEdit</tabstop>
+ <tabstop>genreEdit</tabstop>
+ <tabstop>yearEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/demos/books/images/star.png b/demos/books/images/star.png
new file mode 100644
index 0000000000..87f4464bd5
--- /dev/null
+++ b/demos/books/images/star.png
Binary files differ
diff --git a/demos/books/initdb.h b/demos/books/initdb.h
new file mode 100644
index 0000000000..5351ad58e6
--- /dev/null
+++ b/demos/books/initdb.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INITDB_H
+#define INITDB_H
+
+#include <QtSql>
+
+void addBook(QSqlQuery &q, const QString &title, int year, const QVariant &authorId,
+ const QVariant &genreId, int rating)
+{
+ q.addBindValue(title);
+ q.addBindValue(year);
+ q.addBindValue(authorId);
+ q.addBindValue(genreId);
+ q.addBindValue(rating);
+ q.exec();
+}
+
+QVariant addGenre(QSqlQuery &q, const QString &name)
+{
+ q.addBindValue(name);
+ q.exec();
+ return q.lastInsertId();
+}
+
+QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate)
+{
+ q.addBindValue(name);
+ q.addBindValue(birthdate);
+ q.exec();
+ return q.lastInsertId();
+}
+
+QSqlError initDb()
+{
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(":memory:");
+
+ if (!db.open())
+ return db.lastError();
+
+ QStringList tables = db.tables();
+ if (tables.contains("books", Qt::CaseInsensitive)
+ && tables.contains("authors", Qt::CaseInsensitive))
+ return QSqlError();
+
+ QSqlQuery q;
+ if (!q.exec(QLatin1String("create table books(id integer primary key, title varchar, author integer, genre integer, year integer, rating integer)")))
+ return q.lastError();
+ if (!q.exec(QLatin1String("create table authors(id integer primary key, name varchar, birthdate date)")))
+ return q.lastError();
+ if (!q.exec(QLatin1String("create table genres(id integer primary key, name varchar)")))
+ return q.lastError();
+
+ if (!q.prepare(QLatin1String("insert into authors(name, birthdate) values(?, ?)")))
+ return q.lastError();
+ QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1));
+ QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2));
+ QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28));
+
+ if (!q.prepare(QLatin1String("insert into genres(name) values(?)")))
+ return q.lastError();
+ QVariant sfiction = addGenre(q, QLatin1String("Science Fiction"));
+ QVariant fiction = addGenre(q, QLatin1String("Fiction"));
+ QVariant fantasy = addGenre(q, QLatin1String("Fantasy"));
+
+ if (!q.prepare(QLatin1String("insert into books(title, year, author, genre, rating) values(?, ?, ?, ?, ?)")))
+ return q.lastError();
+ addBook(q, QLatin1String("Foundation"), 1951, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Empire"), 1952, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Second Foundation"), 1953, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation's Edge"), 1982, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Earth"), 1986, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Prelude to Foundation"), 1988, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Forward the Foundation"), 1993, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("The Power and the Glory"), 1940, greeneId, fiction, 4);
+ addBook(q, QLatin1String("The Third Man"), 1950, greeneId, fiction, 5);
+ addBook(q, QLatin1String("Our Man in Havana"), 1958, greeneId, fiction, 4);
+ addBook(q, QLatin1String("Guards! Guards!"), 1989, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Night Watch"), 2002, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Going Postal"), 2004, pratchettId, fantasy, 3);
+
+ return QSqlError();
+}
+
+#endif
diff --git a/demos/books/main.cpp b/demos/books/main.cpp
new file mode 100644
index 0000000000..3481c9a2a8
--- /dev/null
+++ b/demos/books/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookwindow.h"
+
+#include <QtGui>
+
+int main(int argc, char * argv[])
+{
+ Q_INIT_RESOURCE(books);
+
+ QApplication app(argc, argv);
+
+ BookWindow win;
+ win.show();
+
+ return app.exec();
+}
diff --git a/demos/boxes/3rdparty/fbm.c b/demos/boxes/3rdparty/fbm.c
new file mode 100644
index 0000000000..98eb87a33b
--- /dev/null
+++ b/demos/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/demos/boxes/3rdparty/fbm.h b/demos/boxes/3rdparty/fbm.h
new file mode 100644
index 0000000000..b8a4a99ae4
--- /dev/null
+++ b/demos/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/demos/boxes/basic.fsh b/demos/boxes/basic.fsh
new file mode 100644
index 0000000000..175b718883
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/basic.vsh b/demos/boxes/basic.vsh
new file mode 100644
index 0000000000..989b571413
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/boxes.pro b/demos/boxes/boxes.pro
new file mode 100644
index 0000000000..d599a3a0ac
--- /dev/null
+++ b/demos/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/demos/boxes/boxes.qrc b/demos/boxes/boxes.qrc
new file mode 100644
index 0000000000..d27506dc5a
--- /dev/null
+++ b/demos/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/demos/boxes/cubemap_negx.jpg b/demos/boxes/cubemap_negx.jpg
new file mode 100644
index 0000000000..07c282eab9
--- /dev/null
+++ b/demos/boxes/cubemap_negx.jpg
Binary files differ
diff --git a/demos/boxes/cubemap_negy.jpg b/demos/boxes/cubemap_negy.jpg
new file mode 100644
index 0000000000..46cd2f9cf3
--- /dev/null
+++ b/demos/boxes/cubemap_negy.jpg
Binary files differ
diff --git a/demos/boxes/cubemap_negz.jpg b/demos/boxes/cubemap_negz.jpg
new file mode 100644
index 0000000000..40c01ddff3
--- /dev/null
+++ b/demos/boxes/cubemap_negz.jpg
Binary files differ
diff --git a/demos/boxes/cubemap_posx.jpg b/demos/boxes/cubemap_posx.jpg
new file mode 100644
index 0000000000..0b42e8a1b1
--- /dev/null
+++ b/demos/boxes/cubemap_posx.jpg
Binary files differ
diff --git a/demos/boxes/cubemap_posy.jpg b/demos/boxes/cubemap_posy.jpg
new file mode 100644
index 0000000000..2aca9b1e98
--- /dev/null
+++ b/demos/boxes/cubemap_posy.jpg
Binary files differ
diff --git a/demos/boxes/cubemap_posz.jpg b/demos/boxes/cubemap_posz.jpg
new file mode 100644
index 0000000000..2e49173848
--- /dev/null
+++ b/demos/boxes/cubemap_posz.jpg
Binary files differ
diff --git a/demos/boxes/dotted.fsh b/demos/boxes/dotted.fsh
new file mode 100644
index 0000000000..8f4621d581
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/fresnel.fsh b/demos/boxes/fresnel.fsh
new file mode 100644
index 0000000000..02d6b0cc60
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/glass.fsh b/demos/boxes/glass.fsh
new file mode 100644
index 0000000000..9dad845f43
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/glbuffers.cpp b/demos/boxes/glbuffers.cpp
new file mode 100644
index 0000000000..9e5a5ff3a0
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/glbuffers.h b/demos/boxes/glbuffers.h
new file mode 100644
index 0000000000..fb6455b28c
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/glextensions.cpp b/demos/boxes/glextensions.cpp
new file mode 100644
index 0000000000..102159401c
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/glextensions.h b/demos/boxes/glextensions.h
new file mode 100644
index 0000000000..342e5d8930
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/gltrianglemesh.h b/demos/boxes/gltrianglemesh.h
new file mode 100644
index 0000000000..d0afa35295
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/granite.fsh b/demos/boxes/granite.fsh
new file mode 100644
index 0000000000..025153bc26
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/main.cpp b/demos/boxes/main.cpp
new file mode 100644
index 0000000000..568031ed41
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/marble.fsh b/demos/boxes/marble.fsh
new file mode 100644
index 0000000000..fbd1f5c77f
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/parameters.par b/demos/boxes/parameters.par
new file mode 100644
index 0000000000..50e20739b9
--- /dev/null
+++ b/demos/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/demos/boxes/qt-logo.jpg b/demos/boxes/qt-logo.jpg
new file mode 100644
index 0000000000..4014b4659c
--- /dev/null
+++ b/demos/boxes/qt-logo.jpg
Binary files differ
diff --git a/demos/boxes/qt-logo.png b/demos/boxes/qt-logo.png
new file mode 100644
index 0000000000..7d3e97eb36
--- /dev/null
+++ b/demos/boxes/qt-logo.png
Binary files differ
diff --git a/demos/boxes/qtbox.cpp b/demos/boxes/qtbox.cpp
new file mode 100644
index 0000000000..9916a3540e
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/qtbox.h b/demos/boxes/qtbox.h
new file mode 100644
index 0000000000..71c1304a60
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/reflection.fsh b/demos/boxes/reflection.fsh
new file mode 100644
index 0000000000..50b0a4ae06
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/refraction.fsh b/demos/boxes/refraction.fsh
new file mode 100644
index 0000000000..c846d6ae96
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/roundedbox.cpp b/demos/boxes/roundedbox.cpp
new file mode 100644
index 0000000000..913cc54235
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/roundedbox.h b/demos/boxes/roundedbox.h
new file mode 100644
index 0000000000..a19f1a3acc
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/scene.cpp b/demos/boxes/scene.cpp
new file mode 100644
index 0000000000..85c9a5be70
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/boxes/scene.h b/demos/boxes/scene.h
new file mode 100644
index 0000000000..d1c65268fb
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_H
+#define SCENE_H
+
+//#include <GL/glew.h>
+#include "glextensions.h"
+
+#include <QtGui>
+#include <QtOpenGL>
+
+#include "roundedbox.h"
+#include "gltrianglemesh.h"
+#include "trackball.h"
+#include "glbuffers.h"
+#include "qtbox.h"
+
+#define PI 3.14159265358979
+
+QT_BEGIN_NAMESPACE
+class QMatrix4x4;
+QT_END_NAMESPACE
+
+class ParameterEdit : public QWidget
+{
+public:
+ virtual void emitChange() = 0;
+};
+
+class ColorEdit : public ParameterEdit
+{
+ Q_OBJECT
+public:
+ ColorEdit(QRgb initialColor, int id);
+ QRgb color() const {return m_color;}
+ virtual void emitChange() {emit colorChanged(m_color, m_id);}
+public slots:
+ void editDone();
+signals:
+ void colorChanged(QRgb color, int id);
+protected:
+ virtual void mousePressEvent(QMouseEvent *event);
+ void setColor(QRgb color); // also emits colorChanged()
+private:
+ QGraphicsScene *m_dialogParentScene;
+ QLineEdit *m_lineEdit;
+ QFrame *m_button;
+ QRgb m_color;
+ int m_id;
+};
+
+class FloatEdit : public ParameterEdit
+{
+ Q_OBJECT
+public:
+ FloatEdit(float initialValue, int id);
+ float value() const {return m_value;}
+ virtual void emitChange() {emit valueChanged(m_value, m_id);}
+public slots:
+ void editDone();
+signals:
+ void valueChanged(float value, int id);
+private:
+ QGraphicsScene *m_dialogParentScene;
+ QLineEdit *m_lineEdit;
+ float m_value;
+ int m_id;
+};
+
+class GraphicsWidget : public QGraphicsProxyWidget
+{
+public:
+ GraphicsWidget() : QGraphicsProxyWidget(0, Qt::Window) {}
+protected:
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+};
+
+class TwoSidedGraphicsWidget : public QObject
+{
+ Q_OBJECT
+public:
+ TwoSidedGraphicsWidget(QGraphicsScene *scene);
+ void setWidget(int index, QWidget *widget);
+ QWidget *widget(int index);
+public slots:
+ void flip();
+protected slots:
+ void animateFlip();
+private:
+ GraphicsWidget *m_proxyWidgets[2];
+ int m_current;
+ int m_angle; // angle in degrees
+ int m_delta;
+};
+
+class RenderOptionsDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ RenderOptionsDialog();
+ int addTexture(const QString &name);
+ int addShader(const QString &name);
+ void emitParameterChanged();
+protected slots:
+ void setColorParameter(QRgb color, int id);
+ void setFloatParameter(float value, int id);
+signals:
+ void dynamicCubemapToggled(int);
+ void colorParameterChanged(const QString &, QRgb);
+ void floatParameterChanged(const QString &, float);
+ void textureChanged(int);
+ void shaderChanged(int);
+ void doubleClicked();
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+
+ QVector<QByteArray> m_parameterNames;
+ QComboBox *m_textureCombo;
+ QComboBox *m_shaderCombo;
+ QVector<ParameterEdit *> m_parameterEdits;
+};
+
+class ItemDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ enum ItemType {
+ QtBoxItem,
+ CircleItem,
+ SquareItem,
+ };
+
+ ItemDialog();
+public slots:
+ void triggerNewQtBox();
+ void triggerNewCircleItem();
+ void triggerNewSquareItem();
+signals:
+ void doubleClicked();
+ void newItemTriggered(ItemDialog::ItemType type);
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+};
+
+class Scene : public QGraphicsScene
+{
+ Q_OBJECT
+public:
+ Scene(int width, int height, int maxTextureSize);
+ ~Scene();
+ virtual void drawBackground(QPainter *painter, const QRectF &rect);
+
+public slots:
+ void setShader(int index);
+ void setTexture(int index);
+ void toggleDynamicCubemap(int state);
+ void setColorParameter(const QString &name, QRgb color);
+ void setFloatParameter(const QString &name, float value);
+ void newItem(ItemDialog::ItemType type);
+protected:
+ void renderBoxes(const QMatrix4x4 &view, int excludeBox = -2);
+ void setStates();
+ void setLights();
+ void defaultStates();
+ void renderCubemaps();
+
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void wheelEvent(QGraphicsSceneWheelEvent * event);
+private:
+ void initGL();
+ QPointF pixelPosToViewPos(const QPointF& p);
+
+ QTime m_time;
+ int m_lastTime;
+ int m_mouseEventTime;
+ int m_distExp;
+ int m_frame;
+ int m_maxTextureSize;
+
+ int m_currentShader;
+ int m_currentTexture;
+ bool m_dynamicCubemap;
+ bool m_updateAllCubemaps;
+
+ RenderOptionsDialog *m_renderOptions;
+ ItemDialog *m_itemDialog;
+ QTimer *m_timer;
+ GLRoundedBox *m_box;
+ TrackBall m_trackBalls[3];
+ QVector<GLTexture *> m_textures;
+ GLTextureCube *m_environment;
+ GLTexture3D *m_noise;
+ GLRenderTargetCube *m_mainCubemap;
+ QVector<GLRenderTargetCube *> m_cubemaps;
+ QVector<QGLShaderProgram *> m_programs;
+ QGLShader *m_vertexShader;
+ QVector<QGLShader *> m_fragmentShaders;
+ QGLShader *m_environmentShader;
+ QGLShaderProgram *m_environmentProgram;
+};
+
+#endif
diff --git a/demos/boxes/smiley.png b/demos/boxes/smiley.png
new file mode 100644
index 0000000000..41cfda6b23
--- /dev/null
+++ b/demos/boxes/smiley.png
Binary files differ
diff --git a/demos/boxes/square.jpg b/demos/boxes/square.jpg
new file mode 100644
index 0000000000..03f53bd530
--- /dev/null
+++ b/demos/boxes/square.jpg
Binary files differ
diff --git a/demos/boxes/trackball.cpp b/demos/boxes/trackball.cpp
new file mode 100644
index 0000000000..8a6a01484e
--- /dev/null
+++ b/demos/boxes/trackball.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "trackball.h"
+#include "scene.h"
+
+//============================================================================//
+// TrackBall //
+//============================================================================//
+
+TrackBall::TrackBall(TrackMode mode)
+ : m_angularVelocity(0)
+ , m_paused(false)
+ , m_pressed(false)
+ , m_mode(mode)
+{
+ m_axis = QVector3D(0, 1, 0);
+ m_rotation = QQuaternion();
+ m_lastTime = QTime::currentTime();
+}
+
+TrackBall::TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode)
+ : m_axis(axis)
+ , m_angularVelocity(angularVelocity)
+ , m_paused(false)
+ , m_pressed(false)
+ , m_mode(mode)
+{
+ m_rotation = QQuaternion();
+ m_lastTime = QTime::currentTime();
+}
+
+void TrackBall::push(const QPointF& p, const QQuaternion &)
+{
+ m_rotation = rotation();
+ m_pressed = true;
+ m_lastTime = QTime::currentTime();
+ m_lastPos = p;
+ m_angularVelocity = 0.0f;
+}
+
+void TrackBall::move(const QPointF& p, const QQuaternion &transformation)
+{
+ if (!m_pressed)
+ return;
+
+ QTime currentTime = QTime::currentTime();
+ int msecs = m_lastTime.msecsTo(currentTime);
+ if (msecs <= 20)
+ return;
+
+ switch (m_mode) {
+ case Plane:
+ {
+ QLineF delta(m_lastPos, p);
+ m_angularVelocity = 180*delta.length() / (PI*msecs);
+ m_axis = QVector3D(-delta.dy(), delta.dx(), 0.0f).normalized();
+ m_axis = transformation.rotatedVector(m_axis);
+ m_rotation = QQuaternion::fromAxisAndAngle(m_axis, 180 / PI * delta.length()) * m_rotation;
+ }
+ break;
+ case Sphere:
+ {
+ QVector3D lastPos3D = QVector3D(m_lastPos.x(), m_lastPos.y(), 0.0f);
+ float sqrZ = 1 - QVector3D::dotProduct(lastPos3D, lastPos3D);
+ if (sqrZ > 0)
+ lastPos3D.setZ(sqrt(sqrZ));
+ else
+ lastPos3D.normalize();
+
+ QVector3D currentPos3D = QVector3D(p.x(), p.y(), 0.0f);
+ sqrZ = 1 - QVector3D::dotProduct(currentPos3D, currentPos3D);
+ if (sqrZ > 0)
+ currentPos3D.setZ(sqrt(sqrZ));
+ else
+ currentPos3D.normalize();
+
+ m_axis = QVector3D::crossProduct(lastPos3D, currentPos3D);
+ float angle = 180 / PI * asin(sqrt(QVector3D::dotProduct(m_axis, m_axis)));
+
+ m_angularVelocity = angle / msecs;
+ m_axis.normalize();
+ m_axis = transformation.rotatedVector(m_axis);
+ m_rotation = QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation;
+ }
+ break;
+ }
+
+
+ m_lastPos = p;
+ m_lastTime = currentTime;
+}
+
+void TrackBall::release(const QPointF& p, const QQuaternion &transformation)
+{
+ // Calling move() caused the rotation to stop if the framerate was too low.
+ move(p, transformation);
+ m_pressed = false;
+}
+
+void TrackBall::start()
+{
+ m_lastTime = QTime::currentTime();
+ m_paused = false;
+}
+
+void TrackBall::stop()
+{
+ m_rotation = rotation();
+ m_paused = true;
+}
+
+QQuaternion TrackBall::rotation() const
+{
+ if (m_paused || m_pressed)
+ return m_rotation;
+
+ QTime currentTime = QTime::currentTime();
+ float angle = m_angularVelocity * m_lastTime.msecsTo(currentTime);
+ return QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation;
+}
+
diff --git a/demos/boxes/trackball.h b/demos/boxes/trackball.h
new file mode 100644
index 0000000000..e43b00d7b3
--- /dev/null
+++ b/demos/boxes/trackball.h
@@ -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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRACKBALL_H
+#define TRACKBALL_H
+
+#include <QtGui>
+
+#include <QtGui/qvector3d.h>
+#include <QtGui/qquaternion.h>
+
+class TrackBall
+{
+public:
+ enum TrackMode
+ {
+ Plane,
+ Sphere,
+ };
+ TrackBall(TrackMode mode = Sphere);
+ TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode = Sphere);
+ // coordinates in [-1,1]x[-1,1]
+ void push(const QPointF& p, const QQuaternion &transformation);
+ void move(const QPointF& p, const QQuaternion &transformation);
+ void release(const QPointF& p, const QQuaternion &transformation);
+ void start(); // starts clock
+ void stop(); // stops clock
+ QQuaternion rotation() const;
+private:
+ QQuaternion m_rotation;
+ QVector3D m_axis;
+ float m_angularVelocity;
+
+ QPointF m_lastPos;
+ QTime m_lastTime;
+ bool m_paused;
+ bool m_pressed;
+ TrackMode m_mode;
+};
+
+#endif
diff --git a/demos/boxes/wood.fsh b/demos/boxes/wood.fsh
new file mode 100644
index 0000000000..8e47b69f9c
--- /dev/null
+++ b/demos/boxes/wood.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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+varying vec3 position, normal;
+varying vec4 specular, ambient, diffuse, lightDirection;
+
+uniform sampler2D tex;
+uniform sampler3D noise;
+
+//const vec4 woodColors[2] = {vec4(0.37,0.24,0.20,1), vec4(0.8,0.6,0.4,1)};
+uniform vec4 woodColors[2];
+//const float woodTubulence = 0.1;
+uniform float woodTubulence;
+
+void main()
+{
+ float r = length(gl_TexCoord[1].yz);
+ r += woodTubulence * texture3D(noise, 0.25 * gl_TexCoord[1].xyz).x;
+
+ 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);
+
+ float f = fract(16.0 * r);
+ vec4 unlitColor = mix(woodColors[0], woodColors[1], min(1.25 * f, 5.0 - 5.0 * f));
+ gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor +
+ M.specular * specular * pow(max(RdotL, 0.0), M.shininess);
+}
diff --git a/demos/chip/chip.cpp b/demos/chip/chip.cpp
new file mode 100644
index 0000000000..6f3b529f16
--- /dev/null
+++ b/demos/chip/chip.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "chip.h"
+
+#include <QtGui>
+
+Chip::Chip(const QColor &color, int x, int y)
+{
+ this->x = x;
+ this->y = y;
+ this->color = color;
+ setZValue((x + y) % 2);
+
+ setFlags(ItemIsSelectable | ItemIsMovable);
+ setAcceptsHoverEvents(true);
+}
+
+QRectF Chip::boundingRect() const
+{
+ return QRectF(0, 0, 110, 70);
+}
+
+QPainterPath Chip::shape() const
+{
+ QPainterPath path;
+ path.addRect(14, 14, 82, 42);
+ return path;
+}
+
+void Chip::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+
+ QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color;
+ if (option->state & QStyle::State_MouseOver)
+ fillColor = fillColor.light(125);
+
+ const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform());
+ if (lod < 0.2) {
+ if (lod < 0.125) {
+ painter->fillRect(QRectF(0, 0, 110, 70), fillColor);
+ return;
+ }
+
+ QBrush b = painter->brush();
+ painter->setBrush(fillColor);
+ painter->drawRect(13, 13, 97, 57);
+ painter->setBrush(b);
+ return;
+ }
+
+ QPen oldPen = painter->pen();
+ QPen pen = oldPen;
+ int width = 0;
+ if (option->state & QStyle::State_Selected)
+ width += 2;
+
+ pen.setWidth(width);
+ QBrush b = painter->brush();
+ painter->setBrush(QBrush(fillColor.dark(option->state & QStyle::State_Sunken ? 120 : 100)));
+
+ painter->drawRect(QRect(14, 14, 79, 39));
+ painter->setBrush(b);
+
+ if (lod >= 1) {
+ painter->setPen(QPen(Qt::gray, 1));
+ painter->drawLine(15, 54, 94, 54);
+ painter->drawLine(94, 53, 94, 15);
+ painter->setPen(QPen(Qt::black, 0));
+ }
+
+ // Draw text
+ if (lod >= 2) {
+ QFont font("Times", 10);
+ font.setStyleStrategy(QFont::ForceOutline);
+ painter->setFont(font);
+ painter->save();
+ painter->scale(0.1, 0.1);
+ painter->drawText(170, 180, QString("Model: VSC-2000 (Very Small Chip) at %1x%2").arg(x).arg(y));
+ painter->drawText(170, 200, QString("Serial number: DLWR-WEER-123L-ZZ33-SDSJ"));
+ painter->drawText(170, 220, QString("Manufacturer: Chip Manufacturer"));
+ painter->restore();
+ }
+
+ // Draw lines
+ QVarLengthArray<QLineF, 36> lines;
+ if (lod >= 0.5) {
+ for (int i = 0; i <= 10; i += (lod > 0.5 ? 1 : 2)) {
+ lines.append(QLineF(18 + 7 * i, 13, 18 + 7 * i, 5));
+ lines.append(QLineF(18 + 7 * i, 54, 18 + 7 * i, 62));
+ }
+ for (int i = 0; i <= 6; i += (lod > 0.5 ? 1 : 2)) {
+ lines.append(QLineF(5, 18 + i * 5, 13, 18 + i * 5));
+ lines.append(QLineF(94, 18 + i * 5, 102, 18 + i * 5));
+ }
+ }
+ if (lod >= 0.4) {
+ const QLineF lineData[] = {
+ QLineF(25, 35, 35, 35),
+ QLineF(35, 30, 35, 40),
+ QLineF(35, 30, 45, 35),
+ QLineF(35, 40, 45, 35),
+ QLineF(45, 30, 45, 40),
+ QLineF(45, 35, 55, 35)
+ };
+ lines.append(lineData, 6);
+ }
+ painter->drawLines(lines.data(), lines.size());
+
+ // Draw red ink
+ if (stuff.size() > 1) {
+ QPen p = painter->pen();
+ painter->setPen(QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+ painter->setBrush(Qt::NoBrush);
+ QPainterPath path;
+ path.moveTo(stuff.first());
+ for (int i = 1; i < stuff.size(); ++i)
+ path.lineTo(stuff.at(i));
+ painter->drawPath(path);
+ painter->setPen(p);
+ }
+}
+
+void Chip::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsItem::mousePressEvent(event);
+ update();
+}
+
+void Chip::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->modifiers() & Qt::ShiftModifier) {
+ stuff << event->pos();
+ update();
+ return;
+ }
+ QGraphicsItem::mouseMoveEvent(event);
+}
+
+void Chip::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsItem::mouseReleaseEvent(event);
+ update();
+}
diff --git a/demos/chip/chip.h b/demos/chip/chip.h
new file mode 100644
index 0000000000..dca63b71fc
--- /dev/null
+++ b/demos/chip/chip.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHIP_H
+#define CHIP_H
+
+#include <QtGui/QColor>
+#include <QtGui/QGraphicsItem>
+
+class Chip : public QGraphicsItem
+{
+public:
+ Chip(const QColor &color, int x, int y);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget);
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ int x, y;
+ QColor color;
+ QList<QPointF> stuff;
+};
+
+#endif
diff --git a/demos/chip/chip.pro b/demos/chip/chip.pro
new file mode 100644
index 0000000000..8ff2aa45f1
--- /dev/null
+++ b/demos/chip/chip.pro
@@ -0,0 +1,20 @@
+RESOURCES += images.qrc
+
+HEADERS += mainwindow.h view.h chip.h
+SOURCES += main.cpp
+SOURCES += mainwindow.cpp view.cpp chip.cpp
+
+contains(QT_CONFIG, opengl):QT += opengl
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/chip
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.png *.pro *.html *.doc images
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/chip
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
diff --git a/demos/chip/fileprint.png b/demos/chip/fileprint.png
new file mode 100644
index 0000000000..ba7c02dc18
--- /dev/null
+++ b/demos/chip/fileprint.png
Binary files differ
diff --git a/demos/chip/images.qrc b/demos/chip/images.qrc
new file mode 100644
index 0000000000..c7cdf0c4c0
--- /dev/null
+++ b/demos/chip/images.qrc
@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>qt4logo.png</file>
+ <file>zoomin.png</file>
+ <file>zoomout.png</file>
+ <file>rotateleft.png</file>
+ <file>rotateright.png</file>
+ <file>fileprint.png</file>
+</qresource>
+</RCC>
diff --git a/demos/chip/main.cpp b/demos/chip/main.cpp
new file mode 100644
index 0000000000..a4353bfde4
--- /dev/null
+++ b/demos/chip/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 demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(images);
+
+ QApplication app(argc, argv);
+ app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
+
+ MainWindow window;
+ window.show();
+
+ return app.exec();
+}
diff --git a/demos/chip/mainwindow.cpp b/demos/chip/mainwindow.cpp
new file mode 100644
index 0000000000..825c38823a
--- /dev/null
+++ b/demos/chip/mainwindow.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "view.h"
+#include "chip.h"
+
+#include <QtGui>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QWidget(parent)
+{
+ populateScene();
+
+ h1Splitter = new QSplitter;
+ h2Splitter = new QSplitter;
+
+ QSplitter *vSplitter = new QSplitter;
+ vSplitter->setOrientation(Qt::Vertical);
+ vSplitter->addWidget(h1Splitter);
+ vSplitter->addWidget(h2Splitter);
+
+ View *view = new View("Top left view");
+ view->view()->setScene(scene);
+ h1Splitter->addWidget(view);
+
+ view = new View("Top right view");
+ view->view()->setScene(scene);
+ h1Splitter->addWidget(view);
+
+ view = new View("Bottom left view");
+ view->view()->setScene(scene);
+ h2Splitter->addWidget(view);
+
+ view = new View("Bottom right view");
+ view->view()->setScene(scene);
+ h2Splitter->addWidget(view);
+
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->addWidget(vSplitter);
+ setLayout(layout);
+
+ setWindowTitle(tr("Chip Demo"));
+}
+
+void MainWindow::populateScene()
+{
+ scene = new QGraphicsScene;
+
+ QImage image(":/qt4logo.png");
+
+ // Populate scene
+ int xx = 0;
+ int nitems = 0;
+ for (int i = -11000; i < 11000; i += 110) {
+ ++xx;
+ int yy = 0;
+ for (int j = -7000; j < 7000; j += 70) {
+ ++yy;
+ qreal x = (i + 11000) / 22000.0;
+ qreal y = (j + 7000) / 14000.0;
+
+ QColor color(image.pixel(int(image.width() * x), int(image.height() * y)));
+ QGraphicsItem *item = new Chip(color, xx, yy);
+ item->setPos(QPointF(i, j));
+ scene->addItem(item);
+
+ ++nitems;
+ }
+ }
+}
diff --git a/demos/chip/mainwindow.h b/demos/chip/mainwindow.h
new file mode 100644
index 0000000000..9c8ac03638
--- /dev/null
+++ b/demos/chip/mainwindow.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/qwidget.h>
+
+QT_FORWARD_DECLARE_CLASS(QGraphicsScene)
+QT_FORWARD_DECLARE_CLASS(QGraphicsView)
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QSlider)
+QT_FORWARD_DECLARE_CLASS(QSplitter)
+
+class MainWindow : public QWidget
+{
+ Q_OBJECT
+public:
+ MainWindow(QWidget *parent = 0);
+
+private:
+ void setupMatrix();
+ void populateScene();
+
+ QGraphicsScene *scene;
+ QSplitter *h1Splitter;
+ QSplitter *h2Splitter;
+};
+
+#endif
diff --git a/demos/chip/qt4logo.png b/demos/chip/qt4logo.png
new file mode 100644
index 0000000000..157e86ed64
--- /dev/null
+++ b/demos/chip/qt4logo.png
Binary files differ
diff --git a/demos/chip/rotateleft.png b/demos/chip/rotateleft.png
new file mode 100644
index 0000000000..8cfa931986
--- /dev/null
+++ b/demos/chip/rotateleft.png
Binary files differ
diff --git a/demos/chip/rotateright.png b/demos/chip/rotateright.png
new file mode 100644
index 0000000000..ec5e8664a1
--- /dev/null
+++ b/demos/chip/rotateright.png
Binary files differ
diff --git a/demos/chip/view.cpp b/demos/chip/view.cpp
new file mode 100644
index 0000000000..49d02ecb52
--- /dev/null
+++ b/demos/chip/view.cpp
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "view.h"
+
+#include <QtGui>
+#ifndef QT_NO_OPENGL
+#include <QtOpenGL>
+#endif
+
+#include <qmath.h>
+
+void GraphicsView::wheelEvent(QWheelEvent *e)
+{
+ if (e->modifiers() & Qt::ControlModifier) {
+ if (e->delta() > 0)
+ view->zoomIn(6);
+ else
+ view->zoomOut(6);
+ e->accept();
+ } else {
+ QGraphicsView::wheelEvent(e);
+ }
+}
+
+View::View(const QString &name, QWidget *parent)
+ : QFrame(parent)
+{
+ setFrameStyle(Sunken | StyledPanel);
+ graphicsView = new GraphicsView(this);
+ graphicsView->setRenderHint(QPainter::Antialiasing, false);
+ graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
+ graphicsView->setOptimizationFlags(QGraphicsView::DontSavePainterState);
+ graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
+ graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+
+ int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
+ QSize iconSize(size, size);
+
+ QToolButton *zoomInIcon = new QToolButton;
+ zoomInIcon->setAutoRepeat(true);
+ zoomInIcon->setAutoRepeatInterval(33);
+ zoomInIcon->setAutoRepeatDelay(0);
+ zoomInIcon->setIcon(QPixmap(":/zoomin.png"));
+ zoomInIcon->setIconSize(iconSize);
+ QToolButton *zoomOutIcon = new QToolButton;
+ zoomOutIcon->setAutoRepeat(true);
+ zoomOutIcon->setAutoRepeatInterval(33);
+ zoomOutIcon->setAutoRepeatDelay(0);
+ zoomOutIcon->setIcon(QPixmap(":/zoomout.png"));
+ zoomOutIcon->setIconSize(iconSize);
+ zoomSlider = new QSlider;
+ zoomSlider->setMinimum(0);
+ zoomSlider->setMaximum(500);
+ zoomSlider->setValue(250);
+ zoomSlider->setTickPosition(QSlider::TicksRight);
+
+ // Zoom slider layout
+ QVBoxLayout *zoomSliderLayout = new QVBoxLayout;
+ zoomSliderLayout->addWidget(zoomInIcon);
+ zoomSliderLayout->addWidget(zoomSlider);
+ zoomSliderLayout->addWidget(zoomOutIcon);
+
+ QToolButton *rotateLeftIcon = new QToolButton;
+ rotateLeftIcon->setIcon(QPixmap(":/rotateleft.png"));
+ rotateLeftIcon->setIconSize(iconSize);
+ QToolButton *rotateRightIcon = new QToolButton;
+ rotateRightIcon->setIcon(QPixmap(":/rotateright.png"));
+ rotateRightIcon->setIconSize(iconSize);
+ rotateSlider = new QSlider;
+ rotateSlider->setOrientation(Qt::Horizontal);
+ rotateSlider->setMinimum(-360);
+ rotateSlider->setMaximum(360);
+ rotateSlider->setValue(0);
+ rotateSlider->setTickPosition(QSlider::TicksBelow);
+
+ // Rotate slider layout
+ QHBoxLayout *rotateSliderLayout = new QHBoxLayout;
+ rotateSliderLayout->addWidget(rotateLeftIcon);
+ rotateSliderLayout->addWidget(rotateSlider);
+ rotateSliderLayout->addWidget(rotateRightIcon);
+
+ resetButton = new QToolButton;
+ resetButton->setText(tr("0"));
+ resetButton->setEnabled(false);
+
+ // Label layout
+ QHBoxLayout *labelLayout = new QHBoxLayout;
+ label = new QLabel(name);
+ label2 = new QLabel(tr("Pointer Mode"));
+ selectModeButton = new QToolButton;
+ selectModeButton->setText(tr("Select"));
+ selectModeButton->setCheckable(true);
+ selectModeButton->setChecked(true);
+ dragModeButton = new QToolButton;
+ dragModeButton->setText(tr("Drag"));
+ dragModeButton->setCheckable(true);
+ dragModeButton->setChecked(false);
+ antialiasButton = new QToolButton;
+ antialiasButton->setText(tr("Antialiasing"));
+ antialiasButton->setCheckable(true);
+ antialiasButton->setChecked(false);
+ openGlButton = new QToolButton;
+ openGlButton->setText(tr("OpenGL"));
+ openGlButton->setCheckable(true);
+#ifndef QT_NO_OPENGL
+ openGlButton->setEnabled(QGLFormat::hasOpenGL());
+#else
+ openGlButton->setEnabled(false);
+#endif
+ printButton = new QToolButton;
+ printButton->setIcon(QIcon(QPixmap(":/fileprint.png")));
+
+ QButtonGroup *pointerModeGroup = new QButtonGroup;
+ pointerModeGroup->setExclusive(true);
+ pointerModeGroup->addButton(selectModeButton);
+ pointerModeGroup->addButton(dragModeButton);
+
+ labelLayout->addWidget(label);
+ labelLayout->addStretch();
+ labelLayout->addWidget(label2);
+ labelLayout->addWidget(selectModeButton);
+ labelLayout->addWidget(dragModeButton);
+ labelLayout->addStretch();
+ labelLayout->addWidget(antialiasButton);
+ labelLayout->addWidget(openGlButton);
+ labelLayout->addWidget(printButton);
+
+ QGridLayout *topLayout = new QGridLayout;
+ topLayout->addLayout(labelLayout, 0, 0);
+ topLayout->addWidget(graphicsView, 1, 0);
+ topLayout->addLayout(zoomSliderLayout, 1, 1);
+ topLayout->addLayout(rotateSliderLayout, 2, 0);
+ topLayout->addWidget(resetButton, 2, 1);
+ setLayout(topLayout);
+
+ connect(resetButton, SIGNAL(clicked()), this, SLOT(resetView()));
+ connect(zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
+ connect(rotateSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix()));
+ connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(setResetButtonEnabled()));
+ connect(graphicsView->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(setResetButtonEnabled()));
+ connect(selectModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
+ connect(dragModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode()));
+ connect(antialiasButton, SIGNAL(toggled(bool)), this, SLOT(toggleAntialiasing()));
+ connect(openGlButton, SIGNAL(toggled(bool)), this, SLOT(toggleOpenGL()));
+ connect(rotateLeftIcon, SIGNAL(clicked()), this, SLOT(rotateLeft()));
+ connect(rotateRightIcon, SIGNAL(clicked()), this, SLOT(rotateRight()));
+ connect(zoomInIcon, SIGNAL(clicked()), this, SLOT(zoomIn()));
+ connect(zoomOutIcon, SIGNAL(clicked()), this, SLOT(zoomOut()));
+ connect(printButton, SIGNAL(clicked()), this, SLOT(print()));
+
+ setupMatrix();
+}
+
+QGraphicsView *View::view() const
+{
+ return static_cast<QGraphicsView *>(graphicsView);
+}
+
+void View::resetView()
+{
+ zoomSlider->setValue(250);
+ rotateSlider->setValue(0);
+ setupMatrix();
+ graphicsView->ensureVisible(QRectF(0, 0, 0, 0));
+
+ resetButton->setEnabled(false);
+}
+
+void View::setResetButtonEnabled()
+{
+ resetButton->setEnabled(true);
+}
+
+void View::setupMatrix()
+{
+ qreal scale = qPow(qreal(2), (zoomSlider->value() - 250) / qreal(50));
+
+ QMatrix matrix;
+ matrix.scale(scale, scale);
+ matrix.rotate(rotateSlider->value());
+
+ graphicsView->setMatrix(matrix);
+ setResetButtonEnabled();
+}
+
+void View::togglePointerMode()
+{
+ graphicsView->setDragMode(selectModeButton->isChecked()
+ ? QGraphicsView::RubberBandDrag
+ : QGraphicsView::ScrollHandDrag);
+ graphicsView->setInteractive(selectModeButton->isChecked());
+}
+
+void View::toggleOpenGL()
+{
+#ifndef QT_NO_OPENGL
+ graphicsView->setViewport(openGlButton->isChecked() ? new QGLWidget(QGLFormat(QGL::SampleBuffers)) : new QWidget);
+#endif
+}
+
+void View::toggleAntialiasing()
+{
+ graphicsView->setRenderHint(QPainter::Antialiasing, antialiasButton->isChecked());
+}
+
+void View::print()
+{
+#ifndef QT_NO_PRINTER
+ QPrinter printer;
+ QPrintDialog dialog(&printer, this);
+ if (dialog.exec() == QDialog::Accepted) {
+ QPainter painter(&printer);
+ graphicsView->render(&painter);
+ }
+#endif
+}
+
+void View::zoomIn(int level)
+{
+ zoomSlider->setValue(zoomSlider->value() + level);
+}
+
+void View::zoomOut(int level)
+{
+ zoomSlider->setValue(zoomSlider->value() - level);
+}
+
+void View::rotateLeft()
+{
+ rotateSlider->setValue(rotateSlider->value() - 10);
+}
+
+void View::rotateRight()
+{
+ rotateSlider->setValue(rotateSlider->value() + 10);
+}
+
diff --git a/demos/chip/view.h b/demos/chip/view.h
new file mode 100644
index 0000000000..15aa2cf4c9
--- /dev/null
+++ b/demos/chip/view.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <QFrame>
+#include <QGraphicsView>
+
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QSlider)
+QT_FORWARD_DECLARE_CLASS(QToolButton)
+
+class View;
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(View *v) : QGraphicsView(), view(v) { }
+
+protected:
+ void wheelEvent(QWheelEvent *);
+
+private:
+ View *view;
+};
+
+class View : public QFrame
+{
+ Q_OBJECT
+public:
+ View(const QString &name, QWidget *parent = 0);
+
+ QGraphicsView *view() const;
+
+public slots:
+ void zoomIn(int level = 1);
+ void zoomOut(int level = 1);
+
+private slots:
+ void resetView();
+ void setResetButtonEnabled();
+ void setupMatrix();
+ void togglePointerMode();
+ void toggleOpenGL();
+ void toggleAntialiasing();
+ void print();
+ void rotateLeft();
+ void rotateRight();
+
+private:
+ GraphicsView *graphicsView;
+ QLabel *label;
+ QLabel *label2;
+ QToolButton *selectModeButton;
+ QToolButton *dragModeButton;
+ QToolButton *openGlButton;
+ QToolButton *antialiasButton;
+ QToolButton *printButton;
+ QToolButton *resetButton;
+ QSlider *zoomSlider;
+ QSlider *rotateSlider;
+};
+
+#endif
diff --git a/demos/chip/zoomin.png b/demos/chip/zoomin.png
new file mode 100644
index 0000000000..8b0daeea48
--- /dev/null
+++ b/demos/chip/zoomin.png
Binary files differ
diff --git a/demos/chip/zoomout.png b/demos/chip/zoomout.png
new file mode 100644
index 0000000000..1575dd24f6
--- /dev/null
+++ b/demos/chip/zoomout.png
Binary files differ
diff --git a/demos/composition/composition.cpp b/demos/composition/composition.cpp
new file mode 100644
index 0000000000..15f5529611
--- /dev/null
+++ b/demos/composition/composition.cpp
@@ -0,0 +1,544 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "composition.h"
+#include <QBoxLayout>
+#include <QRadioButton>
+#include <QTimer>
+#include <QDateTime>
+#include <QSlider>
+#include <QMouseEvent>
+#include <qmath.h>
+
+const int animationInterval = 15; // update every 16 ms = ~60FPS
+
+CompositionWidget::CompositionWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ CompositionRenderer *view = new CompositionRenderer(this);
+
+ QGroupBox *mainGroup = new QGroupBox(parent);
+ mainGroup->setTitle(tr("Composition Modes"));
+
+ QGroupBox *modesGroup = new QGroupBox(mainGroup);
+ modesGroup->setTitle(tr("Mode"));
+
+ rbClear = new QRadioButton(tr("Clear"), modesGroup);
+ connect(rbClear, SIGNAL(clicked()), view, SLOT(setClearMode()));
+ rbSource = new QRadioButton(tr("Source"), modesGroup);
+ connect(rbSource, SIGNAL(clicked()), view, SLOT(setSourceMode()));
+ rbDest = new QRadioButton(tr("Destination"), modesGroup);
+ connect(rbDest, SIGNAL(clicked()), view, SLOT(setDestMode()));
+ rbSourceOver = new QRadioButton(tr("Source Over"), modesGroup);
+ connect(rbSourceOver, SIGNAL(clicked()), view, SLOT(setSourceOverMode()));
+ rbDestOver = new QRadioButton(tr("Destination Over"), modesGroup);
+ connect(rbDestOver, SIGNAL(clicked()), view, SLOT(setDestOverMode()));
+ rbSourceIn = new QRadioButton(tr("Source In"), modesGroup);
+ connect(rbSourceIn, SIGNAL(clicked()), view, SLOT(setSourceInMode()));
+ rbDestIn = new QRadioButton(tr("Dest In"), modesGroup);
+ connect(rbDestIn, SIGNAL(clicked()), view, SLOT(setDestInMode()));
+ rbSourceOut = new QRadioButton(tr("Source Out"), modesGroup);
+ connect(rbSourceOut, SIGNAL(clicked()), view, SLOT(setSourceOutMode()));
+ rbDestOut = new QRadioButton(tr("Dest Out"), modesGroup);
+ connect(rbDestOut, SIGNAL(clicked()), view, SLOT(setDestOutMode()));
+ rbSourceAtop = new QRadioButton(tr("Source Atop"), modesGroup);
+ connect(rbSourceAtop, SIGNAL(clicked()), view, SLOT(setSourceAtopMode()));
+ rbDestAtop = new QRadioButton(tr("Dest Atop"), modesGroup);
+ connect(rbDestAtop, SIGNAL(clicked()), view, SLOT(setDestAtopMode()));
+ rbXor = new QRadioButton(tr("Xor"), modesGroup);
+ connect(rbXor, SIGNAL(clicked()), view, SLOT(setXorMode()));
+
+ rbPlus = new QRadioButton(tr("Plus"), modesGroup);
+ connect(rbPlus, SIGNAL(clicked()), view, SLOT(setPlusMode()));
+ rbMultiply = new QRadioButton(tr("Multiply"), modesGroup);
+ connect(rbMultiply, SIGNAL(clicked()), view, SLOT(setMultiplyMode()));
+ rbScreen = new QRadioButton(tr("Screen"), modesGroup);
+ connect(rbScreen, SIGNAL(clicked()), view, SLOT(setScreenMode()));
+ rbOverlay = new QRadioButton(tr("Overlay"), modesGroup);
+ connect(rbOverlay, SIGNAL(clicked()), view, SLOT(setOverlayMode()));
+ rbDarken = new QRadioButton(tr("Darken"), modesGroup);
+ connect(rbDarken, SIGNAL(clicked()), view, SLOT(setDarkenMode()));
+ rbLighten = new QRadioButton(tr("Lighten"), modesGroup);
+ connect(rbLighten, SIGNAL(clicked()), view, SLOT(setLightenMode()));
+ rbColorDodge = new QRadioButton(tr("Color Dodge"), modesGroup);
+ connect(rbColorDodge, SIGNAL(clicked()), view, SLOT(setColorDodgeMode()));
+ rbColorBurn = new QRadioButton(tr("Color Burn"), modesGroup);
+ connect(rbColorBurn, SIGNAL(clicked()), view, SLOT(setColorBurnMode()));
+ rbHardLight = new QRadioButton(tr("Hard Light"), modesGroup);
+ connect(rbHardLight, SIGNAL(clicked()), view, SLOT(setHardLightMode()));
+ rbSoftLight = new QRadioButton(tr("Soft Light"), modesGroup);
+ connect(rbSoftLight, SIGNAL(clicked()), view, SLOT(setSoftLightMode()));
+ rbDifference = new QRadioButton(tr("Difference"), modesGroup);
+ connect(rbDifference, SIGNAL(clicked()), view, SLOT(setDifferenceMode()));
+ rbExclusion = new QRadioButton(tr("Exclusion"), modesGroup);
+ connect(rbExclusion, SIGNAL(clicked()), view, SLOT(setExclusionMode()));
+
+ QGroupBox *circleColorGroup = new QGroupBox(mainGroup);
+ circleColorGroup->setTitle(tr("Circle color"));
+ QSlider *circleColorSlider = new QSlider(Qt::Horizontal, circleColorGroup);
+ circleColorSlider->setRange(0, 359);
+ circleColorSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ connect(circleColorSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleColor(int)));
+
+ QGroupBox *circleAlphaGroup = new QGroupBox(mainGroup);
+ circleAlphaGroup->setTitle(tr("Circle alpha"));
+ QSlider *circleAlphaSlider = new QSlider(Qt::Horizontal, circleAlphaGroup);
+ circleAlphaSlider->setRange(0, 255);
+ circleAlphaSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ connect(circleAlphaSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleAlpha(int)));
+
+ QPushButton *showSourceButton = new QPushButton(mainGroup);
+ showSourceButton->setText(tr("Show Source"));
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(view->usesOpenGL());
+
+ if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers())
+ enableOpenGLButton->hide();
+#endif
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+ QPushButton *animateButton = new QPushButton(mainGroup);
+ animateButton->setText(tr("Animated"));
+ animateButton->setCheckable(true);
+ animateButton->setChecked(true);
+
+ QHBoxLayout *viewLayout = new QHBoxLayout(this);
+ viewLayout->addWidget(view);
+ viewLayout->addWidget(mainGroup);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(circleColorGroup);
+ mainGroupLayout->addWidget(circleAlphaGroup);
+ mainGroupLayout->addWidget(modesGroup);
+ mainGroupLayout->addStretch();
+ mainGroupLayout->addWidget(animateButton);
+ mainGroupLayout->addWidget(whatsThisButton);
+ mainGroupLayout->addWidget(showSourceButton);
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+
+ QGridLayout *modesLayout = new QGridLayout(modesGroup);
+ modesLayout->addWidget(rbClear, 0, 0);
+ modesLayout->addWidget(rbSource, 1, 0);
+ modesLayout->addWidget(rbDest, 2, 0);
+ modesLayout->addWidget(rbSourceOver, 3, 0);
+ modesLayout->addWidget(rbDestOver, 4, 0);
+ modesLayout->addWidget(rbSourceIn, 5, 0);
+ modesLayout->addWidget(rbDestIn, 6, 0);
+ modesLayout->addWidget(rbSourceOut, 7, 0);
+ modesLayout->addWidget(rbDestOut, 8, 0);
+ modesLayout->addWidget(rbSourceAtop, 9, 0);
+ modesLayout->addWidget(rbDestAtop, 10, 0);
+ modesLayout->addWidget(rbXor, 11, 0);
+
+ modesLayout->addWidget(rbPlus, 0, 1);
+ modesLayout->addWidget(rbMultiply, 1, 1);
+ modesLayout->addWidget(rbScreen, 2, 1);
+ modesLayout->addWidget(rbOverlay, 3, 1);
+ modesLayout->addWidget(rbDarken, 4, 1);
+ modesLayout->addWidget(rbLighten, 5, 1);
+ modesLayout->addWidget(rbColorDodge, 6, 1);
+ modesLayout->addWidget(rbColorBurn, 7, 1);
+ modesLayout->addWidget(rbHardLight, 8, 1);
+ modesLayout->addWidget(rbSoftLight, 9, 1);
+ modesLayout->addWidget(rbDifference, 10, 1);
+ modesLayout->addWidget(rbExclusion, 11, 1);
+
+
+ QVBoxLayout *circleColorLayout = new QVBoxLayout(circleColorGroup);
+ circleColorLayout->addWidget(circleColorSlider);
+
+ QVBoxLayout *circleAlphaLayout = new QVBoxLayout(circleAlphaGroup);
+ circleAlphaLayout->addWidget(circleAlphaSlider);
+
+ view->loadDescription(":res/composition/composition.html");
+ view->loadSourceFile(":res/composition/composition.cpp");
+
+ connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
+ connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
+ connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
+#endif
+ connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool)));
+
+ circleColorSlider->setValue(270);
+ circleAlphaSlider->setValue(200);
+ rbSourceOut->animateClick();
+
+ setWindowTitle(tr("Composition Modes"));
+}
+
+
+void CompositionWidget::nextMode()
+{
+ /*
+ if (!m_animation_enabled)
+ return;
+ if (rbClear->isChecked()) rbSource->animateClick();
+ if (rbSource->isChecked()) rbDest->animateClick();
+ if (rbDest->isChecked()) rbSourceOver->animateClick();
+ if (rbSourceOver->isChecked()) rbDestOver->animateClick();
+ if (rbDestOver->isChecked()) rbSourceIn->animateClick();
+ if (rbSourceIn->isChecked()) rbDestIn->animateClick();
+ if (rbDestIn->isChecked()) rbSourceOut->animateClick();
+ if (rbSourceOut->isChecked()) rbDestOut->animateClick();
+ if (rbDestOut->isChecked()) rbSourceAtop->animateClick();
+ if (rbSourceAtop->isChecked()) rbDestAtop->animateClick();
+ if (rbDestAtop->isChecked()) rbXor->animateClick();
+ if (rbXor->isChecked()) rbClear->animateClick();
+ */
+}
+
+CompositionRenderer::CompositionRenderer(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ m_animation_enabled = true;
+ m_animationTimer = startTimer(animationInterval);
+#ifdef Q_WS_QWS
+ m_image = QPixmap(":res/composition/flower.jpg");
+ m_image.setAlphaChannel(QPixmap(":res/composition/flower_alpha.jpg"));
+#else
+ m_image = QImage(":res/composition/flower.jpg");
+ m_image.setAlphaChannel(QImage(":res/composition/flower_alpha.jpg"));
+#endif
+ m_circle_alpha = 127;
+ m_circle_hue = 255;
+ m_current_object = NoObject;
+ m_composition_mode = QPainter::CompositionMode_SourceOut;
+
+ m_circle_pos = QPoint(200, 100);
+
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+#ifdef QT_OPENGL_SUPPORT
+ m_pbuffer = 0;
+ m_pbuffer_size = 1024;
+#endif
+}
+
+QRectF rectangle_around(const QPointF &p, const QSizeF &size = QSize(250, 200))
+{
+ QRectF rect(p, size);
+ rect.translate(-size.width()/2, -size.height()/2);
+ return rect;
+}
+
+void CompositionRenderer::setAnimationEnabled(bool enabled)
+{
+ if (m_animation_enabled == enabled)
+ return;
+ m_animation_enabled = enabled;
+ if (enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ } else {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
+}
+
+void CompositionRenderer::updateCirclePos()
+{
+ if (m_current_object != NoObject)
+ return;
+ QDateTime dt = QDateTime::currentDateTime();
+ qreal t = (dt.toTime_t() * 1000 + dt.time().msec()) / 1000.0;
+
+ qreal x = width() / qreal(2) + (qCos(t*8/11) + qSin(-t)) * width() / qreal(4);
+ qreal y = height() / qreal(2) + (qSin(t*6/7) + qCos(t * qreal(1.5))) * height() / qreal(4);
+
+ setCirclePos(QLineF(m_circle_pos, QPointF(x, y)).pointAt(0.02));
+}
+
+void CompositionRenderer::drawBase(QPainter &p)
+{
+ p.setPen(Qt::NoPen);
+
+ QLinearGradient rect_gradient(0, 0, 0, height());
+ rect_gradient.setColorAt(0, Qt::red);
+ rect_gradient.setColorAt(.17, Qt::yellow);
+ rect_gradient.setColorAt(.33, Qt::green);
+ rect_gradient.setColorAt(.50, Qt::cyan);
+ rect_gradient.setColorAt(.66, Qt::blue);
+ rect_gradient.setColorAt(.81, Qt::magenta);
+ rect_gradient.setColorAt(1, Qt::red);
+ p.setBrush(rect_gradient);
+ p.drawRect(width() / 2, 0, width() / 2, height());
+
+ QLinearGradient alpha_gradient(0, 0, width(), 0);
+ alpha_gradient.setColorAt(0, Qt::white);
+ alpha_gradient.setColorAt(0.2, Qt::white);
+ alpha_gradient.setColorAt(0.5, Qt::transparent);
+ alpha_gradient.setColorAt(0.8, Qt::white);
+ alpha_gradient.setColorAt(1, Qt::white);
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ p.setBrush(alpha_gradient);
+ p.drawRect(0, 0, width(), height());
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
+
+ p.setPen(Qt::NoPen);
+ p.setRenderHint(QPainter::SmoothPixmapTransform);
+#ifdef Q_WS_QWS
+ p.drawPixmap(rect(), m_image);
+#else
+ p.drawImage(rect(), m_image);
+#endif
+}
+
+void CompositionRenderer::drawSource(QPainter &p)
+{
+ p.setPen(Qt::NoPen);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setCompositionMode(m_composition_mode);
+
+ QRectF circle_rect = rectangle_around(m_circle_pos);
+ QColor color = QColor::fromHsvF(m_circle_hue / 360.0, 1, 1, m_circle_alpha / 255.0);
+ QLinearGradient circle_gradient(circle_rect.topLeft(), circle_rect.bottomRight());
+ circle_gradient.setColorAt(0, color.light());
+ circle_gradient.setColorAt(0.5, color);
+ circle_gradient.setColorAt(1, color.dark());
+ p.setBrush(circle_gradient);
+
+ p.drawEllipse(circle_rect);
+}
+
+void CompositionRenderer::paint(QPainter *painter)
+{
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ if (usesOpenGL()) {
+
+ int new_pbuf_size = m_pbuffer_size;
+ if (size().width() > m_pbuffer_size ||
+ size().height() > m_pbuffer_size)
+ new_pbuf_size *= 2;
+
+ if (size().width() < m_pbuffer_size/2 &&
+ size().height() < m_pbuffer_size/2)
+ new_pbuf_size /= 2;
+
+ if (!m_pbuffer || new_pbuf_size != m_pbuffer_size) {
+ if (m_pbuffer) {
+ m_pbuffer->deleteTexture(m_base_tex);
+ m_pbuffer->deleteTexture(m_compositing_tex);
+ delete m_pbuffer;
+ }
+
+ m_pbuffer = new QGLPixelBuffer(QSize(new_pbuf_size, new_pbuf_size), QGLFormat::defaultFormat(), glWidget());
+ m_pbuffer->makeCurrent();
+ m_base_tex = m_pbuffer->generateDynamicTexture();
+ m_compositing_tex = m_pbuffer->generateDynamicTexture();
+ m_pbuffer_size = new_pbuf_size;
+ }
+
+ if (size() != m_previous_size) {
+ m_previous_size = size();
+ QPainter p(m_pbuffer);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
+ drawBase(p);
+ p.end();
+ m_pbuffer->updateDynamicTexture(m_base_tex);
+ }
+
+ qreal x_fraction = width()/float(m_pbuffer->width());
+ qreal y_fraction = height()/float(m_pbuffer->height());
+
+ {
+ QPainter p(m_pbuffer);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
+
+ p.save(); // Needed when using the GL1 engine
+ p.beginNativePainting(); // Needed when using the GL2 engine
+
+ glBindTexture(GL_TEXTURE_2D, m_base_tex);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1.,1.,1.,1.);
+
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0, 1.0);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(x_fraction, 1.0);
+ glVertex2f(width(), 0);
+
+ glTexCoord2f(x_fraction, 1.0-y_fraction);
+ glVertex2f(width(), height());
+
+ glTexCoord2f(0, 1.0-y_fraction);
+ glVertex2f(0, height());
+ }
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ p.endNativePainting(); // Needed when using the GL2 engine
+ p.restore(); // Needed when using the GL1 engine
+
+ drawSource(p);
+ p.end();
+ m_pbuffer->updateDynamicTexture(m_compositing_tex);
+ }
+
+ painter->beginNativePainting(); // Needed when using the GL2 engine
+ glWidget()->makeCurrent(); // Needed when using the GL1 engine
+ glBindTexture(GL_TEXTURE_2D, m_compositing_tex);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(1.,1.,1.,1.);
+ glBegin(GL_QUADS);
+ {
+ glTexCoord2f(0, 1.0);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(x_fraction, 1.0);
+ glVertex2f(width(), 0);
+
+ glTexCoord2f(x_fraction, 1.0-y_fraction);
+ glVertex2f(width(), height());
+
+ glTexCoord2f(0, 1.0-y_fraction);
+ glVertex2f(0, height());
+ }
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ painter->endNativePainting(); // Needed when using the GL2 engine
+ } else
+#endif
+ {
+ // using a QImage
+ if (m_buffer.size() != size()) {
+#ifdef Q_WS_QWS
+ m_base_buffer = QPixmap(size());
+ m_base_buffer.fill(Qt::transparent);
+#else
+ m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+ m_base_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+
+ m_base_buffer.fill(0);
+#endif
+
+ QPainter p(&m_base_buffer);
+
+ drawBase(p);
+ }
+
+#ifdef Q_WS_QWS
+ m_buffer = m_base_buffer;
+#else
+ memcpy(m_buffer.bits(), m_base_buffer.bits(), m_buffer.byteCount());
+#endif
+
+ {
+ QPainter p(&m_buffer);
+ drawSource(p);
+ }
+
+#ifdef Q_WS_QWS
+ painter->drawPixmap(0, 0, m_buffer);
+#else
+ painter->drawImage(0, 0, m_buffer);
+#endif
+ }
+}
+
+void CompositionRenderer::mousePressEvent(QMouseEvent *e)
+{
+ setDescriptionEnabled(false);
+
+ QRectF circle = rectangle_around(m_circle_pos);
+
+ if (circle.contains(e->pos())) {
+ m_current_object = Circle;
+ m_offset = circle.center() - e->pos();
+ } else {
+ m_current_object = NoObject;
+ }
+ if (m_animation_enabled) {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
+}
+
+void CompositionRenderer::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_current_object == Circle) setCirclePos(e->pos() + m_offset);
+}
+
+void CompositionRenderer::mouseReleaseEvent(QMouseEvent *)
+{
+ m_current_object = NoObject;
+
+ if (m_animation_enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ }
+}
+
+void CompositionRenderer::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_animationTimer)
+ updateCirclePos();
+}
+
+void CompositionRenderer::setCirclePos(const QPointF &pos)
+{
+ const QRect oldRect = rectangle_around(m_circle_pos).toAlignedRect();
+ m_circle_pos = pos;
+ const QRect newRect = rectangle_around(m_circle_pos).toAlignedRect();
+#if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
+ if (usesOpenGL())
+ update();
+ else
+#endif
+ update(oldRect | newRect);
+}
+
diff --git a/demos/composition/composition.h b/demos/composition/composition.h
new file mode 100644
index 0000000000..e1b5ed76b8
--- /dev/null
+++ b/demos/composition/composition.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPOSITION_H
+#define COMPOSITION_H
+
+#include "arthurwidgets.h"
+
+#include <QPainter>
+#include <QEvent>
+
+QT_FORWARD_DECLARE_CLASS(QPushButton)
+QT_FORWARD_DECLARE_CLASS(QRadioButton)
+
+#ifdef QT_OPENGL_SUPPORT
+#include <QtOpenGL>
+#endif
+
+class CompositionWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CompositionWidget(QWidget *parent);
+
+public slots:
+void nextMode();
+
+private:
+ bool m_cycle_enabled;
+
+ QRadioButton *rbClear;
+ QRadioButton *rbSource;
+ QRadioButton *rbDest;
+ QRadioButton *rbSourceOver;
+ QRadioButton *rbDestOver;
+ QRadioButton *rbSourceIn;
+ QRadioButton *rbDestIn;
+ QRadioButton *rbSourceOut;
+ QRadioButton *rbDestOut;
+ QRadioButton *rbSourceAtop;
+ QRadioButton *rbDestAtop;
+ QRadioButton *rbXor;
+
+ QRadioButton *rbPlus;
+ QRadioButton *rbMultiply;
+ QRadioButton *rbScreen;
+ QRadioButton *rbOverlay;
+ QRadioButton *rbDarken;
+ QRadioButton *rbLighten;
+ QRadioButton *rbColorDodge;
+ QRadioButton *rbColorBurn;
+ QRadioButton *rbHardLight;
+ QRadioButton *rbSoftLight;
+ QRadioButton *rbDifference;
+ QRadioButton *rbExclusion;
+};
+
+class CompositionRenderer : public ArthurFrame
+{
+ Q_OBJECT
+
+ enum ObjectType { NoObject, Circle, Rectangle, Image };
+
+ Q_PROPERTY(int circleColor READ circleColor WRITE setCircleColor)
+ Q_PROPERTY(int circleAlpha READ circleAlpha WRITE setCircleAlpha)
+ Q_PROPERTY(bool animation READ animationEnabled WRITE setAnimationEnabled)
+
+public:
+ CompositionRenderer(QWidget *parent);
+
+ void paint(QPainter *);
+
+ void setCirclePos(const QPointF &pos);
+
+ QSize sizeHint() const { return QSize(500, 400); }
+
+ bool animationEnabled() const { return m_animation_enabled; }
+ int circleColor() const { return m_circle_hue; }
+ int circleAlpha() const { return m_circle_alpha; }
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void timerEvent(QTimerEvent *);
+
+public slots:
+ void setClearMode() { m_composition_mode = QPainter::CompositionMode_Clear; update(); }
+ void setSourceMode() { m_composition_mode = QPainter::CompositionMode_Source; update(); }
+ void setDestMode() { m_composition_mode = QPainter::CompositionMode_Destination; update(); }
+ void setSourceOverMode() { m_composition_mode = QPainter::CompositionMode_SourceOver; update(); }
+ void setDestOverMode() { m_composition_mode = QPainter::CompositionMode_DestinationOver; update(); }
+ void setSourceInMode() { m_composition_mode = QPainter::CompositionMode_SourceIn; update(); }
+ void setDestInMode() { m_composition_mode = QPainter::CompositionMode_DestinationIn; update(); }
+ void setSourceOutMode() { m_composition_mode = QPainter::CompositionMode_SourceOut; update(); }
+ void setDestOutMode() { m_composition_mode = QPainter::CompositionMode_DestinationOut; update(); }
+ void setSourceAtopMode() { m_composition_mode = QPainter::CompositionMode_SourceAtop; update(); }
+ void setDestAtopMode() { m_composition_mode = QPainter::CompositionMode_DestinationAtop; update(); }
+ void setXorMode() { m_composition_mode = QPainter::CompositionMode_Xor; update(); }
+
+ void setPlusMode() { m_composition_mode = QPainter::CompositionMode_Plus; update(); }
+ void setMultiplyMode() { m_composition_mode = QPainter::CompositionMode_Multiply; update(); }
+ void setScreenMode() { m_composition_mode = QPainter::CompositionMode_Screen; update(); }
+ void setOverlayMode() { m_composition_mode = QPainter::CompositionMode_Overlay; update(); }
+ void setDarkenMode() { m_composition_mode = QPainter::CompositionMode_Darken; update(); }
+ void setLightenMode() { m_composition_mode = QPainter::CompositionMode_Lighten; update(); }
+ void setColorDodgeMode() { m_composition_mode = QPainter::CompositionMode_ColorDodge; update(); }
+ void setColorBurnMode() { m_composition_mode = QPainter::CompositionMode_ColorBurn; update(); }
+ void setHardLightMode() { m_composition_mode = QPainter::CompositionMode_HardLight; update(); }
+ void setSoftLightMode() { m_composition_mode = QPainter::CompositionMode_SoftLight; update(); }
+ void setDifferenceMode() { m_composition_mode = QPainter::CompositionMode_Difference; update(); }
+ void setExclusionMode() { m_composition_mode = QPainter::CompositionMode_Exclusion; update(); }
+
+ void setCircleAlpha(int alpha) { m_circle_alpha = alpha; update(); }
+ void setCircleColor(int hue) { m_circle_hue = hue; update(); }
+ void setAnimationEnabled(bool enabled);
+
+private:
+ void updateCirclePos();
+ void drawBase(QPainter &p);
+ void drawSource(QPainter &p);
+
+ QPainter::CompositionMode m_composition_mode;
+
+#ifdef Q_WS_QWS
+ QPixmap m_image;
+ QPixmap m_buffer;
+ QPixmap m_base_buffer;
+#else
+ QImage m_image;
+ QImage m_buffer;
+ QImage m_base_buffer;
+#endif
+
+ int m_circle_alpha;
+ int m_circle_hue;
+
+ QPointF m_circle_pos;
+ QPointF m_offset;
+
+ ObjectType m_current_object;
+ bool m_animation_enabled;
+ int m_animationTimer;
+
+#ifdef QT_OPENGL_SUPPORT
+ QGLPixelBuffer *m_pbuffer;
+ GLuint m_base_tex;
+ GLuint m_compositing_tex;
+ int m_pbuffer_size; // width==height==size of pbuffer
+ QSize m_previous_size;
+#endif
+};
+
+#endif // COMPOSITION_H
diff --git a/demos/composition/composition.html b/demos/composition/composition.html
new file mode 100644
index 0000000000..1848ad8bd1
--- /dev/null
+++ b/demos/composition/composition.html
@@ -0,0 +1,23 @@
+<html>
+
+<h1>Demo for composition modes</h1>
+
+<p>
+ This demo shows some of the more advanced composition modes supported by Qt.
+</p>
+
+<p>
+ The two most common forms of composition are <b>Source</b> and <b>SourceOver</b>.
+ <b>Source</b> is used to draw opaque objects onto a paint device. In this mode,
+ each pixel in the source replaces the corresponding pixel in the destination.
+ In <b>SourceOver</b> composition mode, the source object is transparent and is
+ drawn on top of the destination.
+</p>
+
+<p>
+ In addition to these standard modes, Qt defines the complete set of composition
+ modes as defined by Thomas Porter and Tom Duff. See the <tt>QPainter</tt> documentation
+ for details.
+</p>
+
+</html>
diff --git a/demos/composition/composition.pro b/demos/composition/composition.pro
new file mode 100644
index 0000000000..bb5cac5dea
--- /dev/null
+++ b/demos/composition/composition.pro
@@ -0,0 +1,29 @@
+SOURCES += main.cpp composition.cpp
+HEADERS += composition.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += composition.qrc
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/composition
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.png *.jpg *.pro *.html
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/composition
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+win32-msvc* {
+ QMAKE_CXXFLAGS += /Zm500
+ QMAKE_CFLAGS += /Zm500
+}
+
+wince* {
+ DEPLOYMENT_PLUGIN += qjpeg
+}
diff --git a/demos/composition/composition.qrc b/demos/composition/composition.qrc
new file mode 100644
index 0000000000..d02c397ee8
--- /dev/null
+++ b/demos/composition/composition.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/composition">
+ <file>composition.cpp</file>
+ <file>composition.html</file>
+ <file>flower.jpg</file>
+ <file>flower_alpha.jpg</file>
+</qresource>
+</RCC>
diff --git a/demos/composition/flower.jpg b/demos/composition/flower.jpg
new file mode 100644
index 0000000000..f8e022c98c
--- /dev/null
+++ b/demos/composition/flower.jpg
Binary files differ
diff --git a/demos/composition/flower_alpha.jpg b/demos/composition/flower_alpha.jpg
new file mode 100644
index 0000000000..6a3c2a02ef
--- /dev/null
+++ b/demos/composition/flower_alpha.jpg
Binary files differ
diff --git a/demos/composition/main.cpp b/demos/composition/main.cpp
new file mode 100644
index 0000000000..70eb0f31a9
--- /dev/null
+++ b/demos/composition/main.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "composition.h"
+
+#include <QApplication>
+#ifdef QT_OPENGL_SUPPORT
+#include <QtOpenGL>
+#endif
+
+int main(int argc, char **argv)
+{
+ // Q_INIT_RESOURCE(deform);
+
+#ifdef QT_OPENGL_SUPPORT
+ QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
+#endif
+ QApplication app(argc, argv);
+
+ CompositionWidget compWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ compWidget.setStyle(arthurStyle);
+
+ QList<QWidget *> widgets = compWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(arthurStyle);
+ compWidget.show();
+
+ return app.exec();
+}
diff --git a/demos/deform/deform.pro b/demos/deform/deform.pro
new file mode 100644
index 0000000000..ee15d2cc3e
--- /dev/null
+++ b/demos/deform/deform.pro
@@ -0,0 +1,24 @@
+SOURCES += main.cpp pathdeform.cpp
+HEADERS += pathdeform.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += deform.qrc
+
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/deform
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/deform
+INSTALLS += target sources
+
+symbian {
+ TARGET.UID3 = 0xA000A63D
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
diff --git a/demos/deform/deform.qrc b/demos/deform/deform.qrc
new file mode 100644
index 0000000000..2e59ebcfc5
--- /dev/null
+++ b/demos/deform/deform.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/deform">
+ <file>pathdeform.cpp</file>
+ <file>pathdeform.html</file>
+</qresource>
+</RCC>
diff --git a/demos/deform/main.cpp b/demos/deform/main.cpp
new file mode 100644
index 0000000000..5ddae0dd49
--- /dev/null
+++ b/demos/deform/main.cpp
@@ -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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pathdeform.h"
+
+#include <QApplication>
+#include <QDebug>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(deform);
+
+ QApplication app(argc, argv);
+
+ bool smallScreen = QApplication::arguments().contains("-small-screen");
+
+ PathDeformWidget deformWidget(0, smallScreen);
+
+ QStyle *arthurStyle = new ArthurStyle();
+ deformWidget.setStyle(arthurStyle);
+ QList<QWidget *> widgets = deformWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(arthurStyle);
+
+ if (smallScreen)
+ deformWidget.showFullScreen();
+ else
+ deformWidget.show();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
+#endif
+ return app.exec();
+}
diff --git a/demos/deform/pathdeform.cpp b/demos/deform/pathdeform.cpp
new file mode 100644
index 0000000000..1806438051
--- /dev/null
+++ b/demos/deform/pathdeform.cpp
@@ -0,0 +1,647 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pathdeform.h"
+
+#include <QApplication>
+#include <QtDebug>
+#include <QMouseEvent>
+#include <QTimerEvent>
+#include <QLayout>
+#include <QLineEdit>
+#include <QPainter>
+#include <QSlider>
+#include <QLabel>
+#include <QDesktopWidget>
+#include <qmath.h>
+
+PathDeformControls::PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen)
+ : QWidget(parent)
+{
+ m_renderer = renderer;
+
+ if (smallScreen)
+ layoutForSmallScreen();
+ else
+ layoutForDesktop();
+}
+
+
+void PathDeformControls::layoutForDesktop()
+{
+ QGroupBox* mainGroup = new QGroupBox(this);
+ mainGroup->setTitle(tr("Controls"));
+
+ QGroupBox *radiusGroup = new QGroupBox(mainGroup);
+ radiusGroup->setTitle(tr("Lens Radius"));
+ QSlider *radiusSlider = new QSlider(Qt::Horizontal, radiusGroup);
+ radiusSlider->setRange(15, 150);
+ radiusSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *deformGroup = new QGroupBox(mainGroup);
+ deformGroup->setTitle(tr("Deformation"));
+ QSlider *deformSlider = new QSlider(Qt::Horizontal, deformGroup);
+ deformSlider->setRange(-100, 100);
+ deformSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *fontSizeGroup = new QGroupBox(mainGroup);
+ fontSizeGroup->setTitle(tr("Font Size"));
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, fontSizeGroup);
+ fontSizeSlider->setRange(16, 200);
+ fontSizeSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ QGroupBox *textGroup = new QGroupBox(mainGroup);
+ textGroup->setTitle(tr("Text"));
+ QLineEdit *textInput = new QLineEdit(textGroup);
+
+ QPushButton *animateButton = new QPushButton(mainGroup);
+ animateButton->setText(tr("Animated"));
+ animateButton->setCheckable(true);
+
+ QPushButton *showSourceButton = new QPushButton(mainGroup);
+ showSourceButton->setText(tr("Show Source"));
+
+#ifdef QT_OPENGL_SUPPORT
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+
+ mainGroup->setFixedWidth(180);
+
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(radiusGroup);
+ mainGroupLayout->addWidget(deformGroup);
+ mainGroupLayout->addWidget(fontSizeGroup);
+ mainGroupLayout->addWidget(textGroup);
+ mainGroupLayout->addWidget(animateButton);
+ mainGroupLayout->addStretch(1);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(showSourceButton);
+ mainGroupLayout->addWidget(whatsThisButton);
+
+ QVBoxLayout *radiusGroupLayout = new QVBoxLayout(radiusGroup);
+ radiusGroupLayout->addWidget(radiusSlider);
+
+ QVBoxLayout *deformGroupLayout = new QVBoxLayout(deformGroup);
+ deformGroupLayout->addWidget(deformSlider);
+
+ QVBoxLayout *fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
+ fontSizeGroupLayout->addWidget(fontSizeSlider);
+
+ QVBoxLayout *textGroupLayout = new QVBoxLayout(textGroup);
+ textGroupLayout->addWidget(textInput);
+
+ QVBoxLayout * mainLayout = new QVBoxLayout(this);
+ mainLayout->addWidget(mainGroup);
+ mainLayout->setMargin(0);
+
+ connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int)));
+ connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int)));
+ connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int)));
+ connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool)));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+
+ connect(textInput, SIGNAL(textChanged(QString)), m_renderer, SLOT(setText(QString)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ whatsThisButton, SLOT(setChecked(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
+ connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
+
+ animateButton->animateClick();
+ deformSlider->setValue(80);
+ fontSizeSlider->setValue(120);
+ radiusSlider->setValue(100);
+ textInput->setText(tr("Qt"));
+}
+
+void PathDeformControls::layoutForSmallScreen()
+{
+ QGroupBox* mainGroup = new QGroupBox(this);
+ mainGroup->setTitle(tr("Controls"));
+
+ QLabel *radiusLabel = new QLabel(mainGroup);
+ radiusLabel->setText(tr("Lens Radius:"));
+ QSlider *radiusSlider = new QSlider(Qt::Horizontal, mainGroup);
+ radiusSlider->setRange(15, 150);
+ radiusSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ QLabel *deformLabel = new QLabel(mainGroup);
+ deformLabel->setText(tr("Deformation:"));
+ QSlider *deformSlider = new QSlider(Qt::Horizontal, mainGroup);
+ deformSlider->setRange(-100, 100);
+ deformSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ QLabel *fontSizeLabel = new QLabel(mainGroup);
+ fontSizeLabel->setText(tr("Font Size:"));
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, mainGroup);
+ fontSizeSlider->setRange(16, 200);
+ fontSizeSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ QPushButton *animateButton = new QPushButton(tr("Animated"), mainGroup);
+ animateButton->setCheckable(true);
+
+#ifdef QT_OPENGL_SUPPORT
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(mainGroup);
+ enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+
+ QPushButton *quitButton = new QPushButton(tr("Quit"), mainGroup);
+ QPushButton *okButton = new QPushButton(tr("OK"), mainGroup);
+
+
+ QGridLayout *mainGroupLayout = new QGridLayout(mainGroup);
+ mainGroupLayout->setMargin(0);
+ mainGroupLayout->addWidget(radiusLabel, 0, 0, Qt::AlignRight);
+ mainGroupLayout->addWidget(radiusSlider, 0, 1);
+ mainGroupLayout->addWidget(deformLabel, 1, 0, Qt::AlignRight);
+ mainGroupLayout->addWidget(deformSlider, 1, 1);
+ mainGroupLayout->addWidget(fontSizeLabel, 2, 0, Qt::AlignRight);
+ mainGroupLayout->addWidget(fontSizeSlider, 2, 1);
+ mainGroupLayout->addWidget(animateButton, 3,0, 1,2);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton, 4,0, 1,2);
+#endif
+
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->addWidget(mainGroup);
+ mainLayout->addStretch(1);
+ mainLayout->addWidget(okButton);
+ mainLayout->addWidget(quitButton);
+
+ connect(quitButton, SIGNAL(clicked()), this, SLOT(emitQuitSignal()));
+ connect(okButton, SIGNAL(clicked()), this, SLOT(emitOkSignal()));
+ connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int)));
+ connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int)));
+ connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int)));
+ connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool)));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+
+
+ animateButton->animateClick();
+ deformSlider->setValue(80);
+ fontSizeSlider->setValue(120);
+
+ QRect screen_size = QApplication::desktop()->screenGeometry();
+ radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5);
+
+ m_renderer->setText(tr("Qt"));
+}
+
+
+void PathDeformControls::emitQuitSignal()
+{ emit quitPressed(); }
+
+void PathDeformControls::emitOkSignal()
+{ emit okPressed(); }
+
+
+PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen)
+ : QWidget(parent)
+{
+ setWindowTitle(tr("Vector Deformation"));
+
+ m_renderer = new PathDeformRenderer(this, smallScreen);
+ m_renderer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // Layouts
+ QHBoxLayout *mainLayout = new QHBoxLayout(this);
+ mainLayout->addWidget(m_renderer);
+
+ m_controls = new PathDeformControls(0, m_renderer, smallScreen);
+ m_controls->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+
+ if (!smallScreen)
+ mainLayout->addWidget(m_controls);
+
+ m_renderer->loadSourceFile(":res/deform/pathdeform.cpp");
+ m_renderer->loadDescription(":res/deform/pathdeform.html");
+ m_renderer->setDescriptionEnabled(false);
+
+ connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls()));
+ connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls()));
+ connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit()));
+}
+
+
+void PathDeformWidget::showControls()
+{
+ m_controls->showFullScreen();
+}
+
+void PathDeformWidget::hideControls()
+{
+ m_controls->hide();
+}
+
+void PathDeformWidget::setStyle( QStyle * style )
+{
+ QWidget::setStyle(style);
+ if (m_controls != 0)
+ {
+ m_controls->setStyle(style);
+
+ QList<QWidget *> widgets = m_controls->findChildren<QWidget *>();
+ foreach (QWidget *w, widgets)
+ w->setStyle(style);
+ }
+}
+
+static inline QRect circle_bounds(const QPointF &center, qreal radius, qreal compensation)
+{
+ return QRect(qRound(center.x() - radius - compensation),
+ qRound(center.y() - radius - compensation),
+ qRound((radius + compensation) * 2),
+ qRound((radius + compensation) * 2));
+
+}
+
+const int LENS_EXTENT = 10;
+
+PathDeformRenderer::PathDeformRenderer(QWidget *widget, bool smallScreen)
+ : ArthurFrame(widget)
+{
+ m_radius = 100;
+ m_pos = QPointF(m_radius, m_radius);
+ m_direction = QPointF(1, 1);
+ m_fontSize = 24;
+ m_animated = true;
+ m_repaintTimer.start(25, this);
+ m_repaintTracker.start();
+ m_intensity = 100;
+ m_smallScreen = smallScreen;
+
+// m_fpsTimer.start(1000, this);
+// m_fpsCounter = 0;
+
+ generateLensPixmap();
+}
+
+void PathDeformRenderer::setText(const QString &text)
+{
+ m_text = text;
+
+ QFont f("times new roman,utopia");
+ f.setStyleStrategy(QFont::ForceOutline);
+ f.setPointSize(m_fontSize);
+ f.setStyleHint(QFont::Times);
+
+ QFontMetrics fm(f);
+
+ m_paths.clear();
+ m_pathBounds = QRect();
+
+ QPointF advance(0, 0);
+
+ bool do_quick = true;
+ for (int i=0; i<text.size(); ++i) {
+ if (text.at(i).unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
+ do_quick = false;
+ break;
+ }
+ }
+
+ if (do_quick) {
+ for (int i=0; i<text.size(); ++i) {
+ QPainterPath path;
+ path.addText(advance, f, text.mid(i, 1));
+ m_pathBounds |= path.boundingRect();
+ m_paths << path;
+ advance += QPointF(fm.width(text.mid(i, 1)), 0);
+ }
+ } else {
+ QPainterPath path;
+ path.addText(advance, f, text);
+ m_pathBounds |= path.boundingRect();
+ m_paths << path;
+ }
+
+ for (int i=0; i<m_paths.size(); ++i)
+ m_paths[i] = m_paths[i] * QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y());
+
+ update();
+}
+
+
+void PathDeformRenderer::generateLensPixmap()
+{
+ qreal rad = m_radius + LENS_EXTENT;
+
+ QRect bounds = circle_bounds(QPointF(), rad, 0);
+
+ QPainter painter;
+
+ if (preferImage()) {
+ m_lens_image = QImage(bounds.size(), QImage::Format_ARGB32_Premultiplied);
+ m_lens_image.fill(0);
+ painter.begin(&m_lens_image);
+ } else {
+ m_lens_pixmap = QPixmap(bounds.size());
+ m_lens_pixmap.fill(Qt::transparent);
+ painter.begin(&m_lens_pixmap);
+ }
+
+ QRadialGradient gr(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
+ gr.setColorAt(0.0, QColor(255, 255, 255, 191));
+ gr.setColorAt(0.2, QColor(255, 255, 127, 191));
+ gr.setColorAt(0.9, QColor(150, 150, 200, 63));
+ gr.setColorAt(0.95, QColor(0, 0, 0, 127));
+ gr.setColorAt(1, QColor(0, 0, 0, 0));
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setBrush(gr);
+ painter.setPen(Qt::NoPen);
+ painter.drawEllipse(0, 0, bounds.width(), bounds.height());
+}
+
+
+void PathDeformRenderer::setAnimated(bool animated)
+{
+ m_animated = animated;
+
+ if (m_animated) {
+// m_fpsTimer.start(1000, this);
+// m_fpsCounter = 0;
+ m_repaintTimer.start(25, this);
+ m_repaintTracker.start();
+ } else {
+// m_fpsTimer.stop();
+ m_repaintTimer.stop();
+ }
+}
+
+void PathDeformRenderer::timerEvent(QTimerEvent *e)
+{
+
+ if (e->timerId() == m_repaintTimer.timerId()) {
+
+ if (QLineF(QPointF(0,0), m_direction).length() > 1)
+ m_direction *= 0.995;
+ qreal time = m_repaintTracker.restart();
+
+ QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
+
+ qreal dx = m_direction.x();
+ qreal dy = m_direction.y();
+ if (time > 0) {
+ dx = dx * time * .1;
+ dy = dy * time * .1;
+ }
+
+ m_pos += QPointF(dx, dy);
+
+
+
+ if (m_pos.x() - m_radius < 0) {
+ m_direction.setX(-m_direction.x());
+ m_pos.setX(m_radius);
+ } else if (m_pos.x() + m_radius > width()) {
+ m_direction.setX(-m_direction.x());
+ m_pos.setX(width() - m_radius);
+ }
+
+ if (m_pos.y() - m_radius < 0) {
+ m_direction.setY(-m_direction.y());
+ m_pos.setY(m_radius);
+ } else if (m_pos.y() + m_radius > height()) {
+ m_direction.setY(-m_direction.y());
+ m_pos.setY(height() - m_radius);
+ }
+
+#ifdef QT_OPENGL_SUPPORT
+ if (usesOpenGL()) {
+ update();
+ } else
+#endif
+ {
+ QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
+ update(rectAfter | rectBefore);
+ QApplication::syncX();
+ }
+ }
+// else if (e->timerId() == m_fpsTimer.timerId()) {
+// printf("fps: %d\n", m_fpsCounter);
+// emit frameRate(m_fpsCounter);
+// m_fpsCounter = 0;
+
+// }
+}
+
+void PathDeformRenderer::mousePressEvent(QMouseEvent *e)
+{
+ setDescriptionEnabled(false);
+
+ m_repaintTimer.stop();
+ m_offset = QPointF();
+ if (QLineF(m_pos, e->pos()).length() <= m_radius)
+ m_offset = m_pos - e->pos();
+
+ m_mousePress = e->pos();
+
+ // If we're not running in small screen mode, always assume we're dragging
+ m_mouseDrag = !m_smallScreen;
+
+ mouseMoveEvent(e);
+}
+
+void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->buttons() == Qt::NoButton && m_animated) {
+ m_repaintTimer.start(10, this);
+ m_repaintTracker.start();
+ }
+
+ if (!m_mouseDrag && m_smallScreen)
+ emit clicked();
+}
+
+void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!m_mouseDrag && (QLineF(m_mousePress, e->pos()).length() > 25.0) )
+ m_mouseDrag = true;
+
+ if (m_mouseDrag) {
+ QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
+ if (e->type() == QEvent::MouseMove) {
+ QLineF line(m_pos, e->pos() + m_offset);
+ line.setLength(line.length() * .1);
+ QPointF dir(line.dx(), line.dy());
+ m_direction = (m_direction + dir) / 2;
+ }
+ m_pos = e->pos() + m_offset;
+#ifdef QT_OPENGL_SUPPORT
+ if (usesOpenGL()) {
+ update();
+ } else
+#endif
+ {
+ QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
+ update(rectBefore | rectAfter);
+ }
+ }
+}
+
+QPainterPath PathDeformRenderer::lensDeform(const QPainterPath &source, const QPointF &offset)
+{
+ QPainterPath path;
+ path.addPath(source);
+
+ qreal flip = m_intensity / qreal(100);
+
+ for (int i=0; i<path.elementCount(); ++i) {
+ const QPainterPath::Element &e = path.elementAt(i);
+
+ qreal x = e.x + offset.x();
+ qreal y = e.y + offset.y();
+
+ qreal dx = x - m_pos.x();
+ qreal dy = y - m_pos.y();
+ qreal len = m_radius - qSqrt(dx * dx + dy * dy);
+
+ if (len > 0) {
+ path.setElementPositionAt(i,
+ x + flip * dx * len / m_radius,
+ y + flip * dy * len / m_radius);
+ } else {
+ path.setElementPositionAt(i, x, y);
+ }
+
+ }
+
+ return path;
+}
+
+
+void PathDeformRenderer::paint(QPainter *painter)
+{
+ int pad_x = 5;
+ int pad_y = 5;
+
+ int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
+ int skip_y = qRound(m_pathBounds.height() + pad_y);
+
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(Qt::black);
+
+ QRectF clip(painter->clipPath().boundingRect());
+
+ int overlap = pad_x / 2;
+
+ for (int start_y=0; start_y < height(); start_y += skip_y) {
+
+ if (start_y > clip.bottom())
+ break;
+
+ int start_x = -overlap;
+ for (; start_x < width(); start_x += skip_x) {
+
+ if (start_y + skip_y >= clip.top() &&
+ start_x + skip_x >= clip.left() &&
+ start_x <= clip.right()) {
+ for (int i=0; i<m_paths.size(); ++i) {
+ QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
+ painter->drawPath(path);
+ }
+ }
+ }
+ overlap = skip_x - (start_x - width());
+
+ }
+
+ if (preferImage()) {
+ painter->drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
+ m_lens_image);
+ } else {
+ painter->drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT),
+ m_lens_pixmap);
+ }
+}
+
+
+
+void PathDeformRenderer::setRadius(int radius)
+{
+ qreal max = qMax(m_radius, (qreal)radius);
+ m_radius = radius;
+ generateLensPixmap();
+ if (!m_animated || m_radius < max) {
+#ifdef QT_OPENGL_SUPPORT
+ if (usesOpenGL()) {
+ update();
+ } else
+#endif
+ {
+ update(circle_bounds(m_pos, max, m_fontSize));
+ }
+ }
+}
+
+void PathDeformRenderer::setIntensity(int intensity)
+{
+ m_intensity = intensity;
+ if (!m_animated) {
+#ifdef QT_OPENGL_SUPPORT
+ if (usesOpenGL()) {
+ update();
+ } else
+#endif
+ {
+ update(circle_bounds(m_pos, m_radius, m_fontSize));
+ }
+ }
+}
diff --git a/demos/deform/pathdeform.h b/demos/deform/pathdeform.h
new file mode 100644
index 0000000000..1305543b85
--- /dev/null
+++ b/demos/deform/pathdeform.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PATHDEFORM_H
+#define PATHDEFORM_H
+
+#include "arthurwidgets.h"
+
+#include <QPainterPath>
+#include <QBasicTimer>
+#include <QDateTime>
+
+class PathDeformRenderer : public ArthurFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(bool animated READ animated WRITE setAnimated)
+ Q_PROPERTY(int radius READ radius WRITE setRadius)
+ Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(int intensity READ intensity WRITE setIntensity)
+ Q_PROPERTY(QString text READ text WRITE setText)
+
+public:
+ PathDeformRenderer(QWidget *widget, bool smallScreen = false);
+
+ void paint(QPainter *painter);
+
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void timerEvent(QTimerEvent *e);
+
+ QSize sizeHint() const { return QSize(600, 500); }
+
+ bool animated() const { return m_animated; }
+ int radius() const { return int(m_radius); }
+ int fontSize() const { return m_fontSize; }
+ int intensity() const { return int(m_intensity); }
+ QString text() const { return m_text; }
+
+public slots:
+ void setRadius(int radius);
+ void setFontSize(int fontSize) { m_fontSize = fontSize; setText(m_text); }
+ void setText(const QString &text);
+ void setIntensity(int intensity);
+
+ void setAnimated(bool animated);
+
+signals:
+ void clicked();
+// void frameRate(double fps);
+
+private:
+ void generateLensPixmap();
+ QPainterPath lensDeform(const QPainterPath &source, const QPointF &offset);
+
+ QBasicTimer m_repaintTimer;
+// QBasicTimer m_fpsTimer;
+// int m_fpsCounter;
+ QTime m_repaintTracker;
+
+ QVector<QPainterPath> m_paths;
+ QVector<QPointF> m_advances;
+ QRectF m_pathBounds;
+ QString m_text;
+
+ QPixmap m_lens_pixmap;
+ QImage m_lens_image;
+
+ int m_fontSize;
+ bool m_animated;
+
+ qreal m_intensity;
+ qreal m_radius;
+ QPointF m_pos;
+ QPointF m_offset;
+ QPointF m_direction;
+ QPointF m_mousePress;
+ bool m_mouseDrag;
+ bool m_smallScreen;
+};
+
+class PathDeformControls : public QWidget
+{
+ Q_OBJECT
+public:
+ PathDeformControls(QWidget *parent, PathDeformRenderer* renderer, bool smallScreen);
+signals:
+ void okPressed();
+ void quitPressed();
+private:
+ PathDeformRenderer* m_renderer;
+ void layoutForDesktop();
+ void layoutForSmallScreen();
+private slots:
+ void emitQuitSignal();
+ void emitOkSignal();
+};
+
+class PathDeformWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ PathDeformWidget(QWidget *parent, bool smallScreen);
+ void setStyle ( QStyle * style );
+
+private:
+ PathDeformRenderer *m_renderer;
+ PathDeformControls *m_controls;
+
+private slots:
+ void showControls();
+ void hideControls();
+};
+
+#endif // PATHDEFORM_H
diff --git a/demos/deform/pathdeform.html b/demos/deform/pathdeform.html
new file mode 100644
index 0000000000..b3f63a8e0a
--- /dev/null
+++ b/demos/deform/pathdeform.html
@@ -0,0 +1,24 @@
+<html>
+<center>
+<h2>Vector deformation</h2>
+</center>
+
+<p>This demo shows how to use advanced vector techniques to draw text
+using a <code>QPainterPath</code>.</p>
+
+<p>We define a vector deformation field in the shape of a lens and apply
+this to all points in a path. This means that what is rendered on
+screen is not pixel manipulation, but modified vector representations of
+the glyphs themselves. This is visible from the high quality of the
+antialiased edges for the deformed glyphs.</p>
+
+<p>To get a fairly complex path we allow the user to type in text and
+convert the text to paths. This is done using the
+<code>QPainterPath::addText()</code> function.</p>
+
+<p>The lens is drawn using a single call to <code>drawEllipse()</code>, using
+a <code>QRadialGradient</code> to fill it with a specialized color table,
+giving the effect of the Sun's reflection and a drop shadow. The lens
+is cached as a pixmap for better performance.</p>
+
+</html>
diff --git a/demos/demos.pro b/demos/demos.pro
new file mode 100644
index 0000000000..f1d5b009a8
--- /dev/null
+++ b/demos/demos.pro
@@ -0,0 +1,116 @@
+TEMPLATE = subdirs
+
+!contains(QT_CONFIG, no-gui) {
+SUBDIRS = \
+ demos_shared \
+ demos_deform \
+ demos_gradients \
+ demos_pathstroke \
+ demos_affine \
+ demos_composition \
+ demos_books \
+ demos_interview \
+ demos_mainwindow \
+ demos_spreadsheet \
+ demos_textedit \
+ demos_chip \
+ demos_embeddeddialogs \
+ demos_undo \
+ demos_sub-attaq
+
+symbian: SUBDIRS = \
+ demos_shared \
+ demos_deform \
+ demos_pathstroke
+
+
+wince*: SUBDIRS = \
+ demos_shared \
+ demos_deform \
+ demos_gradients \
+ demos_pathstroke \
+ demos_affine \
+ demos_composition \
+ demos_books \
+ demos_interview \
+ demos_mainwindow \
+ demos_spreadsheet \
+ demos_textedit \
+ # demos_chip \
+ demos_embeddeddialogs \
+ demos_undo \
+ demos_sub-attaq
+
+contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles2):{
+SUBDIRS += demos_boxes
+}
+
+mac* && !qpa: SUBDIRS += demos_macmainwindow
+wince*|symbian|embedded|x11: SUBDIRS += demos_embedded
+
+!contains(QT_EDITION, Console):!cross_compile:!embedded:!wince*:SUBDIRS += demos_arthurplugin
+
+!cross_compile:{
+contains(QT_BUILD_PARTS, tools):{
+!wince*:SUBDIRS += demos_sqlbrowser demos_qtdemo
+wince*:SUBDIRS += demos_sqlbrowser
+}
+}
+contains(QT_CONFIG, phonon):!static:SUBDIRS += demos_mediaplayer
+contains(QT_CONFIG, webkit):contains(QT_CONFIG, svg):!symbian:SUBDIRS += demos_browser
+contains(QT_CONFIG, declarative):SUBDIRS += demos_declarative
+contains(QT_CONFIG, multimedia):!static:SUBDIRS += demos_spectrum
+
+# install
+sources.files = README *.pro
+sources.path = $$[QT_INSTALL_DEMOS]
+INSTALLS += sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+
+demos_chip.subdir = chip
+demos_embeddeddialogs.subdir = embeddeddialogs
+demos_embedded.subdir = embedded
+# Because of fluidlauncher
+demos_embedded.depends = demos_deform demos_pathstroke
+demos_shared.subdir = shared
+demos_deform.subdir = deform
+demos_gradients.subdir = gradients
+demos_pathstroke.subdir = pathstroke
+demos_affine.subdir = affine
+demos_composition.subdir = composition
+demos_books.subdir = books
+demos_interview.subdir = interview
+demos_macmainwindow.subdir = macmainwindow
+demos_mainwindow.subdir = mainwindow
+demos_spreadsheet.subdir = spreadsheet
+demos_textedit.subdir = textedit
+demos_arthurplugin.subdir = arthurplugin
+demos_sqlbrowser.subdir = sqlbrowser
+demos_undo.subdir = undo
+demos_qtdemo.subdir = qtdemo
+demos_mediaplayer.subdir = qmediaplayer
+demos_declarative.subdir = declarative
+
+#mobile demos. Requires QtMobility sources. Not included in demo build
+demos_guitartuner.subdir = mobile/guitartuner
+demos_qcamera.subdir = mobile/qcamera
+demos_qtbubblelevel.subdir = mobile/qtbubblelevel
+demos_quickhit.subdir = mobile/quickhit
+
+demos_browser.subdir = browser
+
+demos_boxes.subdir = boxes
+demos_sub-attaq.subdir = sub-attaq
+demos_spectrum.subdir = spectrum
+
+#CONFIG += ordered
+!ordered {
+ demos_affine.depends = demos_shared
+ demos_deform.depends = demos_shared
+ demos_gradients.depends = demos_shared
+ demos_composition.depends = demos_shared
+ demos_arthurplugin.depends = demos_shared
+ demos_pathstroke.depends = demos_shared
+}
+}
diff --git a/demos/embedded/digiflip/digiflip.cpp b/demos/embedded/digiflip/digiflip.cpp
new file mode 100644
index 0000000000..d756f21776
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/digiflip/digiflip.pro b/demos/embedded/digiflip/digiflip.pro
new file mode 100644
index 0000000000..73309db9e5
--- /dev/null
+++ b/demos/embedded/digiflip/digiflip.pro
@@ -0,0 +1,11 @@
+SOURCES = digiflip.cpp
+
+symbian {
+ TARGET.UID3 = 0xA000CF72
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
+
+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/demos/embedded/embedded.pro b/demos/embedded/embedded.pro
new file mode 100644
index 0000000000..efe3af5122
--- /dev/null
+++ b/demos/embedded/embedded.pro
@@ -0,0 +1,32 @@
+TEMPLATE = subdirs
+SUBDIRS = styledemo raycasting flickable digiflip
+
+contains(QT_CONFIG, svg) {
+ SUBDIRS += embeddedsvgviewer \
+ desktopservices
+ fluidlauncher.subdir = fluidlauncher
+ fluidlauncher.depends = styledemo desktopservices raycasting flickable digiflip lightmaps flightinfo
+ !vxworks:!qnx:SUBDIRS += fluidlauncher
+}
+
+SUBDIRS += lightmaps
+SUBDIRS += flightinfo
+contains(QT_CONFIG, svg) {
+ SUBDIRS += weatherinfo
+}
+
+contains(QT_CONFIG, webkit) {
+ SUBDIRS += anomaly
+}
+
+contains(QT_CONFIG, declarative) {
+ # Qml demos require DEPLOYMENT support. Therefore, only symbian.
+ symbian:SUBDIRS += qmlcalculator qmlclocks qmldialcontrol qmleasing qmlflickr qmlphotoviewer qmltwitter
+}
+
+# install
+sources.files = README *.pro
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embedded
+INSTALLS += sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
diff --git a/demos/embedded/flickable/flickable.cpp b/demos/embedded/flickable/flickable.cpp
new file mode 100644
index 0000000000..e2d240d64f
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/flickable/flickable.h b/demos/embedded/flickable/flickable.h
new file mode 100644
index 0000000000..69c379c508
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/flickable/flickable.pro b/demos/embedded/flickable/flickable.pro
new file mode 100644
index 0000000000..0fa15d939f
--- /dev/null
+++ b/demos/embedded/flickable/flickable.pro
@@ -0,0 +1,12 @@
+SOURCES = flickable.cpp main.cpp
+HEADERS = flickable.h
+
+symbian {
+ TARGET.UID3 = 0xA000CF73
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
+
+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/demos/embedded/flickable/main.cpp b/demos/embedded/flickable/main.cpp
new file mode 100644
index 0000000000..431a99bfa1
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/flightinfo/aircraft.png b/demos/embedded/flightinfo/aircraft.png
new file mode 100644
index 0000000000..2312bcc9f0
--- /dev/null
+++ b/demos/embedded/flightinfo/aircraft.png
Binary files differ
diff --git a/demos/embedded/flightinfo/flightinfo.cpp b/demos/embedded/flightinfo/flightinfo.cpp
new file mode 100644
index 0000000000..6f7c039973
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/flightinfo/flightinfo.pro b/demos/embedded/flightinfo/flightinfo.pro
new file mode 100644
index 0000000000..c015fdf0af
--- /dev/null
+++ b/demos/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
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+ 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/demos/embedded/flightinfo/flightinfo.qrc b/demos/embedded/flightinfo/flightinfo.qrc
new file mode 100644
index 0000000000..babea7e0cb
--- /dev/null
+++ b/demos/embedded/flightinfo/flightinfo.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>aircraft.png</file>
+ </qresource>
+</RCC>
diff --git a/demos/embedded/flightinfo/form.ui b/demos/embedded/flightinfo/form.ui
new file mode 100644
index 0000000000..3a24c758a6
--- /dev/null
+++ b/demos/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/demos/embedded/lightmaps/lightmaps.cpp b/demos/embedded/lightmaps/lightmaps.cpp
new file mode 100644
index 0000000000..8e64e7370c
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/lightmaps.h b/demos/embedded/lightmaps/lightmaps.h
new file mode 100644
index 0000000000..42a80c9f05
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/lightmaps.pro b/demos/embedded/lightmaps/lightmaps.pro
new file mode 100644
index 0000000000..a792e60709
--- /dev/null
+++ b/demos/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
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+ 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/demos/embedded/lightmaps/main.cpp b/demos/embedded/lightmaps/main.cpp
new file mode 100644
index 0000000000..34d8d3d066
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/mapzoom.cpp b/demos/embedded/lightmaps/mapzoom.cpp
new file mode 100644
index 0000000000..6cafc59b1d
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/mapzoom.h b/demos/embedded/lightmaps/mapzoom.h
new file mode 100644
index 0000000000..0b1ea8b8c7
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/slippymap.cpp b/demos/embedded/lightmaps/slippymap.cpp
new file mode 100644
index 0000000000..2c76f748bc
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/lightmaps/slippymap.h b/demos/embedded/lightmaps/slippymap.h
new file mode 100644
index 0000000000..ba43e40c9b
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/raycasting/raycasting.cpp b/demos/embedded/raycasting/raycasting.cpp
new file mode 100644
index 0000000000..8ca4f8bf74
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/raycasting/raycasting.pro b/demos/embedded/raycasting/raycasting.pro
new file mode 100644
index 0000000000..bc1692a458
--- /dev/null
+++ b/demos/embedded/raycasting/raycasting.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+SOURCES = raycasting.cpp
+RESOURCES += raycasting.qrc
+
+symbian {
+ TARGET.UID3 = 0xA000CF76
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
+
+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/demos/embedded/raycasting/raycasting.qrc b/demos/embedded/raycasting/raycasting.qrc
new file mode 100644
index 0000000000..974a06093c
--- /dev/null
+++ b/demos/embedded/raycasting/raycasting.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>textures.png</file>
+ </qresource>
+</RCC>
diff --git a/demos/embedded/raycasting/textures.png b/demos/embedded/raycasting/textures.png
new file mode 100644
index 0000000000..2eb1ba7ff6
--- /dev/null
+++ b/demos/embedded/raycasting/textures.png
Binary files differ
diff --git a/demos/embedded/styledemo/files/add.png b/demos/embedded/styledemo/files/add.png
new file mode 100755
index 0000000000..fc5c16d4c8
--- /dev/null
+++ b/demos/embedded/styledemo/files/add.png
Binary files differ
diff --git a/demos/embedded/styledemo/files/application.qss b/demos/embedded/styledemo/files/application.qss
new file mode 100644
index 0000000000..432fe6bc76
--- /dev/null
+++ b/demos/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/demos/embedded/styledemo/files/blue.qss b/demos/embedded/styledemo/files/blue.qss
new file mode 100644
index 0000000000..ac8671b5e4
--- /dev/null
+++ b/demos/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/demos/embedded/styledemo/files/khaki.qss b/demos/embedded/styledemo/files/khaki.qss
new file mode 100644
index 0000000000..b0d4a0fa6f
--- /dev/null
+++ b/demos/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/demos/embedded/styledemo/files/nature_1.jpg b/demos/embedded/styledemo/files/nature_1.jpg
new file mode 100644
index 0000000000..3a04edb96a
--- /dev/null
+++ b/demos/embedded/styledemo/files/nature_1.jpg
Binary files differ
diff --git a/demos/embedded/styledemo/files/nostyle.qss b/demos/embedded/styledemo/files/nostyle.qss
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/demos/embedded/styledemo/files/nostyle.qss
diff --git a/demos/embedded/styledemo/files/remove.png b/demos/embedded/styledemo/files/remove.png
new file mode 100755
index 0000000000..a0ab1fa21a
--- /dev/null
+++ b/demos/embedded/styledemo/files/remove.png
Binary files differ
diff --git a/demos/embedded/styledemo/files/transparent.qss b/demos/embedded/styledemo/files/transparent.qss
new file mode 100644
index 0000000000..b38eb366f4
--- /dev/null
+++ b/demos/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/demos/embedded/styledemo/main.cpp b/demos/embedded/styledemo/main.cpp
new file mode 100644
index 0000000000..395d40515e
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/styledemo/styledemo.pro b/demos/embedded/styledemo/styledemo.pro
new file mode 100644
index 0000000000..81a45403ad
--- /dev/null
+++ b/demos/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
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+}
diff --git a/demos/embedded/styledemo/styledemo.qrc b/demos/embedded/styledemo/styledemo.qrc
new file mode 100644
index 0000000000..96237d4203
--- /dev/null
+++ b/demos/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/demos/embedded/styledemo/stylewidget.cpp b/demos/embedded/styledemo/stylewidget.cpp
new file mode 100644
index 0000000000..c40e90834a
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/styledemo/stylewidget.h b/demos/embedded/styledemo/stylewidget.h
new file mode 100644
index 0000000000..6339f7ad76
--- /dev/null
+++ b/demos/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $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/demos/embedded/styledemo/stylewidget.ui b/demos/embedded/styledemo/stylewidget.ui
new file mode 100644
index 0000000000..767f44aead
--- /dev/null
+++ b/demos/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/demos/embeddeddialogs/No-Ones-Laughing-3.jpg b/demos/embeddeddialogs/No-Ones-Laughing-3.jpg
new file mode 100644
index 0000000000..445567fbda
--- /dev/null
+++ b/demos/embeddeddialogs/No-Ones-Laughing-3.jpg
Binary files differ
diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp
new file mode 100644
index 0000000000..e56823dfbd
--- /dev/null
+++ b/demos/embeddeddialogs/customproxy.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "customproxy.h"
+
+#include <QtGui>
+
+CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags)
+ : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0)
+{
+ timeLine = new QTimeLine(250, this);
+ connect(timeLine, SIGNAL(valueChanged(qreal)),
+ this, SLOT(updateStep(qreal)));
+ connect(timeLine, SIGNAL(stateChanged(QTimeLine::State)),
+ this, SLOT(stateChanged(QTimeLine::State)));
+}
+
+QRectF CustomProxy::boundingRect() const
+{
+ return QGraphicsProxyWidget::boundingRect().adjusted(0, 0, 10, 10);
+}
+
+void CustomProxy::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ const QColor color(0, 0, 0, 64);
+
+ QRectF r = windowFrameRect();
+ QRectF right(r.right(), r.top() + 10, 10, r.height() - 10);
+ QRectF bottom(r.left() + 10, r.bottom(), r.width(), 10);
+ bool intersectsRight = right.intersects(option->exposedRect);
+ bool intersectsBottom = bottom.intersects(option->exposedRect);
+ if (intersectsRight && intersectsBottom) {
+ QPainterPath path;
+ path.addRect(right);
+ path.addRect(bottom);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(color);
+ painter->drawPath(path);
+ } else if (intersectsBottom) {
+ painter->fillRect(bottom, color);
+ } else if (intersectsRight) {
+ painter->fillRect(right, color);
+ }
+
+ QGraphicsProxyWidget::paintWindowFrame(painter, option, widget);
+}
+
+void CustomProxy::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ QGraphicsProxyWidget::hoverEnterEvent(event);
+ scene()->setActiveWindow(this);
+ if (timeLine->currentValue() != 1)
+ zoomIn();
+}
+
+void CustomProxy::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ QGraphicsProxyWidget::hoverLeaveEvent(event);
+ if (!popupShown && (timeLine->direction() != QTimeLine::Backward || timeLine->currentValue() != 0))
+ zoomOut();
+}
+
+bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+ if (watched->isWindow() && (event->type() == QEvent::UngrabMouse || event->type() == QEvent::GrabMouse)) {
+ popupShown = watched->isVisible();
+ if (!popupShown && !isUnderMouse())
+ zoomOut();
+ }
+ return QGraphicsProxyWidget::sceneEventFilter(watched, event);
+}
+
+QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ if (change == ItemChildAddedChange) {
+ currentPopup = qvariant_cast<QGraphicsItem *>(value);
+ currentPopup->setCacheMode(ItemCoordinateCache);
+ if (scene())
+ currentPopup->installSceneEventFilter(this);
+ } else if (scene()) {
+ currentPopup->removeSceneEventFilter(this);
+ currentPopup = 0;
+ }
+ } else if (currentPopup && change == ItemSceneHasChanged) {
+ currentPopup->installSceneEventFilter(this);
+ }
+ return QGraphicsProxyWidget::itemChange(change, value);
+}
+
+void CustomProxy::updateStep(qreal step)
+{
+ QRectF r = boundingRect();
+ setTransform(QTransform()
+ .translate(r.width() / 2, r.height() / 2)
+ .rotate(step * 30, Qt::XAxis)
+ .rotate(step * 10, Qt::YAxis)
+ .rotate(step * 5, Qt::ZAxis)
+ .scale(1 + 1.5 * step, 1 + 1.5 * step)
+ .translate(-r.width() / 2, -r.height() / 2));
+}
+
+void CustomProxy::stateChanged(QTimeLine::State state)
+{
+ if (state == QTimeLine::Running) {
+ if (timeLine->direction() == QTimeLine::Forward)
+ setCacheMode(ItemCoordinateCache);
+ } else if (state == QTimeLine::NotRunning) {
+ if (timeLine->direction() == QTimeLine::Backward)
+ setCacheMode(DeviceCoordinateCache);
+ }
+}
+
+void CustomProxy::zoomIn()
+{
+ if (timeLine->direction() != QTimeLine::Forward)
+ timeLine->setDirection(QTimeLine::Forward);
+ if (timeLine->state() == QTimeLine::NotRunning)
+ timeLine->start();
+}
+
+void CustomProxy::zoomOut()
+{
+ if (timeLine->direction() != QTimeLine::Backward)
+ timeLine->setDirection(QTimeLine::Backward);
+ if (timeLine->state() == QTimeLine::NotRunning)
+ timeLine->start();
+}
diff --git a/demos/embeddeddialogs/customproxy.h b/demos/embeddeddialogs/customproxy.h
new file mode 100644
index 0000000000..67d2152f98
--- /dev/null
+++ b/demos/embeddeddialogs/customproxy.h
@@ -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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CUSTOMPROXY_H
+#define CUSTOMPROXY_H
+
+#include <QtCore/qtimeline.h>
+#include <QtGui/qgraphicsproxywidget.h>
+
+class CustomProxy : public QGraphicsProxyWidget
+{
+ Q_OBJECT
+public:
+ CustomProxy(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+
+ QRectF boundingRect() const;
+ void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget);
+
+protected:
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+ bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+private slots:
+ void updateStep(qreal step);
+ void stateChanged(QTimeLine::State);
+ void zoomIn();
+ void zoomOut();
+
+private:
+ QTimeLine *timeLine;
+ bool popupShown;
+ QGraphicsItem *currentPopup;
+};
+
+#endif
diff --git a/demos/embeddeddialogs/embeddeddialog.cpp b/demos/embeddeddialogs/embeddeddialog.cpp
new file mode 100644
index 0000000000..e359afe555
--- /dev/null
+++ b/demos/embeddeddialogs/embeddeddialog.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "embeddeddialog.h"
+#include "ui_embeddeddialog.h"
+
+#include <QtGui>
+
+EmbeddedDialog::EmbeddedDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ ui = new Ui_embeddedDialog;
+ ui->setupUi(this);
+ ui->layoutDirection->setCurrentIndex(layoutDirection() != Qt::LeftToRight);
+
+ foreach (QString styleName, QStyleFactory::keys()) {
+ ui->style->addItem(styleName);
+ if (style()->objectName().toLower() == styleName.toLower())
+ ui->style->setCurrentIndex(ui->style->count() - 1);
+ }
+
+ connect(ui->layoutDirection, SIGNAL(activated(int)),
+ this, SLOT(layoutDirectionChanged(int)));
+ connect(ui->spacing, SIGNAL(valueChanged(int)),
+ this, SLOT(spacingChanged(int)));
+ connect(ui->fontComboBox, SIGNAL(currentFontChanged(QFont)),
+ this, SLOT(fontChanged(QFont)));
+ connect(ui->style, SIGNAL(activated(QString)),
+ this, SLOT(styleChanged(QString)));
+}
+
+EmbeddedDialog::~EmbeddedDialog()
+{
+ delete ui;
+}
+
+void EmbeddedDialog::layoutDirectionChanged(int index)
+{
+ setLayoutDirection(index == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+}
+
+void EmbeddedDialog::spacingChanged(int spacing)
+{
+ layout()->setSpacing(spacing);
+ adjustSize();
+}
+
+void EmbeddedDialog::fontChanged(const QFont &font)
+{
+ setFont(font);
+}
+
+static void setStyleHelper(QWidget *widget, QStyle *style)
+{
+ widget->setStyle(style);
+ widget->setPalette(style->standardPalette());
+ foreach (QObject *child, widget->children()) {
+ if (QWidget *childWidget = qobject_cast<QWidget *>(child))
+ setStyleHelper(childWidget, style);
+ }
+}
+
+void EmbeddedDialog::styleChanged(const QString &styleName)
+{
+ QStyle *style = QStyleFactory::create(styleName);
+ if (style)
+ setStyleHelper(this, style);
+}
diff --git a/demos/embeddeddialogs/embeddeddialog.h b/demos/embeddeddialogs/embeddeddialog.h
new file mode 100644
index 0000000000..54263f64e3
--- /dev/null
+++ b/demos/embeddeddialogs/embeddeddialog.h
@@ -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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EMBEDDEDDIALOG_H
+#define EMBEDDEDDIALOG_H
+
+#include <QtGui/qdialog.h>
+
+QT_FORWARD_DECLARE_CLASS(Ui_embeddedDialog);
+
+class EmbeddedDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ EmbeddedDialog(QWidget *parent = 0);
+ ~EmbeddedDialog();
+
+private slots:
+ void layoutDirectionChanged(int index);
+ void spacingChanged(int spacing);
+ void fontChanged(const QFont &font);
+ void styleChanged(const QString &styleName);
+
+private:
+ Ui_embeddedDialog *ui;
+};
+
+#endif
diff --git a/demos/embeddeddialogs/embeddeddialog.ui b/demos/embeddeddialogs/embeddeddialog.ui
new file mode 100644
index 0000000000..f967b10085
--- /dev/null
+++ b/demos/embeddeddialogs/embeddeddialog.ui
@@ -0,0 +1,87 @@
+<ui version="4.0" >
+ <class>embeddedDialog</class>
+ <widget class="QDialog" name="embeddedDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>407</width>
+ <height>134</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Embedded Dialog</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Layout Direction:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>layoutDirection</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QComboBox" name="layoutDirection" >
+ <item>
+ <property name="text" >
+ <string>Left to Right</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Right to Left</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Select Font:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>fontComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QFontComboBox" name="fontComboBox" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Style:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>style</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="style" />
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Layout spacing:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>spacing</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSlider" name="spacing" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/demos/embeddeddialogs/embeddeddialogs.pro b/demos/embeddeddialogs/embeddeddialogs.pro
new file mode 100644
index 0000000000..7e403112aa
--- /dev/null
+++ b/demos/embeddeddialogs/embeddeddialogs.pro
@@ -0,0 +1,19 @@
+SOURCES += main.cpp
+SOURCES += customproxy.cpp embeddeddialog.cpp
+HEADERS += customproxy.h embeddeddialog.h
+
+FORMS += embeddeddialog.ui
+RESOURCES += embeddeddialogs.qrc
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/embeddeddialogs
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.png *.jpg *.plist *.icns *.ico *.rc *.pro *.html *.doc images
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/embeddeddialogs
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
diff --git a/demos/embeddeddialogs/embeddeddialogs.qrc b/demos/embeddeddialogs/embeddeddialogs.qrc
new file mode 100644
index 0000000000..33be5038da
--- /dev/null
+++ b/demos/embeddeddialogs/embeddeddialogs.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource>
+ <file>No-Ones-Laughing-3.jpg</file>
+ </qresource>
+</RCC>
diff --git a/demos/embeddeddialogs/main.cpp b/demos/embeddeddialogs/main.cpp
new file mode 100644
index 0000000000..01f1ca9c0e
--- /dev/null
+++ b/demos/embeddeddialogs/main.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "customproxy.h"
+#include "embeddeddialog.h"
+
+#include <QtGui>
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(embeddeddialogs);
+ QApplication app(argc, argv);
+
+ QGraphicsScene scene;
+ scene.setStickyFocus(true);
+#ifndef Q_OS_WINCE
+ const int gridSize = 10;
+#else
+ const int gridSize = 5;
+#endif
+
+ for (int y = 0; y < gridSize; ++y) {
+ for (int x = 0; x < gridSize; ++x) {
+ CustomProxy *proxy = new CustomProxy(0, Qt::Window);
+ proxy->setWidget(new EmbeddedDialog);
+
+ QRectF rect = proxy->boundingRect();
+
+ proxy->setPos(x * rect.width() * 1.05, y * rect.height() * 1.05);
+ proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+
+ scene.addItem(proxy);
+ }
+ }
+ scene.setSceneRect(scene.itemsBoundingRect());
+
+ QGraphicsView view(&scene);
+ view.scale(0.5, 0.5);
+ view.setRenderHints(view.renderHints() | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+ view.setBackgroundBrush(QPixmap(":/No-Ones-Laughing-3.jpg"));
+ view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+ view.show();
+ view.setWindowTitle("Embedded Dialogs Demo");
+ return app.exec();
+}
diff --git a/demos/gradients/gradients.cpp b/demos/gradients/gradients.cpp
new file mode 100644
index 0000000000..8dfc684d66
--- /dev/null
+++ b/demos/gradients/gradients.cpp
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gradients.h"
+#include "hoverpoints.h"
+
+ShadeWidget::ShadeWidget(ShadeType type, QWidget *parent)
+ : QWidget(parent), m_shade_type(type), m_alpha_gradient(QLinearGradient(0, 0, 0, 0))
+{
+
+ // Checkers background
+ if (m_shade_type == ARGBShade) {
+ QPixmap pm(20, 20);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, 10, 10, Qt::lightGray);
+ pmp.fillRect(10, 10, 10, 10, Qt::lightGray);
+ pmp.fillRect(0, 10, 10, 10, Qt::darkGray);
+ pmp.fillRect(10, 0, 10, 10, Qt::darkGray);
+ pmp.end();
+ QPalette pal = palette();
+ pal.setBrush(backgroundRole(), QBrush(pm));
+ setAutoFillBackground(true);
+ setPalette(pal);
+
+ } else {
+ setAttribute(Qt::WA_NoBackground);
+
+ }
+
+ QPolygonF points;
+ points << QPointF(0, sizeHint().height())
+ << QPointF(sizeHint().width(), 0);
+
+ m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
+// m_hoverPoints->setConnectionType(HoverPoints::LineConnection);
+ m_hoverPoints->setPoints(points);
+ m_hoverPoints->setPointLock(0, HoverPoints::LockToLeft);
+ m_hoverPoints->setPointLock(1, HoverPoints::LockToRight);
+ m_hoverPoints->setSortType(HoverPoints::XSort);
+
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ connect(m_hoverPoints, SIGNAL(pointsChanged(QPolygonF)), this, SIGNAL(colorsChanged()));
+}
+
+
+QPolygonF ShadeWidget::points() const
+{
+ return m_hoverPoints->points();
+}
+
+
+uint ShadeWidget::colorAt(int x)
+{
+ generateShade();
+
+ QPolygonF pts = m_hoverPoints->points();
+ for (int i=1; i < pts.size(); ++i) {
+ if (pts.at(i-1).x() <= x && pts.at(i).x() >= x) {
+ QLineF l(pts.at(i-1), pts.at(i));
+ l.setLength(l.length() * ((x - l.x1()) / l.dx()));
+ return m_shade.pixel(qRound(qMin(l.x2(), (qreal(m_shade.width() - 1)))),
+ qRound(qMin(l.y2(), qreal(m_shade.height() - 1))));
+ }
+ }
+ return 0;
+}
+
+
+void ShadeWidget::setGradientStops(const QGradientStops &stops)
+{
+ if (m_shade_type == ARGBShade) {
+ m_alpha_gradient = QLinearGradient(0, 0, width(), 0);
+
+ for (int i=0; i<stops.size(); ++i) {
+ QColor c = stops.at(i).second;
+ m_alpha_gradient.setColorAt(stops.at(i).first, QColor(c.red(), c.green(), c.blue()));
+ }
+
+ m_shade = QImage();
+ generateShade();
+ update();
+ }
+}
+
+
+void ShadeWidget::paintEvent(QPaintEvent *)
+{
+ generateShade();
+
+ QPainter p(this);
+ p.drawImage(0, 0, m_shade);
+
+ p.setPen(QColor(146, 146, 146));
+ p.drawRect(0, 0, width() - 1, height() - 1);
+}
+
+
+void ShadeWidget::generateShade()
+{
+ if (m_shade.isNull() || m_shade.size() != size()) {
+
+ if (m_shade_type == ARGBShade) {
+ m_shade = QImage(size(), QImage::Format_ARGB32_Premultiplied);
+ m_shade.fill(0);
+
+ QPainter p(&m_shade);
+ p.fillRect(rect(), m_alpha_gradient);
+
+ p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ QLinearGradient fade(0, 0, 0, height());
+ fade.setColorAt(0, QColor(0, 0, 0, 255));
+ fade.setColorAt(1, QColor(0, 0, 0, 0));
+ p.fillRect(rect(), fade);
+
+ } else {
+ m_shade = QImage(size(), QImage::Format_RGB32);
+ QLinearGradient shade(0, 0, 0, height());
+ shade.setColorAt(1, Qt::black);
+
+ if (m_shade_type == RedShade)
+ shade.setColorAt(0, Qt::red);
+ else if (m_shade_type == GreenShade)
+ shade.setColorAt(0, Qt::green);
+ else
+ shade.setColorAt(0, Qt::blue);
+
+ QPainter p(&m_shade);
+ p.fillRect(rect(), shade);
+ }
+ }
+
+
+}
+
+
+GradientEditor::GradientEditor(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setSpacing(1);
+ vbox->setMargin(1);
+
+ m_red_shade = new ShadeWidget(ShadeWidget::RedShade, this);
+ m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this);
+ m_blue_shade = new ShadeWidget(ShadeWidget::BlueShade, this);
+ m_alpha_shade = new ShadeWidget(ShadeWidget::ARGBShade, this);
+
+ vbox->addWidget(m_red_shade);
+ vbox->addWidget(m_green_shade);
+ vbox->addWidget(m_blue_shade);
+ vbox->addWidget(m_alpha_shade);
+
+ connect(m_red_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_green_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_blue_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+ connect(m_alpha_shade, SIGNAL(colorsChanged()), this, SLOT(pointsUpdated()));
+}
+
+
+inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.x() < p2.x();
+}
+
+
+void GradientEditor::pointsUpdated()
+{
+ qreal w = m_alpha_shade->width();
+
+ QGradientStops stops;
+
+ QPolygonF points;
+
+ points += m_red_shade->points();
+ points += m_green_shade->points();
+ points += m_blue_shade->points();
+ points += m_alpha_shade->points();
+
+ qSort(points.begin(), points.end(), x_less_than);
+
+ for (int i=0; i<points.size(); ++i) {
+ qreal x = int(points.at(i).x());
+ if (i < points.size() - 1 && x == points.at(i+1).x())
+ continue;
+ QColor color((0x00ff0000 & m_red_shade->colorAt(int(x))) >> 16,
+ (0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8,
+ (0x000000ff & m_blue_shade->colorAt(int(x))),
+ (0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24);
+
+ if (x / w > 1)
+ return;
+
+ stops << QGradientStop(x / w, color);
+ }
+
+ m_alpha_shade->setGradientStops(stops);
+
+ emit gradientStopsChanged(stops);
+}
+
+
+static void set_shade_points(const QPolygonF &points, ShadeWidget *shade)
+{
+ shade->hoverPoints()->setPoints(points);
+ shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft);
+ shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight);
+ shade->update();
+}
+
+void GradientEditor::setGradientStops(const QGradientStops &stops)
+{
+ QPolygonF pts_red, pts_green, pts_blue, pts_alpha;
+
+ qreal h_red = m_red_shade->height();
+ qreal h_green = m_green_shade->height();
+ qreal h_blue = m_blue_shade->height();
+ qreal h_alpha = m_alpha_shade->height();
+
+ for (int i=0; i<stops.size(); ++i) {
+ qreal pos = stops.at(i).first;
+ QRgb color = stops.at(i).second.rgba();
+ pts_red << QPointF(pos * m_red_shade->width(), h_red - qRed(color) * h_red / 255);
+ pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255);
+ pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255);
+ pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255);
+ }
+
+ set_shade_points(pts_red, m_red_shade);
+ set_shade_points(pts_green, m_green_shade);
+ set_shade_points(pts_blue, m_blue_shade);
+ set_shade_points(pts_alpha, m_alpha_shade);
+
+}
+
+GradientWidget::GradientWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setWindowTitle(tr("Gradients"));
+
+ m_renderer = new GradientRenderer(this);
+
+ QGroupBox *mainGroup = new QGroupBox(this);
+ mainGroup->setTitle(tr("Gradients"));
+
+ QGroupBox *editorGroup = new QGroupBox(mainGroup);
+ editorGroup->setTitle(tr("Color Editor"));
+ m_editor = new GradientEditor(editorGroup);
+
+ QGroupBox *typeGroup = new QGroupBox(mainGroup);
+ typeGroup->setTitle(tr("Gradient Type"));
+ m_linearButton = new QRadioButton(tr("Linear Gradient"), typeGroup);
+ m_radialButton = new QRadioButton(tr("Radial Gradient"), typeGroup);
+ m_conicalButton = new QRadioButton(tr("Conical Gradient"), typeGroup);
+
+ QGroupBox *spreadGroup = new QGroupBox(mainGroup);
+ spreadGroup->setTitle(tr("Spread Method"));
+ m_padSpreadButton = new QRadioButton(tr("Pad Spread"), spreadGroup);
+ m_reflectSpreadButton = new QRadioButton(tr("Reflect Spread"), spreadGroup);
+ m_repeatSpreadButton = new QRadioButton(tr("Repeat Spread"), spreadGroup);
+
+ QGroupBox *defaultsGroup = new QGroupBox(mainGroup);
+ defaultsGroup->setTitle(tr("Defaults"));
+ QPushButton *default1Button = new QPushButton(tr("1"), defaultsGroup);
+ QPushButton *default2Button = new QPushButton(tr("2"), defaultsGroup);
+ QPushButton *default3Button = new QPushButton(tr("3"), defaultsGroup);
+ QPushButton *default4Button = new QPushButton(tr("Reset"), editorGroup);
+
+ QPushButton *showSourceButton = new QPushButton(mainGroup);
+ showSourceButton->setText(tr("Show Source"));
+#ifdef QT_OPENGL_SUPPORT
+ QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
+ enableOpenGLButton->setText(tr("Use OpenGL"));
+ enableOpenGLButton->setCheckable(true);
+ enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
+ if (!QGLFormat::hasOpenGL())
+ enableOpenGLButton->hide();
+#endif
+ QPushButton *whatsThisButton = new QPushButton(mainGroup);
+ whatsThisButton->setText(tr("What's This?"));
+ whatsThisButton->setCheckable(true);
+
+ // Layouts
+ QHBoxLayout *mainLayout = new QHBoxLayout(this);
+ mainLayout->addWidget(m_renderer);
+ mainLayout->addWidget(mainGroup);
+
+ mainGroup->setFixedWidth(180);
+ QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
+ mainGroupLayout->addWidget(editorGroup);
+ mainGroupLayout->addWidget(typeGroup);
+ mainGroupLayout->addWidget(spreadGroup);
+ mainGroupLayout->addWidget(defaultsGroup);
+ mainGroupLayout->addStretch(1);
+ mainGroupLayout->addWidget(showSourceButton);
+#ifdef QT_OPENGL_SUPPORT
+ mainGroupLayout->addWidget(enableOpenGLButton);
+#endif
+ mainGroupLayout->addWidget(whatsThisButton);
+
+ QVBoxLayout *editorGroupLayout = new QVBoxLayout(editorGroup);
+ editorGroupLayout->addWidget(m_editor);
+
+ QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
+ typeGroupLayout->addWidget(m_linearButton);
+ typeGroupLayout->addWidget(m_radialButton);
+ typeGroupLayout->addWidget(m_conicalButton);
+
+ QVBoxLayout *spreadGroupLayout = new QVBoxLayout(spreadGroup);
+ spreadGroupLayout->addWidget(m_padSpreadButton);
+ spreadGroupLayout->addWidget(m_repeatSpreadButton);
+ spreadGroupLayout->addWidget(m_reflectSpreadButton);
+
+ QHBoxLayout *defaultsGroupLayout = new QHBoxLayout(defaultsGroup);
+ defaultsGroupLayout->addWidget(default1Button);
+ defaultsGroupLayout->addWidget(default2Button);
+ defaultsGroupLayout->addWidget(default3Button);
+ editorGroupLayout->addWidget(default4Button);
+
+ connect(m_editor, SIGNAL(gradientStopsChanged(QGradientStops)),
+ m_renderer, SLOT(setGradientStops(QGradientStops)));
+
+ connect(m_linearButton, SIGNAL(clicked()), m_renderer, SLOT(setLinearGradient()));
+ connect(m_radialButton, SIGNAL(clicked()), m_renderer, SLOT(setRadialGradient()));
+ connect(m_conicalButton, SIGNAL(clicked()), m_renderer, SLOT(setConicalGradient()));
+
+ connect(m_padSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setPadSpread()));
+ connect(m_reflectSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setReflectSpread()));
+ connect(m_repeatSpreadButton, SIGNAL(clicked()), m_renderer, SLOT(setRepeatSpread()));
+
+ connect(default1Button, SIGNAL(clicked()), this, SLOT(setDefault1()));
+ connect(default2Button, SIGNAL(clicked()), this, SLOT(setDefault2()));
+ connect(default3Button, SIGNAL(clicked()), this, SLOT(setDefault3()));
+ connect(default4Button, SIGNAL(clicked()), this, SLOT(setDefault4()));
+
+ connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
+#ifdef QT_OPENGL_SUPPORT
+ connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
+#endif
+ connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
+ connect(whatsThisButton, SIGNAL(clicked(bool)),
+ m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ whatsThisButton, SLOT(setChecked(bool)));
+ connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)),
+ m_renderer->hoverPoints(), SLOT(setDisabled(bool)));
+
+ m_renderer->loadSourceFile(":res/gradients/gradients.cpp");
+ m_renderer->loadDescription(":res/gradients/gradients.html");
+
+ QTimer::singleShot(50, this, SLOT(setDefault1()));
+}
+
+void GradientWidget::setDefault(int config)
+{
+ QGradientStops stops;
+ QPolygonF points;
+ switch (config) {
+ case 1:
+ stops << QGradientStop(0.00, QColor::fromRgba(0));
+ stops << QGradientStop(0.04, QColor::fromRgba(0xff131360));
+ stops << QGradientStop(0.08, QColor::fromRgba(0xff202ccc));
+ stops << QGradientStop(0.42, QColor::fromRgba(0xff93d3f9));
+ stops << QGradientStop(0.51, QColor::fromRgba(0xffb3e6ff));
+ stops << QGradientStop(0.73, QColor::fromRgba(0xffffffec));
+ stops << QGradientStop(0.92, QColor::fromRgba(0xff5353d9));
+ stops << QGradientStop(0.96, QColor::fromRgba(0xff262666));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_linearButton->animateClick();
+ m_repeatSpreadButton->animateClick();
+ break;
+
+ case 2:
+ stops << QGradientStop(0.00, QColor::fromRgba(0xffffffff));
+ stops << QGradientStop(0.11, QColor::fromRgba(0xfff9ffa0));
+ stops << QGradientStop(0.13, QColor::fromRgba(0xfff9ff99));
+ stops << QGradientStop(0.14, QColor::fromRgba(0xfff3ff86));
+ stops << QGradientStop(0.49, QColor::fromRgba(0xff93b353));
+ stops << QGradientStop(0.87, QColor::fromRgba(0xff264619));
+ stops << QGradientStop(0.96, QColor::fromRgba(0xff0c1306));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_radialButton->animateClick();
+ m_padSpreadButton->animateClick();
+ break;
+
+ case 3:
+ stops << QGradientStop(0.00, QColor::fromRgba(0));
+ stops << QGradientStop(0.10, QColor::fromRgba(0xffe0cc73));
+ stops << QGradientStop(0.17, QColor::fromRgba(0xffc6a006));
+ stops << QGradientStop(0.46, QColor::fromRgba(0xff600659));
+ stops << QGradientStop(0.72, QColor::fromRgba(0xff0680ac));
+ stops << QGradientStop(0.92, QColor::fromRgba(0xffb9d9e6));
+ stops << QGradientStop(1.00, QColor::fromRgba(0));
+ m_conicalButton->animateClick();
+ m_padSpreadButton->animateClick();
+ break;
+
+ case 4:
+ stops << QGradientStop(0.00, QColor::fromRgba(0xff000000));
+ stops << QGradientStop(1.00, QColor::fromRgba(0xffffffff));
+ break;
+
+ default:
+ qWarning("bad default: %d\n", config);
+ break;
+ }
+
+ QPolygonF pts;
+ int h_off = m_renderer->width() / 10;
+ int v_off = m_renderer->height() / 8;
+ pts << QPointF(m_renderer->width() / 2, m_renderer->height() / 2)
+ << QPointF(m_renderer->width() / 2 - h_off, m_renderer->height() / 2 - v_off);
+
+ m_editor->setGradientStops(stops);
+ m_renderer->hoverPoints()->setPoints(pts);
+ m_renderer->setGradientStops(stops);
+}
+
+
+GradientRenderer::GradientRenderer(QWidget *parent)
+ : ArthurFrame(parent)
+{
+ m_hoverPoints = new HoverPoints(this, HoverPoints::CircleShape);
+ m_hoverPoints->setPointSize(QSize(20, 20));
+ m_hoverPoints->setConnectionType(HoverPoints::NoConnection);
+ m_hoverPoints->setEditable(false);
+
+ QVector<QPointF> points;
+ points << QPointF(100, 100) << QPointF(200, 200);
+ m_hoverPoints->setPoints(points);
+
+ m_spread = QGradient::PadSpread;
+ m_gradientType = Qt::LinearGradientPattern;
+}
+
+void GradientRenderer::setGradientStops(const QGradientStops &stops)
+{
+ m_stops = stops;
+ update();
+}
+
+
+void GradientRenderer::mousePressEvent(QMouseEvent *)
+{
+ setDescriptionEnabled(false);
+}
+
+void GradientRenderer::paint(QPainter *p)
+{
+ QPolygonF pts = m_hoverPoints->points();
+
+ QGradient g;
+
+ if (m_gradientType == Qt::LinearGradientPattern) {
+ g = QLinearGradient(pts.at(0), pts.at(1));
+
+ } else if (m_gradientType == Qt::RadialGradientPattern) {
+ g = QRadialGradient(pts.at(0), qMin(width(), height()) / 3.0, pts.at(1));
+
+ } else {
+ QLineF l(pts.at(0), pts.at(1));
+ qreal angle = l.angle(QLineF(0, 0, 1, 0));
+ if (l.dy() > 0)
+ angle = 360 - angle;
+ g = QConicalGradient(pts.at(0), angle);
+ }
+
+ for (int i=0; i<m_stops.size(); ++i)
+ g.setColorAt(m_stops.at(i).first, m_stops.at(i).second);
+
+ g.setSpread(m_spread);
+
+ p->setBrush(g);
+ p->setPen(Qt::NoPen);
+
+ p->drawRect(rect());
+
+}
diff --git a/demos/gradients/gradients.h b/demos/gradients/gradients.h
new file mode 100644
index 0000000000..bdd5c713ec
--- /dev/null
+++ b/demos/gradients/gradients.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTS_H
+#define GRADIENTS_H
+
+#include "arthurwidgets.h"
+
+#include <QtGui>
+
+class HoverPoints;
+
+
+class ShadeWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ enum ShadeType {
+ RedShade,
+ GreenShade,
+ BlueShade,
+ ARGBShade
+ };
+
+ ShadeWidget(ShadeType type, QWidget *parent);
+
+ void setGradientStops(const QGradientStops &stops);
+
+ void paintEvent(QPaintEvent *e);
+
+ QSize sizeHint() const { return QSize(150, 40); }
+ QPolygonF points() const;
+
+ HoverPoints *hoverPoints() const { return m_hoverPoints; }
+
+ uint colorAt(int x);
+
+signals:
+ void colorsChanged();
+
+private:
+ void generateShade();
+
+ ShadeType m_shade_type;
+ QImage m_shade;
+ HoverPoints *m_hoverPoints;
+ QLinearGradient m_alpha_gradient;
+};
+
+class GradientEditor : public QWidget
+{
+ Q_OBJECT
+public:
+ GradientEditor(QWidget *parent);
+
+ void setGradientStops(const QGradientStops &stops);
+
+public slots:
+ void pointsUpdated();
+
+signals:
+ void gradientStopsChanged(const QGradientStops &stops);
+
+private:
+ ShadeWidget *m_red_shade;
+ ShadeWidget *m_green_shade;
+ ShadeWidget *m_blue_shade;
+ ShadeWidget *m_alpha_shade;
+};
+
+
+class GradientRenderer : public ArthurFrame
+{
+ Q_OBJECT
+public:
+ GradientRenderer(QWidget *parent);
+ void paint(QPainter *p);
+
+ QSize sizeHint() const { return QSize(400, 400); }
+
+ HoverPoints *hoverPoints() const { return m_hoverPoints; }
+ void mousePressEvent(QMouseEvent *e);
+
+public slots:
+ void setGradientStops(const QGradientStops &stops);
+
+ void setPadSpread() { m_spread = QGradient::PadSpread; update(); }
+ void setRepeatSpread() { m_spread = QGradient::RepeatSpread; update(); }
+ void setReflectSpread() { m_spread = QGradient::ReflectSpread; update(); }
+
+ void setLinearGradient() { m_gradientType = Qt::LinearGradientPattern; update(); }
+ void setRadialGradient() { m_gradientType = Qt::RadialGradientPattern; update(); }
+ void setConicalGradient() { m_gradientType = Qt::ConicalGradientPattern; update(); }
+
+
+private:
+ QGradientStops m_stops;
+ HoverPoints *m_hoverPoints;
+
+ QGradient::Spread m_spread;
+ Qt::BrushStyle m_gradientType;
+};
+
+
+class GradientWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ GradientWidget(QWidget *parent);
+
+public slots:
+ void setDefault1() { setDefault(1); }
+ void setDefault2() { setDefault(2); }
+ void setDefault3() { setDefault(3); }
+ void setDefault4() { setDefault(4); }
+
+private:
+ void setDefault(int i);
+
+ GradientRenderer *m_renderer;
+ GradientEditor *m_editor;
+
+ QRadioButton *m_linearButton;
+ QRadioButton *m_radialButton;
+ QRadioButton *m_conicalButton;
+ QRadioButton *m_padSpreadButton;
+ QRadioButton *m_reflectSpreadButton;
+ QRadioButton *m_repeatSpreadButton;
+
+};
+
+#endif // GRADIENTS_H
diff --git a/demos/gradients/gradients.html b/demos/gradients/gradients.html
new file mode 100644
index 0000000000..1ea2c0ed6c
--- /dev/null
+++ b/demos/gradients/gradients.html
@@ -0,0 +1,31 @@
+<html>
+<center>
+<h2>Gradients</h2>
+</center>
+
+<p>In this demo we show the various types of gradients that can
+be used in Qt.</p>
+
+<p>There are three types of gradients:
+
+<ul>
+ <li><b>Linear</b> gradients interpolate colors between start and end
+ points.</li>
+ <li><b>Radial</b> gradients interpolate colors between a focal point and the
+ points on a circle surrounding it.</li>
+ <li><b>Conical</b> gradients interpolate colors around a center point.</li>
+</ul>
+
+</p>
+
+<p>The panel on the right contains a color table editor that defines
+the colors in the gradient. The three topmost controls determine the red,
+green and blue components while the last defines the alpha of the
+gradient. You can move points, and add new ones, by clicking with the left
+mouse button, and remove points by clicking with the right button.</p>
+
+<p>There are three default configurations available at the bottom of
+the page that are provided as suggestions on how a color table could be
+configured.</p>
+
+</html>
diff --git a/demos/gradients/gradients.pro b/demos/gradients/gradients.pro
new file mode 100644
index 0000000000..ba8910351a
--- /dev/null
+++ b/demos/gradients/gradients.pro
@@ -0,0 +1,20 @@
+SOURCES += main.cpp gradients.cpp
+HEADERS += gradients.h
+
+SHARED_FOLDER = ../shared
+
+include($$SHARED_FOLDER/shared.pri)
+
+RESOURCES += gradients.qrc
+contains(QT_CONFIG, opengl) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/gradients
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.html
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/gradients
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
diff --git a/demos/gradients/gradients.qrc b/demos/gradients/gradients.qrc
new file mode 100644
index 0000000000..fb971eb17b
--- /dev/null
+++ b/demos/gradients/gradients.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res/gradients">
+ <file>gradients.cpp</file>
+ <file>gradients.html</file>
+</qresource>
+</RCC>
diff --git a/demos/gradients/main.cpp b/demos/gradients/main.cpp
new file mode 100644
index 0000000000..a27951ce4a
--- /dev/null
+++ b/demos/gradients/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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gradients.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(gradients);
+
+ QApplication app(argc, argv);
+
+ GradientWidget gradientWidget(0);
+ QStyle *arthurStyle = new ArthurStyle();
+ gradientWidget.setStyle(arthurStyle);
+ QList<QWidget *> widgets = gradientWidget.findChildren<QWidget *>();
+ foreach (QWidget *w, widgets) {
+ w->setStyle(arthurStyle);
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ gradientWidget.show();
+
+ return app.exec();
+}
diff --git a/demos/interview/README b/demos/interview/README
new file mode 100644
index 0000000000..50894428f6
--- /dev/null
+++ b/demos/interview/README
@@ -0,0 +1,2 @@
+The interview example shows the same model and selection being shared
+between three different views.
diff --git a/demos/interview/images/folder.png b/demos/interview/images/folder.png
new file mode 100644
index 0000000000..589fd2df59
--- /dev/null
+++ b/demos/interview/images/folder.png
Binary files differ
diff --git a/demos/interview/images/interview.png b/demos/interview/images/interview.png
new file mode 100644
index 0000000000..0c3d690258
--- /dev/null
+++ b/demos/interview/images/interview.png
Binary files differ
diff --git a/demos/interview/images/services.png b/demos/interview/images/services.png
new file mode 100644
index 0000000000..6b2ad969d4
--- /dev/null
+++ b/demos/interview/images/services.png
Binary files differ
diff --git a/demos/interview/interview.pro b/demos/interview/interview.pro
new file mode 100644
index 0000000000..c69f7ba975
--- /dev/null
+++ b/demos/interview/interview.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on
+HEADERS += model.h
+SOURCES += model.cpp main.cpp
+RESOURCES += interview.qrc
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/qtbase/interview
+sources.files = $$SOURCES $$HEADERS $$RESOURCES README *.pro images
+sources.path = $$[QT_INSTALL_DEMOS]/qtbase/interview
+INSTALLS += target sources
+
+symbian: include($$QT_SOURCE_TREE/demos/symbianpk