aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/dependencies.json1
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp2
-rw-r--r--src/quick/designer/qquickdesignercustomobjectdata.cpp4
-rw-r--r--src/quick/doc/snippets/qml/listview/ReusableDelegate.qml82
-rw-r--r--src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml81
-rw-r--r--src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp47
-rw-r--r--src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h94
-rw-r--r--src/quick/doc/snippets/qml/tableview/tableview.pro20
-rw-r--r--src/quick/doc/src/advtutorial.qdoc4
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc20
-rw-r--r--src/quick/doc/src/dynamicview-tutorial.qdoc4
-rw-r--r--src/quick/doc/src/examples.qdoc1
-rw-r--r--src/quick/doc/src/tutorial.qdoc3
-rw-r--r--src/quick/handlers/qquickdragaxis_p.h4
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp3
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h2
-rw-r--r--src/quick/handlers/qquickhandlerpoint.cpp7
-rw-r--r--src/quick/handlers/qquickhoverhandler.cpp70
-rw-r--r--src/quick/handlers/qquickhoverhandler_p.h3
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp9
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h2
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp157
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h23
-rw-r--r--src/quick/handlers/qquickpointerhandler_p_p.h9
-rw-r--r--src/quick/handlers/qquickpointhandler_p.h2
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp2
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp9
-rw-r--r--src/quick/handlers/qquicktaphandler_p.h3
-rw-r--r--src/quick/handlers/qquickwheelhandler_p.h3
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp6
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h1
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp20
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h5
-rw-r--r--src/quick/items/qquickanchors_p.h1
-rw-r--r--src/quick/items/qquickanimatedimage.cpp2
-rw-r--r--src/quick/items/qquickanimatedimage_p.h1
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp64
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h12
-rw-r--r--src/quick/items/qquickanimatedsprite_p_p.h5
-rw-r--r--src/quick/items/qquickborderimage.cpp92
-rw-r--r--src/quick/items/qquickborderimage_p.h1
-rw-r--r--src/quick/items/qquickdrag.cpp6
-rw-r--r--src/quick/items/qquickdrag_p.h8
-rw-r--r--src/quick/items/qquickdroparea.cpp8
-rw-r--r--src/quick/items/qquickdroparea_p.h3
-rw-r--r--src/quick/items/qquickevents.cpp180
-rw-r--r--src/quick/items/qquickevents_p_p.h118
-rw-r--r--src/quick/items/qquickflickable.cpp14
-rw-r--r--src/quick/items/qquickflickable_p.h1
-rw-r--r--src/quick/items/qquickflickable_p_p.h3
-rw-r--r--src/quick/items/qquickflipable_p.h1
-rw-r--r--src/quick/items/qquickfocusscope_p.h1
-rw-r--r--src/quick/items/qquickframebufferobject.cpp30
-rw-r--r--src/quick/items/qquickframebufferobject.h3
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp3
-rw-r--r--src/quick/items/qquickgraphicsinfo_p.h7
-rw-r--r--src/quick/items/qquickgridview.cpp8
-rw-r--r--src/quick/items/qquickgridview_p.h3
-rw-r--r--src/quick/items/qquickimage.cpp62
-rw-r--r--src/quick/items/qquickimage_p.h2
-rw-r--r--src/quick/items/qquickimage_p_p.h13
-rw-r--r--src/quick/items/qquickimagebase.cpp182
-rw-r--r--src/quick/items/qquickimagebase_p.h26
-rw-r--r--src/quick/items/qquickimagebase_p_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp429
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitem_p.h33
-rw-r--r--src/quick/items/qquickitemanimation.cpp2
-rw-r--r--src/quick/items/qquickitemanimation_p.h3
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp2
-rw-r--r--src/quick/items/qquickitemgrabresult.h8
-rw-r--r--src/quick/items/qquickitemsmodule.cpp327
-rw-r--r--src/quick/items/qquickitemsmodule_p.h22
-rw-r--r--src/quick/items/qquickitemview.cpp91
-rw-r--r--src/quick/items/qquickitemview_p.h16
-rw-r--r--src/quick/items/qquickitemview_p_p.h17
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp2
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h5
-rw-r--r--src/quick/items/qquicklistview.cpp156
-rw-r--r--src/quick/items/qquicklistview_p.h6
-rw-r--r--src/quick/items/qquickloader.cpp6
-rw-r--r--src/quick/items/qquickloader_p.h1
-rw-r--r--src/quick/items/qquickmousearea.cpp22
-rw-r--r--src/quick/items/qquickmousearea_p.h1
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp44
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h11
-rw-r--r--src/quick/items/qquickopenglinfo_p.h7
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp2
-rw-r--r--src/quick/items/qquickpainteditem.cpp1
-rw-r--r--src/quick/items/qquickpainteditem.h3
-rw-r--r--src/quick/items/qquickpathview.cpp12
-rw-r--r--src/quick/items/qquickpathview_p.h3
-rw-r--r--src/quick/items/qquickpincharea.cpp8
-rw-r--r--src/quick/items/qquickpincharea_p.h3
-rw-r--r--src/quick/items/qquickpositioners.cpp8
-rw-r--r--src/quick/items/qquickpositioners_p.h11
-rw-r--r--src/quick/items/qquickrectangle.cpp2
-rw-r--r--src/quick/items/qquickrectangle_p.h4
-rw-r--r--src/quick/items/qquickrepeater.cpp4
-rw-r--r--src/quick/items/qquickrepeater_p.h1
-rw-r--r--src/quick/items/qquickscalegrid_p_p.h1
-rw-r--r--src/quick/items/qquickscreen.cpp3
-rw-r--r--src/quick/items/qquickscreen_p.h17
-rw-r--r--src/quick/items/qquickshadereffect_p.h1
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h10
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h1
-rw-r--r--src/quick/items/qquicksprite_p.h1
-rw-r--r--src/quick/items/qquickspriteengine_p.h16
-rw-r--r--src/quick/items/qquickspritesequence.cpp4
-rw-r--r--src/quick/items/qquickspritesequence_p.h1
-rw-r--r--src/quick/items/qquickstateoperations.cpp94
-rw-r--r--src/quick/items/qquickstateoperations_p.h3
-rw-r--r--src/quick/items/qquicktableview.cpp118
-rw-r--r--src/quick/items/qquicktableview_p.h9
-rw-r--r--src/quick/items/qquicktableview_p_p.h16
-rw-r--r--src/quick/items/qquicktext.cpp102
-rw-r--r--src/quick/items/qquicktext_p.h15
-rw-r--r--src/quick/items/qquicktext_p_p.h2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp19
-rw-r--r--src/quick/items/qquicktextcontrol_p.h3
-rw-r--r--src/quick/items/qquicktextdocument.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp6
-rw-r--r--src/quick/items/qquicktextedit_p.h1
-rw-r--r--src/quick/items/qquicktextinput.cpp8
-rw-r--r--src/quick/items/qquicktextinput_p.h1
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp2
-rw-r--r--src/quick/items/qquicktranslate_p.h5
-rw-r--r--src/quick/items/qquickview.cpp20
-rw-r--r--src/quick/items/qquickwindow.cpp266
-rw-r--r--src/quick/items/qquickwindow.h8
-rw-r--r--src/quick/items/qquickwindow_p.h40
-rw-r--r--src/quick/items/qquickwindowmodule.cpp23
-rw-r--r--src/quick/items/qquickwindowmodule_p.h8
-rw-r--r--src/quick/qtquick.tracepoints48
-rw-r--r--src/quick/qtquick2.cpp13
-rw-r--r--src/quick/qtquickglobal_p.h2
-rw-r--r--src/quick/quick.pro9
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp43
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp21
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp131
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h109
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp1
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp21
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp11
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode_p.h9
-rw-r--r--src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp58
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.h6
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp9
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp3
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp1
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp13
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp66
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h5
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp4
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp71
-rw-r--r--src/quick/scenegraph/qsgrhisupport_p.h3
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp123
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp20
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsbbin1873 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsbbin1754 -> 1344 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsbbin1753 -> 1351 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsbbin1280 -> 845 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsbbin2209 -> 1783 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsbbin2209 -> 1802 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsbbin2210 -> 1780 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsbbin2319 -> 1867 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsbbin2340 -> 1930 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsbbin2334 -> 1858 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsbbin1883 -> 1488 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsbbin2048 -> 1692 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsbbin1883 -> 1479 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.frag.qsbbin1149 -> 864 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/flatcolor.vert.qsbbin1597 -> 1284 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsbbin3314 -> 2848 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsbbin3675 -> 3282 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsbbin3304 -> 2863 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsbbin2411 -> 1971 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsbbin3028 -> 2614 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsbbin2412 -> 1979 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsbbin1173 -> 927 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsbbin1791 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsbbin2549 -> 2107 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsbbin3029 -> 2623 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsbbin1859 -> 1402 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.frag.qsbbin1622 -> 1247 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/shadereffect.vert.qsbbin1860 -> 1501 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsbbin838 -> 672 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsbbin3682 -> 3320 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsbbin1299 -> 1038 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsbbin4350 -> 3954 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.frag.qsbbin1908 -> 1498 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/sprite.vert.qsbbin2437 -> 2087 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.frag.qsbbin853 -> 715 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/stencilclip.vert.qsbbin1510 -> 1230 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.frag.qsbbin2210 -> 1740 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext.vert.qsbbin2618 -> 2175 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsbbin1631 -> 1158 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.frag.qsbbin1873 -> 1469 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/textmask.vert.qsbbin2307 -> 1933 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.frag.qsbbin1618 -> 1242 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/texture.vert.qsbbin1865 -> 1516 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsbbin851 -> 672 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsbbin1837 -> 1507 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.frag.qsbbin1877 -> 1504 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/visualization.vert.qsbbin2099 -> 1704 bytes
-rw-r--r--src/quick/scenegraph/util/qsgengine.cpp5
-rw-r--r--src/quick/scenegraph/util/qsgengine.h5
-rw-r--r--src/quick/scenegraph/util/qsgengine_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture.cpp5
-rw-r--r--src/quick/scenegraph/util/qsgplaintexture.cpp19
-rw-r--r--src/quick/scenegraph/util/qsgrhiatlastexture.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp104
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h7
-rw-r--r--src/quick/util/qquickanimation.cpp109
-rw-r--r--src/quick/util/qquickanimation_p.h15
-rw-r--r--src/quick/util/qquickanimation_p_p.h5
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h1
-rw-r--r--src/quick/util/qquickanimator_p.h16
-rw-r--r--src/quick/util/qquickanimatorjob.cpp4
-rw-r--r--src/quick/util/qquickapplication_p.h3
-rw-r--r--src/quick/util/qquickbehavior.cpp76
-rw-r--r--src/quick/util/qquickbehavior_p.h5
-rw-r--r--src/quick/util/qquickboundaryrule.cpp574
-rw-r--r--src/quick/util/qquickboundaryrule_p.h145
-rw-r--r--src/quick/util/qquickfontloader_p.h1
-rw-r--r--src/quick/util/qquickfontmetrics_p.h2
-rw-r--r--src/quick/util/qquickforeignutils_p.h (renamed from src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h)72
-rw-r--r--src/quick/util/qquickglobal.cpp62
-rw-r--r--src/quick/util/qquickimageprovider.cpp28
-rw-r--r--src/quick/util/qquickpath.cpp229
-rw-r--r--src/quick/util/qquickpath_p.h123
-rw-r--r--src/quick/util/qquickpath_p_p.h1
-rw-r--r--src/quick/util/qquickpathinterpolator_p.h1
-rw-r--r--src/quick/util/qquickpixmapcache.cpp147
-rw-r--r--src/quick/util/qquickpixmapcache_p.h18
-rw-r--r--src/quick/util/qquickpropertychanges_p.h7
-rw-r--r--src/quick/util/qquickshortcut.cpp6
-rw-r--r--src/quick/util/qquickshortcut_p.h3
-rw-r--r--src/quick/util/qquicksmoothedanimation.cpp2
-rw-r--r--src/quick/util/qquicksmoothedanimation_p.h1
-rw-r--r--src/quick/util/qquickspringanimation.cpp2
-rw-r--r--src/quick/util/qquickspringanimation_p.h1
-rw-r--r--src/quick/util/qquickstate.cpp10
-rw-r--r--src/quick/util/qquickstate_p.h2
-rw-r--r--src/quick/util/qquickstate_p_p.h17
-rw-r--r--src/quick/util/qquickstatechangescript_p.h1
-rw-r--r--src/quick/util/qquickstategroup.cpp36
-rw-r--r--src/quick/util/qquickstategroup_p.h1
-rw-r--r--src/quick/util/qquickstyledtext.cpp20
-rw-r--r--src/quick/util/qquicksystempalette_p.h1
-rw-r--r--src/quick/util/qquicktextmetrics_p.h2
-rw-r--r--src/quick/util/qquicktimeline.cpp2
-rw-r--r--src/quick/util/qquicktimeline_p_p.h3
-rw-r--r--src/quick/util/qquicktransition_p.h1
-rw-r--r--src/quick/util/qquickutilmodule.cpp143
-rw-r--r--src/quick/util/qquickutilmodule_p.h66
-rw-r--r--src/quick/util/qquickvalidator_p.h2
-rw-r--r--src/quick/util/qquickvaluetypes.cpp43
-rw-r--r--src/quick/util/qquickvaluetypes_p.h56
-rw-r--r--src/quick/util/util.pri7
277 files changed, 4013 insertions, 2733 deletions
diff --git a/src/quick/dependencies.json b/src/quick/dependencies.json
new file mode 100644
index 0000000000..fe51488c70
--- /dev/null
+++ b/src/quick/dependencies.json
@@ -0,0 +1 @@
+[]
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index de7da7f9be..0aa5dc2613 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -240,7 +240,7 @@ int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id,
if (call == QMetaObject::WriteProperty
&& propertyById.userType() == QMetaType::QVariant
- && reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
+ && reinterpret_cast<QVariant *>(a[0])->userType() == QMetaType::Double
&& qt_is_nan(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
return -1;
}
diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp
index 8989de711e..66a86bffd5 100644
--- a/src/quick/designer/qquickdesignercustomobjectdata.cpp
+++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp
@@ -192,7 +192,7 @@ void QQuickDesignerCustomObjectData::doResetProperty(QQmlContext *context, const
QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(property);
if (binding && !(hasValidResetBinding(propertyName) && getResetBinding(propertyName) == binding)) {
- binding->setEnabled(false, nullptr);
+ binding->setEnabled(false, {});
}
@@ -278,7 +278,7 @@ void QQuickDesignerCustomObjectData::setPropertyBinding(QQmlContext *context,
//Refcounting is taking take care of deletion
binding->update();
if (binding->hasError()) {
- if (property.property().userType() == QVariant::String)
+ if (property.property().userType() == QMetaType::QString)
property.write(QVariant(QLatin1Char('#') + expression + QLatin1Char('#')));
}
diff --git a/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
new file mode 100644
index 0000000000..050572d5f2
--- /dev/null
+++ b/src/quick/doc/snippets/qml/listview/ReusableDelegate.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.15
+
+//![0]
+Component {
+ id: listViewDelegate
+ Rectangle {
+ width: 100
+ height: 50
+
+ ListView.onPooled: rotationAnimation.pause()
+ ListView.onReused: rotationAnimation.resume()
+
+ Rectangle {
+ id: rect
+ anchors.centerIn: parent
+ width: 40
+ height: 5
+ color: "green"
+
+ RotationAnimation {
+ id: rotationAnimation
+ target: rect
+ duration: (Math.random() * 2000) + 200
+ from: 0
+ to: 359
+ running: true
+ loops: Animation.Infinite
+ }
+ }
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
new file mode 100644
index 0000000000..e9a668ed8f
--- /dev/null
+++ b/src/quick/doc/snippets/qml/qml-data-models/listmodel-listview-required.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [document]
+import QtQuick 2.0
+
+Item {
+ width: 200
+ height: 250
+
+ ListModel {
+ id: myModel
+ ListElement { type: "Dog"; age: 8; noise: "meow" }
+ ListElement { type: "Cat"; age: 5; noise: "woof" }
+ }
+
+ component MyDelegate : Text {
+ required property string type
+ required property int age
+ text: type + ", " + age
+ // WRONG: Component.onCompleted: () => console.log(noise)
+ // The above line would cause a ReferenceError
+ // as there is no required property noise,
+ // and the presence of the required properties prevents
+ // noise from being injected into the scope
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: myModel
+ delegate: MyDelegate {}
+ }
+}
+//! [document]
diff --git a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
index ea9f76f131..a8a37f80af 100644
--- a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
+++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp
@@ -48,56 +48,19 @@
**
****************************************************************************/
-//![0]
+#include "cpp-tablemodel.h"
#include <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QAbstractTableModel>
-
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-
-public:
-
- int rowCount(const QModelIndex & = QModelIndex()) const override
- {
- return 200;
- }
-
- int columnCount(const QModelIndex & = QModelIndex()) const override
- {
- return 200;
- }
-
- QVariant data(const QModelIndex &index, int role) const override
- {
- switch (role) {
- case Qt::DisplayRole:
- return QString("%1, %2").arg(index.column()).arg(index.row());
- default:
- break;
- }
-
- return QVariant();
- }
-
- QHash<int, QByteArray> roleNames() const override
- {
- return { {Qt::DisplayRole, "display"} };
- }
-};
+#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- qmlRegisterType<TableModel>("TableModel", 0, 1, "TableModel");
-
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ QQuickView view;
+ view.setSource(QStringLiteral("qrc:/cpp-tablemodel.qml"));
+ view.show();
return app.exec();
}
-#include "main.moc"
//![0]
diff --git a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h
new file mode 100644
index 0000000000..4a3c46b573
--- /dev/null
+++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2020 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the documentation of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** BSD License Usage
+ ** Alternatively, you may use this file under the terms of the BSD license
+ ** as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of The Qt Company Ltd nor the names of its
+ ** contributors may be used to endorse or promote products derived
+ ** from this software without specific prior written permission.
+ **
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef CPPTABLEMODEL_H
+#define CPPTABLEMODEL_H
+
+//![0]
+#include <qqml.h>
+#include <QAbstractTableModel>
+
+class TableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_ADDED_IN_MINOR_VERSION(1)
+
+public:
+ int rowCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return 200;
+ }
+
+ int columnCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return 200;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ switch (role) {
+ case Qt::DisplayRole:
+ return QString("%1, %2").arg(index.column()).arg(index.row());
+ default:
+ break;
+ }
+
+ return QVariant();
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return { {Qt::DisplayRole, "display"} };
+ }
+};
+//![0]
+
+#endif // CPPTABLEMODEL_H
diff --git a/src/quick/doc/snippets/qml/tableview/tableview.pro b/src/quick/doc/snippets/qml/tableview/tableview.pro
new file mode 100644
index 0000000000..0821f1b5d3
--- /dev/null
+++ b/src/quick/doc/snippets/qml/tableview/tableview.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+
+QT += qml quick
+
+CONFIG += qmltypes
+QML_IMPORT_NAME = TableModel
+QML_IMPORT_MAJOR_VERSION = 0
+
+SOURCES += \
+ cpp-tablemodel.cpp
+
+HEADERS += \
+ cpp-tablemodel.h
+
+RESOURCES += \
+ cpp-tablemodel.qml \
+ qml-tablemodel.qml \
+ reusabledelegate.qml \
+ tableviewwithheader.qml \
+ tableviewwithprovider.qml
diff --git a/src/quick/doc/src/advtutorial.qdoc b/src/quick/doc/src/advtutorial.qdoc
index a18d4493ea..63c70067fd 100644
--- a/src/quick/doc/src/advtutorial.qdoc
+++ b/src/quick/doc/src/advtutorial.qdoc
@@ -64,7 +64,6 @@ directory.
/*!
\title QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial
\nextpage QML Advanced Tutorial 2 - Populating the Game Canvas
@@ -132,7 +131,6 @@ types to get started. Next, we will populate the game canvas with some blocks.
/*!
\title QML Advanced Tutorial 2 - Populating the Game Canvas
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 1 - Creating the Game Canvas and Blocks
\nextpage QML Advanced Tutorial 3 - Implementing the Game Logic
@@ -206,7 +204,6 @@ Now, we have a screen of blocks, and we can begin to add the game mechanics.
/*!
\title QML Advanced Tutorial 3 - Implementing the Game Logic
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 2 - Populating the Game Canvas
\nextpage QML Advanced Tutorial 4 - Finishing Touches
@@ -293,7 +290,6 @@ until the next chapter - where your application becomes alive!
/*!
\title QML Advanced Tutorial 4 - Finishing Touches
-\contentspage QML Advanced Tutorial
\previouspage QML Advanced Tutorial 3 - Implementing the Game Logic
\example tutorials/samegame/samegame4
diff --git a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
index 04dbf1cf20..555f730c9e 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/modelview.qdoc
@@ -164,6 +164,16 @@ To visualize data, bind the view's \c model property to a model and the
\snippet qml/qml-data-models/listmodel-listview.qml document
+ To get finer control over which roles are accessible, and to make delegates
+ more self-contained and usable outside of views,
+ \li{Required Properties}{required properties} can be used. If a delegate
+ contains required properties, the named roles are not provided. Instead,
+ the QML engine will check if the name of a required property matches that of
+ a model role. If so, that property will be bound to the corresponding value
+ from the model.
+
+ \snippet qml/qml-data-models/listmodel-listview-required.qml document
+
If there is a naming clash between the model's properties and the delegate's
properties, the roles can be accessed with the qualified \e model name
instead. For example, if a \l Text type had \e type or \e age properties,
@@ -186,6 +196,10 @@ To visualize data, bind the view's \c model property to a model and the
modelData role is also provided for models that have only one role. In this
case the \e modelData role contains the same data as the named role.
+ \note \e model, \e index, and \e modelData roles are not accessible
+ if the delegate contains required properties, unless it has also required
+ properties with matching names.
+
QML provides several types of data models among the built-in set of QML
types. In addition, models can be created with Qt C++ and then made
available to \l{QQmlEngine} for use by
@@ -417,6 +431,12 @@ ListView {
\note The \c edit role is equal to \l Qt::EditRole. See \l{QAbstractItemModel::}{roleNames}()
for the built-in role names. However, real life models would usually register custom roles.
+\node If a model role is bound to a \li{Required Property}{required property}, assigning to
+that property will not modify the model. It will instead break the binding to the model (just
+like assigning to any other property breaks existing bindings). If you want to use
+required properties and change the model data, make model also a required property and assign to
+\e model.propertyName.
+
For more information, visit the \l{qtquick-modelviewsdata-cppmodels.html#changing-model-data}{Using C++ Models with Qt Quick Views}
article.
diff --git a/src/quick/doc/src/dynamicview-tutorial.qdoc b/src/quick/doc/src/dynamicview-tutorial.qdoc
index 6f44ba1947..d221e2ae62 100644
--- a/src/quick/doc/src/dynamicview-tutorial.qdoc
+++ b/src/quick/doc/src/dynamicview-tutorial.qdoc
@@ -50,7 +50,6 @@ directory.
/*!
\title QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial
\nextpage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
@@ -85,7 +84,6 @@ The second part of the application is the ListView itself to which we bind the m
/*!
\title QML Dynamic View Ordering Tutorial 2 - Dragging View Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 1 - A Simple ListView and Delegate
\nextpage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
@@ -128,7 +126,6 @@ so that is above other items in the stacking order and isn't obscured as it is d
/*!
\title QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 2 - Dragging View Items
\nextpage QML Dynamic View Ordering Tutorial 4 - Sorting Items
@@ -180,7 +177,6 @@ property of the view and bind the \l {DelegateModel::}{model} and
/*!
\title QML Dynamic View Ordering Tutorial 4 - Sorting Items
-\contentspage QML Dynamic View Ordering Tutorial
\previouspage QML Dynamic View Ordering Tutorial 3 - Moving Dragged Items
\example tutorials/dynamicview/dynamicview4
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index a913af47c1..9a1308440f 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -177,6 +177,7 @@ Creator.
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
\li \l{Scene Graph - Direct3D 11 Under QML}{Direct3D 11 Under QML}
\li \l{Scene Graph - Vulkan Under QML}{Vulkan Under QML}
+ \li \l{Scene Graph - Vulkan Texture Import}{Vulkan Texture Import}
\li \l{Scene Graph - Custom Rendering with QSGRenderNode}{Render Node}
\li \l{Scene Graph - Painted Item}{Painted Item}
\li \l{Scene Graph - Graph}{Graph}
diff --git a/src/quick/doc/src/tutorial.qdoc b/src/quick/doc/src/tutorial.qdoc
index 20021f2432..7cb5f655e8 100644
--- a/src/quick/doc/src/tutorial.qdoc
+++ b/src/quick/doc/src/tutorial.qdoc
@@ -54,7 +54,6 @@ Tutorial chapters:
/*!
\page qml-tutorial1.html
\title QML Tutorial 1 - Basic Types
-\contentspage QML Tutorial
\previouspage QML Tutorial
\nextpage QML Tutorial 2 - QML Components
@@ -112,7 +111,6 @@ qmlscene tutorials/helloworld/tutorial1.qml
/*!
\page qml-tutorial2.html
\title QML Tutorial 2 - QML Components
-\contentspage QML Tutorial
\previouspage QML Tutorial 1 - Basic Types
\nextpage QML Tutorial 3 - States and Transitions
@@ -184,7 +182,6 @@ We can react to any signal of our component through a property of the name \e 'o
/*!
\page qml-tutorial3.html
\title QML Tutorial 3 - States and Transitions
-\contentspage QML Tutorial
\previouspage QML Tutorial 2 - QML Components
In this chapter, we make this example a little bit more dynamic by introducing states and transitions.
diff --git a/src/quick/handlers/qquickdragaxis_p.h b/src/quick/handlers/qquickdragaxis_p.h
index a4649d5eb9..ef74902122 100644
--- a/src/quick/handlers/qquickdragaxis_p.h
+++ b/src/quick/handlers/qquickdragaxis_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtQml/qqml.h>
#include <private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +62,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragAxis : public QObject
Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+ QML_NAMED_ELEMENT(DragAxis)
+ QML_ADDED_IN_MINOR_VERSION(12)
+ QML_UNCREATABLE("DragAxis is only available as a grouped property of DragHandler.")
public:
QQuickDragAxis();
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 61b66beff4..492897b68b 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -39,6 +39,7 @@
#include "qquickdraghandler_p.h"
#include <private/qquickwindow_p.h>
+#include <private/qquickmultipointhandler_p_p.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -228,7 +229,7 @@ void QQuickDragHandler::handlePointerEventImpl(QQuickPointerEvent *event)
accumulatedDragDelta.setY(0);
}
qreal angle = std::atan2(accumulatedDragDelta.y(), accumulatedDragDelta.x()) * 180 / M_PI;
- bool overThreshold = QQuickWindowPrivate::dragOverThreshold(accumulatedDragDelta);
+ bool overThreshold = d_func()->dragOverThreshold(accumulatedDragDelta);
qCDebug(lcDragHandler) << "movement" << accumulatedDragDelta << "angle" << angle << "of point" << point
<< "pressed @" << point->scenePressPosition() << "over threshold?" << overThreshold;
minAngle = qMin(angle, minAngle);
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
index e8f47163ed..22d51c78ec 100644
--- a/src/quick/handlers/qquickdraghandler_p.h
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -63,6 +63,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged REVISION 14)
+ QML_NAMED_ELEMENT(DragHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
enum SnapMode {
diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index f3d92cf200..72efdfd0f4 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -119,8 +119,13 @@ void QQuickHandlerPoint::reset(const QQuickEventPoint *point)
m_rotation = tp->rotation();
m_pressure = tp->pressure();
m_ellipseDiameters = tp->ellipseDiameters();
+#if QT_CONFIG(tabletevent)
} else if (event->asPointerTabletEvent()) {
- // TODO
+ m_uniqueId = event->device()->uniqueId();
+ m_rotation = static_cast<const QQuickEventTabletPoint *>(point)->rotation();
+ m_pressure = static_cast<const QQuickEventTabletPoint *>(point)->pressure();
+ m_ellipseDiameters = QSizeF();
+#endif
} else {
m_uniqueId = event->device()->uniqueId();
m_rotation = 0;
diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp
index 79cb288af8..b12d85784a 100644
--- a/src/quick/handlers/qquickhoverhandler.cpp
+++ b/src/quick/handlers/qquickhoverhandler.cpp
@@ -64,6 +64,9 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover")
properties can be used to narrow the behavior to detect hovering of
specific kinds of devices or while holding a modifier key.
+ The \l cursorShape property allows changing the cursor whenever
+ \l hovered changes to \c true.
+
\sa MouseArea, PointHandler
*/
@@ -90,11 +93,22 @@ bool QQuickHoverHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
QQuickEventPoint *point = event->point(0);
if (QQuickPointerDeviceHandler::wantsPointerEvent(event) && wantsEventPoint(point) && parentContains(point)) {
- // assume this is a mouse event, so there's only one point
+ // assume this is a mouse or tablet event, so there's only one point
setPointId(point->pointId());
return true;
}
- setHovered(false);
+
+ // Some hover events come from QQuickWindow::tabletEvent(). In between,
+ // some hover events come from QQWindowPrivate::flushFrameSynchronousEvents(),
+ // but those look like mouse events. If a particular HoverHandler instance
+ // is filtering for tablet events only (e.g. by setting
+ // acceptedDevices:PointerDevice.Stylus), those events should not cause
+ // the hovered property to transition to false prematurely.
+ // If a QQuickPointerTabletEvent caused the hovered property to become true,
+ // then only another QQuickPointerTabletEvent can make it become false.
+ if (!(m_hoveredTablet && event->asPointerMouseEvent()))
+ setHovered(false);
+
return false;
}
@@ -104,6 +118,8 @@ void QQuickHoverHandler::handleEventPoint(QQuickEventPoint *point)
if (point->state() == QQuickEventPoint::Released &&
point->pointerEvent()->device()->pointerType() == QQuickPointerDevice::Finger)
hovered = false;
+ else if (point->pointerEvent()->asPointerTabletEvent())
+ m_hoveredTablet = true;
setHovered(hovered);
setPassiveGrab(point);
}
@@ -121,8 +137,58 @@ void QQuickHoverHandler::setHovered(bool hovered)
if (m_hovered != hovered) {
qCDebug(lcHoverHandler) << objectName() << "hovered" << m_hovered << "->" << hovered;
m_hovered = hovered;
+ if (!hovered)
+ m_hoveredTablet = false;
emit hoveredChanged();
}
}
+/*!
+ \since 5.15
+ \qmlproperty Qt::CursorShape QtQuick::HoverHandler::cursorShape
+ This property holds the cursor shape that will appear whenever
+ \l hovered is \c true and no other handler is overriding it.
+
+ The available cursor shapes are:
+ \list
+ \li Qt.ArrowCursor
+ \li Qt.UpArrowCursor
+ \li Qt.CrossCursor
+ \li Qt.WaitCursor
+ \li Qt.IBeamCursor
+ \li Qt.SizeVerCursor
+ \li Qt.SizeHorCursor
+ \li Qt.SizeBDiagCursor
+ \li Qt.SizeFDiagCursor
+ \li Qt.SizeAllCursor
+ \li Qt.BlankCursor
+ \li Qt.SplitVCursor
+ \li Qt.SplitHCursor
+ \li Qt.PointingHandCursor
+ \li Qt.ForbiddenCursor
+ \li Qt.WhatsThisCursor
+ \li Qt.BusyCursor
+ \li Qt.OpenHandCursor
+ \li Qt.ClosedHandCursor
+ \li Qt.DragCopyCursor
+ \li Qt.DragMoveCursor
+ \li Qt.DragLinkCursor
+ \endlist
+
+ The default value of this property is not set, which allows any active
+ handler on the same \l parentItem to determine the cursor shape.
+ This property can be reset to the initial condition by setting it to
+ \c undefined.
+
+ If any handler with defined \c cursorShape is
+ \l {PointerHandler::active}{active}, that cursor will appear.
+ Else if the HoverHandler has a defined \c cursorShape, that cursor will appear.
+ Otherwise, the \l {QQuickItem::cursor()}{cursor} of \l parentItem will appear.
+
+ \note When this property has not been set, or has been set to \c undefined,
+ if you read the value it will return \c Qt.ArrowCursor.
+
+ \sa Qt::CursorShape, QQuickItem::cursor()
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h
index d8e5fc00a1..313b87217c 100644
--- a/src/quick/handlers/qquickhoverhandler_p.h
+++ b/src/quick/handlers/qquickhoverhandler_p.h
@@ -62,6 +62,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandle
{
Q_OBJECT
Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged)
+ QML_NAMED_ELEMENT(HoverHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickHoverHandler(QQuickItem *parent = nullptr);
@@ -82,6 +84,7 @@ private:
private:
bool m_hovered = false;
+ bool m_hoveredTablet = false;
};
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index a5a867015c..5b30d08557 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -43,6 +43,7 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
#include <private/qguiapplication_p.h>
+#include <private/qquickmultipointhandler_p_p.h>
#include <private/qquickwindow_p.h>
#include <QEvent>
#include <QMouseEvent>
@@ -289,7 +290,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
{
if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) {
for (const QQuickHandlerPoint &p : currentPoints())
- qCDebug(lcPinchHandler) << hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition();
+ qCDebug(lcPinchHandler) << Qt::hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition();
}
QQuickMultiPointHandler::handlePointerEventImpl(event);
@@ -338,8 +339,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
const QVector2D currentCentroid(centroid().scenePosition());
const QVector2D pressCentroid(centroid().scenePressPosition());
- QStyleHints *styleHints = QGuiApplication::styleHints();
- const int dragThreshold = styleHints->startDragDistance();
+ const int dragThreshold = QQuickPointerHandler::dragThreshold();
const int dragThresholdSquared = dragThreshold * dragThreshold;
double accumulatedCentroidDistance = 0; // Used to detect scale
@@ -399,7 +399,8 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
point->setAccepted(false); // don't stop propagation
setPassiveGrab(point);
}
- if (QQuickWindowPrivate::dragOverThreshold(point))
+ Q_D(QQuickMultiPointHandler);
+ if (d->dragOverThreshold(point))
++numberOfPointsDraggedOverThreshold;
}
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
index cea794f0c8..708c836acf 100644
--- a/src/quick/handlers/qquickpinchhandler_p.h
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -78,6 +78,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
#endif
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
+ QML_NAMED_ELEMENT(PinchHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPinchHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 0f5cf59c67..adb753e000 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -51,7 +51,6 @@ Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active")
\qmltype PointerHandler
\qmlabstract
\since 5.10
- \preliminary
\instantiates QQuickPointerHandler
\inqmlmodule QtQuick
\brief Abstract handler for pointer events.
@@ -113,6 +112,128 @@ void QQuickPointerHandler::setMargin(qreal pointDistanceThreshold)
}
/*!
+ \qmlproperty int PointerHandler::dragThreshold
+ \since 5.15
+
+ The distance in pixels that the user must drag an event point in order to
+ have it treated as a drag gesture.
+
+ The default value depends on the platform and screen resolution.
+ It can be reset back to the default value by setting it to undefined.
+ The behavior when a drag gesture begins varies in different handlers.
+*/
+int QQuickPointerHandler::dragThreshold() const
+{
+ Q_D(const QQuickPointerHandler);
+ if (d->dragThreshold < 0)
+ return qApp->styleHints()->startDragDistance();
+ return d->dragThreshold;
+}
+
+void QQuickPointerHandler::setDragThreshold(int t)
+{
+ Q_D(QQuickPointerHandler);
+ if (d->dragThreshold == t)
+ return;
+
+ if (t > std::numeric_limits<qint16>::max())
+ qWarning() << "drag threshold cannot exceed" << std::numeric_limits<qint16>::max();
+ d->dragThreshold = qint16(t);
+ emit dragThresholdChanged();
+}
+
+void QQuickPointerHandler::resetDragThreshold()
+{
+ Q_D(QQuickPointerHandler);
+ if (d->dragThreshold < 0)
+ return;
+
+ d->dragThreshold = -1;
+ emit dragThresholdChanged();
+}
+
+/*!
+ \since 5.15
+ \qmlproperty Qt::CursorShape PointerHandler::cursorShape
+ This property holds the cursor shape that will appear whenever the mouse is
+ hovering over the \l parentItem while \l active is \c true.
+
+ The available cursor shapes are:
+ \list
+ \li Qt.ArrowCursor
+ \li Qt.UpArrowCursor
+ \li Qt.CrossCursor
+ \li Qt.WaitCursor
+ \li Qt.IBeamCursor
+ \li Qt.SizeVerCursor
+ \li Qt.SizeHorCursor
+ \li Qt.SizeBDiagCursor
+ \li Qt.SizeFDiagCursor
+ \li Qt.SizeAllCursor
+ \li Qt.BlankCursor
+ \li Qt.SplitVCursor
+ \li Qt.SplitHCursor
+ \li Qt.PointingHandCursor
+ \li Qt.ForbiddenCursor
+ \li Qt.WhatsThisCursor
+ \li Qt.BusyCursor
+ \li Qt.OpenHandCursor
+ \li Qt.ClosedHandCursor
+ \li Qt.DragCopyCursor
+ \li Qt.DragMoveCursor
+ \li Qt.DragLinkCursor
+ \endlist
+
+ The default value is not set, which allows the \l {QQuickItem::cursor()}{cursor}
+ of \l parentItem to appear. This property can be reset to the same initial
+ condition by setting it to undefined.
+
+ \note When this property has not been set, or has been set to \c undefined,
+ if you read the value it will return \c Qt.ArrowCursor.
+
+ \sa Qt::CursorShape, QQuickItem::cursor(), HoverHandler::cursorShape
+*/
+#if QT_CONFIG(cursor)
+Qt::CursorShape QQuickPointerHandler::cursorShape() const
+{
+ Q_D(const QQuickPointerHandler);
+ return d->cursorShape;
+}
+
+void QQuickPointerHandler::setCursorShape(Qt::CursorShape shape)
+{
+ Q_D(QQuickPointerHandler);
+ if (d->cursorSet && shape == d->cursorShape)
+ return;
+ d->cursorShape = shape;
+ d->cursorSet = true;
+ QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem());
+ itemPriv->hasCursorHandler = true;
+ itemPriv->setHasCursorInChild(true);
+ emit cursorShapeChanged();
+}
+
+void QQuickPointerHandler::resetCursorShape()
+{
+ Q_D(QQuickPointerHandler);
+ if (!d->cursorSet)
+ return;
+ d->cursorShape = Qt::ArrowCursor;
+ d->cursorSet = false;
+ QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem());
+ itemPriv->hasCursorHandler = false;
+ itemPriv->setHasCursorInChild(itemPriv->hasCursor);
+ emit cursorShapeChanged();
+}
+
+bool QQuickPointerHandler::isCursorShapeExplicitlySet() const
+{
+ Q_D(const QQuickPointerHandler);
+ return d->cursorSet;
+}
+#endif
+
+/*!
Notification that the grab has changed in some way which is relevant to this handler.
The \a grabber (subject) will be the Input Handler whose state is changing,
or null if the state change regards an Item.
@@ -266,7 +387,7 @@ bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObjec
allowed = true;
}
}
- qCDebug(lcPointerHandlerGrab) << "point" << hex << point->pointId() << "permission" <<
+ qCDebug(lcPointerHandlerGrab) << "point" << Qt::hex << point->pointId() << "permission" <<
QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) <<
':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber;
return allowed;
@@ -490,7 +611,7 @@ bool QQuickPointerHandler::wantsPointerEvent(QQuickPointerEvent *event)
bool QQuickPointerHandler::wantsEventPoint(QQuickEventPoint *point)
{
bool ret = point->exclusiveGrabber() == this || point->passiveGrabbers().contains(this) || parentContains(point);
- qCDebug(lcPointerHandlerDispatch) << hex << point->pointId() << "@" << point->scenePosition()
+ qCDebug(lcPointerHandlerDispatch) << Qt::hex << point->pointId() << "@" << point->scenePosition()
<< metaObject()->className() << objectName() << ret;
return ret;
}
@@ -556,12 +677,42 @@ QQuickPointerHandlerPrivate::QQuickPointerHandlerPrivate()
: grabPermissions(QQuickPointerHandler::CanTakeOverFromItems |
QQuickPointerHandler::CanTakeOverFromHandlersOfDifferentType |
QQuickPointerHandler::ApprovesTakeOverByAnything)
+ , cursorShape(Qt::ArrowCursor)
, enabled(true)
, active(false)
, targetExplicitlySet(false)
, hadKeepMouseGrab(false)
, hadKeepTouchGrab(false)
+ , cursorSet(false)
+{
+}
+
+template <typename TEventPoint>
+bool QQuickPointerHandlerPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p) const
+{
+ Q_Q(const QQuickPointerHandler);
+ QStyleHints *styleHints = qApp->styleHints();
+ bool overThreshold = qAbs(d) > q->dragThreshold();
+ const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
+ if (!overThreshold && dragVelocityLimitAvailable) {
+ qreal velocity = qreal(axis == Qt::XAxis ? p->velocity().x() : p->velocity().y());
+ overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
+ }
+ return overThreshold;
+}
+
+bool QQuickPointerHandlerPrivate::dragOverThreshold(QVector2D delta) const
+{
+ Q_Q(const QQuickPointerHandler);
+ const float threshold = q->dragThreshold();
+ return qAbs(delta.x()) > threshold || qAbs(delta.y()) > threshold;
+}
+
+bool QQuickPointerHandlerPrivate::dragOverThreshold(const QQuickEventPoint *point) const
{
+ QPointF delta = point->scenePosition() - point->scenePressPosition();
+ return (dragOverThreshold(delta.x(), Qt::XAxis, point) ||
+ dragOverThreshold(delta.y(), Qt::YAxis, point));
}
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
index c600e42491..7262f4bcd3 100644
--- a/src/quick/handlers/qquickpointerhandler_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -71,6 +71,14 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlP
Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT)
Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged)
Q_PROPERTY(qreal margin READ margin WRITE setMargin NOTIFY marginChanged)
+ Q_PROPERTY(int dragThreshold READ dragThreshold WRITE setDragThreshold RESET resetDragThreshold NOTIFY dragThresholdChanged REVISION 15)
+#if QT_CONFIG(cursor)
+ Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape RESET resetCursorShape NOTIFY cursorShapeChanged REVISION 15)
+#endif
+
+ QML_NAMED_ELEMENT(PointerHandler)
+ QML_UNCREATABLE("PointerHandler is an abstract base class.")
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPointerHandler(QQuickItem *parent = nullptr);
@@ -110,14 +118,29 @@ public:
qreal margin() const;
void setMargin(qreal pointDistanceThreshold);
+ int dragThreshold() const;
+ void setDragThreshold(int t);
+ void resetDragThreshold();
+
+#if QT_CONFIG(cursor)
+ Qt::CursorShape cursorShape() const;
+ void setCursorShape(Qt::CursorShape shape);
+ void resetCursorShape();
+ bool isCursorShapeExplicitlySet() const;
+#endif
+
Q_SIGNALS:
void enabledChanged();
void activeChanged();
void targetChanged();
void marginChanged();
+ Q_REVISION(15) void dragThresholdChanged();
void grabChanged(QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point);
void grabPermissionChanged();
void canceled(QQuickEventPoint *point);
+#if QT_CONFIG(cursor)
+ Q_REVISION(15) void cursorShapeChanged();
+#endif
protected:
QQuickPointerHandler(QQuickPointerHandlerPrivate &dd, QQuickItem *parent);
diff --git a/src/quick/handlers/qquickpointerhandler_p_p.h b/src/quick/handlers/qquickpointerhandler_p_p.h
index 2ea4905643..db053fb6b4 100644
--- a/src/quick/handlers/qquickpointerhandler_p_p.h
+++ b/src/quick/handlers/qquickpointerhandler_p_p.h
@@ -68,15 +68,24 @@ public:
QQuickPointerHandlerPrivate();
+ template<typename TEventPoint>
+ bool dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p) const;
+
+ bool dragOverThreshold(QVector2D delta) const;
+ bool dragOverThreshold(const QQuickEventPoint *point) const;
+
QQuickPointerEvent *currentEvent = nullptr;
QQuickItem *target = nullptr;
qreal m_margin = 0;
+ qint16 dragThreshold = -1; // -1 means use the platform default
uint8_t grabPermissions : 8;
+ Qt::CursorShape cursorShape : 6;
bool enabled : 1;
bool active : 1;
bool targetExplicitlySet : 1;
bool hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state
bool hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state
+ bool cursorSet : 1;
};
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h
index c197cb4f20..42677540a7 100644
--- a/src/quick/handlers/qquickpointhandler_p.h
+++ b/src/quick/handlers/qquickpointhandler_p.h
@@ -59,6 +59,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointHandler : public QQuickSinglePointHandle
{
Q_OBJECT
Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
+ QML_NAMED_ELEMENT(PointHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
public:
explicit QQuickPointHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index 15fe0cc89e..b51f53b74f 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -95,7 +95,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
}
}
if (missing)
- qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << hex << d->pointInfo.id()
+ qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << Qt::hex << d->pointInfo.id()
<< "is missing from current event, but was neither canceled nor released";
if (point) {
if (candidatePointCount == 1 || (candidatePointCount > 1 && d->ignoreAdditionalPoints)) {
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index bfb3df7c6c..f3674d6fa9 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -97,13 +97,6 @@ QQuickTapHandler::QQuickTapHandler(QQuickItem *parent)
}
}
-static bool dragOverThreshold(const QQuickEventPoint *point)
-{
- QPointF delta = point->scenePosition() - point->scenePressPosition();
- return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
- QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
-}
-
bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
{
if (!point->pointerEvent()->asPointerMouseEvent() &&
@@ -115,7 +108,7 @@ bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
// (e.g. DragHandler) gets a chance to take over.
// Don't forget to emit released in case of a cancel.
bool ret = false;
- bool overThreshold = dragOverThreshold(point);
+ bool overThreshold = d_func()->dragOverThreshold(point);
if (overThreshold) {
m_longPressTimer.stop();
m_holdTimer.invalidate();
diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h
index 56e08590b2..07454bccb8 100644
--- a/src/quick/handlers/qquicktaphandler_p.h
+++ b/src/quick/handlers/qquicktaphandler_p.h
@@ -67,6 +67,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler
Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged)
Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged)
+ QML_NAMED_ELEMENT(TapHandler)
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum GesturePolicy {
DragThreshold,
diff --git a/src/quick/handlers/qquickwheelhandler_p.h b/src/quick/handlers/qquickwheelhandler_p.h
index f8d1c00726..26b052c5b3 100644
--- a/src/quick/handlers/qquickwheelhandler_p.h
+++ b/src/quick/handlers/qquickwheelhandler_p.h
@@ -72,6 +72,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWheelHandler : public QQuickSinglePointHandle
Q_PROPERTY(qreal targetScaleMultiplier READ targetScaleMultiplier WRITE setTargetScaleMultiplier NOTIFY targetScaleMultiplierChanged)
Q_PROPERTY(bool targetTransformAroundCursor READ isTargetTransformAroundCursor WRITE setTargetTransformAroundCursor NOTIFY targetTransformAroundCursorChanged)
+ QML_NAMED_ELEMENT(WheelHandler)
+ QML_ADDED_IN_MINOR_VERSION(14)
+
public:
explicit QQuickWheelHandler(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index b8e6d58af4..bfee190baf 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -1019,8 +1019,6 @@ QQmlRefPointer<QQuickCanvasPixmap> QQuickCanvasItem::loadedPixmap(const QUrl& ur
This signal is emitted when an image has been loaded.
- The corresponding handler is \c onImageLoaded.
-
\sa loadImage()
*/
@@ -1244,8 +1242,6 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize)
This signal can be triggered by markdirty(), requestPaint() or by changing
the current canvas window.
-
- The corresponding handler is \c onPaint.
*/
/*!
@@ -1253,8 +1249,6 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize)
This signal is emitted after all context painting commands are executed and
the Canvas has been rendered.
-
- The corresponding handler is \c onPainted.
*/
QT_END_NAMESPACE
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index cd2977429b..6575caf806 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -99,6 +99,7 @@ class QQuickCanvasItem : public QQuickItem
Q_PROPERTY(QRectF canvasWindow READ canvasWindow WRITE setCanvasWindow NOTIFY canvasWindowChanged)
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
Q_PROPERTY(RenderStrategy renderStrategy READ renderStrategy WRITE setRenderStrategy NOTIFY renderStrategyChanged)
+ QML_NAMED_ELEMENT(Canvas)
public:
enum RenderTarget {
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index 2da01e9151..ae23c4c07e 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -273,71 +273,51 @@ QT_BEGIN_NAMESPACE
\qmlsignal QtQuick::Accessible::pressAction()
This signal is emitted when a press action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onPressAction.
*/
/*!
\qmlsignal QtQuick::Accessible::toggleAction()
This signal is emitted when a toggle action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onToggleAction.
*/
/*!
\qmlsignal QtQuick::Accessible::increaseAction()
This signal is emitted when a increase action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onIncreaseAction.
*/
/*!
\qmlsignal QtQuick::Accessible::decreaseAction()
This signal is emitted when a decrease action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onDecreaseAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollUpAction()
This signal is emitted when a scroll up action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollUpAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollDownAction()
This signal is emitted when a scroll down action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollDownAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollLeftAction()
This signal is emitted when a scroll left action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollLeftAction.
*/
/*!
\qmlsignal QtQuick::Accessible::scrollRightAction()
This signal is emitted when a scroll right action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onScrollRightAction.
*/
/*!
\qmlsignal QtQuick::Accessible::previousPageAction()
This signal is emitted when a previous page action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onPreviousPageAction.
*/
/*!
\qmlsignal QtQuick::Accessible::nextPageAction()
This signal is emitted when a next page action is received from an assistive tool such as a screen-reader.
-
- The corresponding handler is \c onNextPageAction.
*/
QMetaMethod QQuickAccessibleAttached::sigPress;
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 87fb79ecc9..b7254d6686 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -90,6 +90,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged FINAL)
+ QML_NAMED_ELEMENT(Accessible)
+ QML_UNCREATABLE("Accessible is only available via attached properties.")
+ QML_ATTACHED(QQuickAccessibleAttached)
+
public:
Q_ENUMS(QAccessible::Role QAccessible::Event)
STATE_PROPERTY(checkable)
@@ -242,7 +246,6 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickAccessibleAttached)
-QML_DECLARE_TYPEINFO(QQuickAccessibleAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // accessibility
diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h
index c7995cb7a8..e0276549e9 100644
--- a/src/quick/items/qquickanchors_p.h
+++ b/src/quick/items/qquickanchors_p.h
@@ -84,6 +84,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnchors : public QObject
Q_PROPERTY(QQuickItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged)
Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
Q_PROPERTY(bool alignWhenCentered READ alignWhenCentered WRITE setAlignWhenCentered NOTIFY centerAlignedChanged)
+ QML_ANONYMOUS
public:
QQuickAnchors(QQuickItem *item, QObject *parent=nullptr);
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 18d492cd68..192ed289e2 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
.arg(current));
}
if (!requestedUrl.isEmpty()) {
- if (QQuickPixmap::isCached(requestedUrl, QSize(), 0, QQuickImageProviderOptions()))
+ if (QQuickPixmap::isCached(requestedUrl, QRect(), QSize(), 0, QQuickImageProviderOptions()))
pixmap = new QQuickPixmap(engine, requestedUrl);
else
pixmap = new QQuickPixmap(requestedUrl, movie->currentImage());
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index 13eae83350..7f2199fd2a 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage
// read-only for AnimatedImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+ QML_NAMED_ELEMENT(AnimatedImage)
public:
QQuickAnimatedImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index d22e77c8ad..b285fe56ed 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -263,6 +263,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \qmlproperty enumeration QtQuick::AnimatedSprite::finishBehavior
+
+ The behavior when the animation finishes on its own.
+
+ \value FinishAtInitialFrame
+ When the animation finishes it returns to the initial frame.
+ This is the default behavior.
+
+ \value FinishAtFinalFrame
+ When the animation finishes it stays on the final frame.
+*/
+
+/*!
\qmlmethod int QtQuick::AnimatedSprite::restart()
Stops, then starts the sprite animation.
@@ -381,6 +394,12 @@ int QQuickAnimatedSprite::currentFrame() const
return d->m_curFrame;
}
+QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior() const
+{
+ Q_D(const QQuickAnimatedSprite);
+ return d->m_finishBehavior;
+}
+
bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
{
IS_SIGNAL_CONNECTED(this, QQuickAnimatedSprite, currentFrameChanged, (int));
@@ -395,20 +414,34 @@ void QQuickAnimatedSprite::reloadImage()
void QQuickAnimatedSprite::componentComplete()
{
- Q_D(const QQuickAnimatedSprite);
+ Q_D(QQuickAnimatedSprite);
createEngine();
QQuickItem::componentComplete();
- if (d->m_running)
+ if (d->m_running) {
+ d->m_running = false;
start();
+ }
}
+/*!
+ \qmlmethod QtQuick::AnimatedSprite::start()
+ \since 5.15
+
+ Starts the sprite animation. If the animation is already running, calling
+ this method has no effect.
+
+ \sa stop()
+*/
void QQuickAnimatedSprite::start()
{
Q_D(QQuickAnimatedSprite);
+ if (d->m_running)
+ return;
d->m_running = true;
if (!isComponentComplete())
return;
d->m_curLoop = 0;
+ d->m_curFrame = 0;
d->m_timestamp.start();
if (d->m_spriteEngine) {
d->m_spriteEngine->stop(0);
@@ -420,9 +453,20 @@ void QQuickAnimatedSprite::start()
maybeUpdate();
}
+/*!
+ \qmlmethod QtQuick::AnimatedSprite::stop()
+ \since 5.15
+
+ Stops the sprite animation. If the animation is not running, calling this
+ method has no effect.
+
+ \sa start()
+*/
void QQuickAnimatedSprite::stop()
{
Q_D(QQuickAnimatedSprite);
+ if (!d->m_running)
+ return;
d->m_running = false;
if (!isComponentComplete())
return;
@@ -679,6 +723,16 @@ void QQuickAnimatedSprite::setCurrentFrame(int arg) //TODO-C: Probably only work
}
}
+void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
+{
+ Q_D(QQuickAnimatedSprite);
+
+ if (d->m_finishBehavior != arg) {
+ d->m_finishBehavior = arg;
+ Q_EMIT finishBehaviorChanged(arg);
+ }
+}
+
void QQuickAnimatedSprite::createEngine()
{
Q_D(QQuickAnimatedSprite);
@@ -813,7 +867,11 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
progress = 0;
}
if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
- frameAt = 0;
+ if (d->m_finishBehavior == FinishAtInitialFrame)
+ frameAt = 0;
+ else
+ frameAt = frameCount() - 1;
+ d->m_curFrame = frameAt;
d->m_running = false;
emit runningChanged(false);
emit finished();
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index d36f908c78..546598a409 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -92,6 +92,8 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
+ Q_PROPERTY(FinishBehavior finishBehavior READ finishBehavior WRITE setFinishBehavior NOTIFY finishBehaviorChanged REVISION 15)
+ QML_NAMED_ELEMENT(AnimatedSprite)
public:
explicit QQuickAnimatedSprite(QQuickItem *parent = nullptr);
@@ -100,6 +102,12 @@ public:
};
Q_ENUM(LoopParameters)
+ enum FinishBehavior {
+ FinishAtInitialFrame,
+ FinishAtFinalFrame
+ };
+ Q_ENUM(FinishBehavior)
+
bool running() const;
bool interpolate() const;
QUrl source() const;
@@ -115,6 +123,8 @@ public:
int loops() const;
bool paused() const;
int currentFrame() const;
+ FinishBehavior finishBehavior() const;
+ void setFinishBehavior(FinishBehavior arg);
Q_SIGNALS:
@@ -134,6 +144,7 @@ Q_SIGNALS:
void frameDurationChanged(int arg);
void loopsChanged(int arg);
void currentFrameChanged(int arg);
+ Q_REVISION(15) void finishBehaviorChanged(FinishBehavior arg);
Q_REVISION(12) void finished();
@@ -163,7 +174,6 @@ public Q_SLOTS:
void setLoops(int arg);
void setCurrentFrame(int arg);
-
private Q_SLOTS:
void createEngine();
diff --git a/src/quick/items/qquickanimatedsprite_p_p.h b/src/quick/items/qquickanimatedsprite_p_p.h
index 3610e58861..fb8faefbee 100644
--- a/src/quick/items/qquickanimatedsprite_p_p.h
+++ b/src/quick/items/qquickanimatedsprite_p_p.h
@@ -57,11 +57,10 @@ QT_REQUIRE_CONFIG(quick_sprite);
#include "qquickitem_p.h"
#include "qquicksprite_p.h"
+#include "qquickanimatedsprite_p.h"
QT_BEGIN_NAMESPACE
-class QQuickAnimatedSprite;
-
class QQuickAnimatedSpritePrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickAnimatedSprite)
@@ -78,6 +77,7 @@ public:
, m_loops(-1)
, m_curLoop(0)
, m_pauseOffset(0)
+ , m_finishBehavior(QQuickAnimatedSprite::FinishAtInitialFrame)
{
}
@@ -93,6 +93,7 @@ public:
int m_loops;
int m_curLoop;
int m_pauseOffset;
+ QQuickAnimatedSprite::FinishBehavior m_finishBehavior;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 462a44634e..3679df37d1 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -168,6 +168,7 @@ QT_BEGIN_NAMESPACE
QQuickBorderImage::QQuickBorderImage(QQuickItem *parent)
: QQuickImageBase(*(new QQuickBorderImagePrivate), parent)
{
+ connect(this, &QQuickImageBase::sourceSizeChanged, this, &QQuickBorderImage::sourceSizeChanged);
}
QQuickBorderImage::~QQuickBorderImage()
@@ -295,20 +296,7 @@ void QQuickBorderImage::load()
Q_D(QQuickBorderImage);
if (d->url.isEmpty()) {
- d->pix.clear(this);
- d->status = Null;
- setImplicitSize(0, 0);
- emit statusChanged(d->status);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (sourceSize() != d->oldSourceSize) {
- d->oldSourceSize = sourceSize();
- emit sourceSizeChanged();
- }
- pixmapChange();
- return;
+ loadEmptyUrl();
} else {
if (d->url.path().endsWith(QLatin1String("sci"))) {
QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
@@ -316,7 +304,6 @@ void QQuickBorderImage::load()
QFile file(lf);
file.open(QIODevice::ReadOnly);
setGridScaledImage(QQuickGridScaledImage(&file));
- return;
} else {
#if QT_CONFIG(qml_network)
if (d->progress != 0.0) {
@@ -328,50 +315,13 @@ void QQuickBorderImage::load()
d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
this, QQuickBorderImage, SLOT(sciRequestFinished()));
+ emit statusChanged(d->status);
#endif
}
} else {
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
-
- const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qGuiApp->devicePixelRatio());
- d->devicePixelRatio = 1.0;
-
- QUrl loadUrl = d->url;
- resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- d->status = Loading;
-
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
- }
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
-
- update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
- } else {
- requestFinished();
- return;
- }
+ loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
}
}
-
- emit statusChanged(d->status);
}
/*!
@@ -472,39 +422,7 @@ void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
d->verticalTileMode = sci.verticalTileRule();
d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
-
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
- d->pix.load(qmlEngine(this), d->sciurl, options);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (d->status != Loading) {
- d->status = Loading;
- emit statusChanged(d->status);
- }
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
- }
-
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
-
- } else {
- requestFinished();
- }
+ loadPixmap(d->sciurl);
}
}
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 61bd26ba83..515edb33da 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
// read-only for BorderImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+ QML_NAMED_ELEMENT(BorderImage)
public:
QQuickBorderImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 7c6f1caa54..32695e9245 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickDragAttached)
+ QML_ANONYMOUS
+
public:
static QQuickDragAttachedPrivate *get(QQuickDragAttached *attached) {
return static_cast<QQuickDragAttachedPrivate *>(QObjectPrivate::get(attached)); }
@@ -742,8 +744,6 @@ void QQuickDragAttached::cancel()
This signal is emitted when a drag is started with the \l startDrag() method
or when it is started automatically using the \l dragType property.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -754,8 +754,6 @@ void QQuickDragAttached::cancel()
\a dropAction holds the action accepted by the target item.
- The corresponding handler is \c onDragFinished.
-
\sa drop()
*/
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 094070aa2c..9dbaac18f9 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -172,6 +172,10 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold)
//### consider drag and drop
+ QML_NAMED_ELEMENT(Drag)
+ QML_UNCREATABLE("Drag is only available via attached properties.")
+ QML_ATTACHED(QQuickDragAttached)
+
public:
QQuickDrag(QObject *parent=nullptr);
~QQuickDrag();
@@ -254,6 +258,9 @@ class QQuickDragAttached : public QObject
Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged)
Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction WRITE setProposedAction NOTIFY proposedActionChanged)
Q_PROPERTY(QQuickDrag::DragType dragType READ dragType WRITE setDragType NOTIFY dragTypeChanged)
+
+ QML_ANONYMOUS
+
public:
QQuickDragAttached(QObject *parent);
~QQuickDragAttached();
@@ -316,6 +323,5 @@ Q_SIGNALS:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickDrag)
-QML_DECLARE_TYPEINFO(QQuickDrag, QML_HAS_ATTACHED_PROPERTIES)
#endif
diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp
index 76be8cc261..d90ee209d6 100644
--- a/src/quick/items/qquickdroparea.cpp
+++ b/src/quick/items/qquickdroparea.cpp
@@ -212,8 +212,6 @@ qreal QQuickDropAreaDrag::y() const
\qmlsignal QtQuick::DropArea::positionChanged(DragEvent drag)
This signal is emitted when the position of a \a drag has changed.
-
- The corresponding handler is \c onPositionChanged.
*/
void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
@@ -254,8 +252,6 @@ QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
\qmlsignal QtQuick::DropArea::entered(DragEvent drag)
This signal is emitted when a \a drag enters the bounds of a DropArea.
-
- The corresponding handler is \c onEntered.
*/
void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
@@ -291,8 +287,6 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
\qmlsignal QtQuick::DropArea::exited()
This signal is emitted when a drag exits the bounds of a DropArea.
-
- The corresponding handler is \c onExited.
*/
void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
@@ -315,8 +309,6 @@ void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
This signal is emitted when a \a drop event occurs within the bounds of
a DropArea.
-
- The corresponding handler is \c onDropped.
*/
void QQuickDropArea::dropEvent(QDropEvent *event)
diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h
index 2b2ace2eae..ee2deaa97a 100644
--- a/src/quick/items/qquickdroparea_p.h
+++ b/src/quick/items/qquickdroparea_p.h
@@ -80,6 +80,7 @@ class QQuickDropEvent : public QObject
Q_PROPERTY(QString text READ text)
Q_PROPERTY(QList<QUrl> urls READ urls)
Q_PROPERTY(QStringList formats READ formats)
+ QML_ANONYMOUS
public:
QQuickDropEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {}
@@ -125,6 +126,7 @@ class QQuickDropAreaDrag : public QObject
Q_PROPERTY(qreal x READ x NOTIFY positionChanged)
Q_PROPERTY(qreal y READ y NOTIFY positionChanged)
Q_PROPERTY(QObject *source READ source NOTIFY sourceChanged)
+ QML_ANONYMOUS
public:
QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent = 0);
~QQuickDropAreaDrag();
@@ -151,6 +153,7 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem
Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
Q_PROPERTY(QQuickDropAreaDrag *drag READ drag CONSTANT)
+ QML_NAMED_ELEMENT(DropArea)
public:
QQuickDropArea(QQuickItem *parent=0);
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index b5644d55e6..eddd15c6da 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -597,8 +597,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(ConstructableQQuickPointerDevice, g_genericMouseDevice
QQuickPointerDevice::Position | QQuickPointerDevice::Scroll | QQuickPointerDevice::Hover,
1, 3, QLatin1String("core pointer"), 0))
+#if QT_CONFIG(tabletevent)
typedef QHash<qint64, QQuickPointerDevice *> PointerDeviceForDeviceIdHash;
Q_GLOBAL_STATIC(PointerDeviceForDeviceIdHash, g_tabletDevices)
+#endif
// debugging helpers
static const char *pointStateString(const QQuickEventPoint *point)
@@ -658,15 +660,76 @@ QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
return g_genericMouseDevice;
}
-QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
+#if QT_CONFIG(tabletevent)
+QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
{
- auto it = g_tabletDevices->find(id);
+ // QTabletEvent::uniqueId() is the same for the pointy end and the eraser end of the stylus.
+ // We need to make those unique. QTabletEvent::PointerType only needs 2 bits' worth of storage.
+ // The key into g_tabletDevices just needs to be unique; we don't need to extract uniqueId
+ // back out of it, because QQuickPointerDevice stores that separately anyway.
+ // So the shift-and-add can be thought of as a sort of hash function, even though
+ // most of the time the result will be recognizable because the uniqueId MSBs are often 0.
+ qint64 key = event->uniqueId() + (qint64(event->pointerType()) << 60);
+ auto it = g_tabletDevices->find(key);
if (it != g_tabletDevices->end())
return it.value();
- // ### Figure out how to populate the tablet devices
- return nullptr;
+ DeviceType type = UnknownDevice;
+ int buttonCount = 0;
+ Capabilities caps = Position | Pressure | Hover;
+ // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a
+ // QTabletDevice populated with capabilities provided by QPA plugins
+
+ switch (event->deviceType()) {
+ case QTabletEvent::Stylus:
+ type = QQuickPointerDevice::Stylus;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::RotationStylus:
+ type = QQuickPointerDevice::Stylus;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 1;
+ break;
+ case QTabletEvent::Airbrush:
+ type = QQuickPointerDevice::Airbrush;
+ buttonCount = 2;
+ break;
+ case QTabletEvent::Puck:
+ type = QQuickPointerDevice::Puck;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::FourDMouse:
+ type = QQuickPointerDevice::Mouse;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 3;
+ break;
+ default:
+ type = QQuickPointerDevice::UnknownDevice;
+ break;
+ }
+
+ PointerType ptype = GenericPointer;
+ switch (event->pointerType()) {
+ case QTabletEvent::Pen:
+ ptype = Pen;
+ break;
+ case QTabletEvent::Eraser:
+ ptype = Eraser;
+ break;
+ case QTabletEvent::Cursor:
+ ptype = Cursor;
+ break;
+ case QTabletEvent::UnknownPointer:
+ break;
+ }
+
+ QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
+ QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());
+
+ g_tabletDevices->insert(key, device);
+ return device;
}
+#endif
/*!
\qmltype EventPoint
@@ -852,7 +915,7 @@ void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
if (oldGrabberHandler && !oldGrabberHandler->approveGrabTransition(this, grabber))
return;
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this) << "@" << m_scenePos
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this) << "@" << m_scenePos
<< ": grab" << m_exclusiveGrabber << "->" << grabber;
}
QQuickItem *oldGrabberItem = grabberItem();
@@ -893,10 +956,10 @@ void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, b
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
if (exclusive) {
if (m_exclusiveGrabber != grabber)
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (exclusive)" << m_exclusiveGrabber << "->" << grabber;
} else {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (passive)" << grabber;
}
}
@@ -959,7 +1022,7 @@ void QQuickEventPoint::cancelExclusiveGrabImpl(QTouchEvent *cancelEvent)
if (m_exclusiveGrabber.isNull())
return;
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (exclusive)" << m_exclusiveGrabber << "-> nullptr";
}
if (auto handler = grabberPointerHandler()) {
@@ -982,7 +1045,7 @@ void QQuickEventPoint::cancelPassiveGrab(QQuickPointerHandler *handler)
{
if (removePassiveGrabber(handler)) {
if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
- qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << Qt::hex << m_pointId << pointStateString(this)
<< ": grab (passive)" << handler << "removed";
}
handler->onGrabChanged(handler, CancelGrabPassive, this);
@@ -1284,6 +1347,12 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
QQuickPointerEvent::~QQuickPointerEvent()
{}
+QQuickPointerMouseEvent::QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
{
auto ev = static_cast<QMouseEvent*>(event);
@@ -1398,6 +1467,12 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
}
#if QT_CONFIG(gestures)
+QQuickPointerNativeGestureEvent::QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
auto ev = static_cast<QNativeGestureEvent*>(event);
@@ -1560,6 +1635,12 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
\note Many platforms provide no such information. On such platforms,
\c inverted always returns false.
*/
+QQuickPointerScrollEvent::QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
@@ -1626,6 +1707,8 @@ bool QQuickSinglePointEvent::allPointsGrabbed() const
QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) const
{
+ if (!m_event)
+ return nullptr;
auto event = static_cast<QMouseEvent *>(m_event);
event->setLocalPos(localPos);
return event;
@@ -1830,6 +1913,81 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
return &m_synthMouseEvent;
}
+#if QT_CONFIG(tabletevent)
+QQuickPointerTabletEvent::QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventTabletPoint(this);
+}
+
+QQuickPointerEvent *QQuickPointerTabletEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QTabletEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ Q_ASSERT(m_device == QQuickPointerDevice::tabletDevice(ev));
+ m_device->eventDeliveryTargets().clear();
+ m_button = ev->button();
+ m_pressedButtons = ev->buttons();
+ static_cast<QQuickEventTabletPoint *>(m_point)->reset(ev);
+ return this;
+}
+
+QQuickEventTabletPoint::QQuickEventTabletPoint(QQuickPointerTabletEvent *parent)
+ : QQuickEventPoint(parent)
+{
+}
+
+void QQuickEventTabletPoint::reset(const QTabletEvent *ev)
+{
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (ev->type()) {
+ case QEvent::TabletPress:
+ state = Qt::TouchPointPressed;
+ clearPassiveGrabbers();
+ break;
+ case QEvent::TabletRelease:
+ state = Qt::TouchPointReleased;
+ break;
+ case QEvent::TabletMove:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ break;
+ }
+ QQuickEventPoint::reset(state, ev->posF(), 1, ev->timestamp());
+ m_rotation = ev->rotation();
+ m_pressure = ev->pressure();
+ m_tangentialPressure = ev->tangentialPressure();
+ m_tilt = QVector2D(ev->xTilt(), ev->yTilt());
+}
+
+bool QQuickPointerTabletEvent::isPressEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletPress;
+}
+
+bool QQuickPointerTabletEvent::isUpdateEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletMove;
+}
+
+bool QQuickPointerTabletEvent::isReleaseEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletRelease;
+}
+
+QTabletEvent *QQuickPointerTabletEvent::asTabletEvent() const
+{
+ return static_cast<QTabletEvent *>(m_event);
+}
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::isPressEvent() const
{
@@ -1998,7 +2156,7 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
tpCopy.setPos(item->mapFromScene(tpCopy.scenePos()));
tpCopy.setLastPos(item->mapFromScene(tpCopy.lastScenePos()));
tpCopy.setStartPos(item->mapFromScene(tpCopy.startScenePos()));
- tpCopy.setRect(item->mapRectFromScene(tpCopy.sceneRect()));
+ tpCopy.setEllipseDiameters(tpCopy.ellipseDiameters());
tpCopy.setVelocity(transformMatrix.mapVector(tpCopy.velocity()).toVector2D());
touchPoints << tpCopy;
}
@@ -2102,7 +2260,7 @@ Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickEventPoint *eve
dbg << "QQuickEventPoint(accepted:" << event->isAccepted()
<< " state:";
QtDebugUtils::formatQEnum(dbg, event->state());
- dbg << " scenePos:" << event->scenePosition() << " id:" << hex << event->pointId() << dec
+ dbg << " scenePos:" << event->scenePosition() << " id:" << Qt::hex << event->pointId() << Qt::dec
<< " timeHeld:" << event->timeHeld() << ')';
return dbg;
}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 1a3737091f..7004b341de 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -58,7 +58,9 @@
#include <QtCore/qpointer.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qevent.h>
-#include <QtGui/qkeysequence.h>
+#if QT_CONFIG(shortcut)
+# include <QtGui/qkeysequence.h>
+#endif
#include <QtQuick/qquickitem.h>
QT_BEGIN_NAMESPACE
@@ -84,10 +86,11 @@ class QQuickKeyEvent : public QObject
Q_PROPERTY(int count READ count CONSTANT)
Q_PROPERTY(quint32 nativeScanCode READ nativeScanCode CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickKeyEvent()
- : event(QEvent::None, 0, nullptr)
+ : event(QEvent::None, 0, { })
{}
void reset(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
@@ -135,17 +138,17 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject
Q_PROPERTY(bool isClick READ isClick CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_PROPERTY(int flags READ flags CONSTANT REVISION 11)
+ QML_ANONYMOUS
public:
QQuickMouseEvent()
: _buttons(Qt::NoButton), _modifiers(Qt::NoModifier)
, _wasHeld(false), _isClick(false), _accepted(false)
- , _flags(Qt::MouseEventFlags(nullptr))
{}
void reset(qreal x, qreal y, Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false,
- Qt::MouseEventFlags flags = nullptr)
+ Qt::MouseEventFlags flags = { })
{
_x = x;
_y = y;
@@ -201,6 +204,7 @@ class QQuickWheelEvent : public QObject
Q_PROPERTY(int modifiers READ modifiers CONSTANT)
Q_PROPERTY(bool inverted READ inverted CONSTANT)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickWheelEvent()
@@ -245,6 +249,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCloseEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickCloseEvent() {}
@@ -271,6 +276,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
Q_PROPERTY(QObject *exclusiveGrabber READ exclusiveGrabber WRITE setExclusiveGrabber)
+ QML_NAMED_ELEMENT(EventPoint)
+ QML_UNCREATABLE("EventPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum State {
Pressed = Qt::TouchPointPressed,
@@ -362,6 +371,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint
Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
+ QML_NAMED_ELEMENT(EventTouchPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickEventTouchPoint(QQuickPointerTouchEvent *parent);
@@ -391,6 +404,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject
Q_PROPERTY(Qt::MouseButtons button READ button CONSTANT)
Q_PROPERTY(Qt::MouseButtons buttons READ buttons CONSTANT)
+ QML_NAMED_ELEMENT(PointerEvent)
+ QML_UNCREATABLE("PointerEvent is only available as a parameter of several signals in PointerHandler")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickPointerEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
: QObject(parent)
@@ -459,8 +476,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointEvent : public QQuickPointerEvent
{
Q_OBJECT
public:
- QQuickSinglePointEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickPointerEvent(parent, device), m_point(new QQuickEventPoint(this)) { }
+ QQuickSinglePointEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickPointerEvent(parent, device) { }
void localize(QQuickItem *target) override;
int pointCount() const override { return 1; }
@@ -474,7 +491,7 @@ public:
bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
protected:
- QQuickEventPoint *m_point;
+ QQuickEventPoint *m_point = nullptr;
Q_DISABLE_COPY(QQuickSinglePointEvent)
};
@@ -482,9 +499,13 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointEvent
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(PointerMouseEvent)
+ QML_UNCREATABLE("PointerMouseEvent is only available as a parameter of several signals in PointerHandler")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
- QQuickPointerMouseEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -502,6 +523,11 @@ public:
class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(PointerTouchEvent)
+ QML_UNCREATABLE("PointerTouchEvent is only available as a parameter of several signals in PointerHandler")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
QQuickPointerTouchEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
: QQuickPointerEvent(parent, device)
@@ -541,6 +567,60 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+#if QT_CONFIG(tabletevent)
+class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(qreal tangentialPressure READ tangentialPressure)
+ Q_PROPERTY(QVector2D tilt READ tilt)
+
+ QML_NAMED_ELEMENT(EventTabletPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(15)
+
+public:
+ QQuickEventTabletPoint(QQuickPointerTabletEvent *parent);
+
+ void reset(const QTabletEvent *e);
+
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ qreal tangentialPressure() const { return m_tangentialPressure; }
+ QVector2D tilt() const { return m_tilt; }
+
+private:
+ qreal m_rotation;
+ qreal m_pressure;
+ qreal m_tangentialPressure;
+ QVector2D m_tilt;
+
+ friend class QQuickPointerTouchEvent;
+
+ Q_DISABLE_COPY(QQuickEventTabletPoint)
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerTabletEvent : public QQuickSinglePointEvent
+{
+ Q_OBJECT
+public:
+ QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device);
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerTabletEvent *asPointerTabletEvent() override { return this; }
+ const QQuickPointerTabletEvent *asPointerTabletEvent() const override { return this; }
+ const QQuickEventTabletPoint *tabletPoint() const { return static_cast<QQuickEventTabletPoint *>(m_point); }
+
+ QTabletEvent *asTabletEvent() const;
+
+ Q_DISABLE_COPY(QQuickPointerTabletEvent)
+};
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSinglePointEvent
{
@@ -549,8 +629,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSing
Q_PROPERTY(qreal value READ value CONSTANT)
public:
- QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -574,9 +653,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
Q_PROPERTY(bool hasPixelDelta READ hasPixelDelta CONSTANT)
Q_PROPERTY(bool inverted READ isInverted CONSTANT)
+ QML_NAMED_ELEMENT(PointerScrollEvent)
+ QML_UNCREATABLE("PointerScrollEvent is only available via the WheelHandler::wheel signal.")
+ QML_ADDED_IN_MINOR_VERSION(14)
+
public:
- QQuickPointerScrollEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
void localize(QQuickItem *target) override;
@@ -623,6 +705,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT)
+ QML_NAMED_ELEMENT(PointerDevice)
+ QML_UNCREATABLE("PointerDevice is only available as a property of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(12)
+
public:
enum DeviceType : qint16 {
UnknownDevice = 0x0000,
@@ -677,7 +763,9 @@ public:
static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
- static QQuickPointerDevice *tabletDevice(qint64);
+#if QT_CONFIG(tabletevent)
+ static QQuickPointerDevice *tabletDevice(const QTabletEvent *event);
+#endif
QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 445fa0215b..c91a5ef92b 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -327,7 +327,7 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr
{
Q_Q(QQuickFlickable);
if (item == contentItem) {
- Qt::Orientations orient = nullptr;
+ Qt::Orientations orient;
if (change.xChange())
orient |= Qt::Horizontal;
if (change.yChange())
@@ -591,8 +591,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view starts to be dragged due to user
interaction.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -602,8 +600,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
If the velocity of the drag is sufficient at the time the
touch/mouse button is released then a flick will start.
-
- The corresponding handler is \c onDragEnded.
*/
/*!
@@ -689,8 +685,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view begins moving due to user
interaction or a generated flick().
-
- The corresponding handler is \c onMovementStarted.
*/
/*!
@@ -701,8 +695,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
be emitted once the flick stops. If a flick was not
active, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
-
- The corresponding handler is \c onMovementEnded.
*/
/*!
@@ -711,16 +703,12 @@ void QQuickFlickablePrivate::updateBeginningEnd()
This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
-
- The corresponding handler is \c onFlickStarted.
*/
/*!
\qmlsignal QtQuick::Flickable::flickEnded()
This signal is emitted when the view stops moving due to a flick.
-
- The corresponding handler is \c onFlickEnded.
*/
/*!
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index c54ed5ce71..2d8d4a5e9a 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -114,6 +114,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(QQmlListProperty<QObject> flickableData READ flickableData)
Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren)
Q_CLASSINFO("DefaultProperty", "flickableData")
+ QML_NAMED_ELEMENT(Flickable)
public:
QQuickFlickable(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 835c54170f..3f5f11effd 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -73,7 +73,7 @@ class QQuickFlickableVisibleArea;
class QQuickTransition;
class QQuickFlickableReboundTransition;
-class Q_AUTOTEST_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickFlickable)
@@ -284,6 +284,7 @@ class QQuickFlickableVisibleArea : public QObject
Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
+ QML_ANONYMOUS
public:
QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr);
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index d70cd02d35..42c632a33c 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem
Q_PROPERTY(QQuickItem *front READ front WRITE setFront NOTIFY frontChanged)
Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged)
Q_PROPERTY(Side side READ side NOTIFY sideChanged)
+ QML_NAMED_ELEMENT(Flipable)
//### flipAxis
//### flipRotation
public:
diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h
index af750fc127..c32fa93cd9 100644
--- a/src/quick/items/qquickfocusscope_p.h
+++ b/src/quick/items/qquickfocusscope_p.h
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem
{
Q_OBJECT
+ QML_NAMED_ELEMENT(FocusScope)
public:
QQuickFocusScope(QQuickItem *parent=nullptr);
virtual ~QQuickFocusScope();
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 190bc6853c..d5550e78b6 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -83,6 +83,11 @@ public:
* Everything that relates to rendering must be located in the
* QQuickFramebufferObject::Renderer class.
*
+ * \warning This class is only functional when Qt Quick is rendering
+ * via OpenGL, either directly or through the \l{Scene Graph
+ * Adaptations}{RHI-based rendering path}. It is not compatible with
+ * other RHI backends, such as, Vulkan or Metal.
+ *
* To avoid race conditions and read/write issues from two threads
* it is important that the renderer and the item never read or
* write shared variables. Communication between the item and the renderer
@@ -109,10 +114,6 @@ public:
* and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
* classes that consume texture providers.
*
- * \warning This class is only suitable when working directly with OpenGL. It
- * is not compatible with the \l{Scene Graph Adaptations}{RHI-based rendering
- * path}.
- *
* \sa {Scene Graph - Rendering FBOs}, {Scene Graph and Rendering}
*/
@@ -233,6 +234,13 @@ public Q_SLOTS:
{
if (renderPending) {
renderPending = false;
+
+ const bool needsWrap = QSGRendererInterface::isApiRhiBased(window->rendererInterface()->graphicsApi());
+ if (needsWrap) {
+ window->beginExternalCommands();
+ window->resetOpenGLState();
+ }
+
fbo->bind();
QOpenGLContext::currentContext()->functions()->glViewport(0, 0, fbo->width(), fbo->height());
renderer->render();
@@ -241,6 +249,9 @@ public Q_SLOTS:
if (msDisplayFbo)
QOpenGLFramebufferObject::blitFramebuffer(msDisplayFbo, fbo);
+ if (needsWrap)
+ window->endExternalCommands();
+
markDirty(QSGNode::DirtyMaterial);
emit textureChanged();
}
@@ -270,7 +281,8 @@ public:
static inline bool isOpenGL(QSGRenderContext *rc)
{
QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
- return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL;
+ return rif && (rif->graphicsApi() == QSGRendererInterface::OpenGL
+ || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi);
}
/*!
@@ -335,9 +347,11 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode
displayTexture = n->msDisplayFbo->texture();
}
- n->setTexture(window()->createTextureFromId(displayTexture,
- n->fbo->size(),
- QQuickWindow::TextureHasAlphaChannel));
+ QSGTexture *wrapper = window()->createTextureFromNativeObject(QQuickWindow::NativeObjectTexture,
+ &displayTexture, 0,
+ n->fbo->size(),
+ QQuickWindow::TextureHasAlphaChannel);
+ n->setTexture(wrapper);
}
n->setTextureCoordinatesTransform(d->mirrorVertically ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform);
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index db143e48cf..e26c8293a6 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -48,7 +48,8 @@ class QOpenGLFramebufferObject;
class QQuickFramebufferObjectPrivate;
class QSGFramebufferObjectNode;
-// ### Qt 6: To be removed. To be seen if an alternative will need to be introduced.
+// ### Qt 6: Consider what to do here. QQuickFbo supports both direct OpenGL and
+// OpenGL via QRhi, but it cannot function when running with another rhi backend.
class Q_QUICK_EXPORT QQuickFramebufferObject : public QQuickItem
{
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index df61ee853d..a3d04f5dd3 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -78,7 +78,6 @@ QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, Q
, m_mgr(nullptr)
, m_fragNeedsUpdate(true)
, m_vertNeedsUpdate(true)
- , m_dirty(nullptr)
{
qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type");
for (int i = 0; i < NShader; ++i)
@@ -311,7 +310,7 @@ QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQui
m_dirty &= ~QSGShaderEffectNode::DirtyShaderGeometry;
}
- m_dirty = nullptr;
+ m_dirty = {};
for (int i = 0; i < NShader; ++i) {
m_dirtyConstants[i].clear();
m_dirtyTextures[i].clear();
diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h
index f0a18c29cc..066a419c37 100644
--- a/src/quick/items/qquickgraphicsinfo_p.h
+++ b/src/quick/items/qquickgraphicsinfo_p.h
@@ -75,6 +75,11 @@ class QQuickGraphicsInfo : public QObject
Q_PROPERTY(OpenGLContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
+ QML_NAMED_ELEMENT(GraphicsInfo)
+ QML_ADDED_IN_MINOR_VERSION(8)
+ QML_UNCREATABLE("GraphicsInfo is only available via attached properties.")
+ QML_ATTACHED(QQuickGraphicsInfo)
+
public:
enum GraphicsApi {
Unknown = QSGRendererInterface::Unknown,
@@ -168,6 +173,4 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickGraphicsInfo, QML_HAS_ATTACHED_PROPERTIES)
-
#endif // QQUICKGRAPHICSINFO_P_H
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index e69e9cff46..7ca5b0c34c 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -497,7 +497,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex += count;
if (modelIndex >= model->count())
modelIndex = model->count() - 1;
@@ -576,7 +576,7 @@ void QQuickGridViewPrivate::removeItem(FxViewItem *item)
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
} else {
- releaseItem(item);
+ releaseItem(item, QQmlDelegateModel::NotReusable);
}
}
@@ -1298,8 +1298,6 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
/*!
\qmlattachedsignal QtQuick::GridView::add()
This attached signal is emitted immediately after an item is added to the view.
-
- The corresponding handler is \c onAdd.
*/
/*!
@@ -1308,8 +1306,6 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
If a \l remove transition has been specified, it is applied after
this signal is handled, providing that \l delayRemove is false.
-
- The corresponding handler is \c onRemove.
*/
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 7daeaf41a1..9072e5f269 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -73,6 +73,8 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(GridView)
+ QML_ATTACHED(QQuickGridViewAttached)
public:
enum Flow {
@@ -136,6 +138,5 @@ public:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickGridView)
-QML_DECLARE_TYPEINFO(QQuickGridView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKGRIDVIEW_P_H
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 840cfe15da..1882ec8997 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -76,14 +76,8 @@ QSGTexture *QQuickImageTextureProvider::texture() const {
}
QQuickImagePrivate::QQuickImagePrivate()
- : fillMode(QQuickImage::Stretch)
- , paintedWidth(0)
- , paintedHeight(0)
- , pixmapChanged(false)
+ : pixmapChanged(false)
, mipmap(false)
- , hAlign(QQuickImage::AlignHCenter)
- , vAlign(QQuickImage::AlignVCenter)
- , provider(nullptr)
{
}
@@ -433,10 +427,10 @@ qreal QQuickImage::paintedHeight() const
/*!
\qmlproperty QSize QtQuick::Image::sourceSize
- This property holds the actual width and height of the loaded image.
+ This property holds the scaled width and height of the full-frame image.
Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
- the painting of the image, this property sets the actual number of pixels
+ the painting of the image, this property sets the maximum number of pixels
stored for the loaded image so that large images do not use more
memory than necessary. For example, this ensures the image in memory is no
larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
@@ -461,7 +455,7 @@ qreal QQuickImage::paintedHeight() const
other dimension is set in proportion to preserve the source image's aspect ratio.
(The \l fillMode is independent of this.)
- If both the sourceSize.width and sourceSize.height are set the image will be scaled
+ If both the sourceSize.width and sourceSize.height are set, the image will be scaled
down to fit within the specified size (unless PreserveAspectCrop or PreserveAspectFit
are used, then it will be scaled to match the optimal size for cropping/fitting),
maintaining the image's aspect ratio. The actual
@@ -476,6 +470,9 @@ qreal QQuickImage::paintedHeight() const
be no greater than this property specifies. For some formats (currently only JPEG),
the whole image will never actually be loaded into memory.
+ If the \l sourceClipRect property is also set, \c sourceSize determines the scale,
+ but it will be clipped to the size of the clip rectangle.
+
sourceSize can be cleared to the natural size of the image
by setting sourceSize to \c undefined.
@@ -484,6 +481,51 @@ qreal QQuickImage::paintedHeight() const
*/
/*!
+ \qmlproperty rect QtQuick::Image::sourceClipRect
+ \since 5.15
+
+ This property, if set, holds the rectangular region of the source image to
+ be loaded.
+
+ The \c sourceClipRect works together with the \l sourceSize property to
+ conserve system resources when only a portion of an image needs to be
+ loaded.
+
+ \code
+ Rectangle {
+ width: ...
+ height: ...
+
+ Image {
+ anchors.fill: parent
+ source: "reallyBigImage.svg"
+ sourceSize.width: 1024
+ sourceSize.height: 1024
+ sourceClipRect: Qt.rect(100, 100, 512, 512)
+ }
+ }
+ \endcode
+
+ In the above example, we conceptually scale the SVG graphic to 1024x1024
+ first, and then cut out a region of interest that is 512x512 pixels from a
+ location 100 pixels from the top and left edges. Thus \c sourceSize
+ determines the scale, but the actual output image is 512x512 pixels.
+
+ Some image formats are able to conserve CPU time by rendering only the
+ specified region. Others will need to load the entire image first and then
+ clip it to the specified region.
+
+ This property can be cleared to reload the entire image by setting
+ \c sourceClipRect to \c undefined.
+
+ \note \e {Changing this property dynamically causes the image source to be reloaded,
+ potentially even from the network, if it is not in the disk cache.}
+
+ \note Sub-pixel clipping is not supported: the given rectangle will be
+ passed to \l QImageReader::setScaledClipRect().
+*/
+
+/*!
\qmlproperty url QtQuick::Image::source
Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 257cde5313..e22a94c5af 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -68,6 +68,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged REVISION 3)
Q_PROPERTY(bool autoTransform READ autoTransform WRITE setAutoTransform NOTIFY autoTransformChanged REVISION 5)
+ Q_PROPERTY(QRectF sourceClipRect READ sourceClipRect WRITE setSourceClipRect RESET resetSourceClipRect NOTIFY sourceClipRectChanged REVISION 15)
+ QML_NAMED_ELEMENT(Image)
public:
QQuickImage(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index e2c467c311..1c4ba88655 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -80,19 +80,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate
public:
QQuickImagePrivate();
-
- QQuickImage::FillMode fillMode;
- qreal paintedWidth;
- qreal paintedHeight;
void setImage(const QImage &img);
void setPixmap(const QQuickPixmap &pixmap);
bool pixmapChanged : 1;
bool mipmap : 1;
- QQuickImage::HAlignment hAlign;
- QQuickImage::VAlignment vAlign;
+ QQuickImage::HAlignment hAlign = QQuickImage::AlignHCenter;
+ QQuickImage::VAlignment vAlign = QQuickImage::AlignVCenter;
+ QQuickImage::FillMode fillMode = QQuickImage::Stretch;
- QQuickImageTextureProvider *provider;
+ qreal paintedWidth = 0;
+ qreal paintedHeight = 0;
+ QQuickImageTextureProvider *provider = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 8bab14bfd1..8849c2005c 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -167,6 +167,29 @@ void QQuickImageBase::resetSourceSize()
setSourceSize(QSize());
}
+QRectF QQuickImageBase::sourceClipRect() const
+{
+ Q_D(const QQuickImageBase);
+ return d->sourceClipRect;
+}
+
+void QQuickImageBase::setSourceClipRect(const QRectF &r)
+{
+ Q_D(QQuickImageBase);
+ if (d->sourceClipRect == r)
+ return;
+
+ d->sourceClipRect = r;
+ emit sourceClipRectChanged();
+ if (isComponentComplete())
+ load();
+}
+
+void QQuickImageBase::resetSourceClipRect()
+{
+ setSourceClipRect(QRect());
+}
+
bool QQuickImageBase::cache() const
{
Q_D(const QQuickImageBase);
@@ -241,46 +264,47 @@ int QQuickImageBase::frameCount() const
return d->frameCount;
}
-void QQuickImageBase::load()
+void QQuickImageBase::loadEmptyUrl()
{
Q_D(QQuickImageBase);
+ d->pix.clear(this);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ d->status = Null;
+ setImplicitSize(0, 0); // also called in QQuickImageBase::pixmapChange, but not QQuickImage/QQuickBorderImage overrides
+ pixmapChange(); // This calls update() in QQuickBorderImage and QQuickImage, not in QQuickImageBase...
- if (d->url.isEmpty()) {
- d->pix.clear(this);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- pixmapChange();
- d->status = Null;
- emit statusChanged(d->status);
-
- if (sourceSize() != d->oldSourceSize) {
- d->oldSourceSize = sourceSize();
- emit sourceSizeChanged();
- }
- if (autoTransform() != d->oldAutoTransform) {
- d->oldAutoTransform = autoTransform();
- emitAutoTransformBaseChanged();
- }
- update();
-
- } else {
- QQuickPixmap::Options options;
- if (d->async)
- options |= QQuickPixmap::Asynchronous;
- if (d->cache)
- options |= QQuickPixmap::Cache;
- d->pix.clear(this);
+ emit statusChanged(d->status);
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
+ if (autoTransform() != d->oldAutoTransform) {
+ d->oldAutoTransform = autoTransform();
+ emitAutoTransformBaseChanged();
+ }
+ update(); // .. but double updating should be harmless
+}
+void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions)
+{
+ Q_D(QQuickImageBase);
+ QQuickPixmap::Options options;
+ if (d->async)
+ options |= QQuickPixmap::Asynchronous;
+ if (d->cache)
+ options |= QQuickPixmap::Cache;
+ d->pix.clear(this);
+ QUrl loadUrl = url;
+ QQmlEngine* engine = qmlEngine(this);
+ if (engine && engine->urlInterceptor())
+ loadUrl = engine->urlInterceptor()->intercept(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
+
+ if (loadOptions & HandleDPR) {
const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
d->devicePixelRatio = 1.0;
-
- QUrl loadUrl = d->url;
- QQmlEngine* engine = qmlEngine(this);
- if (engine && engine->urlInterceptor())
- loadUrl = engine->urlInterceptor()->intercept(loadUrl, QQmlAbstractUrlInterceptor::UrlString);
-
bool updatedDevicePixelRatio = false;
if (d->sourcesize.isValid())
updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
@@ -290,34 +314,52 @@ void QQuickImageBase::load()
// an "@2x" file is found.
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
}
+ }
- d->pix.load(qmlEngine(this), loadUrl, d->sourcesize * d->devicePixelRatio, options, d->providerOptions, d->currentFrame, d->frameCount);
-
- if (d->pix.isLoading()) {
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
- if (d->status != Loading) {
- d->status = Loading;
- emit statusChanged(d->status);
- }
-
- static int thisRequestProgress = -1;
- static int thisRequestFinished = -1;
- if (thisRequestProgress == -1) {
- thisRequestProgress =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
- thisRequestFinished =
- QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
- }
-
- d->pix.connectFinished(this, thisRequestFinished);
- d->pix.connectDownloadProgress(this, thisRequestProgress);
- update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
- } else {
- requestFinished();
+ d->pix.load(qmlEngine(this),
+ loadUrl,
+ d->sourceClipRect.toRect(),
+ (loadOptions & HandleDPR) ? d->sourcesize * d->devicePixelRatio : QSize(),
+ options,
+ (loadOptions & UseProviderOptions) ? d->providerOptions : QQuickImageProviderOptions(),
+ d->currentFrame, d->frameCount);
+
+ if (d->pix.isLoading()) {
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
+
+ static int thisRequestProgress = -1;
+ static int thisRequestFinished = -1;
+ if (thisRequestProgress == -1) {
+ thisRequestProgress =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+ thisRequestFinished =
+ QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
}
+
+ d->pix.connectFinished(this, thisRequestFinished);
+ d->pix.connectDownloadProgress(this, thisRequestProgress);
+ update(); //pixmap may have invalidated texture, updatePaintNode needs to be called before the next repaint
+ } else {
+ requestFinished();
+ }
+}
+
+void QQuickImageBase::load()
+{
+ Q_D(QQuickImageBase);
+
+ if (d->url.isEmpty()) {
+ loadEmptyUrl();
+ update();
+ } else {
+ loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
}
}
@@ -354,6 +396,10 @@ void QQuickImageBase::requestFinished()
d->frameCount = d->pix.frameCount();
emit frameCountChanged();
}
+ if (d->colorSpace != d->pix.colorSpace()) {
+ d->colorSpace = d->pix.colorSpace();
+ emit colorSpaceChanged();
+ }
update();
}
@@ -446,6 +492,22 @@ void QQuickImageBase::setAutoTransform(bool transform)
emitAutoTransformBaseChanged();
}
+QColorSpace QQuickImageBase::colorSpace() const
+{
+ Q_D(const QQuickImageBase);
+ return d->colorSpace;
+}
+
+void QQuickImageBase::setColorSpace(const QColorSpace &colorSpace)
+{
+ Q_D(QQuickImageBase);
+ if (d->colorSpace == colorSpace)
+ return;
+ d->colorSpace = colorSpace;
+ d->providerOptions.setTargetColorSpace(colorSpace);
+ emit colorSpaceChanged();
+}
+
QT_END_NAMESPACE
#include "moc_qquickimagebase_p.cpp"
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 8cd59c8cea..095547a2cf 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -53,6 +53,7 @@
#include "qquickimplicitsizeitem_p.h"
#include <private/qtquickglobal_p.h>
+#include <QtGui/qcolorspace.h>
QT_BEGIN_NAMESPACE
@@ -70,8 +71,22 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged REVISION 14)
Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged REVISION 14)
+ Q_PROPERTY(QColorSpace colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged REVISION 15)
+
+ QML_NAMED_ELEMENT(ImageBase);
+ QML_ADDED_IN_MINOR_VERSION(14)
+ QML_UNCREATABLE("ImageBase is an abstract base class.")
public:
+ enum LoadPixmapOption {
+ NoOption = 0x0000,
+ HandleDPR = 0x0001,
+ UseProviderOptions = 0x0002
+ };
+
+ Q_DECLARE_FLAGS(LoadPixmapOptions, LoadPixmapOption)
+ Q_FLAG(LoadPixmapOptions)
+
QQuickImageBase(QQuickItem *parent=nullptr);
~QQuickImageBase();
enum Status { Null, Ready, Loading, Error };
@@ -94,6 +109,10 @@ public:
QSize sourceSize() const;
void resetSourceSize();
+ QRectF sourceClipRect() const;
+ void setSourceClipRect(const QRectF &r);
+ void resetSourceClipRect();
+
virtual void setMirror(bool mirror);
bool mirror() const;
@@ -105,6 +124,9 @@ public:
virtual void setAutoTransform(bool transform);
bool autoTransform() const;
+ QColorSpace colorSpace() const;
+ virtual void setColorSpace(const QColorSpace &colorSpace);
+
static void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio);
// Use a virtual rather than a signal->signal to avoid the huge
@@ -121,8 +143,12 @@ Q_SIGNALS:
void mirrorChanged();
Q_REVISION(14) void currentFrameChanged();
Q_REVISION(14) void frameCountChanged();
+ Q_REVISION(15) void sourceClipRectChanged();
+ Q_REVISION(15) void colorSpaceChanged();
protected:
+ void loadEmptyUrl();
+ void loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions = NoOption);
virtual void load();
void componentComplete() override;
virtual void pixmapChange();
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index 88e18ba32e..ebb7568caf 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -86,7 +86,9 @@ public:
QSize sourcesize;
QSize oldSourceSize;
qreal devicePixelRatio;
+ QRectF sourceClipRect;
QQuickImageProviderOptions providerOptions;
+ QColorSpace colorSpace;
int currentFrame;
int frameCount;
bool async : 1;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 11c1f12e75..3f655e84fa 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -74,6 +74,7 @@
#include <private/qv4object_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qdebug_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#if QT_CONFIG(cursor)
# include <QtGui/qcursor.h>
@@ -938,8 +939,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when a key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onPressed.
*/
/*!
@@ -947,8 +946,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when a key has been released. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onReleased.
*/
/*!
@@ -986,8 +983,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
As with the other signals, \c shortcutOverride will only be emitted for an
item if that item has \l {Item::}{activeFocus}.
- The corresponding handler is \c onShortcutOverride.
-
\sa Shortcut
*/
@@ -996,8 +991,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '0' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit0Pressed.
*/
/*!
@@ -1005,8 +998,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '1' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit1Pressed.
*/
/*!
@@ -1014,8 +1005,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '2' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit2Pressed.
*/
/*!
@@ -1023,8 +1012,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '3' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit3Pressed.
*/
/*!
@@ -1032,8 +1019,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '4' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit4Pressed.
*/
/*!
@@ -1041,8 +1026,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '5' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit5Pressed.
*/
/*!
@@ -1050,8 +1033,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '6' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit6Pressed.
*/
/*!
@@ -1059,8 +1040,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '7' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit7Pressed.
*/
/*!
@@ -1068,8 +1047,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '8' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit8Pressed.
*/
/*!
@@ -1077,8 +1054,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the digit '9' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDigit9Pressed.
*/
/*!
@@ -1086,8 +1061,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Left arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onLeftPressed.
*/
/*!
@@ -1095,8 +1068,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Right arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onRightPressed.
*/
/*!
@@ -1104,8 +1075,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Up arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onUpPressed.
*/
/*!
@@ -1113,8 +1082,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Down arrow has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDownPressed.
*/
/*!
@@ -1122,8 +1089,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Tab key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onTabPressed.
*/
/*!
@@ -1131,8 +1096,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Shift+Tab key combination (Backtab) has
been pressed. The \a event parameter provides information about the event.
-
- The corresponding handler is \c onBacktabPressed.
*/
/*!
@@ -1140,8 +1103,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Asterisk '*' has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onAsteriskPressed.
*/
/*!
@@ -1149,8 +1110,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Escape key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onEscapePressed.
*/
/*!
@@ -1158,8 +1117,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Return key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onReturnPressed.
*/
/*!
@@ -1167,8 +1124,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Enter key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onEnterPressed.
*/
/*!
@@ -1176,8 +1131,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Delete key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onDeletePressed.
*/
/*!
@@ -1185,8 +1138,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Space key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onSpacePressed.
*/
/*!
@@ -1194,8 +1145,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Back key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onBackPressed.
*/
/*!
@@ -1203,8 +1152,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Cancel key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onCancelPressed.
*/
/*!
@@ -1212,8 +1159,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Select key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onSelectPressed.
*/
/*!
@@ -1221,8 +1166,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Yes key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onYesPressed.
*/
/*!
@@ -1230,8 +1173,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the No key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onNoPressed.
*/
/*!
@@ -1239,8 +1180,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context1 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext1Pressed.
*/
/*!
@@ -1248,8 +1187,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context2 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext2Pressed.
*/
/*!
@@ -1257,8 +1194,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context3 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext3Pressed.
*/
/*!
@@ -1266,8 +1201,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Context4 key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onContext4Pressed.
*/
/*!
@@ -1275,8 +1208,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Call key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onCallPressed.
*/
/*!
@@ -1284,8 +1215,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Hangup key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onHangupPressed.
*/
/*!
@@ -1293,8 +1222,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Flip key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onFlipPressed.
*/
/*!
@@ -1302,8 +1229,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the Menu key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onMenuPressed.
*/
/*!
@@ -1311,8 +1236,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the VolumeUp key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onVolumeUpPressed.
*/
/*!
@@ -1320,8 +1243,6 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const
This signal is emitted when the VolumeDown key has been pressed. The \a event
parameter provides information about the event.
-
- The corresponding handler is \c onVolumeDownPressed.
*/
QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
@@ -1478,7 +1399,7 @@ QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
//### how robust is i == d->imeItem check?
QVariant v = i->inputMethodQuery(query);
- if (v.userType() == QVariant::RectF)
+ if (v.userType() == QMetaType::QRectF)
v = d->item->mapRectFromItem(i, v.toRectF()); //### cost?
return v;
}
@@ -3249,6 +3170,7 @@ QQuickItemPrivate::QQuickItemPrivate()
#else
, touchEnabled(false)
#endif
+ , hasCursorHandler(false)
, dirtyAttributes(0)
, nextDirtyItem(nullptr)
, prevDirtyItem(nullptr)
@@ -4055,6 +3977,9 @@ void QQuickItem::focusOutEvent(QFocusEvent * /*event*/)
press events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse press events, \l acceptedMouseButtons() must
+ return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mousePressEvent(QMouseEvent *event)
@@ -4067,6 +3992,10 @@ void QQuickItem::mousePressEvent(QMouseEvent *event)
move events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse movement events, the preceding mouse press event
+ must be accepted (by overriding \l mousePressEvent(), for example) and
+ \l acceptedMouseButtons() must return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mouseMoveEvent(QMouseEvent *event)
@@ -4079,6 +4008,10 @@ void QQuickItem::mouseMoveEvent(QMouseEvent *event)
release events for an item. The event information is provided by the
\a event parameter.
+ In order to receive mouse release events, the preceding mouse press event
+ must be accepted (by overriding \l mousePressEvent(), for example) and
+ \l acceptedMouseButtons() must return the relevant mouse button.
+
\input item.qdocinc accepting-events
*/
void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
@@ -4481,9 +4414,94 @@ void QQuickItem::polish()
}
}
+static bool unwrapMapFromToFromItemArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning,
+ QQuickItem **itemObj, qreal *x, qreal *y, qreal *w, qreal *h, bool *isRect)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ if (args->length() != 2 && args->length() != 3 && args->length() != 5) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ QV4::Scope scope(v4);
+ QV4::ScopedValue item(scope, (*args)[0]);
+
+ *itemObj = nullptr;
+ if (!item->isNull()) {
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
+ if (qobjectWrapper)
+ *itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
+ }
+
+ if (!(*itemObj) && !item->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << " given argument \"" << item->toQStringNoThrow()
+ << "\" which is neither null nor an Item";
+ v4->throwTypeError();
+ return false;
+ }
+
+ *isRect = false;
+
+ if (args->length() == 2) {
+ QV4::ScopedValue sv(scope, (*args)[1]);
+ if (sv->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
+ const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
+ if (v.canConvert<QPointF>()) {
+ const QPointF p = v.toPointF();
+ *x = p.x();
+ *y = p.y();
+ } else if (v.canConvert<QRectF>()) {
+ const QRectF r = v.toRectF();
+ *x = r.x();
+ *y = r.y();
+ *w = r.width();
+ *h = r.height();
+ *isRect = true;
+ } else {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is neither a point nor a rect";
+ v4->throwTypeError();
+ return false;
+ }
+ } else {
+ QV4::ScopedValue vx(scope, (*args)[1]);
+ QV4::ScopedValue vy(scope, (*args)[2]);
+
+ if (!vx->isNumber() || !vy->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+
+ *x = vx->asDouble();
+ *y = vy->asDouble();
+
+ if (args->length() > 3) {
+ QV4::ScopedValue vw(scope, (*args)[3]);
+ QV4::ScopedValue vh(scope, (*args)[4]);
+ if (!vw->isNumber() || !vh->isNumber()) {
+ v4->throwTypeError();
+ return false;
+ }
+ *w = vw->asDouble();
+ *h = vh->asDouble();
+ *isRect = true;
+ }
+ }
+
+ return true;
+}
+
/*!
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapFromItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect
@@ -4493,6 +4511,8 @@ void QQuickItem::polish()
If \a item is a \c null value, this maps the point or rect from the coordinate system of
the root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4500,55 +4520,16 @@ void QQuickItem::polish()
void QQuickItem::mapFromItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapFromItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
-
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
- return;
- }
-
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
-
- QVariant result;
-
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
- v4->throwTypeError();
- return;
- }
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
-
- result = mapRectFromItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapFromItem(itemObj, QPointF(x, y));
- }
+ const QVariant result = isRect ? QVariant(mapRectFromItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapFromItem(itemObj, QPointF(x, y)));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
args->setReturnValue(rv.asReturnedValue());
@@ -4573,7 +4554,9 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
/*!
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, point p)
\qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height)
+ \qmlmethod object QtQuick::Item::mapToItem(Item item, rect r)
Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect
@@ -4583,6 +4566,8 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
If \a item is a \c null value, this maps the point or rect to the coordinate system of the
root QML view.
+
+ The versions accepting point and rect are since Qt 5.15.
*/
/*!
\internal
@@ -4590,58 +4575,65 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
void QQuickItem::mapToItem(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 3 && args->length() != 5) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue item(scope, (*args)[0]);
-
- QQuickItem *itemObj = nullptr;
- if (!item->isNull()) {
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, item->as<QV4::QObjectWrapper>());
- if (qobjectWrapper)
- itemObj = qobject_cast<QQuickItem*>(qobjectWrapper->object());
- }
- if (!itemObj && !item->isNull()) {
- qmlWarning(this) << "mapToItem() given argument \"" << item->toQStringNoThrow()
- << "\" which is neither null nor an Item";
- v4->throwTypeError();
+ qreal x, y, w, h;
+ bool isRect;
+ QQuickItem *itemObj;
+ if (!unwrapMapFromToFromItemArgs(args, this, QStringLiteral("mapToItem()"), &itemObj, &x, &y, &w, &h, &isRect))
return;
- }
- QV4::ScopedValue vx(scope, (*args)[1]);
- QV4::ScopedValue vy(scope, (*args)[2]);
+ const QVariant result = isRect ? QVariant(mapRectToItem(itemObj, QRectF(x, y, w, h)))
+ : QVariant(mapToItem(itemObj, QPointF(x, y)));
+
+ QV4::ScopedObject rv(scope, v4->fromVariant(result));
+ args->setReturnValue(rv.asReturnedValue());
+}
- if (!vx->isNumber() || !vy->isNumber()) {
+static bool unwrapMapFromToFromGlobalArgs(QQmlV4Function *args, const QQuickItem *itemForWarning, const QString &functionNameForWarning, qreal *x, qreal *y)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ if (args->length() != 1 && args->length() != 2) {
v4->throwTypeError();
- return;
+ return false;
}
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
+ QV4::Scope scope(v4);
- QVariant result;
+ if (args->length() == 1) {
+ QV4::ScopedValue sv(scope, (*args)[0]);
+ if (sv->isNull()) {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is not a point";
+ v4->throwTypeError();
+ return false;
+ }
+ const QV4::Scoped<QV4::QQmlValueTypeWrapper> variantWrapper(scope, sv->as<QV4::QQmlValueTypeWrapper>());
+ const QVariant v = variantWrapper ? variantWrapper->toVariant() : QVariant();
+ if (v.canConvert<QPointF>()) {
+ const QPointF p = v.toPointF();
+ *x = p.x();
+ *y = p.y();
+ } else {
+ qmlWarning(itemForWarning) << functionNameForWarning << "given argument \"" << sv->toQStringNoThrow()
+ << "\" which is not a point";
+ v4->throwTypeError();
+ return false;
+ }
+ } else {
+ QV4::ScopedValue vx(scope, (*args)[0]);
+ QV4::ScopedValue vy(scope, (*args)[1]);
- if (args->length() > 3) {
- QV4::ScopedValue vw(scope, (*args)[3]);
- QV4::ScopedValue vh(scope, (*args)[4]);
- if (!vw->isNumber() || !vh->isNumber()) {
+ if (!vx->isNumber() || !vy->isNumber()) {
v4->throwTypeError();
- return;
+ return false;
}
- qreal w = vw->asDouble();
- qreal h = vh->asDouble();
- result = mapRectToItem(itemObj, QRectF(x, y, w, h));
- } else {
- result = mapToItem(itemObj, QPointF(x, y));
+ *x = vx->asDouble();
+ *y = vy->asDouble();
}
- QV4::ScopedObject rv(scope, v4->fromVariant(result));
- args->setReturnValue(rv.asReturnedValue());
+ return true;
}
/*!
@@ -4659,22 +4651,12 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const
void QQuickItem::mapFromGlobal(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 2) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue vx(scope, (*args)[0]);
- QV4::ScopedValue vy(scope, (*args)[1]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y;
+ if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
return;
- }
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
QVariant result = mapFromGlobal(QPointF(x, y));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
@@ -4696,22 +4678,12 @@ void QQuickItem::mapFromGlobal(QQmlV4Function *args) const
void QQuickItem::mapToGlobal(QQmlV4Function *args) const
{
QV4::ExecutionEngine *v4 = args->v4engine();
- if (args->length() != 2) {
- v4->throwTypeError();
- return;
- }
-
QV4::Scope scope(v4);
- QV4::ScopedValue vx(scope, (*args)[0]);
- QV4::ScopedValue vy(scope, (*args)[1]);
- if (!vx->isNumber() || !vy->isNumber()) {
- v4->throwTypeError();
+ qreal x, y;
+ if (!unwrapMapFromToFromGlobalArgs(args, this, QStringLiteral("mapFromGlobal()"), &x, &y))
return;
- }
- qreal x = vx->asDouble();
- qreal y = vy->asDouble();
QVariant result = mapToGlobal(QPointF(x, y));
QV4::ScopedObject rv(scope, v4->fromVariant(result));
@@ -7438,14 +7410,14 @@ void QQuickItem::setAcceptTouchEvents(bool enabled)
d->touchEnabled = enabled;
}
-void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
+void QQuickItemPrivate::setHasCursorInChild(bool hc)
{
#if QT_CONFIG(cursor)
Q_Q(QQuickItem);
// if we're asked to turn it off (because of an unsetcursor call, or a node
// removal) then we should make sure it's really ok to turn it off.
- if (!hasCursor && subtreeCursorEnabled) {
+ if (!hc && subtreeCursorEnabled) {
if (hasCursor)
return; // nope! sorry, I have a cursor myself
for (QQuickItem *otherChild : qAsConst(childItems)) {
@@ -7455,14 +7427,14 @@ void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
}
}
- subtreeCursorEnabled = hasCursor;
+ subtreeCursorEnabled = hc;
QQuickItem *parent = q->parentItem();
if (parent) {
QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
- parentPrivate->setHasCursorInChild(hasCursor);
+ parentPrivate->setHasCursorInChild(hc);
}
#else
- Q_UNUSED(hasCursor);
+ Q_UNUSED(hc);
#endif
}
@@ -7539,17 +7511,20 @@ void QQuickItem::setCursor(const QCursor &cursor)
}
}
+ QPointF updateCursorPos;
if (!d->hasCursor) {
- d->setHasCursorInChild(true);
d->hasCursor = true;
if (d->window) {
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window);
QWindow *window = renderWindow ? renderWindow : d->window;
QPointF pos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint());
if (contains(mapFromScene(pos)))
- QQuickWindowPrivate::get(d->window)->updateCursor(pos);
+ updateCursorPos = pos;
}
}
+ d->setHasCursorInChild(d->hasCursor || d->hasCursorHandler);
+ if (!updateCursorPos.isNull())
+ QQuickWindowPrivate::get(d->window)->updateCursor(updateCursorPos);
}
/*!
@@ -7563,8 +7538,8 @@ void QQuickItem::unsetCursor()
Q_D(QQuickItem);
if (!d->hasCursor)
return;
- d->setHasCursorInChild(false);
d->hasCursor = false;
+ d->setHasCursorInChild(d->hasCursorHandler);
if (d->extra.isAllocated())
d->extra->cursor = QCursor();
@@ -7577,6 +7552,64 @@ void QQuickItem::unsetCursor()
}
}
+/*!
+ \internal
+ Returns the cursor that should actually be shown, allowing the given
+ \handler to override the Item cursor if it is active or hovered.
+
+ \sa cursor(), setCursor(), QtQuick::PointerHandler::cursor
+*/
+QCursor QQuickItemPrivate::effectiveCursor(const QQuickPointerHandler *handler) const
+{
+ Q_Q(const QQuickItem);
+ if (!handler)
+ return q->cursor();
+ bool hoverCursorSet = false;
+ QCursor hoverCursor;
+ bool activeCursorSet = false;
+ QCursor activeCursor;
+ if (const QQuickHoverHandler *hoverHandler = qobject_cast<const QQuickHoverHandler *>(handler)) {
+ hoverCursorSet = hoverHandler->isCursorShapeExplicitlySet();
+ hoverCursor = hoverHandler->cursorShape();
+ } else if (handler->active()) {
+ activeCursorSet = handler->isCursorShapeExplicitlySet();
+ activeCursor = handler->cursorShape();
+ }
+ if (activeCursorSet)
+ return activeCursor;
+ if (hoverCursorSet)
+ return hoverCursor;
+ return q->cursor();
+}
+
+/*!
+ \internal
+ Returns the Pointer Handler that is currently attempting to set the cursor shape,
+ or null if there is no such handler.
+
+ \sa QtQuick::PointerHandler::cursor
+*/
+QQuickPointerHandler *QQuickItemPrivate::effectiveCursorHandler() const
+{
+ if (!hasPointerHandlers())
+ return nullptr;
+ QQuickPointerHandler *retHoverHandler = nullptr;
+ for (QQuickPointerHandler *h : extra->pointerHandlers) {
+ if (!h->isCursorShapeExplicitlySet())
+ continue;
+ QQuickHoverHandler *hoverHandler = qmlobject_cast<QQuickHoverHandler *>(h);
+ // For now, we don't expect multiple hover handlers in one Item, so we choose the first one found;
+ // but a future use case could be to have different cursors for different tablet stylus devices.
+ // In that case, this function needs more information: which device did the event come from.
+ // TODO Qt 6: add QPointerDevice* as argument to this function? (it doesn't exist yet in Qt 5)
+ if (!retHoverHandler && hoverHandler)
+ retHoverHandler = hoverHandler;
+ if (!hoverHandler && h->active())
+ return h;
+ }
+ return retHoverHandler;
+}
+
#endif
/*!
@@ -8158,6 +8191,10 @@ bool QQuickItem::event(QEvent *ev)
ev->ignore();
break;
#endif // gestures
+ case QEvent::LanguageChange:
+ for (QQuickItem *item : d->childItems)
+ QCoreApplication::sendEvent(item, ev);
+ break;
default:
return QObject::event(ev);
}
@@ -8818,7 +8855,7 @@ QQuickItemPrivate::ExtraData::ExtraData()
effectRefCount(0), hideRefCount(0),
recursiveEffectRefCount(0),
opacityNode(nullptr), clipNode(nullptr), rootNode(nullptr),
- acceptedMouseButtons(nullptr), origin(QQuickItem::Center),
+ origin(QQuickItem::Center),
transparentForPositioner(false)
{
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 394a5adb8c..8c04ced11b 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -58,6 +58,7 @@ class QQuickTransformPrivate;
class Q_QUICK_EXPORT QQuickTransform : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
explicit QQuickTransform(QObject *parent = nullptr);
~QQuickTransform() override;
@@ -150,6 +151,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_CLASSINFO("DefaultProperty", "data")
Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
+ QML_NAMED_ELEMENT(Item)
public:
enum Flag {
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 2faf694eeb..841d91bb40 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -152,6 +152,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged)
Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged)
+ QML_ANONYMOUS
public:
QQuickItemLayer(QQuickItem *item);
@@ -335,7 +336,7 @@ public:
struct ChangeListener {
using ChangeTypes = QQuickItemPrivate::ChangeTypes;
- ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = nullptr)
+ ChangeListener(QQuickItemChangeListener *l = nullptr, ChangeTypes t = { })
: listener(l)
, types(t)
, gTypes(QQuickGeometryChange::All)
@@ -470,6 +471,7 @@ public:
bool isTabFence:1;
bool replayingPressEvent:1;
bool touchEnabled:1;
+ bool hasCursorHandler:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -650,6 +652,10 @@ public:
void setHasCursorInChild(bool hasCursor);
void setHasHoverInChild(bool hasHover);
+#if QT_CONFIG(cursor)
+ QCursor effectiveCursor(const QQuickPointerHandler *handler) const;
+ QQuickPointerHandler *effectiveCursorHandler() const;
+#endif
virtual void updatePolish() { }
};
@@ -715,6 +721,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickKeyNavigationAttached : public QObject, publi
Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+ QML_NAMED_ELEMENT(KeyNavigation)
+ QML_UNCREATABLE("KeyNavigation is only available via attached properties.")
+ QML_ATTACHED(QQuickKeyNavigationAttached)
+
public:
QQuickKeyNavigationAttached(QObject * = nullptr);
@@ -760,6 +770,10 @@ class QQuickLayoutMirroringAttached : public QObject
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
+ QML_NAMED_ELEMENT(LayoutMirroring)
+ QML_UNCREATABLE("LayoutMirroring is only available via attached properties.")
+ QML_ATTACHED(QQuickLayoutMirroringAttached)
+
public:
explicit QQuickLayoutMirroringAttached(QObject *parent = nullptr);
@@ -784,6 +798,11 @@ class QQuickEnterKeyAttached : public QObject
Q_OBJECT
Q_PROPERTY(Qt::EnterKeyType type READ type WRITE setType NOTIFY typeChanged)
+ QML_NAMED_ELEMENT(EnterKey)
+ QML_UNCREATABLE("EnterKey is only available via attached properties")
+ QML_ADDED_IN_MINOR_VERSION(6)
+ QML_ATTACHED(QQuickEnterKeyAttached)
+
public:
explicit QQuickEnterKeyAttached(QObject *parent = nullptr);
@@ -829,6 +848,10 @@ class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
Q_PROPERTY(QQmlListProperty<QQuickItem> forwardTo READ forwardTo)
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+ QML_NAMED_ELEMENT(Keys)
+ QML_UNCREATABLE("Keys is only available via attached properties")
+ QML_ATTACHED(QQuickKeysAttached)
+
public:
QQuickKeysAttached(QObject *parent=nullptr);
~QQuickKeysAttached() override;
@@ -849,7 +872,7 @@ public:
QQmlListProperty<QQuickItem> forwardTo() {
Q_D(QQuickKeysAttached);
- return QQmlListProperty<QQuickItem>(this, d->targets);
+ return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
void componentComplete() override;
@@ -919,7 +942,7 @@ private:
Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
{
return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
- (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(nullptr)));
+ (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons{}));
}
QSGContext *QQuickItemPrivate::sceneGraphContext() const
@@ -984,12 +1007,8 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickItemLayer)
#endif
QML_DECLARE_TYPE(QQuickKeysAttached)
-QML_DECLARE_TYPEINFO(QQuickKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickKeyNavigationAttached)
-QML_DECLARE_TYPEINFO(QQuickKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickLayoutMirroringAttached)
-QML_DECLARE_TYPEINFO(QQuickLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickEnterKeyAttached)
-QML_DECLARE_TYPEINFO(QQuickEnterKeyAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKITEM_P_H
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 8251282736..23694e2de3 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -456,7 +456,7 @@ QQuickAnchorAnimation::~QQuickAnchorAnimation()
QQmlListProperty<QQuickItem> QQuickAnchorAnimation::targets()
{
Q_D(QQuickAnchorAnimation);
- return QQmlListProperty<QQuickItem>(this, d->targets);
+ return QQmlListProperty<QQuickItem>(this, &(d->targets));
}
/*!
diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h
index b803455f12..28c18c874d 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -66,6 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup
Q_PROPERTY(QQuickItem *target READ target WRITE setTargetObject NOTIFY targetChanged)
Q_PROPERTY(QQuickItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged)
Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged)
+ QML_NAMED_ELEMENT(ParentAnimation)
public:
QQuickParentAnimation(QObject *parent=nullptr);
@@ -100,6 +101,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation
Q_PROPERTY(QQmlListProperty<QQuickItem> targets READ targets)
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+ QML_NAMED_ELEMENT(AnchorAnimation)
public:
QQuickAnchorAnimation(QObject *parent=nullptr);
@@ -143,6 +145,7 @@ class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation
Q_PROPERTY(int orientationEntryDuration READ orientationEntryDuration WRITE setOrientationEntryDuration NOTIFY orientationEntryDurationChanged)
Q_PROPERTY(int orientationExitDuration READ orientationExitDuration WRITE setOrientationExitDuration NOTIFY orientationExitDurationChanged)
Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
+ QML_NAMED_ELEMENT(PathAnimation)
public:
QQuickPathAnimation(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index f298803c7f..00e84536e9 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -195,6 +195,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName) const
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
* \overload
* \internal
@@ -203,6 +204,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName)
{
return qAsConst(*this).saveToFile(fileName);
}
+#endif
#endif // < Qt 6
QUrl QQuickItemGrabResult::url() const
diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h
index 3dc10e2d75..a45ed62ed5 100644
--- a/src/quick/items/qquickitemgrabresult.h
+++ b/src/quick/items/qquickitemgrabresult.h
@@ -45,6 +45,7 @@
#include <QtCore/QUrl>
#include <QtGui/QImage>
#include <QtQml/QJSValue>
+#include <QtQml/qqml.h>
#include <QtQuick/qtquickglobal.h>
QT_BEGIN_NAMESPACE
@@ -60,12 +61,17 @@ class Q_QUICK_EXPORT QQuickItemGrabResult : public QObject
Q_PROPERTY(QImage image READ image CONSTANT)
Q_PROPERTY(QUrl url READ url CONSTANT)
+ QML_ANONYMOUS
+
public:
QImage image() const;
QUrl url() const;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- Q_INVOKABLE bool saveToFile(const QString &fileName); // ### Qt 6: remove
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("This overload is deprecated. Use the const member function instead")
+ Q_INVOKABLE bool saveToFile(const QString &fileName);
+#endif
#endif
Q_INVOKABLE bool saveToFile(const QString &fileName) const;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 86253e770f..125518e51b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -175,332 +175,14 @@ static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject
return QQmlPrivate::IncompatibleObject;
}
-static void qt_quickitems_defineModule(const char *uri, int major, int minor)
+static void qt_quickitems_defineModule()
{
QQmlPrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
- // Register the latest version, even if there are no new types or new revisions for existing types yet.
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
-
-#if !QT_CONFIG(quick_animatedimage)
- qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", QCoreApplication::translate("QQuickAnimatedImage","Qt was built without support for QMovie"));
-#else
- qmlRegisterType<QQuickAnimatedImage>(uri,major,minor,"AnimatedImage");
-#endif
- qmlRegisterType<QQuickBorderImage>(uri,major,minor,"BorderImage");
- qmlRegisterType<QQuickFlickable>(uri,major,minor,"Flickable");
-#if QT_CONFIG(quick_flipable)
- qmlRegisterType<QQuickFlipable>(uri,major,minor,"Flipable");
-#endif
-// qmlRegisterType<QQuickFocusPanel>(uri,major,minor,"FocusPanel");
- qmlRegisterType<QQuickFocusScope>(uri,major,minor,"FocusScope");
- qmlRegisterType<QQuickGradient>(uri,major,minor,"Gradient");
- qmlRegisterType<QQuickGradientStop>(uri,major,minor,"GradientStop");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterType<QQuickColumn>(uri,major,minor,"Column");
- qmlRegisterType<QQuickFlow>(uri,major,minor,"Flow");
- qmlRegisterType<QQuickGrid>(uri,major,minor,"Grid");
- qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
- qmlRegisterType<QQuickRow>(uri,major,minor,"Row");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView>(uri,major,minor,"GridView");
-#endif
- qmlRegisterType<QQuickImage>(uri,major,minor,"Image");
- qmlRegisterType<QQuickItem>(uri,major,minor,"Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView>(uri,major,minor,"ListView");
- qmlRegisterType<QQuickViewSection>(uri,major,minor,"ViewSection");
-#endif
- qmlRegisterType<QQuickLoader>(uri,major,minor,"Loader");
- qmlRegisterType<QQuickMouseArea>(uri,major,minor,"MouseArea");
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPath>(uri,major,minor,"Path");
- qmlRegisterType<QQuickPathAttribute>(uri,major,minor,"PathAttribute");
- qmlRegisterType<QQuickPathCubic>(uri,major,minor,"PathCubic");
- qmlRegisterType<QQuickPathLine>(uri,major,minor,"PathLine");
- qmlRegisterType<QQuickPathPercent>(uri,major,minor,"PathPercent");
- qmlRegisterType<QQuickPathQuad>(uri,major,minor,"PathQuad");
- qmlRegisterType<QQuickPathCatmullRomCurve>("QtQuick",2,0,"PathCurve");
- qmlRegisterType<QQuickPathArc>("QtQuick",2,0,"PathArc");
- qmlRegisterType<QQuickPathSvg>("QtQuick",2,0,"PathSvg");
- qmlRegisterType<QQuickPath, 14>(uri, 2, 14, "Path");
- qmlRegisterType<QQuickPathPolyline>("QtQuick", 2, 14, "PathPolyline");
- qmlRegisterType<QQuickPathMultiline>("QtQuick", 2, 14, "PathMultiline");
-#endif
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
-#endif
- qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
-#if QT_CONFIG(quick_repeater)
- qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
-#endif
- qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
- qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
- qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
- qmlRegisterType<QQuickMatrix4x4>(uri,2,3,"Matrix4x4");
- qmlRegisterType<QQuickText>(uri,major,minor,"Text");
- qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
- qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
- qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput");
- qmlRegisterType<QQuickTextInput,2>(uri,2,2,"TextInput");
- qmlRegisterType<QQuickTextInput,4>(uri,2,4,"TextInput");
- qmlRegisterAnonymousType<QQuickItemGrabResult>(uri, major);
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterAnonymousType<QQuickItemLayer>(uri, major);
-#endif
- qmlRegisterAnonymousType<QQuickAnchors>(uri, major);
- qmlRegisterAnonymousType<QQuickKeyEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickMouseEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickWheelEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickCloseEvent>(uri, major);
- qmlRegisterAnonymousType<QQuickTransform>(uri, major);
-#if QT_CONFIG(quick_path)
- qmlRegisterAnonymousType<QQuickPathElement>(uri, major);
- qmlRegisterAnonymousType<QQuickCurve>(uri, major);
-#endif
- qmlRegisterAnonymousType<QQuickScaleGrid>(uri, major);
- qmlRegisterAnonymousType<QQuickTextLine>(uri, major);
- qmlRegisterAnonymousType<QQuickPen>(uri, major);
- qmlRegisterAnonymousType<QQuickFlickableVisibleArea>(uri, major);
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
-
- qmlRegisterAnonymousType<QQuickTextDocument>(uri, major);
-
-
- qmlRegisterUncreatableType<QQuickKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QQuickKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
- qmlRegisterUncreatableType<QQuickKeysAttached>(uri,major,minor,"Keys",QQuickKeysAttached::tr("Keys is only available via attached properties"));
- qmlRegisterUncreatableType<QQuickLayoutMirroringAttached>(uri,major,minor,"LayoutMirroring", QQuickLayoutMirroringAttached::tr("LayoutMirroring is only available via attached properties"));
-#if QT_CONFIG(quick_viewtransitions)
- qmlRegisterUncreatableType<QQuickViewTransitionAttached>(uri,major,minor,"ViewTransition",QQuickViewTransitionAttached::tr("ViewTransition is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickPinchArea>(uri,major,minor,"PinchArea");
- qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch");
- qmlRegisterAnonymousType<QQuickPinchEvent>(uri, major);
-
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
- qmlRegisterUncreatableType<QQuickShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QQuickShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh."));
- qmlRegisterType<QQuickGridMesh>("QtQuick", 2, 0, "GridMesh");
- qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
-#endif
-
- qmlRegisterUncreatableType<QQuickPaintedItem>("QtQuick", 2, 0, "PaintedItem", QQuickPaintedItem::tr("Cannot create instance of abstract class PaintedItem"));
-
-#if QT_CONFIG(quick_canvas)
- qmlRegisterType<QQuickCanvasItem>("QtQuick", 2, 0, "Canvas");
-#endif
-
-#if QT_CONFIG(quick_sprite)
- qmlRegisterType<QQuickSprite>("QtQuick", 2, 0, "Sprite");
- qmlRegisterType<QQuickAnimatedSprite>("QtQuick", 2, 0, "AnimatedSprite");
- qmlRegisterType<QQuickSpriteSequence>("QtQuick", 2, 0, "SpriteSequence");
-#endif
-
- qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
- qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
- qmlRegisterAnonymousType<QQuickAnchorSet>(uri, major);
- qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
- qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation");
- qmlRegisterType<QQuickPathInterpolator>("QtQuick",2,0,"PathInterpolator");
-#endif
-
-#if QT_CONFIG(quick_draganddrop)
- qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea");
- qmlRegisterAnonymousType<QQuickDropEvent>(uri, 2);
- qmlRegisterAnonymousType<QQuickDropAreaDrag>(uri, 2);
- qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea");
- qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint");
- qmlRegisterUncreatableType<QQuickGrabGestureEvent>(uri,major,minor, "GestureEvent",
- QQuickMouseEvent::tr("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea"));
-
-#if QT_CONFIG(accessibility)
- qmlRegisterUncreatableType<QQuickAccessibleAttached>("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties"));
-#endif
-
- qmlRegisterType<QQuickItem, 1>(uri, 2, 1,"Item");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid");
-#endif
-#if QT_CONFIG(quick_itemview)
- const char *itemViewName = "ItemView";
- const QString itemViewMessage = QQuickItemView::tr("ItemView is an abstract base class");
- qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, itemViewName, itemViewMessage);
- qmlRegisterUncreatableType<QQuickItemView, 3>(uri, 2, 3, itemViewName, itemViewMessage);
-#endif
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView");
-#endif
- qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit");
-
- qmlRegisterType<QQuickText, 2>(uri, 2, 2, "Text");
- qmlRegisterType<QQuickTextEdit, 2>(uri, 2, 2, "TextEdit");
-
- qmlRegisterType<QQuickText, 3>(uri, 2, 3, "Text");
- qmlRegisterType<QQuickTextEdit, 3>(uri, 2, 3, "TextEdit");
- qmlRegisterType<QQuickImage, 3>(uri, 2, 3,"Image");
-
- qmlRegisterType<QQuickItem, 4>(uri, 2, 4, "Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 4>(uri, 2, 4, "ListView");
-#endif
- qmlRegisterType<QQuickMouseArea, 4>(uri, 2, 4, "MouseArea");
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffect, 4>(uri, 2, 4, "ShaderEffect");
-#endif
-
-#if QT_CONFIG(opengl)
- qmlRegisterUncreatableType<QQuickOpenGLInfo>(uri, 2, 4,"OpenGLInfo", QQuickOpenGLInfo::tr("OpenGLInfo is only available via attached properties"));
-#endif
- qmlRegisterType<QQuickPinchArea, 5>(uri, 2, 5,"PinchArea");
- qmlRegisterType<QQuickImage, 5>(uri, 2, 5,"Image");
- qmlRegisterType<QQuickMouseArea, 5>(uri, 2, 5, "MouseArea");
-
- qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
- qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
- qmlRegisterType<QQuickTextInput, 6>(uri, 2, 6, "TextInput");
-#if QT_CONFIG(quick_positioners)
- qmlRegisterUncreatableType<QQuickBasePositioner, 6>(uri, 2, 6, "Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
- qmlRegisterType<QQuickColumn, 6>(uri, 2, 6, "Column");
- qmlRegisterType<QQuickRow, 6>(uri, 2, 6, "Row");
- qmlRegisterType<QQuickGrid, 6>(uri, 2, 6, "Grid");
- qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow");
-#endif
- qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey",
- QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties"));
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 6>(uri, 2, 6, "ShaderEffectSource");
-#endif
-
- qmlRegisterType<QQuickItem, 7>(uri, 2, 7, "Item");
-#if QT_CONFIG(quick_listview)
- qmlRegisterType<QQuickListView, 7>(uri, 2, 7, "ListView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 7>(uri, 2, 7, "GridView");
-#endif
- qmlRegisterType<QQuickTextInput, 7>(uri, 2, 7, "TextInput");
- qmlRegisterType<QQuickTextEdit, 7>(uri, 2, 7, "TextEdit");
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView, 7>(uri, 2, 7, "PathView");
-#endif
-#if QT_CONFIG(quick_itemview)
- qmlRegisterUncreatableType<QQuickItemView, 7>(uri, 2, 7, itemViewName, itemViewMessage);
-#endif
-
- qmlRegisterUncreatableType<QQuickMouseEvent, 7>(uri, 2, 7, nullptr, QQuickMouseEvent::tr("MouseEvent is only available within handlers in MouseArea"));
-
- qmlRegisterUncreatableType<QQuickGraphicsInfo>(uri, 2, 8,"GraphicsInfo", QQuickGraphicsInfo::tr("GraphicsInfo is only available via attached properties"));
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickBorderImageMesh>("QtQuick", 2, 8, "BorderImageMesh");
-#endif
-
- qmlRegisterType<QQuickFlickable, 9>(uri, 2, 9, "Flickable");
- qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
-
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathArc, 9>(uri, 2, 9, "PathArc");
- qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
-#endif
-
- qmlRegisterType<QQuickText, 9>(uri, 2, 9, "Text");
- qmlRegisterType<QQuickTextInput, 9>(uri, 2, 9, "TextInput");
- qmlRegisterType<QQuickTouchPoint>(uri, 2, 9, "TouchPoint");
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
- qmlRegisterUncreatableType<QPointingDeviceUniqueId>(uri, 2, 9, "PointingDeviceUniqueId", QQuickTouchPoint::tr("PointingDeviceUniqueId is only available via read-only properties"));
-#if QT_CONFIG(quick_positioners)
- qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner",
- QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
-#endif
-
-#if QT_CONFIG(quick_shadereffect)
- qmlRegisterType<QQuickShaderEffectSource, 9>(uri, 2, 9, "ShaderEffectSource");
-#endif
-
- qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
- qmlRegisterType<QQuickTextEdit, 10>(uri, 2, 10, "TextEdit");
- qmlRegisterType<QQuickText, 10>(uri, 2, 10, "Text");
-
-#if QT_CONFIG(quick_path)
- qmlRegisterType<QQuickPathAngleArc>(uri, 2, 11, "PathAngleArc");
-#endif
-
-#if QT_CONFIG(quick_animatedimage)
- qmlRegisterType<QQuickAnimatedImage, 11>(uri, 2, 11,"AnimatedImage");
-#endif
- qmlRegisterType<QQuickItem, 11>(uri, 2, 11,"Item");
- qmlRegisterType<QQuickFlickable, 12>(uri, 2, 12, "Flickable");
-
- // classes related to Input Handlers which are newly exposed since 5.12
- qmlRegisterUncreatableType<QQuickPointerEvent>(uri, 2, 12, "PointerEvent",
- QQuickPointerHandler::tr("PointerEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickPointerMouseEvent>(uri, 2, 12, "PointerMouseEvent",
- QQuickPointerHandler::tr("PointerMouseEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickPointerTouchEvent>(uri, 2, 12, "PointerTouchEvent",
- QQuickPointerHandler::tr("PointerTouchEvent is only available as a parameter of several signals in PointerHandler"));
- qmlRegisterUncreatableType<QQuickEventPoint>(uri, 2, 12, "EventPoint",
- QQuickPointerHandler::tr("EventPoint is only available as a member of PointerEvent"));
- qmlRegisterUncreatableType<QQuickEventTouchPoint>(uri, 2, 12, "EventTouchPoint",
- QQuickPointerHandler::tr("EventTouchPoint is only available as a member of PointerEvent"));
- qmlRegisterUncreatableType<QQuickPointerDevice>(uri, 2, 12, "PointerDevice",
- QQuickPointerHandler::tr("PointerDevice is only available as a property of PointerEvent"));
-
- // Input Handlers are part of QtQuick, not a separate module, since 5.12
- qmlRegisterUncreatableType<QQuickPointerHandler>(uri, 2, 12, "PointerHandler",
- QQuickPointerHandler::tr("PointerHandler is an abstract base class"));
- qmlRegisterType<QQuickPointHandler>(uri, 2, 12, "PointHandler");
- qmlRegisterType<QQuickDragHandler>(uri, 2, 12, "DragHandler");
- qmlRegisterUncreatableType<QQuickDragAxis>(uri, 2, 12, "DragAxis",
- QQuickDragHandler::tr("DragAxis is only available as a grouped property of DragHandler"));
- qmlRegisterType<QQuickHoverHandler>(uri, 2, 12, "HoverHandler");
- qmlRegisterType<QQuickPinchHandler>(uri, 2, 12, "PinchHandler");
- qmlRegisterType<QQuickTapHandler>(uri, 2, 12, "TapHandler");
qRegisterMetaType<QQuickHandlerPoint>();
-
- // The rest of the 5.12 revisions
-#if QT_CONFIG(quick_sprite)
- qmlRegisterType<QQuickAnimatedSprite, 12>("QtQuick", 2, 12, "AnimatedSprite");
-#endif
- qmlRegisterType<QQuickGradient, 12>(uri, 2, 12, "Gradient");
- qmlRegisterType<QQuickFlickable, 12>(uri, 2, 12, "Flickable");
- qmlRegisterType<QQuickText, 12>(uri, 2, 12, "Text");
-#if QT_CONFIG(quick_tableview)
- qmlRegisterType<QQuickTableView>(uri, 2, 12, "TableView");
-#endif
-
-#if QT_CONFIG(quick_itemview)
- qmlRegisterUncreatableType<QQuickItemView, 13>(uri, 2, 13, itemViewName, itemViewMessage);
-#endif
-#if QT_CONFIG(quick_pathview)
- qmlRegisterType<QQuickPathView, 13>(uri, 2, 13, "PathView");
-#endif
-#if QT_CONFIG(quick_gridview)
- qmlRegisterType<QQuickGridView, 13>(uri, 2, 13, "GridView");
-#endif
-#if QT_CONFIG(quick_tableview)
- qmlRegisterType<QQuickTableView, 14>(uri, 2, 14, "TableView");
-#endif
-#if QT_CONFIG(wheelevent)
- qmlRegisterType<QQuickWheelHandler>(uri, 2, 14, "WheelHandler");
- qmlRegisterUncreatableType<QQuickPointerScrollEvent>(uri, 2, 14, "PointerScrollEvent",
- QQuickPointerHandler::tr("PointerScrollEvent is only available via the WheelHandler::wheel signal"));
-#endif
- qmlRegisterUncreatableType<QQuickImageBase, 14>(uri, 2, 14, "ImageBase",
- QQuickPointerHandler::tr("ImageBase is an abstract base class"));
- qmlRegisterType<QQuickImage, 14>(uri, 2, 14, "Image");
- qmlRegisterType<QQuickDragHandler, 14>(uri, 2, 14, "DragHandler");
}
static void initResources()
@@ -513,12 +195,7 @@ QT_BEGIN_NAMESPACE
void QQuickItemsModule::defineModule()
{
initResources();
-
- QByteArray name = "QtQuick";
- int majorVersion = 2;
- int minorVersion = 0;
-
- qt_quickitems_defineModule(name, majorVersion, minorVersion);
+ qt_quickitems_defineModule();
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index cd79efe256..815c5ae644 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
+#include <QtGui/qevent.h>
#include <qqml.h>
QT_BEGIN_NAMESPACE
@@ -61,6 +63,26 @@ public:
static void defineModule();
};
+struct QPointingDeviceUniqueIdForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QPointingDeviceUniqueId)
+ QML_NAMED_ELEMENT(PointingDeviceUniqueId)
+ QML_ADDED_IN_MINOR_VERSION(9)
+ QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.")
+};
+
+#if !QT_CONFIG(quick_animatedimage)
+struct QQuickAnimatedImageNotAvailable
+{
+ Q_GADGET
+ QML_UNAVAILABLE
+ QML_NAMED_ELEMENT(AnimatedImage)
+ QML_ADDED_IN_MINOR_VERSION(0)
+ QML_UNCREATABLE("Qt was built without support for QMovie.")
+};
+#endif
+
QT_END_NAMESPACE
#endif // QQUICKITEMSMODULE_P_H
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index a931abca58..7fb392233e 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -197,6 +197,10 @@ void QQuickItemView::setModel(const QVariant &m)
disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ if (QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
+ disconnect(delegateModel, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ disconnect(delegateModel, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
+ }
}
QQmlInstanceModel *oldModel = d->model;
@@ -232,6 +236,10 @@ void QQuickItemView::setModel(const QVariant &m)
connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*)));
connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*)));
+ if (QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
+ connect(delegateModel, SIGNAL(itemPooled(int, QObject *)), this, SLOT(onItemPooled(int, QObject *)));
+ connect(delegateModel, SIGNAL(itemReused(int, QObject *)), this, SLOT(onItemReused(int, QObject *)));
+ }
if (isComponentComplete()) {
d->updateSectionCriteria();
d->refill();
@@ -694,6 +702,28 @@ void QQuickItemView::setHighlightMoveDuration(int duration)
}
}
+bool QQuickItemView::reuseItems() const
+{
+ return bool(d_func()->reusableFlag == QQmlDelegateModel::Reusable);
+}
+
+void QQuickItemView::setReuseItems(bool reuse)
+{
+ Q_D(QQuickItemView);
+ if (reuseItems() == reuse)
+ return;
+
+ d->reusableFlag = reuse ? QQmlDelegateModel::Reusable : QQmlDelegateModel::NotReusable;
+
+ if (!reuse && d->model) {
+ // When we're told to not reuse items, we
+ // immediately, as documented, drain the pool.
+ d->model->drainReusableItemsPool(0);
+ }
+
+ emit reuseItemsChanged();
+}
+
QQuickTransition *QQuickItemView::populateTransition() const
{
Q_D(const QQuickItemView);
@@ -848,7 +878,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
setPosition(qMin(itemPos, maxExtent));
// now release the reference to all the old visible items.
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
item = visibleItem(idx);
}
if (item) {
@@ -1091,8 +1121,8 @@ qreal QQuickItemViewPrivate::calculatedMaxExtent() const
void QQuickItemViewPrivate::applyDelegateChange()
{
- releaseVisibleItems();
- releaseItem(currentItem);
+ releaseVisibleItems(QQmlDelegateModel::NotReusable);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
updateSectionCriteria();
refill();
@@ -1194,7 +1224,7 @@ void QQuickItemView::destroyRemoved()
} else {
if (hasRemoveTransition)
d->runDelayedRemoveTransition = true;
- d->releaseItem(item);
+ d->releaseItem(item, d->reusableFlag);
it = d->visibleItems.erase(it);
}
} else {
@@ -1638,7 +1668,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (currentItem) {
if (currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
currentIndex = modelIndex;
emit q->currentIndexChanged();
@@ -1675,7 +1705,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
if (oldCurrentItem != currentItem
&& (!oldCurrentItem || !currentItem || oldCurrentItem->item != currentItem->item))
emit q->currentItemChanged();
- releaseItem(oldCurrentItem);
+ releaseItem(oldCurrentItem, reusableFlag);
}
void QQuickItemViewPrivate::clear(bool onDestruction)
@@ -1689,17 +1719,17 @@ void QQuickItemViewPrivate::clear(bool onDestruction)
bufferedChanges.reset();
timeline.clear();
- releaseVisibleItems();
+ releaseVisibleItems(QQmlInstanceModel::NotReusable);
visibleIndex = 0;
for (FxViewItem *item : qAsConst(releasePendingTransition)) {
item->releaseAfterTransition = false;
- releaseItem(item);
+ releaseItem(item, QQmlInstanceModel::NotReusable);
}
releasePendingTransition.clear();
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, QQmlDelegateModel::NotReusable);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -1758,7 +1788,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
currentChanges.reset();
bufferedChanges.reset();
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
}
int prevCount = itemCount;
@@ -1925,7 +1955,7 @@ void QQuickItemViewPrivate::layout()
continue;
if (!success) {
- releaseItem(releasePendingTransition[i]);
+ releaseItem(releasePendingTransition[i], reusableFlag);
releasePendingTransition.remove(i);
--count;
} else {
@@ -2071,9 +2101,9 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
// Whatever removed/moved items remain are no longer visible items.
prepareRemoveTransitions(&currentChanges.removedItems);
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
+ for (auto it = currentChanges.removedItems.begin();
it != currentChanges.removedItems.end(); ++it) {
- releaseItem(it.value());
+ releaseItem(it.value(), reusableFlag);
}
currentChanges.removedItems.clear();
@@ -2082,7 +2112,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
if (currentItem->item && currentItem->attached)
currentItem->attached->setIsCurrentItem(false);
auto oldCurrentItem = currentItem;
- releaseItem(currentItem);
+ releaseItem(currentItem, reusableFlag);
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
@@ -2163,11 +2193,11 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQmlChangeSet::Ch
removeResult->sizeChangesAfterVisiblePos += item->size();
}
if (removal.isMove()) {
- currentChanges.removedItems.insert(removal.moveKey(item->index), item);
+ currentChanges.removedItems.replace(removal.moveKey(item->index), item);
item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true);
} else {
// track item so it is released later
- currentChanges.removedItems.insertMulti(QQmlChangeSet::MoveKey(), item);
+ currentChanges.removedItems.insert(QQmlChangeSet::MoveKey(), item);
}
if (!removeResult->changedFirstItem && item == *visibleItems.constBegin())
removeResult->changedFirstItem = true;
@@ -2238,15 +2268,14 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
visibleItems[i]->prepareTransition(transitioner, viewBounds);
}
-void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
+void QQuickItemViewPrivate::prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems)
{
if (!transitioner)
return;
if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)
|| transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
- for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin();
- it != removedItems->end(); ) {
+ for (auto it = removedItems->begin(); it != removedItems->end(); ) {
bool isRemove = it.key().moveId < 0;
if (isRemove) {
FxViewItem *item = *it;
@@ -2289,7 +2318,7 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona
{
for (int i=0; i<releasePendingTransition.count(); i++) {
if (releasePendingTransition.at(i)->transitionableItem == item) {
- releaseItem(releasePendingTransition.takeAt(i));
+ releaseItem(releasePendingTransition.takeAt(i), reusableFlag);
return;
}
}
@@ -2395,7 +2424,23 @@ void QQuickItemView::destroyingItem(QObject *object)
}
}
-bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
+void QQuickItemView::onItemPooled(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->pooled();
+}
+
+void QQuickItemView::onItemReused(int modelIndex, QObject *object)
+{
+ Q_UNUSED(modelIndex);
+
+ if (auto *attached = d_func()->getAttachedObject(object))
+ emit attached->reused();
+}
+
+bool QQuickItemViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
Q_Q(QQuickItemView);
if (!item)
@@ -2406,7 +2451,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
QQmlInstanceModel::ReleaseFlags flags = {};
if (model && item->item) {
- flags = model->release(item->item);
+ flags = model->release(item->item, reusableFlag);
if (!flags && !isClearing) {
// item was not destroyed, and we no longer reference it.
if (item->item->parentItem() == contentItem) {
@@ -2417,6 +2462,8 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
} else if (flags & QQmlInstanceModel::Destroyed) {
item->item->setParentItem(nullptr);
+ } else if (flags & QQmlInstanceModel::Pooled) {
+ item->setVisible(false);
}
}
delete item;
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 66e09f9ed1..3f83383cd5 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -110,6 +110,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
+ Q_PROPERTY(bool reuseItems READ reuseItems WRITE setReuseItems NOTIFY reuseItemsChanged REVISION 15)
+
+ QML_NAMED_ELEMENT(ItemView)
+ QML_UNCREATABLE("ItemView is an abstract base class.")
+ QML_ADDED_IN_MINOR_VERSION(1)
+
public:
// this holds all layout enum values so they can be referred to by other enums
// to ensure consistent values - e.g. QML references to GridView.TopToBottom flow
@@ -222,6 +228,9 @@ public:
int highlightMoveDuration() const;
virtual void setHighlightMoveDuration(int);
+ bool reuseItems() const;
+ void setReuseItems(bool reuse);
+
enum PositionMode { Beginning, Center, End, Visible, Contain, SnapPosition };
Q_ENUM(PositionMode)
@@ -277,6 +286,8 @@ Q_SIGNALS:
void preferredHighlightEndChanged();
void highlightMoveDurationChanged();
+ Q_REVISION(15) void reuseItemsChanged();
+
protected:
void updatePolish() override;
void componentComplete() override;
@@ -292,6 +303,8 @@ protected Q_SLOTS:
virtual void initItem(int index, QObject *item);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
void destroyingItem(QObject *item);
+ Q_REVISION(15) void onItemPooled(int modelIndex, QObject *object);
+ Q_REVISION(15) void onItemReused(int modelIndex, QObject *object);
void animStopped();
void trackedPositionChanged();
@@ -395,6 +408,9 @@ Q_SIGNALS:
void prevSectionChanged();
void nextSectionChanged();
+ void pooled();
+ void reused();
+
public:
QPointer<QQuickItemView> m_view;
bool m_isCurrent : 1;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a448cf9a38..0bc2a6b768 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -92,7 +92,7 @@ public:
int itemCount;
int newCurrentIndex;
QQmlChangeSet pendingChanges;
- QHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
+ QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems;
bool active : 1;
bool currentChanged : 1;
@@ -174,7 +174,7 @@ public:
void mirrorChange() override;
FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested);
- virtual bool releaseItem(FxViewItem *item);
+ virtual bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag);
QQuickItem *createHighlightItem() const;
QQuickItem *createComponentItem(QQmlComponent *component, qreal zValue, bool createDefault = false) const;
@@ -203,7 +203,7 @@ public:
void createTransitioner();
void prepareVisibleItemTransitions();
- void prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
+ void prepareRemoveTransitions(QMultiHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds);
void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override;
@@ -238,15 +238,17 @@ public:
q->polish();
}
- void releaseVisibleItems() {
+ void releaseVisibleItems(QQmlInstanceModel::ReusableFlag reusableFlag) {
// make a copy and clear the visibleItems first to avoid destroyed
// items being accessed during the loop (QTBUG-61294)
const QList<FxViewItem *> oldVisible = visibleItems;
visibleItems.clear();
for (FxViewItem *item : oldVisible)
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
+ virtual QQuickItemViewAttached *getAttachedObject(const QObject *) const { return nullptr; }
+
QPointer<QQmlInstanceModel> model;
QVariant modelVariant;
int itemCount;
@@ -288,6 +290,11 @@ public:
QQmlComponent *footerComponent;
FxViewItem *footer;
+ // Reusing delegate items cannot be on by default for backwards compatibility.
+ // Reusing an item will e.g mean that Component.onCompleted will only be called for an
+ // item when it's created and not when it's reused, which will break legacy applications.
+ QQmlInstanceModel::ReusableFlag reusableFlag = QQmlInstanceModel::NotReusable;
+
struct MovedItem {
FxViewItem *item;
QQmlChangeSet::MoveKey moveKey;
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 109851608b..b7649c9952 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -925,7 +925,7 @@ QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent)
*/
QQmlListProperty<QObject> QQuickViewTransitionAttached::targetItems()
{
- return QQmlListProperty<QObject>(this, m_targetItems);
+ return QQmlListProperty<QObject>(this, &m_targetItems);
}
QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedProperties(QObject *obj)
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 0c7a9cad75..5f4e74171e 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -194,6 +194,10 @@ class QQuickViewTransitionAttached : public QObject
Q_PROPERTY(QList<int> targetIndexes READ targetIndexes NOTIFY targetIndexesChanged)
Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged)
+ QML_NAMED_ELEMENT(ViewTransition)
+ QML_UNCREATABLE("ViewTransition is only available via attached properties.")
+ QML_ATTACHED(QQuickViewTransitionAttached)
+
public:
QQuickViewTransitionAttached(QObject *parent);
@@ -227,6 +231,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickViewTransitionAttached)
-QML_DECLARE_TYPEINFO(QQuickViewTransitionAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKITEMVIEWTRANSITION_P_P_H
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index ef601dcaec..0d78070401 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -49,6 +49,7 @@
#include <QtCore/qmath.h>
#include <private/qquicksmoothedanimation_p_p.h>
+#include <private/qqmlcomponent_p.h>
#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
@@ -91,7 +92,7 @@ public:
FxViewItem *newViewItem(int index, QQuickItem *item) override;
void initializeViewItem(FxViewItem *item) override;
- bool releaseItem(FxViewItem *item) override;
+ bool releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag) override;
void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override;
void repositionPackageItemAt(QQuickItem *item, int index) override;
void resetFirstItemPosition(qreal pos = 0.0) override;
@@ -138,6 +139,8 @@ public:
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override;
+ QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+
void fixupHeader();
void fixupHeaderCompleted();
QQuickListView::Orientation orient;
@@ -200,6 +203,8 @@ public:
}
friend class QQuickViewSection;
+
+ static void setSectionHelper(QQmlContext *context, QQuickItem *sectionItem, const QString &section);
};
//----------------------------------------------------------------------------
@@ -641,15 +646,15 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
}
}
-bool QQuickListViewPrivate::releaseItem(FxViewItem *item)
+bool QQuickListViewPrivate::releaseItem(FxViewItem *item, QQmlInstanceModel::ReusableFlag reusableFlag)
{
if (!item || !model)
- return QQuickItemViewPrivate::releaseItem(item);
+ return QQuickItemViewPrivate::releaseItem(item, reusableFlag);
QPointer<QQuickItem> it = item->item;
QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached);
- bool released = QQuickItemViewPrivate::releaseItem(item);
+ bool released = QQuickItemViewPrivate::releaseItem(item, reusableFlag);
if (released && it && att && att->m_sectionItem) {
// We hold no more references to this item
int i = 0;
@@ -689,7 +694,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
int newModelIdx = qBound(0, modelIndex + count, model->count());
count = newModelIdx - modelIndex;
if (count) {
- releaseVisibleItems();
+ releaseVisibleItems(reusableFlag);
modelIndex = newModelIdx;
visibleIndex = modelIndex;
visiblePos = itemEnd + count * (averageSize + spacing);
@@ -744,7 +749,7 @@ void QQuickListViewPrivate::removeItem(FxViewItem *item)
releasePendingTransition.append(item);
} else {
qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << (QObject *)(item->item);
- releaseItem(item);
+ releaseItem(item, reusableFlag);
}
}
@@ -1003,14 +1008,20 @@ QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
sectionCache[i] = nullptr;
sectionItem->setVisible(true);
QQmlContext *context = QQmlEngine::contextForObject(sectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), section);
+ setSectionHelper(context, sectionItem, section);
} else {
QQmlContext *creationContext = sectionCriteria->delegate()->creationContext();
QQmlContext *context = new QQmlContext(
creationContext ? creationContext : qmlContext(q));
- context->setContextProperty(QLatin1String("section"), section);
- QObject *nobj = sectionCriteria->delegate()->beginCreate(context);
+ QQmlComponent* delegate = sectionCriteria->delegate();
+ QQmlComponentPrivate* delegatePriv = QQmlComponentPrivate::get(delegate);
+ QObject *nobj = delegate->beginCreate(context);
if (nobj) {
+ if (delegatePriv->hadRequiredProperties()) {
+ delegate->setInitialProperties(nobj, {{"section", section}});
+ } else {
+ context->setContextProperty(QLatin1String("section"), section);
+ }
QQml_setParent_noEvent(context, nobj);
sectionItem = qobject_cast<QQuickItem *>(nobj);
if (!sectionItem) {
@@ -1080,7 +1091,7 @@ void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
listItem->setPosition(pos);
} else {
QQmlContext *context = QQmlEngine::contextForObject(listItem->section())->parentContext();
- context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
+ setSectionHelper(context, listItem->section(), listItem->attached->m_section);
}
} else if (listItem->section()) {
qreal pos = listItem->position();
@@ -1136,7 +1147,7 @@ void QQuickListViewPrivate::updateStickySections()
currentSectionItem = getSectionItem(currentSection);
} else if (QString::compare(currentStickySection, currentSection, Qt::CaseInsensitive)) {
QQmlContext *context = QQmlEngine::contextForObject(currentSectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), currentSection);
+ setSectionHelper(context, currentSectionItem, currentSection);
}
currentStickySection = currentSection;
if (!currentSectionItem)
@@ -1170,7 +1181,7 @@ void QQuickListViewPrivate::updateStickySections()
nextSectionItem = getSectionItem(nextSection);
} else if (QString::compare(nextStickySection, nextSection, Qt::CaseInsensitive)) {
QQmlContext *context = QQmlEngine::contextForObject(nextSectionItem)->parentContext();
- context->setContextProperty(QLatin1String("section"), nextSection);
+ setSectionHelper(context, nextSectionItem, nextSection);
}
nextStickySection = nextSection;
if (!nextSectionItem)
@@ -1893,6 +1904,20 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
}
}
+void QQuickListViewPrivate::setSectionHelper(QQmlContext *context, QQuickItem *sectionItem, const QString &section)
+{
+ if (context->contextProperty(QLatin1String("section")).isValid())
+ context->setContextProperty(QLatin1String("section"), section);
+ else
+ sectionItem->setProperty("section", section);
+}
+
+QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject *object) const
+{
+ QObject *attachedObject = qmlAttachedPropertiesObject<QQuickListView>(object);
+ return static_cast<QQuickItemViewAttached *>(attachedObject);
+}
+
//----------------------------------------------------------------------------
/*!
@@ -2041,6 +2066,39 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
of type \l [QML] {real}, so it is possible to set fractional
values like \c 0.1.
+ \section1 Reusing items
+
+ Since 5.15, ListView can be configured to recycle items instead of instantiating
+ from the \l delegate whenever new rows are flicked into view. This approach improves
+ performance, depending on the complexity of the delegate. Reusing
+ items is off by default (for backwards compatibility reasons), but can be switched
+ on by setting the \l reuseItems property to \c true.
+
+ When an item is flicked out, it moves to the \e{reuse pool}, which is an
+ internal cache of unused items. When this happens, the \l ListView::pooled
+ signal is emitted to inform the item about it. Likewise, when the item is
+ moved back from the pool, the \l ListView::reused signal is emitted.
+
+ Any item properties that come from the model are updated when the
+ item is reused. This includes \c index and \c row, but also
+ any model roles.
+
+ \note Avoid storing any state inside a delegate. If you do, reset it
+ manually on receiving the \l ListView::reused signal.
+
+ If an item has timers or animations, consider pausing them on receiving
+ the \l ListView::pooled signal. That way you avoid using the CPU resources
+ for items that are not visible. Likewise, if an item has resources that
+ cannot be reused, they could be freed up.
+
+ \note While an item is in the pool, it might still be alive and respond
+ to connected signals and bindings.
+
+ The following example shows a delegate that animates a spinning rectangle. When
+ it is pooled, the animation is temporarily paused:
+
+ \snippet qml/listview/reusabledelegate.qml 0
+
\sa {QML Data Models}, GridView, PathView, {Qt Quick Examples - Views}
*/
QQuickListView::QQuickListView(QQuickItem *parent)
@@ -2120,8 +2178,6 @@ QQuickListView::~QQuickListView()
If an \l add transition is specified, it is applied immediately after
this signal is handled.
-
- The corresponding handler is \c onAdd.
*/
/*!
@@ -2130,8 +2186,6 @@ QQuickListView::~QQuickListView()
If a \l remove transition has been specified, it is applied after
this signal is handled, providing that \l delayRemove is false.
-
- The corresponding handler is \c onRemove.
*/
/*!
@@ -2207,6 +2261,20 @@ QQuickListView::~QQuickListView()
*/
/*!
+ \qmlproperty bool QtQuick::ListView::reuseItems
+
+ This property enables you to reuse items that are instantiated
+ from the \l delegate. If set to \c false, any currently
+ pooled items are destroyed.
+
+ This property is \c false by default.
+
+ \since 5.15
+
+ \sa {Reusing items}, ListView::pooled, ListView::reused
+*/
+
+/*!
\qmlproperty Component QtQuick::ListView::highlight
This property holds the component to use as the highlight.
@@ -2776,21 +2844,25 @@ void QQuickListView::setSnapMode(SnapMode mode)
This property determines the positioning of the \l{headerItem}{header item}.
- The possible values are:
- \list
- \li ListView.InlineHeader (default) - the header is positioned in the beginning
+ \value ListView.InlineHeader (default) The header is positioned at the beginning
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayHeader - the header is positioned in the beginning of the view.
- \li ListView.PullBackHeader - the header is positioned in the beginning of the view.
+
+ \value ListView.OverlayHeader The header is positioned at the beginning of the view.
+
+ \value ListView.PullBackHeader The header is positioned at the beginning of the view.
The header can be pushed away by moving the content forwards, and pulled back by
moving the content backwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the header. For example, if the header should be shown above the
\l delegate items when using \c ListView.OverlayHeader, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c headerPositioning is not set to \c ListView.InlineHeader, the
+ user cannot press and flick the list from the header. In any case, the
+ \l{headerItem}{header item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::HeaderPositioning QQuickListView::headerPositioning() const
{
@@ -2819,21 +2891,25 @@ void QQuickListView::setHeaderPositioning(QQuickListView::HeaderPositioning posi
This property determines the positioning of the \l{footerItem}{footer item}.
- The possible values are:
- \list
- \li ListView.InlineFooter (default) - the footer is positioned in the end
+ \value ListView.InlineFooter (default) The footer is positioned at the end
of the content and moves together with the content like an ordinary item.
- \li ListView.OverlayFooter - the footer is positioned in the end of the view.
- \li ListView.PullBackFooter - the footer is positioned in the end of the view.
+
+ \value ListView.OverlayFooter The footer is positioned at the end of the view.
+
+ \value ListView.PullBackFooter The footer is positioned at the end of the view.
The footer can be pushed away by moving the content backwards, and pulled back by
moving the content forwards.
- \endlist
\note This property has no effect on the \l {QQuickItem::z}{stacking order}
of the footer. For example, if the footer should be shown above the
\l delegate items when using \c ListView.OverlayFooter, its Z value
should be set to a value higher than that of the delegates. For more
information, see \l {Stacking Order in ListView}.
+
+ \note If \c footerPositioning is not set to \c ListView.InlineFooter, the
+ user cannot press and flick the list from the footer. In any case, the
+ \l{footerItem}{footer item} may contain items or event handlers that
+ provide custom handling of mouse or touch input.
*/
QQuickListView::FooterPositioning QQuickListView::footerPositioning() const
{
@@ -3307,6 +3383,13 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickListView);
+
+ if (d->model) {
+ // When the view changes size, we force the pool to
+ // shrink by releasing all pooled items.
+ d->model->drainReusableItemsPool(0);
+ }
+
if (d->isRightToLeft()) {
// maintain position relative to the right edge
qreal dx = newGeometry.width() - oldGeometry.width();
@@ -3714,6 +3797,23 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj)
return new QQuickListViewAttached(obj);
}
+bool QQuickListView::contains(const QPointF &point) const
+{
+ bool ret = QQuickItemView::contains(point);
+ // QTBUG-74046: if a mouse press "falls through" a floating header or footer, don't allow dragging the list from there
+ if (ret) {
+ if (auto header = headerItem()) {
+ if (headerPositioning() != QQuickListView::InlineHeader && header->contains(mapToItem(header, point)))
+ ret = false;
+ }
+ if (auto footer = footerItem()) {
+ if (footerPositioning() != QQuickListView::InlineFooter && footer->contains(mapToItem(footer, point)))
+ ret = false;
+ }
+ }
+ return ret;
+}
+
QT_END_NAMESPACE
#include "moc_qquicklistview_p.cpp"
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index f2bab9e018..be21b93155 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -70,6 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickViewSection : public QObject
Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged)
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
+ QML_NAMED_ELEMENT(ViewSection)
public:
QQuickViewSection(QQuickListView *parent=nullptr);
@@ -130,6 +131,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickListView : public QQuickItemView
Q_PROPERTY(FooterPositioning footerPositioning READ footerPositioning WRITE setFooterPositioning NOTIFY footerPositioningChanged REVISION 4)
Q_CLASSINFO("DefaultProperty", "data")
+ QML_NAMED_ELEMENT(ListView)
+ QML_ATTACHED(QQuickListViewAttached)
public:
QQuickListView(QQuickItem *parent=nullptr);
@@ -176,6 +179,8 @@ public:
static QQuickListViewAttached *qmlAttachedProperties(QObject *);
+ bool contains(const QPointF &point) const override;
+
public Q_SLOTS:
void incrementCurrentIndex();
void decrementCurrentIndex();
@@ -216,7 +221,6 @@ public:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickListView, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickListView)
QML_DECLARE_TYPE(QQuickViewSection)
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8c15b60712..e1d533f092 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -45,6 +45,7 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmlcomponent_p.h>
+#include <private/qqmlincubator_p.h>
QT_BEGIN_NAMESPACE
@@ -665,7 +666,8 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj)
QV4::Scope scope(v4);
QV4::ScopedValue ipv(scope, initialPropertyValues.value());
QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
- d->initializeObjectWithInitialProperties(qmlContext, ipv, obj);
+ auto incubatorPriv = QQmlIncubatorPrivate::get(incubator);
+ d->initializeObjectWithInitialProperties(qmlContext, ipv, obj, incubatorPriv->requiredProperties());
}
void QQuickLoaderIncubator::statusChanged(Status status)
@@ -821,8 +823,6 @@ void QQuickLoader::itemChange(QQuickItem::ItemChange change, const QQuickItem::I
This signal is emitted when the \l status becomes \c Loader.Ready, or on successful
initial load.
-
- The corresponding handler is \c onLoaded.
*/
diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h
index de1dfa9da5..2d560fb856 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ QML_NAMED_ELEMENT(Loader)
public:
QQuickLoader(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index dc60712a9c..f54858e4eb 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -62,7 +62,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false), overThreshold(false), pressed(nullptr),
+ propagateComposedEvents(false), overThreshold(false),
pressAndHoldInterval(-1)
#if QT_CONFIG(quick_draganddrop)
, drag(nullptr)
@@ -275,8 +275,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
even when no mouse button is pressed.
\sa hoverEnabled
-
- The corresponding handler is \c onEntered.
*/
/*!
@@ -315,8 +313,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
both be considered to be simultaneously hovered.
\sa hoverEnabled
-
- The corresponding handler is \c onExited.
*/
/*!
@@ -333,8 +329,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect.
-
- The corresponding handler is \c onPositionChanged.
*/
/*!
@@ -349,8 +343,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
-
- The corresponding handler is \c onClicked.
*/
/*!
@@ -365,8 +357,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
release. The default is to accept the event and not allow other MouseAreas beneath this one to
handle the event. If \e accepted is set to false, no further events will be sent to this MouseArea
until the button is next pressed.
-
- The corresponding handler is \c onPressed.
*/
/*!
@@ -379,8 +369,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect.
- The corresponding handler is \c onReleased.
-
\sa canceled
*/
@@ -393,8 +381,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
parameter has no effect, unless the \l propagateComposedEvents property is \c true.
-
- The corresponding handler is \c onPressAndHold.
*/
/*!
@@ -407,8 +393,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
When handling this signal, if the \l {MouseEvent::}{accepted} property of the \a mouse
parameter is set to false, the pressed/released/clicked signals will be emitted for the second
click; otherwise they are suppressed. The \c accepted property defaults to true.
-
- The corresponding handler is \c onDoubleClicked.
*/
/*!
@@ -422,8 +406,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
\l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
the logic when the MouseArea has lost the mouse handling to the \l Flickable,
\c canceled should be handled in addition to \l released.
-
- The corresponding handler is \c onCanceled.
*/
/*!
@@ -434,8 +416,6 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
The \a wheel parameter provides information about the event, including the x and y
position, any buttons currently pressed, and information about the wheel movement, including
angleDelta and pixelDelta.
-
- The corresponding handler is \c onWheel.
*/
QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index 139289c06b..806cc41369 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -85,6 +85,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseArea : public QQuickItem
#endif
Q_PROPERTY(bool containsPress READ containsPress NOTIFY containsPressChanged REVISION 4)
Q_PROPERTY(int pressAndHoldInterval READ pressAndHoldInterval WRITE setPressAndHoldInterval NOTIFY pressAndHoldIntervalChanged RESET resetPressAndHoldInterval REVISION 9)
+ QML_NAMED_ELEMENT(MouseArea)
public:
QQuickMouseArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 9a371207ce..383718c979 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -88,20 +88,18 @@ void QQuickTouchPoint::setPointId(int id)
These properties hold the current position of the touch point.
*/
-void QQuickTouchPoint::setX(qreal x)
+void QQuickTouchPoint::setPosition(QPointF p)
{
- if (_x == x)
+ bool xch = (_x != p.x());
+ bool ych = (_y != p.y());
+ if (!xch && !ych)
return;
- _x = x;
- emit xChanged();
-}
-
-void QQuickTouchPoint::setY(qreal y)
-{
- if (_y == y)
- return;
- _y = y;
- emit yChanged();
+ _x = p.x();
+ _y = p.y();
+ if (xch)
+ emit xChanged();
+ if (ych)
+ emit yChanged();
}
/*!
@@ -365,24 +363,18 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
If minimumTouchPoints is set to a value greater than one, this signal will not be emitted until the minimum number
of required touch points has been reached.
-
- The corresponding handler is \c onPressed.
*/
/*!
\qmlsignal QtQuick::MultiPointTouchArea::updated(list<TouchPoint> touchPoints)
This signal is emitted when existing touch points are updated. \a touchPoints is a list of these updated points.
-
- The corresponding handler is \c onUpdated.
*/
/*!
\qmlsignal QtQuick::MultiPointTouchArea::released(list<TouchPoint> touchPoints)
This signal is emitted when existing touch points are removed. \a touchPoints is a list of these removed points.
-
- The corresponding handler is \c onReleased.
*/
/*!
@@ -398,8 +390,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
\c canceled should be handled in addition to \l released.
\a touchPoints is the list of canceled points.
-
- The corresponding handler is \c onCanceled.
*/
/*!
@@ -413,8 +403,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
gesture is not grabbed, the nesting Flickable, for example, would also have an opportunity to grab.
The \a gesture object also includes information on the current set of \c touchPoints and the \c dragThreshold.
-
- The corresponding handler is \c onGestureStarted.
*/
/*!
@@ -423,8 +411,6 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
This signal is emitted when the touch points handled by the MultiPointTouchArea change. This includes adding new touch points,
removing or canceling previous touch points, as well as updating current touch point data. \a touchPoints is the list of all current touch
points.
-
- The corresponding handler is \c onTouchUpdated.
*/
/*!
@@ -798,13 +784,14 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT
//TODO: if !qmlDefined, could bypass setters.
// also, should only emit signals after all values have been set
dtp->setUniqueId(p->uniqueId());
- dtp->setX(p->pos().x());
- dtp->setY(p->pos().y());
+ dtp->setPosition(p->pos());
dtp->setEllipseDiameters(p->ellipseDiameters());
dtp->setPressure(p->pressure());
dtp->setRotation(p->rotation());
dtp->setVelocity(p->velocity());
- dtp->setArea(p->rect());
+ QRectF area(QPointF(), p->ellipseDiameters());
+ area.moveCenter(p->pos());
+ dtp->setArea(area);
dtp->setStartX(p->startPos().x());
dtp->setStartY(p->startPos().y());
dtp->setPreviousX(p->lastPos().x());
@@ -817,8 +804,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QM
{
dtp->setPreviousX(dtp->x());
dtp->setPreviousY(dtp->y());
- dtp->setX(e->localPos().x());
- dtp->setY(e->localPos().y());
+ dtp->setPosition(e->localPos());
if (e->type() == QEvent::MouseButtonPress) {
dtp->setStartX(e->localPos().x());
dtp->setStartY(e->localPos().y());
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 23f4ebff75..e34a3faad6 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -83,6 +83,7 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
Q_PROPERTY(qreal previousY READ previousY NOTIFY previousYChanged)
Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged)
Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged)
+ QML_NAMED_ELEMENT(TouchPoint)
public:
QQuickTouchPoint(bool qmlDefined = true)
@@ -96,10 +97,8 @@ public:
void setUniqueId(const QPointingDeviceUniqueId &id);
qreal x() const { return _x; }
- void setX(qreal x);
-
qreal y() const { return _y; }
- void setY(qreal y);
+ void setPosition(QPointF pos);
QSizeF ellipseDiameters() const { return _ellipseDiameters; }
void setEllipseDiameters(const QSizeF &d);
@@ -187,6 +186,9 @@ class QQuickGrabGestureEvent : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QObject> touchPoints READ touchPoints CONSTANT)
Q_PROPERTY(qreal dragThreshold READ dragThreshold CONSTANT)
+ QML_NAMED_ELEMENT(GestureEvent)
+ QML_UNCREATABLE("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea.")
+
public:
QQuickGrabGestureEvent() : _dragThreshold(QGuiApplication::styleHints()->startDragDistance()) {}
@@ -194,7 +196,7 @@ public:
bool wantsGrab() const { return _grab; }
QQmlListProperty<QObject> touchPoints() {
- return QQmlListProperty<QObject>(this, _touchPoints);
+ return QQmlListProperty<QObject>(this, &_touchPoints);
}
qreal dragThreshold() const { return _dragThreshold; }
@@ -213,6 +215,7 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem
Q_PROPERTY(int minimumTouchPoints READ minimumTouchPoints WRITE setMinimumTouchPoints NOTIFY minimumTouchPointsChanged)
Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged)
Q_PROPERTY(bool mouseEnabled READ mouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged)
+ QML_NAMED_ELEMENT(MultiPointTouchArea)
public:
QQuickMultiPointTouchArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickopenglinfo_p.h b/src/quick/items/qquickopenglinfo_p.h
index 86683d5348..b733d205e3 100644
--- a/src/quick/items/qquickopenglinfo_p.h
+++ b/src/quick/items/qquickopenglinfo_p.h
@@ -70,6 +70,11 @@ class QQuickOpenGLInfo : public QObject
Q_PROPERTY(ContextProfile profile READ profile NOTIFY profileChanged FINAL)
Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL)
+ QML_NAMED_ELEMENT(OpenGLInfo)
+ QML_UNCREATABLE("OpenGLInfo is only available via attached properties.")
+ QML_ADDED_IN_MINOR_VERSION(4)
+ QML_ATTACHED(QQuickOpenGLInfo)
+
public:
QQuickOpenGLInfo(QQuickItem *item = 0);
@@ -116,6 +121,4 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickOpenGLInfo, QML_HAS_ATTACHED_PROPERTIES)
-
#endif // QQUICKOPENGLINFO_P_H
diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp
index 26ef59c20e..5721f116e8 100644
--- a/src/quick/items/qquickopenglshadereffectnode.cpp
+++ b/src/quick/items/qquickopenglshadereffectnode.cpp
@@ -178,7 +178,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
if (state.isMatrixDirty())
program()->setUniformValue(loc, state.combinedMatrix());
} else if (d.specialType == UniformData::None) {
- switch (int(d.value.type())) {
+ switch (int(d.value.userType())) {
case QMetaType::QColor:
program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast<QColor>(d.value)));
break;
diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp
index 57848919f3..386c8d8862 100644
--- a/src/quick/items/qquickpainteditem.cpp
+++ b/src/quick/items/qquickpainteditem.cpp
@@ -133,7 +133,6 @@ QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
, contentsScale(1.0)
, fillColor(Qt::transparent)
, renderTarget(QQuickPaintedItem::Image)
- , performanceHints(nullptr)
, opaquePainting(false)
, antialiasing(false)
, mipmap(false)
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index ddc1fd99d9..4821a409be 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -56,6 +56,9 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem
Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
+ QML_NAMED_ELEMENT(PaintedItem)
+ QML_UNCREATABLE("Cannot create instance of abstract class PaintedItem.")
+
public:
explicit QQuickPaintedItem(QQuickItem *parent = nullptr);
~QQuickPaintedItem() override;
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 7ebe174a9e..4a8089f49c 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1164,8 +1164,6 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view begins moving due to user
interaction.
-
- The corresponding handler is \c onMovementStarted.
*/
/*!
@@ -1176,8 +1174,6 @@ bool QQuickPathView::isDragging() const
be emitted once the flick stops. If a flick was not
generated, this signal will be emitted when the
user stops dragging - i.e. a mouse or touch release.
-
- The corresponding handler is \c onMovementEnded.
*/
/*!
@@ -1186,16 +1182,12 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
-
- The corresponding handler is \c onFlickStarted.
*/
/*!
\qmlsignal QtQuick::PathView::flickEnded()
This signal is emitted when the view stops moving due to a flick.
-
- The corresponding handler is \c onFlickEnded.
*/
/*!
@@ -1203,8 +1195,6 @@ bool QQuickPathView::isDragging() const
This signal is emitted when the view starts to be dragged due to user
interaction.
-
- The corresponding handler is \c onDragStarted.
*/
/*!
@@ -1214,8 +1204,6 @@ bool QQuickPathView::isDragging() const
If the velocity of the drag is suffient at the time the
touch/mouse button is released then a flick will start.
-
- The corresponding handler is \c onDragEnded.
*/
/*!
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 66be7fa6ff..c12358e4f6 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -100,6 +100,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathView : public QQuickItem
Q_PROPERTY(MovementDirection movementDirection READ movementDirection WRITE setMovementDirection NOTIFY movementDirectionChanged REVISION 7)
Q_PROPERTY(int cacheItemCount READ cacheItemCount WRITE setCacheItemCount NOTIFY cacheItemCountChanged)
+ QML_NAMED_ELEMENT(PathView)
+ QML_ATTACHED(QQuickPathViewAttached)
public:
QQuickPathView(QQuickItem *parent = nullptr);
@@ -299,6 +301,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPathView)
-QML_DECLARE_TYPEINFO(QQuickPathView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKPATHVIEW_P_H
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 2301a5c26e..0692a1da42 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -210,8 +210,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
To ignore this gesture set the \c pinch.accepted property to false. The gesture
will be canceled and no further events will be sent.
-
- The corresponding handler is \c onPinchStarted.
*/
/*!
@@ -224,8 +222,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
reflect changes only since the beginning of the current gesture, and
therefore are not limited by the minimum and maximum limits in the
\l {PinchArea}{pinch} property.
-
- The corresponding handler is \c onPinchUpdated.
*/
/*!
@@ -236,8 +232,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
property) provides information about the pinch gesture, including the
scale, center and angle of the pinch.
-
- The corresponding handler is \c onPinchFinished.
*/
/*!
@@ -252,8 +246,6 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
will be greater than zero when the gesture indicates that the user wishes to
enter smart zoom, and zero when exiting (even though typically the same gesture
is used to toggle between the two states).
-
- The corresponding handler is \c onSmartZoom.
*/
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index cf21555823..d7f814cc8a 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+ QML_NAMED_ELEMENT(Pinch)
public:
QQuickPinch();
@@ -210,6 +211,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject
Q_PROPERTY(QPointF startPoint2 READ startPoint2)
Q_PROPERTY(int pointCount READ pointCount)
Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
+ QML_ANONYMOUS
public:
QQuickPinchEvent(QPointF c, qreal s, qreal a, qreal r)
@@ -268,6 +270,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT)
+ QML_NAMED_ELEMENT(PinchArea)
public:
QQuickPinchArea(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 65c48c583a..a8d050527b 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -928,8 +928,6 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
QQuickColumn::QQuickColumn(QQuickItem *parent)
@@ -1113,8 +1111,6 @@ void QQuickColumn::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickRowPrivate : public QQuickBasePositionerPrivate
@@ -1408,8 +1404,6 @@ void QQuickRow::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickGridPrivate : public QQuickBasePositionerPrivate
@@ -1992,8 +1986,6 @@ void QQuickGrid::reportConflictingAnchors()
\since 5.9
This signal is emitted when positioning has been completed.
-
- The corresponding handler is \c onPositioningComplete.
*/
class QQuickFlowPrivate : public QQuickBasePositionerPrivate
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index 94a737e1f1..b924cb9c12 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -112,6 +112,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
+ QML_NAMED_ELEMENT(Positioner)
+ QML_UNCREATABLE("Positioner is an abstract type that is only available as an attached property.")
+ QML_ATTACHED(QQuickPositionerAttached)
+
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
@@ -230,6 +235,7 @@ private:
class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
{
Q_OBJECT
+ QML_NAMED_ELEMENT(Column)
public:
QQuickColumn(QQuickItem *parent=nullptr);
@@ -246,6 +252,8 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+ QML_NAMED_ELEMENT(Row)
+
public:
QQuickRow(QQuickItem *parent=nullptr);
@@ -279,6 +287,7 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1)
Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1)
Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1)
+ QML_NAMED_ELEMENT(Grid)
public:
QQuickGrid(QQuickItem *parent=nullptr);
@@ -359,6 +368,7 @@ class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+ QML_NAMED_ELEMENT(Flow)
public:
QQuickFlow(QQuickItem *parent=nullptr);
@@ -395,6 +405,5 @@ QML_DECLARE_TYPE(QQuickGrid)
QML_DECLARE_TYPE(QQuickFlow)
QML_DECLARE_TYPE(QQuickBasePositioner)
-QML_DECLARE_TYPEINFO(QQuickBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKPOSITIONERS_P_H
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index f3cefc7463..c1f2b77f5b 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -257,7 +257,7 @@ QQuickGradient::~QQuickGradient()
QQmlListProperty<QQuickGradientStop> QQuickGradient::stops()
{
- return QQmlListProperty<QQuickGradientStop>(this, m_stops);
+ return QQmlListProperty<QQuickGradientStop>(this, &m_stops);
}
/*!
diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h
index d56a03d22d..934300b63b 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject
Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged)
+ QML_ANONYMOUS
public:
QQuickPen(QObject *parent=nullptr);
@@ -96,6 +97,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradientStop : public QObject
Q_PROPERTY(qreal position READ position WRITE setPosition)
Q_PROPERTY(QColor color READ color WRITE setColor)
+ QML_NAMED_ELEMENT(GradientStop)
public:
QQuickGradientStop(QObject *parent=nullptr);
@@ -121,6 +123,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGradient : public QObject
Q_PROPERTY(QQmlListProperty<QQuickGradientStop> stops READ stops)
Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged REVISION 12)
Q_CLASSINFO("DefaultProperty", "stops")
+ QML_NAMED_ELEMENT(Gradient)
Q_ENUMS(QGradient::Preset)
public:
@@ -161,6 +164,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRectangle : public QQuickItem
Q_PROPERTY(QJSValue gradient READ gradient WRITE setGradient RESET resetGradient)
Q_PROPERTY(QQuickPen * border READ border CONSTANT)
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ QML_NAMED_ELEMENT(Rectangle)
public:
QQuickRectangle(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index c8c5281089..20603720c5 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -139,8 +139,6 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
This signal is emitted when an item is added to the repeater. The \a index
parameter holds the index at which the item has been inserted within the
repeater, and the \a item parameter holds the \l Item that has been added.
-
- The corresponding handler is \c onItemAdded.
*/
/*!
@@ -152,8 +150,6 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
Do not keep a reference to \a item if it was created by this repeater, as
in these cases it will be deleted shortly after the signal is handled.
-
- The corresponding handler is \c onItemRemoved.
*/
QQuickRepeater::QQuickRepeater(QQuickItem *parent)
: QQuickItem(*(new QQuickRepeaterPrivate), parent)
diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h
index dbe3cd0c55..20984fa23e 100644
--- a/src/quick/items/qquickrepeater_p.h
+++ b/src/quick/items/qquickrepeater_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ QML_NAMED_ELEMENT(Repeater)
public:
QQuickRepeater(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h
index f5187a8eea..56b0ee86ab 100644
--- a/src/quick/items/qquickscalegrid_p_p.h
+++ b/src/quick/items/qquickscalegrid_p_p.h
@@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject
Q_PROPERTY(int top READ top WRITE setTop NOTIFY topBorderChanged)
Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightBorderChanged)
Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomBorderChanged)
+ QML_ANONYMOUS
public:
QQuickScaleGrid(QObject *parent=nullptr);
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index b17e505f4f..ed2d7eda3e 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -424,9 +424,6 @@ QScreen *QQuickScreenInfo::wrappedScreen() const
QQuickScreenAttached::QQuickScreenAttached(QObject* attachee)
: QQuickScreenInfo(attachee)
- , m_window(nullptr)
- , m_updateMask(nullptr)
- , m_updateMaskSet(false)
{
m_attachee = qobject_cast<QQuickItem*>(attachee);
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 10e524e4a0..9a2a9eaecf 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -54,7 +54,7 @@
#include <qqml.h>
#include <QRect>
#include <QSize>
-#include <private/qqmlglobal_p.h>
+#include <private/qtquickglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -64,7 +64,7 @@ class QQuickWindow;
class QScreen;
-class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickScreenInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
@@ -78,9 +78,7 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged)
Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged)
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
- // TODO Qt 6 Rename primaryOrientation to orientation
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged)
- // TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
Q_PROPERTY(int virtualX READ virtualX NOTIFY virtualXChanged REVISION 3)
@@ -128,7 +126,7 @@ protected:
QPointer<QScreen> m_screen;
};
-class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QQuickScreenInfo
+class Q_QUICK_PRIVATE_EXPORT QQuickScreenAttached : public QQuickScreenInfo
{
Q_OBJECT
Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask
@@ -152,22 +150,23 @@ protected Q_SLOTS:
void screenChanged(QScreen*);
private:
- QQuickWindow* m_window;
+ QQuickWindow* m_window = nullptr;
QQuickItem* m_attachee;
Qt::ScreenOrientations m_updateMask;
- bool m_updateMaskSet;
+ bool m_updateMaskSet = false;
};
-class Q_AUTOTEST_EXPORT QQuickScreen : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickScreen : public QObject
{
Q_OBJECT
+ QML_ATTACHED(QQuickScreenAttached)
+
public:
static QQuickScreenAttached *qmlAttachedProperties(QObject *object){ return new QQuickScreenAttached(object); }
};
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickScreen, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QQuickScreenInfo)
#endif
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 6e2f35882b..c14907092c 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -75,6 +75,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffect : public QQuickItem
Q_PROPERTY(QString log READ log NOTIFY logChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(bool supportsAtlasTextures READ supportsAtlasTextures WRITE setSupportsAtlasTextures NOTIFY supportsAtlasTexturesChanged REVISION 4)
+ QML_NAMED_ELEMENT(ShaderEffect)
public:
enum CullMode {
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index 79e05a5f9f..710d37c275 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -49,6 +49,7 @@ QT_REQUIRE_CONFIG(quick_shadereffect);
#include <QtCore/qsize.h>
#include <QtCore/qvector.h>
#include <QtCore/qbytearray.h>
+#include <QtQml/qqml.h>
#ifndef QQUICKSHADEREFFECTMESH_P_H
#define QQUICKSHADEREFFECTMESH_P_H
@@ -75,6 +76,10 @@ class QRectF;
class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMesh : public QObject
{
Q_OBJECT
+
+ QML_NAMED_ELEMENT(ShaderEffectMesh)
+ QML_UNCREATABLE("Cannot create instance of abstract class ShaderEffectMesh.")
+
public:
QQuickShaderEffectMesh(QObject *parent = nullptr);
virtual bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) = 0;
@@ -96,6 +101,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickGridMesh : public QQuickShaderEffectMesh
{
Q_OBJECT
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
+ QML_NAMED_ELEMENT(GridMesh)
public:
QQuickGridMesh(QObject *parent = nullptr);
bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override;
@@ -123,6 +129,10 @@ class QQuickBorderImageMesh : public QQuickShaderEffectMesh
Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+
+ QML_NAMED_ELEMENT(BorderImageMesh)
+ QML_ADDED_IN_MINOR_VERSION(8)
+
public:
QQuickBorderImageMesh(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index d612d1179f..c0a1ccab78 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -89,6 +89,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 6)
Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 9)
+ QML_NAMED_ELEMENT(ShaderEffectSource)
public:
enum WrapMode {
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index fab9e75190..98e5b82db8 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -86,6 +86,7 @@ class Q_QUICK_EXPORT QQuickSprite : public QQuickStochasticState
Q_PROPERTY(qreal frameRateVariation READ frameRateVariation WRITE setFrameRateVariation NOTIFY frameRateVariationChanged)
Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration)
Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged)
+ QML_NAMED_ELEMENT(Sprite)
public:
explicit QQuickSprite(QObject *parent = nullptr);
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index da505be911..5ad33389de 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -196,7 +196,7 @@ public:
QQmlListProperty<QQuickStochasticState> states()
{
- return QQmlListProperty<QQuickStochasticState>(this, m_states);
+ return QQmlListProperty<QQuickStochasticState>(this, &m_states);
}
QString globalGoal() const
@@ -272,7 +272,7 @@ public:
~QQuickSpriteEngine() override;
QQmlListProperty<QQuickSprite> sprites()
{
- return QQmlListProperty<QQuickSprite>(this, m_sprites);
+ return QQmlListProperty<QQuickSprite>(this, &m_sprites);
}
QQuickSprite* sprite(int sprite = 0) const;
@@ -330,6 +330,18 @@ inline int spriteCount(QQmlListProperty<QQuickSprite> *p)
return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
}
+inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, int idx, QQuickSprite *s)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->replace(idx, s);
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline void spriteRemoveLast(QQmlListProperty<QQuickSprite> *p)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->removeLast();
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
QT_END_NAMESPACE
#endif // QQUICKSPRITEENGINE_P_H
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index eb4b5335e7..c29938a1bb 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -162,7 +162,9 @@ void QQuickSpriteSequence::setInterpolate(bool arg)
QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
{
Q_D(QQuickSpriteSequence);
- return QQmlListProperty<QQuickSprite>(this, &d->m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &d->m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
bool QQuickSpriteSequence::running() const
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index 12c80d6a27..8361f7832a 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem
//###try to share similar spriteEngines for less overhead?
Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
Q_CLASSINFO("DefaultProperty", "sprites")
+ QML_NAMED_ELEMENT(SpriteSequence)
public:
explicit QQuickSpriteSequence(QQuickItem *parent = nullptr);
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 31d1c91649..ddaa1979b6 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -44,6 +44,7 @@
#include <QtQml/qqmlinfo.h>
#include <QtCore/qmath.h>
+#include <memory>
QT_BEGIN_NAMESPACE
@@ -51,15 +52,17 @@ class QQuickParentChangePrivate : public QQuickStateOperationPrivate
{
Q_DECLARE_PUBLIC(QQuickParentChange)
public:
- QQuickParentChangePrivate() : target(nullptr), parent(nullptr), origParent(nullptr), origStackBefore(nullptr),
- rewindParent(nullptr), rewindStackBefore(nullptr) {}
-
- QQuickItem *target;
+ QQuickItem *target = nullptr;
QPointer<QQuickItem> parent;
- QPointer<QQuickItem> origParent;
- QPointer<QQuickItem> origStackBefore;
- QQuickItem *rewindParent;
- QQuickItem *rewindStackBefore;
+
+ struct StateSnapshot {
+ QPointer<QQuickItem> parent;
+ QPointer<QQuickItem> stackBefore;
+ qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0;
+ };
+
+ std::unique_ptr<StateSnapshot> orig;
+ std::unique_ptr<StateSnapshot> rewind;
QQmlNullableValue<QQmlScriptString> xString;
QQmlNullableValue<QQmlScriptString> yString;
@@ -68,10 +71,11 @@ public:
QQmlNullableValue<QQmlScriptString> scaleString;
QQmlNullableValue<QQmlScriptString> rotationString;
- void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = nullptr);
+ void doChange(QQuickItem *targetParent);
+ void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot);
};
-void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore)
+void QQuickParentChangePrivate::doChange(QQuickItem *targetParent)
{
if (targetParent && target && target->parentItem()) {
Q_Q(QQuickParentChange);
@@ -137,11 +141,6 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
} else if (target) {
target->setParentItem(targetParent);
}
-
- //restore the original stack position.
- //### if stackBefore has also been reparented this won't work
- if (target && stackBefore)
- target->stackBefore(stackBefore);
}
/*!
@@ -305,7 +304,7 @@ bool QQuickParentChange::rotationIsSet() const
QQuickItem *QQuickParentChange::originalParent() const
{
Q_D(const QQuickParentChange);
- return d->origParent;
+ return d->orig ? d->orig->parent : nullptr;
}
/*!
@@ -473,21 +472,11 @@ void QQuickParentChange::saveOriginals()
{
Q_D(QQuickParentChange);
saveCurrentValues();
- d->origParent = d->rewindParent;
- d->origStackBefore = d->rewindStackBefore;
+ if (!d->orig)
+ d->orig.reset(new QQuickParentChangePrivate::StateSnapshot);
+ *d->orig = *d->rewind;
}
-/*void QQuickParentChange::copyOriginals(QQuickStateActionEvent *other)
-{
- Q_D(QQuickParentChange);
- QQuickParentChange *pc = static_cast<QQuickParentChange*>(other);
-
- d->origParent = pc->d_func()->rewindParent;
- d->origStackBefore = pc->d_func()->rewindStackBefore;
-
- saveCurrentValues();
-}*/
-
void QQuickParentChange::execute()
{
Q_D(QQuickParentChange);
@@ -499,10 +488,26 @@ bool QQuickParentChange::isReversable()
return true;
}
+void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot)
+{
+ if (!target || !snapshot)
+ return;
+ target->setX(snapshot->x);
+ target->setY(snapshot->y);
+ target->setScale(snapshot->scale);
+ target->setWidth(snapshot->width);
+ target->setHeight(snapshot->height);
+ target->setRotation(snapshot->rotation);
+ target->setParentItem(snapshot->parent);
+ if (snapshot->stackBefore)
+ target->stackBefore(snapshot->stackBefore);
+}
+
+
void QQuickParentChange::reverse()
{
Q_D(QQuickParentChange);
- d->doChange(d->origParent, d->origStackBefore);
+ d->reverseRewindHelper(d->orig);
}
QQuickStateActionEvent::EventType QQuickParentChange::type() const
@@ -524,21 +529,28 @@ void QQuickParentChange::saveCurrentValues()
{
Q_D(QQuickParentChange);
if (!d->target) {
- d->rewindParent = nullptr;
- d->rewindStackBefore = nullptr;
+ d->rewind = nullptr;
return;
}
- d->rewindParent = d->target->parentItem();
- d->rewindStackBefore = nullptr;
+ d->rewind.reset(new QQuickParentChangePrivate::StateSnapshot);
+ d->rewind->x = d->target->x();
+ d->rewind->y = d->target->y();
+ d->rewind->scale = d->target->scale();
+ d->rewind->width = d->target->width();
+ d->rewind->height = d->target->height();
+ d->rewind->rotation = d->target->rotation();
+
+ d->rewind->parent = d->target->parentItem();
+ d->rewind->stackBefore = nullptr;
- if (!d->rewindParent)
+ if (!d->rewind->parent)
return;
- QList<QQuickItem *> children = d->rewindParent->childItems();
+ QList<QQuickItem *> children = d->rewind->parent->childItems();
for (int ii = 0; ii < children.count() - 1; ++ii) {
if (children.at(ii) == d->target) {
- d->rewindStackBefore = children.at(ii + 1);
+ d->rewind->stackBefore = children.at(ii + 1);
break;
}
}
@@ -547,7 +559,8 @@ void QQuickParentChange::saveCurrentValues()
void QQuickParentChange::rewind()
{
Q_D(QQuickParentChange);
- d->doChange(d->rewindParent, d->rewindStackBefore);
+ d->reverseRewindHelper(d->rewind);
+ d->rewind.reset();
}
/*!
@@ -587,11 +600,6 @@ class QQuickAnchorSetPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickAnchorSet)
public:
- QQuickAnchorSetPrivate()
- : usedAnchors(nullptr), resetAnchors(nullptr)
- {
- }
-
QQuickAnchors::Anchors usedAnchors;
QQuickAnchors::Anchors resetAnchors;
diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h
index 357366bc60..d451dc6f77 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -74,6 +74,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public
Q_PROPERTY(QQmlScriptString height READ height WRITE setHeight)
Q_PROPERTY(QQmlScriptString scale READ scale WRITE setScale)
Q_PROPERTY(QQmlScriptString rotation READ rotation WRITE setRotation)
+ QML_NAMED_ELEMENT(ParentChange)
public:
QQuickParentChange(QObject *parent=nullptr);
~QQuickParentChange();
@@ -136,6 +137,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject
Q_PROPERTY(QQmlScriptString bottom READ bottom WRITE setBottom RESET resetBottom)
Q_PROPERTY(QQmlScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter)
Q_PROPERTY(QQmlScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline)
+ QML_ANONYMOUS
public:
QQuickAnchorSet(QObject *parent=nullptr);
@@ -185,6 +187,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, publi
Q_PROPERTY(QQuickItem *target READ object WRITE setObject)
Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT)
+ QML_NAMED_ELEMENT(AnchorChanges)
public:
QQuickAnchorChanges(QObject *parent=nullptr);
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 4105996b31..c7882fb2b1 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -82,7 +82,7 @@
The following example shows how to create a model from C++ with multiple
columns:
- \snippet qml/tableview/cpp-tablemodel.cpp 0
+ \snippet qml/tableview/cpp-tablemodel.h 0
And then how to use it from QML:
@@ -193,8 +193,10 @@
\qmlproperty int QtQuick::TableView::rows
\readonly
- This property holds the number of rows in the table. This is
- equal to the number of rows in the model.
+ This property holds the number of rows in the table.
+
+ \note \a rows is usually equal to the number of rows in the model, but can
+ temporarily differ until all pending model changes have been processed.
This property is read only.
*/
@@ -203,9 +205,12 @@
\qmlproperty int QtQuick::TableView::columns
\readonly
- This property holds the number of columns in the table. This is
- equal to the number of columns in the model. If the model is
- a list, columns will be \c 1.
+ This property holds the number of rows in the table.
+
+ \note \a columns is usually equal to the number of columns in the model, but
+ can temporarily differ until all pending model changes have been processed.
+
+ If the model is a list, columns will be \c 1.
This property is read only.
*/
@@ -457,6 +462,8 @@ QQuickTableViewPrivate::~QQuickTableViewPrivate()
QString QQuickTableViewPrivate::tableLayoutToString() const
{
+ if (loadedItems.isEmpty())
+ return QLatin1String("table is empty!");
return QString(QLatin1String("table cells: (%1,%2) -> (%3,%4), item count: %5, table rect: %6,%7 x %8,%9"))
.arg(leftColumn()).arg(topRow())
.arg(rightColumn()).arg(bottomRow())
@@ -493,20 +500,34 @@ QQuickTableViewAttached *QQuickTableViewPrivate::getAttachedObject(const QObject
int QQuickTableViewPrivate::modelIndexAtCell(const QPoint &cell) const
{
- int availableRows = tableSize.height();
- int modelIndex = cell.y() + (cell.x() * availableRows);
- Q_TABLEVIEW_ASSERT(modelIndex < model->count(),
- "modelIndex:" << modelIndex << "cell:" << cell << "count:" << model->count());
- return modelIndex;
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ return (cell.y() * availableColumns) + cell.x();
+ } else {
+ int availableRows = tableSize.height();
+ return (cell.x() * availableRows) + cell.y();
+ }
}
QPoint QQuickTableViewPrivate::cellAtModelIndex(int modelIndex) const
{
- int availableRows = tableSize.height();
- Q_TABLEVIEW_ASSERT(availableRows > 0, availableRows);
- int column = int(modelIndex / availableRows);
- int row = modelIndex % availableRows;
- return QPoint(column, row);
+ // QQmlTableInstanceModel expects index to be in column-major
+ // order. This means that if the view is transposed (with a flipped
+ // width and height), we need to calculate it in row-major instead.
+ if (isTransposed) {
+ int availableColumns = tableSize.width();
+ int row = int(modelIndex / availableColumns);
+ int column = modelIndex % availableColumns;
+ return QPoint(column, row);
+ } else {
+ int availableRows = tableSize.height();
+ int column = int(modelIndex / availableRows);
+ int row = modelIndex % availableRows;
+ return QPoint(column, row);
+ }
}
int QQuickTableViewPrivate::edgeToArrayIndex(Qt::Edge edge)
@@ -1083,15 +1104,8 @@ void QQuickTableViewPrivate::releaseItem(FxTableItem *fxTableItem, QQmlTableInst
Q_TABLEVIEW_ASSERT(item, fxTableItem->index);
delete item;
} else if (item) {
- // Only QQmlTableInstanceModel supports reusing items
- auto releaseFlag = tableModel ?
- tableModel->release(item, reusableFlag) :
- model->release(item);
-
- if (releaseFlag != QQmlInstanceModel::Destroyed) {
- // When items are not destroyed, it typically means that the
- // item is reused, or that the model is an ObjectModel. If
- // so, we just hide the item instead.
+ auto releaseFlag = model->release(item, reusableFlag);
+ if (releaseFlag == QQmlInstanceModel::Pooled) {
fxTableItem->setVisible(false);
// If the item (or a descendant) has focus, remove it, so
@@ -1241,12 +1255,13 @@ void QQuickTableViewPrivate::updateTableSize()
QSize QQuickTableViewPrivate::calculateTableSize()
{
+ QSize size(0, 0);
if (tableModel)
- return QSize(tableModel->columns(), tableModel->rows());
+ size = QSize(tableModel->columns(), tableModel->rows());
else if (model)
- return QSize(1, model->count());
+ size = QSize(1, model->count());
- return QSize(0, 0);
+ return isTransposed ? size.transposed() : size;
}
qreal QQuickTableViewPrivate::getColumnLayoutWidth(int column)
@@ -2257,6 +2272,21 @@ void QQuickTableViewPrivate::syncDelegate()
tableModel->setDelegate(assignedDelegate);
}
+QVariant QQuickTableViewPrivate::modelImpl() const
+{
+ return assignedModel;
+}
+
+void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel)
+{
+ if (newModel == assignedModel)
+ return;
+
+ assignedModel = newModel;
+ scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
+ emit q_func()->modelChanged();
+}
+
void QQuickTableViewPrivate::syncModel()
{
if (modelVariant == assignedModel)
@@ -2350,14 +2380,11 @@ void QQuickTableViewPrivate::connectToModel()
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::connect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- // Connect atYEndChanged to a function that fetches data if more is available
- QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
// When the model exposes a QAIM, we connect to it directly. This means that if the current model is
@@ -2385,13 +2412,10 @@ void QQuickTableViewPrivate::disconnectFromModel()
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::disconnect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
disconnect(aim, &QAbstractItemModel::rowsMoved, this, &QQuickTableViewPrivate::rowsMovedCallback);
@@ -2678,18 +2702,12 @@ void QQuickTableView::setColumnWidthProvider(const QJSValue &provider)
QVariant QQuickTableView::model() const
{
- return d_func()->assignedModel;
+ return d_func()->modelImpl();
}
void QQuickTableView::setModel(const QVariant &newModel)
{
- Q_D(QQuickTableView);
- if (newModel == d->assignedModel)
- return;
-
- d->assignedModel = newModel;
- d->scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All);
- emit modelChanged();
+ return d_func()->setModelImpl(newModel);
}
QQmlComponent *QQuickTableView::delegate() const
diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h
index a5f727d7a4..d549aaddf7 100644
--- a/src/quick/items/qquicktableview_p.h
+++ b/src/quick/items/qquicktableview_p.h
@@ -82,6 +82,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableView : public QQuickFlickable
Q_PROPERTY(QQuickTableView *syncView READ syncView WRITE setSyncView NOTIFY syncViewChanged REVISION 14)
Q_PROPERTY(Qt::Orientations syncDirection READ syncDirection WRITE setSyncDirection NOTIFY syncDirectionChanged REVISION 14)
+ QML_NAMED_ELEMENT(TableView)
+ QML_ADDED_IN_MINOR_VERSION(12)
+ QML_ATTACHED(QQuickTableViewAttached)
+
public:
QQuickTableView(QQuickItem *parent = nullptr);
~QQuickTableView() override;
@@ -100,8 +104,8 @@ public:
QJSValue columnWidthProvider() const;
void setColumnWidthProvider(const QJSValue &provider);
- virtual QVariant model() const;
- virtual void setModel(const QVariant &newModel);
+ QVariant model() const;
+ void setModel(const QVariant &newModel);
QQmlComponent *delegate() const;
void setDelegate(QQmlComponent *);
@@ -186,6 +190,5 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTableView)
-QML_DECLARE_TYPEINFO(QQuickTableView, QML_HAS_ATTACHED_PROPERTIES)
#endif // QQUICKTABLEVIEW_P_H
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index ec043f5e7e..fe4cf82b46 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -90,7 +90,7 @@ private:
Q_DECLARE_PRIVATE(QQuickTableSectionSizeProvider)
};
-class Q_QML_AUTOTEST_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
{
Q_DECLARE_PUBLIC(QQuickTableView)
@@ -277,6 +277,10 @@ public:
bool inSyncViewportPosRecursive = false;
bool inUpdateContentSize = false;
+ // isTransposed is currently only used by HeaderView.
+ // Consider making it public.
+ bool isTransposed = false;
+
QJSValue rowHeightProvider;
QJSValue columnWidthProvider;
QQuickTableSectionSizeProvider rowHeights;
@@ -403,11 +407,13 @@ public:
void itemReusedCallback(int modelIndex, QObject *object);
void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
- inline void syncWithPendingChanges();
- inline void syncDelegate();
- inline void syncModel();
+ virtual void syncWithPendingChanges();
+ virtual void syncDelegate();
+ virtual QVariant modelImpl() const;
+ virtual void setModelImpl(const QVariant &newModel);
+ virtual void syncModel();
inline void syncRebuildOptions();
- inline void syncSyncView();
+ virtual void syncSyncView();
void connectToModel();
void disconnectFromModel();
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index b95a2559ff..90469ee82b 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -40,6 +40,9 @@
#include "qquicktext_p.h"
#include "qquicktext_p_p.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
@@ -517,6 +520,11 @@ void QQuickTextLine::setLineOffset(int offset)
m_lineOffset = offset;
}
+void QQuickTextLine::setFullLayoutTextLength(int length)
+{
+ m_fullLayoutTextLength = length;
+}
+
int QQuickTextLine::number() const
{
if (m_line)
@@ -524,6 +532,24 @@ int QQuickTextLine::number() const
return 0;
}
+qreal QQuickTextLine::implicitWidth() const
+{
+ if (m_line)
+ return m_line->naturalTextWidth();
+ return 0;
+}
+
+bool QQuickTextLine::isLast() const
+{
+ if (m_line && (m_line->textStart() + m_line->textLength()) == m_fullLayoutTextLength) {
+ // Ensure that isLast will change if the user reduced the width of the line
+ // so that the text no longer fits.
+ return m_line->width() >= m_line->naturalTextWidth();
+ }
+
+ return false;
+}
+
qreal QQuickTextLine::width() const
{
if (m_line)
@@ -585,12 +611,13 @@ bool QQuickTextPrivate::isLineLaidOutConnected()
IS_SIGNAL_CONNECTED(q, QQuickText, lineLaidOut, (QQuickTextLine *));
}
-void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset)
+void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int fullLayoutTextLength, int lineOffset)
{
Q_Q(QQuickText);
if (!textLine)
textLine = new QQuickTextLine;
+ textLine->setFullLayoutTextLength(fullLayoutTextLength);
textLine->setLine(&line);
textLine->setY(height);
textLine->setHeight(0);
@@ -790,7 +817,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
if (noBreakLastLine && visibleCount == maxLineCount)
layout.engine()->option.setWrapMode(QTextOption::WrapAnywhere);
if (customLayout) {
- setupCustomLineGeometry(line, naturalHeight);
+ setupCustomLineGeometry(line, naturalHeight, layoutText.length());
} else {
setLineGeometry(line, lineWidth, naturalHeight);
}
@@ -1122,13 +1149,17 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elideLayout->setFont(layout.font());
elideLayout->setTextOption(layout.textOption());
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ elideText = service->foundElidedText(q, layoutText, elideText);
+ }
elideLayout->setText(elideText);
elideLayout->beginLayout();
QTextLine elidedLine = elideLayout->createLine();
elidedLine.setPosition(QPointF(0, height));
if (customLayout) {
- setupCustomLineGeometry(elidedLine, height, visibleCount - 1);
+ setupCustomLineGeometry(elidedLine, height, elideText.length(), visibleCount - 1);
} else {
setLineGeometry(elidedLine, lineWidth, height);
}
@@ -1188,7 +1219,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
if (!image->pix) {
QUrl url = q->baseUrl().resolved(image->url);
- image->pix = new QQuickPixmap(qmlEngine(q), url, image->size);
+ image->pix = new QQuickPixmap(qmlEngine(q), url, QRect(), image->size);
if (image->pix->isLoading()) {
image->pix->connectFinished(q, SLOT(imageDownloadFinished()));
if (!extra.isAllocated() || !extra->nbActiveDownloads)
@@ -1335,20 +1366,43 @@ QQuickText::~QQuickText()
\qmlsignal QtQuick::Text::lineLaidOut(object line)
This signal is emitted for each line of text that is laid out during the layout
- process. The specified \a line object provides more details about the line that
+ process in plain text or styled text mode. It is not emitted in rich text mode.
+ The specified \a line object provides more details about the line that
is currently being laid out.
This gives the opportunity to position and resize a line as it is being laid out.
It can for example be used to create columns or lay out text around objects.
The properties of the specified \a line object are:
- \list
- \li number (read-only)
- \li x
- \li y
- \li width
- \li height
- \endlist
+
+ \table
+ \header
+ \li Property name
+ \li Description
+ \row
+ \li number (read-only)
+ \li Line number, starts with zero.
+ \row
+ \li x
+ \li Specifies the line's x position inside the \c Text element.
+ \row
+ \li y
+ \li Specifies the line's y position inside the \c Text element.
+ \row
+ \li width
+ \li Specifies the width of the line.
+ \row
+ \li height
+ \li Specifies the height of the line.
+ \row
+ \li implicitWidth (read-only)
+ \li The width that the line would naturally occupy based on its contents,
+ not taking into account any modifications made to \a width.
+ \row
+ \li isLast (read-only)
+ \li Whether the line is the last. This property can change if you
+ set the \a width property to a different value.
+ \endtable
For example, this will move the first 5 lines of a Text item by 100 pixels to the right:
\code
@@ -1360,7 +1414,15 @@ QQuickText::~QQuickText()
}
\endcode
- The corresponding handler is \c onLineLaidOut.
+ The following example will allow you to position an item at the end of the last line:
+ \code
+ onLineLaidOut: {
+ if (line.isLast) {
+ lastLineMarker.x = line.x + line.implicitWidth
+ lastLineMarker.y = line.y + (line.height - lastLineMarker.height) / 2
+ }
+ }
+ \endcode
*/
/*!
@@ -1377,8 +1439,6 @@ QQuickText::~QQuickText()
Clicking on the highlighted link will output
\tt{http://qt-project.org link activated} to the console.
-
- The corresponding handler is \c onLinkActivated.
*/
/*!
@@ -2586,6 +2646,12 @@ void QQuickText::setLineHeightMode(LineHeightMode mode)
If the text does not fit within the item bounds with the minimum font size
the text will be elided as per the \l elide property.
+
+ If the \l textFormat property is set to \l Text.RichText, this will have no effect at all as the
+ property will be ignored completely. If \l textFormat is set to \l Text.StyledText, then the
+ property will be respected provided there is no font size tags inside the text. If there are
+ font size tags, the property will still respect those. This can cause it to not fully comply with
+ the fontSizeMode setting.
*/
QQuickText::FontSizeMode QQuickText::fontSizeMode() const
@@ -2800,8 +2866,6 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
text. The link must be in rich text or HTML format and the \a link
string provides access to the particular link.
- The corresponding handler is \c onLinkHovered.
-
\sa hoveredLink, linkAt()
*/
@@ -2905,6 +2969,8 @@ void QQuickText::setRenderType(QQuickText::RenderType renderType)
d->updateLayout();
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\qmlmethod QtQuick::Text::doLayout()
\deprecated
@@ -2916,6 +2982,8 @@ void QQuickText::doLayout()
forceLayout();
}
+#endif
+#endif
/*!
\qmlmethod QtQuick::Text::forceLayout()
\since 5.9
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 45f387cb12..0fffc1fb9a 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -100,6 +100,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9)
Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10)
+ QML_NAMED_ELEMENT(Text)
public:
QQuickText(QQuickItem *parent=nullptr);
@@ -222,7 +223,12 @@ public:
QRectF boundingRect() const override;
QRectF clipRect() const override;
- Q_INVOKABLE void doLayout(); // ### Qt 6: remove
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use forceLayout() instead")
+ Q_INVOKABLE void doLayout();
+#endif
+#endif
Q_REVISION(9) Q_INVOKABLE void forceLayout();
RenderType renderType() const;
@@ -329,13 +335,19 @@ class QQuickTextLine : public QObject
Q_PROPERTY(qreal height READ height WRITE setHeight)
Q_PROPERTY(qreal x READ x WRITE setX)
Q_PROPERTY(qreal y READ y WRITE setY)
+ Q_PROPERTY(qreal implicitWidth READ implicitWidth REVISION 15)
+ Q_PROPERTY(bool isLast READ isLast REVISION 15)
+ QML_ANONYMOUS
public:
QQuickTextLine();
void setLine(QTextLine* line);
void setLineOffset(int offset);
+ void setFullLayoutTextLength(int length);
int number() const;
+ qreal implicitWidth() const;
+ bool isLast() const;
qreal width() const;
void setWidth(qreal width);
@@ -353,6 +365,7 @@ private:
QTextLine *m_line;
qreal m_height;
int m_lineOffset;
+ int m_fullLayoutTextLength;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index c01998b100..1fbf942130 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -195,7 +195,7 @@ public:
void ensureDoc();
QRectF setupTextLayout(qreal * const baseline);
- void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
+ void setupCustomLineGeometry(QTextLine &line, qreal &height, int fullLayoutTextLength, int lineOffset = 0);
bool isLinkActivatedConnected();
bool isLinkHoveredConnected();
static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 3c392be751..4c741f67e3 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -60,6 +60,7 @@
#include <QtCore/qloggingcategory.h>
#include <qtextformat.h>
+#include <qtransform.h>
#include <qdatetime.h>
#include <qbuffer.h>
#include <qguiapplication.h>
@@ -718,12 +719,12 @@ void QQuickTextControl::selectAll()
void QQuickTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset)
{
- QMatrix m;
- m.translate(coordinateOffset.x(), coordinateOffset.y());
- processEvent(e, m);
+ QTransform t;
+ t.translate(coordinateOffset.x(), coordinateOffset.y());
+ processEvent(e, t);
}
-void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
+void QQuickTextControl::processEvent(QEvent *e, const QTransform &transform)
{
Q_D(QQuickTextControl);
if (d->interactionFlags == Qt::NoTextInteraction) {
@@ -740,25 +741,25 @@ void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
break;
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mousePressEvent(ev, matrix.map(ev->localPos()));
+ d->mousePressEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseMove: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseMoveEvent(ev, matrix.map(ev->localPos()));
+ d->mouseMoveEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonRelease: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseReleaseEvent(ev, matrix.map(ev->localPos()));
+ d->mouseReleaseEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::MouseButtonDblClick: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mouseDoubleClickEvent(ev, matrix.map(ev->localPos()));
+ d->mouseDoubleClickEvent(ev, transform.map(ev->localPos()));
break; }
case QEvent::HoverEnter:
case QEvent::HoverMove:
case QEvent::HoverLeave: {
QHoverEvent *ev = static_cast<QHoverEvent *>(e);
- d->hoverEvent(ev, matrix.map(ev->posF()));
+ d->hoverEvent(ev, transform.map(ev->posF()));
break; }
#if QT_CONFIG(im)
case QEvent::InputMethod:
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index 41b8ed7821..eb5cd27994 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -71,6 +71,7 @@ class QQuickTextControlPrivate;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
+class QTransform;
class Q_AUTOTEST_EXPORT QQuickTextControl : public QInputControl
{
@@ -169,7 +170,7 @@ Q_SIGNALS:
void markerHovered(bool marker);
public:
- virtual void processEvent(QEvent *e, const QMatrix &matrix);
+ virtual void processEvent(QEvent *e, const QTransform &transform);
void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
#if QT_CONFIG(im)
diff --git a/src/quick/items/qquicktextdocument.h b/src/quick/items/qquicktextdocument.h
index affa0ab4d6..bf9162755c 100644
--- a/src/quick/items/qquicktextdocument.h
+++ b/src/quick/items/qquicktextdocument.h
@@ -49,6 +49,7 @@ class QQuickTextDocumentPrivate;
class Q_QUICK_EXPORT QQuickTextDocument : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickTextDocument(QQuickItem *parent);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 650b1961a4..247d8abc3c 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -118,8 +118,6 @@ TextEdit {
This signal is emitted when the user clicks on a link embedded in the text.
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
-
- The corresponding handler is \c onLinkActivated.
*/
// This is a pretty arbitrary figure. The idea is that we don't want to break down the document
@@ -2903,8 +2901,6 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
- The corresponding handler is \c onLinkHovered.
-
\sa hoveredLink, linkAt()
*/
@@ -2913,8 +2909,6 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
\since 5.6
This signal is emitted when the text edit loses focus.
-
- The corresponding handler is \c onEditingFinished.
*/
/*!
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 2d1b6c7f9c..227d8cbf51 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -112,6 +112,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10)
+ QML_NAMED_ELEMENT(TextEdit)
public:
QQuickTextEdit(QQuickItem *parent=nullptr);
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index ee51711d34..06a9f134ac 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1171,8 +1171,6 @@ bool QQuickTextInput::hasAcceptableInput() const
Note that if there is a \l validator or \l inputMask set on the text
input, the signal will only be emitted if the input is in an acceptable
state.
-
- The corresponding handler is \c onAccepted.
*/
/*!
@@ -1184,8 +1182,6 @@ bool QQuickTextInput::hasAcceptableInput() const
inputMask set on the text input and enter/return is pressed, this
signal will only be emitted if the input follows
the inputMask and the validator returns an acceptable state.
-
- The corresponding handler is \c onEditingFinished.
*/
/*!
@@ -1195,8 +1191,6 @@ bool QQuickTextInput::hasAcceptableInput() const
This signal is emitted whenever the text is edited. Unlike \c textChanged(),
this signal is not emitted when the text is changed programmatically, for example,
by changing the value of the \c text property or by calling \c clear().
-
- The corresponding handler is \c onTextEdited.
*/
#if QT_CONFIG(im)
@@ -3956,7 +3950,7 @@ bool QQuickTextInputPrivate::isValidInput(QChar key, QChar mask) const
return true;
break;
case 'X':
- if (key.isPrint())
+ if (key.isPrint() && key != m_blank)
return true;
break;
case 'x':
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index c10b06d02a..9f7b82b168 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -113,6 +113,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+ QML_NAMED_ELEMENT(TextInput)
public:
QQuickTextInput(QQuickItem * parent=nullptr);
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index a0ae4e5f97..2356ab36ef 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -532,7 +532,7 @@ void QQuickTextNodeEngine::addGlyphsForRanges(const QVarLengthArray<QTextLayout:
int remainingLength = end - start;
for (int j=0; j<ranges.size(); ++j) {
const QTextLayout::FormatRange &range = ranges.at(j);
- if (range.start + range.length >= currentPosition
+ if (range.start + range.length > currentPosition
&& range.start < currentPosition + remainingLength) {
if (range.start > currentPosition) {
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index b6ea43342c..aeda6ca589 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform
Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
+ QML_NAMED_ELEMENT(Translate)
public:
QQuickTranslate(QObject *parent = nullptr);
@@ -95,6 +96,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform
Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
+ QML_NAMED_ELEMENT(Scale)
public:
QQuickScale(QObject *parent = nullptr);
~QQuickScale();
@@ -132,6 +134,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform
Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
+ QML_NAMED_ELEMENT(Rotation)
public:
QQuickRotation(QObject *parent = nullptr);
~QQuickRotation();
@@ -163,6 +166,8 @@ class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
Q_OBJECT
Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
+ QML_NAMED_ELEMENT(Matrix4x4)
+ QML_ADDED_IN_MINOR_VERSION(3)
public:
QQuickMatrix4x4(QObject *parent = nullptr);
~QQuickMatrix4x4();
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 2110d4caba..5b3b954460 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -486,7 +486,9 @@ void QQuickView::continueExecute()
return;
}
- QObject *obj = d->initialProperties.empty() ? d->component->create() : d->component->createWithInitialProperties(d->initialProperties);
+ QScopedPointer<QObject> obj(d->initialProperties.empty()
+ ? d->component->create()
+ : d->component->createWithInitialProperties(d->initialProperties));
if (d->component->isError()) {
const QList<QQmlError> errorList = d->component->errors();
@@ -498,7 +500,7 @@ void QQuickView::continueExecute()
return;
}
- d->setRootObject(obj);
+ d->setRootObject(obj.take());
emit statusChanged(status());
}
@@ -516,14 +518,14 @@ void QQuickViewPrivate::setRootObject(QObject *obj)
sgItem->setParentItem(q->QQuickWindow::contentItem());
QQml_setParent_noEvent(sgItem, q->QQuickWindow::contentItem());
} else if (qobject_cast<QWindow *>(obj)) {
- qWarning() << "QQuickView does not support using windows as a root item." << endl
- << endl
- << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
+ qWarning() << "QQuickView does not support using windows as a root item." << Qt::endl
+ << Qt::endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << Qt::endl;
} else {
- qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
- << endl
- << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
- << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
+ qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << Qt::endl
+ << Qt::endl
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << Qt::endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << Qt::endl;
delete obj;
root = nullptr;
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index f07136fcd3..48ba0ecc28 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -39,7 +39,6 @@
#include "qquickwindow.h"
#include "qquickwindow_p.h"
-#include "qquickwindowattached_p.h"
#include "qquickitem.h"
#include "qquickitem_p.h"
@@ -94,6 +93,7 @@ Q_LOGGING_CATEGORY(DBG_TOUCH, "qt.quick.touch")
Q_LOGGING_CATEGORY(DBG_TOUCH_TARGET, "qt.quick.touch.target")
Q_LOGGING_CATEGORY(DBG_MOUSE, "qt.quick.mouse")
Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target")
+Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet")
Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target")
Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target")
Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace")
@@ -430,7 +430,7 @@ void QQuickWindowPrivate::syncSceneGraph()
if (renderTargetId && !QQuickRenderControl::renderWindowFor(q))
devicePixelRatio = 1;
- context->prepareSync(devicePixelRatio);
+ context->prepareSync(devicePixelRatio, rhi ? swapchain->currentFrameCommandBuffer() : nullptr);
animationController->beforeNodeSync();
@@ -528,7 +528,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
renderer->setDeviceRect(rect);
renderer->setViewportRect(rect);
const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (flipY)
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags);
@@ -561,6 +561,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, activeFocusItem(nullptr)
#if QT_CONFIG(cursor)
, cursorItem(nullptr)
+ , cursorHandler(nullptr)
#endif
#if QT_CONFIG(quick_draganddrop)
, dragGrabber(nullptr)
@@ -682,10 +683,13 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear);
+ return QQmlListProperty<QObject>(q_func(), nullptr,
+ QQuickWindowPrivate::data_append,
+ QQuickWindowPrivate::data_count,
+ QQuickWindowPrivate::data_at,
+ QQuickWindowPrivate::data_clear,
+ QQuickWindowPrivate::data_replace,
+ QQuickWindowPrivate::data_removeLast);
}
static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
@@ -771,7 +775,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
if (!item->contains(pos))
break;
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << item;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << p.id() << "->" << item;
QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event.data(), item, false));
// Send a single press and see if that's accepted
@@ -813,7 +817,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << mouseGrabberItem;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << p.id() << "->" << mouseGrabberItem;
}
return event->isAccepted();
} else {
@@ -969,8 +973,7 @@ void QQuickWindowPrivate::translateTouchEvent(QTouchEvent *touchEvent)
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
-
- touchPoint.setSceneRect(touchPoint.rect());
+ touchPoint.setScenePos(touchPoint.pos());
touchPoint.setStartScenePos(touchPoint.startPos());
touchPoint.setLastScenePos(touchPoint.lastPos());
}
@@ -1763,12 +1766,18 @@ bool QQuickWindow::event(QEvent *e)
if (d->activeFocusItem)
QCoreApplication::sendEvent(d->activeFocusItem, e);
return true;
+ case QEvent::LanguageChange:
+ if (d->contentItem)
+ QCoreApplication::sendEvent(d->contentItem, e);
+ break;
default:
break;
}
if (e->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))
update();
+ else if (e->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure))
+ d->windowManager->handleContextCreationFailure(this);
return QWindow::event(e);
}
@@ -2117,6 +2126,17 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
}
#endif // wheelevent
+#if QT_CONFIG(tabletevent)
+/*! \reimp */
+void QQuickWindow::tabletEvent(QTabletEvent *event)
+{
+ Q_D(QQuickWindow);
+ qCDebug(lcTablet) << event;
+ // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here
+ d->deliverPointerEvent(d->pointerEventInstance(event));
+}
+#endif // tabletevent
+
bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
{
qCDebug(DBG_TOUCH) << event;
@@ -2395,8 +2415,14 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
+#if QT_CONFIG(tabletevent)
+ case QQuickPointerDevice::Stylus:
+ case QQuickPointerDevice::Airbrush:
+ case QQuickPointerDevice::Puck:
+ ev = new QQuickPointerTabletEvent(q, device);
+ break;
+#endif
default:
- // TODO tablet event types
break;
}
pointerEventInstances << ev;
@@ -2427,7 +2453,15 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
break;
- // TODO tablet event types
+#if QT_CONFIG(tabletevent)
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ dev = QQuickPointerDevice::tabletDevice(static_cast<QTabletEvent *>(event));
+ break;
+#endif
#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
@@ -2462,6 +2496,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverTouchEvent(event->asPointerTouchEvent());
} else {
deliverSinglePointEventUntilAccepted(event);
+ // If any handler got interested in the tablet event, we don't want to receive a synth-mouse event from QtGui
+ // TODO Qt 6: QTabletEvent will be accepted by default, like other events
+ if (event->asPointerTabletEvent() &&
+ (!event->point(0)->passiveGrabbers().isEmpty() || event->point(0)->exclusiveGrabber()))
+ event->setAccepted(true);
}
event->reset(nullptr);
@@ -2551,7 +2590,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
QQuickEventPoint *point = event->point(i);
if (point->state() == QQuickEventPoint::Released) {
int id = point->pointId();
- qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << id << "released";
+ qCDebug(DBG_TOUCH_TARGET) << "TP" << Qt::hex << id << "released";
point->setGrabberItem(nullptr);
if (id == touchMouseId)
cancelTouchMouseSynthesis();
@@ -2648,7 +2687,7 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
if (point->grabberPointerHandler())
cancelTouchMouseSynthesis();
} else {
- qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << hex << touchMouseId << "is missing from" << event;
+ qCWarning(DBG_TOUCH_TARGET) << "during delivery of touch press, synth-mouse ID" << Qt::hex << touchMouseId << "is missing from" << event;
}
}
for (int i = 0; i < pointCount; ++i) {
@@ -2790,7 +2829,7 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
if (point.state() == Qt::TouchPointPressed) {
if (auto *tp = ptEvent->pointById(point.id())) {
if (tp->exclusiveGrabber() == item) {
- qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << point.id() << "disassociated";
+ qCDebug(DBG_TOUCH_TARGET) << "TP" << Qt::hex << point.id() << "disassociated";
tp->setGrabberItem(nullptr);
}
}
@@ -2966,26 +3005,27 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos)
{
Q_Q(QQuickWindow);
- QQuickItem *oldCursorItem = cursorItem;
- cursorItem = findCursorItem(contentItem, scenePos);
+ auto cursorItemAndHandler = findCursorItemAndHandler(contentItem, scenePos);
- if (cursorItem != oldCursorItem) {
+ if (cursorItem != cursorItemAndHandler.first || cursorHandler != cursorItemAndHandler.second) {
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(q);
QWindow *window = renderWindow ? renderWindow : q;
+ cursorItem = cursorItemAndHandler.first;
+ cursorHandler = cursorItemAndHandler.second;
if (cursorItem)
- window->setCursor(cursorItem->cursor());
+ window->setCursor(QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler));
else
window->unsetCursor();
}
}
-QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF &scenePos)
+QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const
{
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
QPointF p = item->mapFromScene(scenePos);
if (!item->contains(p))
- return nullptr;
+ return {nullptr, nullptr};
}
if (itemPrivate->subtreeCursorEnabled) {
@@ -2994,17 +3034,24 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF
QQuickItem *child = children.at(ii);
if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
continue;
- if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
- return cursorItem;
+ auto ret = findCursorItemAndHandler(child, scenePos);
+ if (ret.first)
+ return ret;
+ }
+ if (itemPrivate->hasCursor || itemPrivate->hasCursorHandler) {
+ QPointF p = item->mapFromScene(scenePos);
+ if (!item->contains(p))
+ return {nullptr, nullptr};
+ if (itemPrivate->hasCursorHandler) {
+ if (auto handler = itemPrivate->effectiveCursorHandler())
+ return {item, handler};
+ }
+ if (itemPrivate->hasCursor)
+ return {item, nullptr};
}
}
- if (itemPrivate->hasCursor) {
- QPointF p = item->mapFromScene(scenePos);
- if (item->contains(p))
- return item;
- }
- return nullptr;
+ return {nullptr, nullptr};
}
#endif
@@ -3106,7 +3153,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
if (t != QEvent::MouseButtonRelease) {
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << Qt::hex << tp.id() << "->" << filteringParent;
pointerEventInstance(dev)->pointById(tp.id())->setGrabberItem(filteringParent);
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
if (mouseEvent->isAccepted())
@@ -3169,6 +3216,18 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent
return overThreshold;
}
+bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, const QTouchEvent::TouchPoint *tp, int startDragThreshold)
+{
+ QStyleHints *styleHints = qApp->styleHints();
+ bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
+ const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
+ if (!overThreshold && dragVelocityLimitAvailable) {
+ qreal velocity = axis == Qt::XAxis ? tp->velocity().x() : tp->velocity().y();
+ overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
+ }
+ return overThreshold;
+}
+
bool QQuickWindowPrivate::dragOverThreshold(QVector2D delta)
{
int threshold = qApp->styleHints()->startDragDistance();
@@ -3235,6 +3294,20 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
itemProperty.clear(&itemProperty);
}
+void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, int i, QObject *o)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.replace(&itemProperty, i, o);
+}
+
+void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.removeLast(&itemProperty);
+}
+
bool QQuickWindowPrivate::isRenderable() const
{
Q_Q(const QQuickWindow);
@@ -3243,10 +3316,9 @@ bool QQuickWindowPrivate::isRenderable() const
void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
- QString *untranslatedMessage,
- bool isEs)
+ QString *untranslatedMessage)
{
- const QString contextType = QLatin1String(isEs ? "EGL" : "OpenGL");
+ const QString contextType = QLatin1String("OpenGL");
QString formatStr;
QDebug(&formatStr) << format;
#if defined(Q_OS_WIN32)
@@ -3271,6 +3343,16 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo
#endif // !Q_OS_WIN32
}
+void QQuickWindowPrivate::rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage)
+{
+ const char msg[] = QT_TRANSLATE_NOOP("QQuickWindow",
+ "Failed to initialize graphics backend for %1.");
+ *translatedMessage = QQuickWindow::tr(msg).arg(backendName);
+ *untranslatedMessage = QString::fromLatin1(msg).arg(backendName);
+}
+
#if QT_DEPRECATED_SINCE(5, 8)
// ### Qt6: remove
@@ -3786,6 +3868,13 @@ bool QQuickWindow::isSceneGraphInitialized() const
This signal will be emitted from the scene graph rendering thread.
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::frameSwapped()
+
+ This signal is emitted when a frame has been queued for presenting. With
+ vertical synchronization enabled the signal is emitted at most once per
+ vsync interval in a continuously animating scene.
+ */
/*!
\fn void QQuickWindow::sceneGraphInitialized()
@@ -3793,9 +3882,12 @@ bool QQuickWindow::isSceneGraphInitialized() const
This signal is emitted when the scene graph has been initialized.
This signal will be emitted from the scene graph rendering thread.
-
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphInitialized()
+ \internal
+ */
/*!
\fn void QQuickWindow::sceneGraphInvalidated()
@@ -3815,6 +3907,11 @@ bool QQuickWindow::isSceneGraphInitialized() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphInvalidated()
+ \internal
+ */
+
+/*!
\fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message)
This signal is emitted when an \a error occurred during scene graph initialization.
@@ -3830,6 +3927,19 @@ bool QQuickWindow::isSceneGraphInitialized() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphError(SceneGraphError error, QString message)
+
+ This signal is emitted when an \a error occurred during scene graph initialization.
+
+ You can implement onSceneGraphError(error, message) to handle errors,
+ such as graphics context creation failures, in a custom way.
+ If no handler is connected to this signal, Quick will print the \a message,
+ or show a message box, and terminate the application.
+
+ \since 5.3
+ */
+
+/*!
\class QQuickCloseEvent
\internal
\since 5.1
@@ -3884,8 +3994,6 @@ bool QQuickWindow::isSceneGraphInitialized() const
property is true by default so that the window is allowed to close; but you
can implement an \c onClosing handler and set \c {close.accepted = false} if
you need to do something else before the window can be closed.
-
- The corresponding handler is \c onClosing.
*/
#if QT_CONFIG(opengl)
@@ -4176,6 +4284,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeSynchronizing()
+ \internal
+*/
+
+/*!
\fn void QQuickWindow::afterSynchronizing()
This signal is emitted after the scene graph is synchronized with the QML state.
@@ -4199,6 +4312,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterSynchronizing()
+ \internal
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::beforeRendering()
This signal is emitted before the scene starts rendering.
@@ -4234,6 +4353,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeRendering()
+ \internal
+*/
+
+/*!
\fn void QQuickWindow::afterRendering()
This signal is emitted after the scene has completed rendering, before swapbuffers is called.
@@ -4267,6 +4391,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterRendering()
+ \internal
+ */
+
+/*!
\fn void QQuickWindow::beforeRenderPassRecording()
This signal is emitted before the scenegraph starts recording commands for
@@ -4299,6 +4428,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::beforeRenderPassRecording()
+ \internal
+ \since 5.14
+*/
+
+/*!
\fn void QQuickWindow::afterRenderPassRecording()
This signal is emitted after the scenegraph has recorded the commands for
@@ -4330,6 +4465,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterRenderPassRecording()
+ \internal
+ \since 5.14
+*/
+
+/*!
\fn void QQuickWindow::afterAnimating()
This signal is emitted on the gui thread before requesting the render thread to
@@ -4344,6 +4485,17 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::afterAnimating()
+
+ This signal is emitted on the gui thread before requesting the render thread to
+ perform the synchronization of the scene graph.
+
+ You can implement onAfterAnimating to do additional processing after each animation step.
+
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::openglContextCreated(QOpenGLContext *context)
This signal is emitted on the gui thread when the OpenGL \a context
@@ -4355,7 +4507,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
OpenGL context is actually created.
QQuickWindow::openglContext() will still return 0 for this window
- until after the QQuickWindow::sceneGraphInitialize() has been
+ until after the QQuickWindow::sceneGraphInitialized() has been
emitted.
\note
@@ -4366,6 +4518,12 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \qmlsignal QtQuick.Window::Window::openglContextCreated()
+ \internal
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::sceneGraphAboutToStop()
This signal is emitted on the render thread when the scene graph is
@@ -4388,6 +4546,11 @@ QQmlIncubationController *QQuickWindow::incubationController() const
\since 5.3
*/
+/*!
+ \qmlsignal QtQuick.Window::Window::sceneGraphAboutToStop()
+ \internal
+ \since 5.3
+ */
/*!
Sets whether the scene graph rendering of QML should clear the color buffer
@@ -4433,7 +4596,7 @@ bool QQuickWindow::clearBeforeRendering() const
QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
{
- return createTextureFromImage(image, nullptr);
+ return createTextureFromImage(image, {});
}
@@ -4491,7 +4654,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
}
-
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
Creates a new QSGTexture object from an existing OpenGL texture \a id and \a size.
@@ -4513,6 +4676,8 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText
\note This function has no effect when running on the RHI graphics
abstraction. Use createTextureFromNativeObject() instead.
+ \obsolete
+
\sa sceneGraphInitialized(), QSGTexture
*/
QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const
@@ -4539,6 +4704,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
#endif
return nullptr;
}
+#endif
/*!
\enum QQuickWindow::NativeObjectType
@@ -4592,7 +4758,7 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
\a nativeLayout is only used for APIs like Vulkan. When applicable, it must
specify the current image layout, such as, a VkImageLayout value.
- \sa sceneGraphInitialized(), QSGTexture
+ \sa sceneGraphInitialized(), QSGTexture, QSGTexture::nativeTexture()
\since 5.14
*/
@@ -4723,9 +4889,13 @@ void QQuickWindow::setDefaultAlphaBuffer(bool useAlpha)
\note This function only has an effect when using the default OpenGL scene graph
adaptation.
+ \note This function will only reset the OpenGL context in relation to what has been changed
+ internally as part of the OpenGL scene graph. It does not reset anything that has been changed
+ externally such as direct OpenGL calls done inside the application code if those same calls are
+ not used internally.
+
\note This function has no effect when running on the RHI graphics
- abstraction. With the RHI, the functions to call when enqueuing native
- graphics commands are beginExternalCommands() and endExternalCommands().
+ abstraction and the underlying RHI backend is not OpenGL.
\sa QQuickWindow::beforeRendering(), beginExternalCommands(), endExternalCommands()
*/
@@ -4733,7 +4903,7 @@ void QQuickWindow::resetOpenGLState()
{
Q_D(QQuickWindow);
- if (d->rhi || !openglContext())
+ if (!openglContext())
return;
QOpenGLContext *ctx = openglContext();
@@ -4848,7 +5018,13 @@ const QQuickWindow::GraphicsStateInfo &QQuickWindow::graphicsStateInfo()
directly and the RHI graphics abstraction layer is not in use. Refer to
resetOpenGLState() in that case.
- \sa endExternalCommands()
+ \note When the scenegraph is using the RHI graphics abstraction layer with
+ the OpenGL backend underneath, pay attention to the fact that the OpenGL
+ state in the context can have arbitrary settings, and this function does not
+ perform any resetting of the state back to defaults. Call
+ resetOpenGLState() if that is seen necessary.
+
+ \sa endExternalCommands(), resetOpenGLState()
\since 5.14
*/
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 56d50cec2a..097627374c 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -157,7 +157,12 @@ public:
// Scene graph specific functions
QSGTexture *createTextureFromImage(const QImage &image) const;
QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const;
+
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use createTextureFromNativeObject() instead")
QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const;
+#endif
+
QSGTexture *createTextureFromNativeObject(NativeObjectType type,
const void *nativeObjectPtr,
int nativeLayout,
@@ -247,6 +252,9 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *) override;
#endif
+#if QT_CONFIG(tabletevent)
+ void tabletEvent(QTabletEvent *) override;
+#endif
private Q_SLOTS:
void maybeUpdate();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 165859b5f3..e1ee7daf1c 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -88,7 +88,7 @@ class QRhiRenderBuffer;
class QRhiRenderPassDescriptor;
//Make it easy to identify and customize the root item if needed
-class QQuickRootItem : public QQuickItem
+class Q_QUICK_PRIVATE_EXPORT QQuickRootItem : public QQuickItem
{
Q_OBJECT
public:
@@ -112,7 +112,8 @@ public:
Q_DECLARE_PUBLIC(QQuickWindow)
enum CustomEvents {
- FullUpdateRequest = QEvent::User + 1
+ FullUpdateRequest = QEvent::User + 1,
+ TriggerContextCreationFailure = QEvent::User + 2
};
static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); }
@@ -133,6 +134,7 @@ public:
// Keeps track of the item currently receiving mouse events
#if QT_CONFIG(cursor)
QQuickItem *cursorItem;
+ QQuickPointerHandler *cursorHandler;
#endif
#if QT_CONFIG(quick_draganddrop)
QQuickDragGrabber *dragGrabber;
@@ -196,7 +198,7 @@ public:
#endif
#if QT_CONFIG(cursor)
void updateCursor(const QPointF &scenePos);
- QQuickItem *findCursorItem(QQuickItem *item, const QPointF &scenePos);
+ QPair<QQuickItem*, QQuickPointerHandler*> findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const;
#endif
QList<QQuickItem*> hoverItems;
@@ -206,8 +208,8 @@ public:
};
Q_DECLARE_FLAGS(FocusOptions, FocusOption)
- void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
- void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = nullptr);
+ void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
+ void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
static void notifyFocusChangesRecur(QQuickItem **item, int remaining);
void clearFocusObject() override;
@@ -288,25 +290,7 @@ public:
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
- template <typename TEventPoint>
- static bool dragOverThreshold(qreal d, Qt::Axis axis, const TEventPoint *p, int startDragThreshold = -1)
- {
- QStyleHints *styleHints = qApp->styleHints();
- bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
- const bool dragVelocityLimitAvailable = (styleHints->startDragVelocity() > 0);
- if (!overThreshold && dragVelocityLimitAvailable) {
- qreal velocity = axis == Qt::XAxis ? p->velocity().x() : p->velocity().y();
- overThreshold |= qAbs(velocity) > styleHints->startDragVelocity();
- }
- return overThreshold;
- }
-
- static bool dragOverThreshold(const QQuickEventPoint *point)
- {
- QPointF delta = point->scenePosition() - point->scenePressPosition();
- return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
- QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
- }
+ static bool dragOverThreshold(qreal d, Qt::Axis axis, const QTouchEvent::TouchPoint *tp, int startDragThreshold = -1);
static bool dragOverThreshold(QVector2D delta);
@@ -315,11 +299,15 @@ public:
static int data_count(QQmlListProperty<QObject> *);
static QObject *data_at(QQmlListProperty<QObject> *, int);
static void data_clear(QQmlListProperty<QObject> *);
+ static void data_replace(QQmlListProperty<QObject> *, int, QObject *);
+ static void data_removeLast(QQmlListProperty<QObject> *);
static void contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,
- QString *untranslatedMessage,
- bool isEs);
+ QString *untranslatedMessage);
+ static void rhiCreationFailureMessage(const QString &backendName,
+ QString *translatedMessage,
+ QString *untranslatedMessage);
static void emitBeforeRenderPassRecording(void *ud);
static void emitAfterRenderPassRecording(void *ud);
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 4b2b8f498d..ee90af4341 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -48,6 +48,7 @@
#include <private/qguiapplication_p.h>
#include <private/qqmlengine_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qqmlglobal_p.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
@@ -195,28 +196,6 @@ void QQuickWindowQmlImpl::setScreen(QObject *screen)
QWindow::setScreen(screenWrapper ? screenWrapper->wrappedScreen() : nullptr);
}
-void QQuickWindowModule::defineModule()
-{
- const char uri[] = "QtQuick.Window";
-
- qmlRegisterType<QQuickWindow>(uri, 2, 0, "Window");
- qmlRegisterRevision<QWindow,1>(uri, 2, 1);
- qmlRegisterRevision<QWindow,2>(uri, 2, 2);
- qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members
- qmlRegisterRevision<QQuickWindow,2>(uri, 2, 2);
- qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,2>(uri, 2, 2, "Window");
- qmlRegisterType<QQuickWindowQmlImpl,3>(uri, 2, 3, "Window");
- qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreen,3>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,3>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
- qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
- qmlRegisterRevision<QWindow,13>(uri, 2, 13);
- qmlRegisterRevision<QQuickWindow,13>(uri, 2, 13);
- qmlRegisterType<QQuickWindowQmlImpl,13>(uri, 2, 13, "Window");
- qmlRegisterRevision<QQuickWindow,14>(uri, 2, 14);
-}
-
QT_END_NAMESPACE
#include "moc_qquickwindowmodule_p.cpp"
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index 1dcf1a1021..d0bf5c29b3 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -68,6 +68,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 3)
+ QML_ATTACHED(QQuickWindowAttached)
public:
QQuickWindowQmlImpl(QWindow *parent = nullptr);
@@ -97,15 +98,8 @@ private:
Q_DECLARE_PRIVATE(QQuickWindowQmlImpl)
};
-class Q_QUICK_PRIVATE_EXPORT QQuickWindowModule
-{
-public:
- static void defineModule();
-};
-
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickWindowQmlImpl)
-QML_DECLARE_TYPEINFO(QQuickWindowQmlImpl, QML_HAS_ATTACHED_PROPERTIES)
#endif
diff --git a/src/quick/qtquick.tracepoints b/src/quick/qtquick.tracepoints
new file mode 100644
index 0000000000..f6518444d2
--- /dev/null
+++ b/src/quick/qtquick.tracepoints
@@ -0,0 +1,48 @@
+QSG_renderWindow_entry()
+QSG_renderWindow_exit()
+QSG_renderScene_entry()
+QSG_renderScene_exit()
+QSG_syncAndRender_entry()
+QSG_syncAndRender_exit()
+QSG_polishAndSync_entry()
+QSG_polishAndSync_exit()
+QSG_preprocess_entry()
+QSG_preprocess_exit()
+QSG_update_entry()
+QSG_update_exit()
+
+QSG_polishItems_entry()
+QSG_polishItems_exit()
+QSG_sync_entry()
+QSG_sync_exit()
+QSG_wait_entry()
+QSG_wait_exit()
+QSG_render_entry()
+QSG_render_exit()
+QSG_swap_entry()
+QSG_swap_exit()
+QSG_animations_entry()
+QSG_animations_exit()
+
+QSG_texture_prepare_entry()
+QSG_texture_prepare_exit()
+QSG_texture_bind_entry()
+QSG_texture_bind_exit()
+QSG_texture_delete_entry()
+QSG_texture_delete_exit()
+QSG_texture_upload_entry()
+QSG_texture_upload_exit()
+QSG_texture_mipmap_entry()
+QSG_texture_mipmap_exit()
+
+QSG_binding_entry()
+QSG_binding_exit()
+QSG_prepareMaterial_entry()
+QSG_prepareMaterial_exit()
+
+QSGDistanceFieldGlyphCache_update_entry(int count)
+QSGDistanceFieldGlyphCache_update_exit()
+QSGDistanceFieldGlyphCache_glyphRender_entry()
+QSGDistanceFieldGlyphCache_glyphRender_exit()
+QSGDistanceFieldGlyphCache_glyphStore_entry()
+QSGDistanceFieldGlyphCache_glyphStore_exit()
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index 7a04c2146c..4ba7e896db 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -39,7 +39,6 @@
#include "qtquick2_p.h"
#include <private/qqmlengine_p.h>
-#include <private/qquickutilmodule_p.h>
#include <private/qquickvaluetypes_p.h>
#include <private/qquickitemsmodule_p.h>
#include <private/qquickaccessiblefactory_p.h>
@@ -55,6 +54,10 @@
#include <qqmlproperty.h>
#include <QtCore/QPointer>
+#if QT_CONFIG(shortcut)
+Q_DECLARE_METATYPE(QKeySequence::StandardKey)
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_CONFIG(qml_debug)
@@ -182,12 +185,12 @@ void QQmlQtQuick2Module::defineModule()
{
QQuick_initializeProviders();
- QQuickUtilModule::defineModule();
- QQuickItemsModule::defineModule();
-
- qmlRegisterUncreatableType<QQuickApplication>("QtQuick",2,0,"Application", QQuickApplication::tr("Application is an abstract class"));
+#if QT_CONFIG(shortcut)
+ qRegisterMetaType<QKeySequence::StandardKey>();
+#endif
QQuickValueTypes::registerValueTypes();
+ QQuickItemsModule::defineModule();
#if QT_CONFIG(accessibility)
QAccessible::installFactory(&qQuickAccessibleFactory);
diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h
index f6376a6d17..80e59563c7 100644
--- a/src/quick/qtquickglobal_p.h
+++ b/src/quick/qtquickglobal_p.h
@@ -61,6 +61,8 @@
#define Q_QUICK_PRIVATE_EXPORT Q_QUICK_EXPORT
+void Q_QUICK_PRIVATE_EXPORT qml_register_types_QtQuick();
+
QT_BEGIN_NAMESPACE
void QQuick_initializeProviders();
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index cd8ee35135..f2d49cf939 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -4,6 +4,9 @@ QT = core-private gui-private qml-private qmlmodels-private
qtConfig(qml-network): \
QT_PRIVATE += network
+TRACEPOINT_PROVIDER = $$PWD/qtquick.tracepoints
+CONFIG += qt_tracepoints
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
msvc:DEFINES *= _CRT_SECURE_NO_WARNINGS
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
@@ -44,3 +47,9 @@ SOURCES += qtquick2.cpp
INCLUDEPATH += $$PWD
load(qt_module)
+
+QMLTYPES_FILENAME = plugins.qmltypes
+QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQuick.2
+QML_IMPORT_NAME = QtQuick
+IMPORT_VERSION = 2.$$QT_MINOR_VERSION
+CONFIG += qmltypes install_qmltypes install_metatypes
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 7b5ee66df6..f1d0e28fc8 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -206,12 +206,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const
QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const
{
- return nullptr;
+ return {};
}
QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const
{
- return nullptr;
+ return {};
}
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
index dd789b78c7..04e9b361ca 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qsgsoftwareglyphnode_p.h"
+#include <QtGui/private/qrawfont_p.h>
QT_BEGIN_NAMESPACE
@@ -52,28 +53,38 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode()
namespace {
QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs)
{
- qreal minX = 0;
- qreal minY = 0;
- qreal maxX = 0;
- qreal maxY = 0;
+ QFixed minX;
+ QFixed minY;
+ QFixed maxX;
+ QFixed maxY;
- for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) {
- QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]);
- glyphRect.translate(glyphs.positions()[i]);
+ QRawFontPrivate *rawFontD = QRawFontPrivate::get(glyphs.rawFont());
+ QFontEngine *fontEngine = rawFontD->fontEngine;
+
+ QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32;
+
+ const QVector<uint> glyphIndexes = glyphs.glyphIndexes();
+ const QVector<QPointF> glyphPositions = glyphs.positions();
+ for (int i = 0, n = qMin(glyphIndexes.size(), glyphPositions.size()); i < n; ++i) {
+ glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyphIndexes.at(i), QFixed(), QTransform(), glyphFormat);
+
+ gm.x += QFixed::fromReal(glyphPositions.at(i).x());
+ gm.y += QFixed::fromReal(glyphPositions.at(i).y());
if (i == 0) {
- minX = glyphRect.left();
- minY = glyphRect.top();
- maxX = glyphRect.right();
- maxY = glyphRect.bottom();
+ minX = gm.x;
+ minY = gm.y;
+ maxX = gm.x + gm.width;
+ maxY = gm.y + gm.height;
} else {
- minX = qMin(glyphRect.left(), minX);
- minY = qMin(glyphRect.top(), minY);
- maxX = qMax(glyphRect.right(),maxX);
- maxY = qMax(glyphRect.bottom(), maxY);
+ minX = qMin(gm.x, minX);
+ minY = qMin(gm.y, minY);
+ maxX = qMax(gm.x + gm.width, maxX);
+ maxY = qMax(gm.y + gm.height, maxY);
}
}
- QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY));
+
+ QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal()));
return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent()));
}
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index da5d39db20..214f7d790b 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -465,7 +465,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter)
m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
- margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
return;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
index 141d8f3c6d..a10a94125c 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
@@ -205,7 +205,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter)
painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height()));
else
QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()),
- m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr));
+ m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
}
QRectF QSGSoftwareNinePatchNode::bounds() const
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index c97dcb9326..c010e0cae5 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -52,6 +52,8 @@
#include <QtGui/QBackingStore>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
QSGSoftwareRenderLoop::QSGSoftwareRenderLoop()
@@ -133,20 +135,25 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (!m_windows.contains(window))
return;
}
+
+ Q_TRACE_SCOPE(QSG_renderWindow)
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -155,8 +162,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
//Tell the renderer about the windows backing store
auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
@@ -167,8 +176,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
grabContent = m_backingStores[window]->handle()->toImage();
@@ -187,6 +198,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index c6b463bb02..f07cc28827 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -60,6 +60,8 @@
#include <QtGui/QBackingStore>
#include <QtQuick/QQuickWindow>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Passed from the RL to the RT when a window is removed obscured and should be
@@ -457,6 +459,8 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
void QSGSoftwareRenderThread::syncAndRender()
{
+ Q_TRACE_SCOPE(QSG_syncAndRender);
+ Q_TRACE(QSG_sync_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
QElapsedTimer waitTimer;
@@ -475,6 +479,7 @@ void QSGSoftwareRenderThread::syncAndRender()
if (syncRequested)
sync(exposeRequested);
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
@@ -487,6 +492,7 @@ void QSGSoftwareRenderThread::syncAndRender()
}
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering started");
+ Q_TRACE(QSG_render_entry);
if (rtAnim->isRunning()) {
wd->animationController->lock();
@@ -502,8 +508,10 @@ void QSGSoftwareRenderThread::syncAndRender()
softwareRenderer->setBackingStore(backingStore);
wd->renderSceneGraph(exposedWindow->size());
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (softwareRenderer && (!wd->customRenderStage || !wd->customRenderStage->swap()))
backingStore->flush(softwareRenderer->flushRegion());
@@ -519,8 +527,10 @@ void QSGSoftwareRenderThread::syncAndRender()
wd->fireFrameSwapped();
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - window not ready, skipping render");
}
@@ -532,6 +542,7 @@ void QSGSoftwareRenderThread::syncAndRender()
mutex.unlock();
}
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
}
@@ -947,13 +958,18 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
return;
}
+ Q_TRACE_SCOPE(QSG_polishAndSync);
+
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
wd->polishItems();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_sync_entry);
w->updateDuringSync = false;
@@ -967,15 +983,19 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - wait for sync");
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_wait_entry);
w->thread->waitCondition.wait(&w->thread->mutex);
lockedForSync = false;
w->thread->mutex.unlock();
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - unlock after sync");
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (!animationTimer && m_anim->isRunning()) {
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - advancing animations");
@@ -987,6 +1007,7 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop:
w->window->requestUpdate();
}
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
index 1a8bddaa6e..65abb2a1af 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -296,7 +296,7 @@ void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdate
return;
}
- QRhiTexture::Flags texFlags = 0;
+ QRhiTexture::Flags texFlags;
if (fmt.second)
texFlags |= QRhiTexture::sRGB;
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
index 1594352dab..258a5fed14 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
@@ -72,6 +72,10 @@ public:
~QSGAbstractRenderer() override;
+ // just have a warning about becoming private, ifdefing the whole class is not feasible
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("QSGAbstractRenderer is no longer going to be public in Qt 6.0. QSGEngine-based workflows are expected to migrate to QQuickRenderControl instead.")
+#endif
void setRootNode(QSGRootNode *node);
QSGRootNode *rootNode() const;
void setDeviceRect(const QRect &rect);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 34027cbac7..e94dd502fc 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -62,6 +62,8 @@
#include "qsgopenglvisualizer_p.h"
#include "qsgrhivisualizer_p.h"
+#include <qtquick_tracepoints_p.h>
+
#include <algorithm>
#ifndef GL_DOUBLE
@@ -270,6 +272,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, boo
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -332,6 +335,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
return nullptr;
}
+ Q_TRACE_SCOPE(QSG_prepareMaterial);
if (QSG_LOG_TIME_COMPILATION().isDebugEnabled())
qsg_renderer_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
@@ -379,6 +383,9 @@ void ShaderManager::invalidated()
qDeleteAll(srbCache);
srbCache.clear();
+
+ qDeleteAll(pipelineCache);
+ pipelineCache.clear();
}
void ShaderManager::clearCachedRendererData()
@@ -447,13 +454,13 @@ void qsg_dumpShadowRoots(Node *n)
QByteArray ind(indent, ' ');
if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
- qDebug() << ind.constData() << "[X]" << n->sgNode << hex << uint(n->sgNode->flags());
+ qDebug() << ind.constData() << "[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
qsg_dumpShadowRoots(n->rootInfo(), indent);
} else {
QDebug d = qDebug();
- d << ind.constData() << "[ ]" << n->sgNode << hex << uint(n->sgNode->flags());
+ d << ind.constData() << "[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
if (n->type() == QSGNode::GeometryNodeType)
- d << "order" << dec << n->element()->order;
+ d << "order" << Qt::dec << n->element()->order;
}
SHADOWNODE_TRAVERSE(n)
@@ -546,7 +553,7 @@ void Updater::visitNode(Node *n)
m_added = count;
m_force_update = force;
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
void Updater::visitClipNode(Node *n)
@@ -1024,6 +1031,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")));
}
+ static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
if (!m_rhi) {
// If rendering with an OpenGL Core profile context, we need to create a VAO
// to hold our vertex specification state.
@@ -1031,9 +1039,9 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
m_vao = new QOpenGLVertexArrayObject(this);
m_vao->create();
}
-
- bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
m_useDepthBuffer = useDepth && ctx->openglContext()->format().depthBufferSize() > 0;
+ } else {
+ m_useDepthBuffer = useDepth;
}
}
@@ -1103,13 +1111,9 @@ void Renderer::destroyGraphicsResources()
// are going to destroy.
m_shaderManager->clearCachedRendererData();
- qDeleteAll(m_pipelines);
qDeleteAll(m_samplers);
-
m_stencilClipCommon.reset();
-
delete m_dummyTexture;
-
m_visualizer->releaseResources();
}
@@ -1119,7 +1123,6 @@ void Renderer::releaseCachedResources()
destroyGraphicsResources();
- m_pipelines.clear();
m_samplers.clear();
m_dummyTexture = nullptr;
@@ -1399,12 +1402,11 @@ void Renderer::nodeWasRemoved(Node *node)
m_elementsToDelete.add(e);
if (m_renderNodeElements.isEmpty()) {
- if (m_rhi) {
- m_useDepthBuffer = true;
- } else {
- static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER");
+ if (m_rhi)
+ m_useDepthBuffer = useDepth;
+ else
m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0;
- }
}
}
}
@@ -2352,7 +2354,7 @@ void Renderer::uploadBatch(Batch *b)
iDump << " -- Index Data, count:" << b->indexCount;
for (int i=0; i<b->indexCount; ++i) {
if ((i % 24) == 0)
- iDump << endl << " --- ";
+ iDump << Qt::endl << " --- ";
iDump << id[i];
}
}
@@ -2627,7 +2629,7 @@ QRhiGraphicsPipeline *Renderer::buildStencilPipeline(const Batch *batch, bool fi
QRhiGraphicsPipeline *ps = m_rhi->newGraphicsPipeline();
ps->setFlags(QRhiGraphicsPipeline::UsesStencilRef);
QRhiGraphicsPipeline::TargetBlend blend;
- blend.colorWrite = 0;
+ blend.colorWrite = {};
ps->setTargetBlends({ blend });
ps->setSampleCount(renderTarget()->sampleCount());
ps->setStencilTest(true);
@@ -3237,15 +3239,17 @@ static inline bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f)
bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) // RHI only, [prepare step]
{
- // In unmerged batches the srbs in the elements are all compatible layout-wise.
+ // In unmerged batches the srbs in the elements are all compatible
+ // layout-wise. Note the key's == and qHash implementations: the rp desc and
+ // srb are tested for (layout) compatibility, not pointer equality.
const GraphicsPipelineStateKey k { m_gstate, sms, renderPassDescriptor(), e->srb };
// Note: dynamic state (viewport rect, scissor rect, stencil ref, blend
// constant) is never a part of GraphicsState/QRhiGraphicsPipeline.
// See if there is an existing, matching pipeline state object.
- auto it = m_pipelines.constFind(k);
- if (it != m_pipelines.constEnd()) {
+ auto it = m_shaderManager->pipelineCache.constFind(k);
+ if (it != m_shaderManager->pipelineCache.constEnd()) {
e->ps = *it;
return true;
}
@@ -3257,7 +3261,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
ps->setShaderResourceBindings(e->srb);
ps->setRenderPassDescriptor(renderPassDescriptor());
- QRhiGraphicsPipeline::Flags flags = 0;
+ QRhiGraphicsPipeline::Flags flags;
if (needsBlendConstant(m_gstate.srcColor) || needsBlendConstant(m_gstate.dstColor))
flags |= QRhiGraphicsPipeline::UsesBlendConstants;
if (m_gstate.usesScissor)
@@ -3302,7 +3306,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms)
return false;
}
- m_pipelines.insert(k, ps);
+ m_shaderManager->pipelineCache.insert(k, ps);
e->ps = ps;
return true;
}
@@ -3713,7 +3717,7 @@ void Renderer::renderMergedBatch(PreparedRenderBatch *renderBatch) // split prep
{ batch->vbo.buf, quint32(draw.vertices) },
{ batch->vbo.buf, quint32(draw.zorders) }
};
- cb->setVertexInput(VERTEX_BUFFER_BINDING, 2, vbufBindings,
+ cb->setVertexInput(VERTEX_BUFFER_BINDING, m_useDepthBuffer ? 2 : 1, vbufBindings,
batch->ibo.buf, draw.indices,
m_uint32IndexForRhi ? QRhiCommandBuffer::IndexUInt32 : QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(draw.indexCount);
@@ -3957,8 +3961,8 @@ void Renderer::setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, El
void Renderer::renderBatches()
{
if (Q_UNLIKELY(debug_render())) {
- qDebug().nospace() << "Rendering:" << endl
- << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << endl
+ qDebug().nospace() << "Rendering:" << Qt::endl
+ << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << Qt::endl
<< " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches...";
}
@@ -4049,8 +4053,8 @@ void Renderer::renderBatches()
m_pstate.viewportSet = false;
m_pstate.scissorSet = false;
- m_gstate.depthTest = true;
- m_gstate.depthWrite = true;
+ m_gstate.depthTest = m_useDepthBuffer;
+ m_gstate.depthWrite = m_useDepthBuffer;
m_gstate.depthFunc = QRhiGraphicsPipeline::Less;
m_gstate.blending = false;
@@ -4082,8 +4086,8 @@ void Renderer::renderBatches()
m_gstate.blending = true;
// factors never change, always set for premultiplied alpha based blending
- // depth test stays enabled but no need to write out depth from the
- // transparent (back-to-front) pass
+ // depth test stays enabled (if m_useDepthBuffer, that is) but no need
+ // to write out depth from the transparent (back-to-front) pass
m_gstate.depthWrite = false;
QVarLengthArray<PreparedRenderBatch, 64> alphaRenderBatches;
@@ -4504,6 +4508,35 @@ bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBat
updateClipState(rd->m_clip_list, batch);
+ QSGNode *xform = e->renderNode->parent();
+ QMatrix4x4 matrix;
+ QSGNode *root = rootNode();
+ if (e->root) {
+ matrix = qsg_matrixForRoot(e->root);
+ root = e->root->sgNode;
+ }
+ while (xform != root) {
+ if (xform->type() == QSGNode::TransformNodeType) {
+ matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
+ break;
+ }
+ xform = xform->parent();
+ }
+ rd->m_matrix = &matrix;
+
+ QSGNode *opacity = e->renderNode->parent();
+ rd->m_opacity = 1.0;
+ while (opacity != rootNode()) {
+ if (opacity->type() == QSGNode::OpacityNodeType) {
+ rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
+ break;
+ }
+ opacity = opacity->parent();
+ }
+
+ if (rd->m_prepareCallback)
+ rd->m_prepareCallback();
+
renderBatch->batch = batch;
renderBatch->sms = nullptr;
@@ -4532,38 +4565,15 @@ void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render (
state.m_scissorEnabled = batch->clipState.type & ClipState::ScissorClip;
state.m_stencilEnabled = batch->clipState.type & ClipState::StencilClip;
- QSGNode *xform = e->renderNode->parent();
- QMatrix4x4 matrix;
- QSGNode *root = rootNode();
- if (e->root) {
- matrix = qsg_matrixForRoot(e->root);
- root = e->root->sgNode;
- }
- while (xform != root) {
- if (xform->type() == QSGNode::TransformNodeType) {
- matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
- break;
- }
- xform = xform->parent();
- }
- rd->m_matrix = &matrix;
-
- QSGNode *opacity = e->renderNode->parent();
- rd->m_opacity = 1.0;
- while (opacity != rootNode()) {
- if (opacity->type() == QSGNode::OpacityNodeType) {
- rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity();
- break;
- }
- opacity = opacity->parent();
- }
-
const QSGRenderNode::StateFlags changes = e->renderNode->changedStates();
QRhiCommandBuffer *cb = commandBuffer();
- cb->beginExternal();
+ const bool needsExternal = rd->m_needsExternalRendering;
+ if (needsExternal)
+ cb->beginExternal();
e->renderNode->render(&state);
- cb->endExternal();
+ if (needsExternal)
+ cb->endExternal();
rd->m_matrix = nullptr;
rd->m_clip_list = nullptr;
@@ -4643,7 +4653,7 @@ bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
{
return a.state == b.state
&& a.sms->programRhi.program == b.sms->programRhi.program
- && a.rpDesc == b.rpDesc
+ && a.compatibleRenderPassDescriptor->isCompatible(b.compatibleRenderPassDescriptor)
&& a.layoutCompatibleSrb->isLayoutCompatible(b.layoutCompatibleSrb);
}
@@ -4654,7 +4664,8 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe
uint qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW
{
- return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed) + qHash(k.rpDesc, seed);
+ // no srb and rp included due to their special comparison semantics and lack of hash keys
+ return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed);
}
Visualizer::Visualizer(Renderer *renderer)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 297df2232a..878b63fc8c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -626,27 +626,65 @@ private:
QMatrix4x4 m_identityMatrix;
};
+struct GraphicsState
+{
+ bool depthTest = false;
+ bool depthWrite = false;
+ QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
+ bool blending = false;
+ QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
+ QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
+ QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
+ QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
+ bool usesScissor = false;
+ bool stencilTest = false;
+ int sampleCount = 1;
+ QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
+ float lineWidth = 1.0f;
+};
+
+bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader;
+
+struct GraphicsPipelineStateKey
+{
+ GraphicsState state;
+ const ShaderManagerShader *sms;
+ const QRhiRenderPassDescriptor *compatibleRenderPassDescriptor;
+ const QRhiShaderResourceBindings *layoutCompatibleSrb;
+};
+
+bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
+uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
+
+struct ShaderManagerShader
+{
+ ~ShaderManagerShader() {
+ delete programRhi.program;
+ delete programGL.program;
+ }
+ struct {
+ QSGMaterialShader *program = nullptr;
+ int pos_order;
+ } programGL;
+ struct {
+ QSGMaterialRhiShader *program = nullptr;
+ QRhiVertexInputLayout inputLayout;
+ QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
+ } programRhi;
+
+ float lastOpacity;
+};
+
class ShaderManager : public QObject
{
Q_OBJECT
public:
- struct Shader {
- ~Shader() {
- delete programRhi.program;
- delete programGL.program;
- }
- struct {
- QSGMaterialShader *program = nullptr;
- int pos_order;
- } programGL;
- struct {
- QSGMaterialRhiShader *program = nullptr;
- QRhiVertexInputLayout inputLayout;
- QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages;
- } programRhi;
-
- float lastOpacity;
- };
+ using Shader = ShaderManagerShader;
ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(nullptr), context(ctx) { }
~ShaderManager() {
@@ -657,9 +695,10 @@ public:
void clearCachedRendererData();
using ShaderResourceBindingList = QVarLengthArray<QRhiShaderResourceBinding, 8>;
-
QRhiShaderResourceBindings *srb(const ShaderResourceBindingList &bindings);
+ QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache;
+
public Q_SLOTS:
void invalidated();
@@ -677,39 +716,6 @@ private:
QHash<ShaderResourceBindingList, QRhiShaderResourceBindings *> srbCache;
};
-struct GraphicsState
-{
- bool depthTest = false;
- bool depthWrite = false;
- QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less;
- bool blending = false;
- QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One;
- QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha;
- QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
- QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None;
- bool usesScissor = false;
- bool stencilTest = false;
- int sampleCount = 1;
- QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles;
- float lineWidth = 1.0f;
-};
-
-bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW;
-
-struct GraphicsPipelineStateKey
-{
- GraphicsState state;
- const ShaderManager::Shader *sms;
- const QRhiRenderPassDescriptor *rpDesc;
- const QRhiShaderResourceBindings *layoutCompatibleSrb;
-};
-
-bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW;
-uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW;
-
struct RenderPassState
{
QRhiViewport viewport;
@@ -903,7 +909,6 @@ private:
GraphicsState m_gstate;
RenderPassState m_pstate;
QStack<GraphicsState> m_gstateStack;
- QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> m_pipelines;
QHash<QSGSamplerDescription, QRhiSampler *> m_samplers;
QRhiTexture *m_dummyTexture = nullptr;
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index c8ae26311b..087c3c4cbf 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -153,7 +153,6 @@ static void qt_print_material_count()
*/
QSGMaterial::QSGMaterial()
- : m_flags(nullptr)
{
Q_UNUSED(m_reserved);
#ifndef QT_NO_DEBUG
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
index 77593591bd..c5cbd0c979 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp
@@ -97,14 +97,14 @@ static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage st
Q_UNREACHABLE();
break;
}
- return 0;
+ return { };
}
void QSGMaterialRhiShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
{
ubufBinding = -1;
ubufSize = 0;
- ubufStages = 0;
+ ubufStages = { };
memset(combinedImageSamplerBindings, 0, sizeof(combinedImageSamplerBindings));
vertexShader = fragmentShader = nullptr;
masterUniformData.clear();
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 1976538aec..a35629d874 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -245,7 +245,6 @@ static void qt_print_node_count()
*/
QSGNode::QSGNode()
: m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -264,7 +263,6 @@ QSGNode::QSGNode(NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
{
init();
}
@@ -283,7 +281,6 @@ QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type)
, m_previousSibling(nullptr)
, m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
- , m_dirtyState(nullptr)
, d_ptr(&dd)
{
init();
@@ -1466,7 +1463,7 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n)
d << "Geometry(null)";
return d;
}
- d << "GeometryNode(" << hex << (const void *) n << dec;
+ d << "GeometryNode(" << Qt::hex << (const void *) n << Qt::dec;
const QSGGeometry *g = n->geometry();
@@ -1517,7 +1514,7 @@ QDebug operator<<(QDebug d, const QSGClipNode *n)
d << "ClipNode(null)";
return d;
}
- d << "ClipNode(" << hex << (const void *) n << dec;
+ d << "ClipNode(" << Qt::hex << (const void *) n << Qt::dec;
if (n->childCount())
d << "children=" << n->childCount();
@@ -1540,7 +1537,7 @@ QDebug operator<<(QDebug d, const QSGTransformNode *n)
}
const QMatrix4x4 m = n->matrix();
d << "TransformNode(";
- d << hex << (const void *) n << dec;
+ d << Qt::hex << (const void *) n << Qt::dec;
if (m.isIdentity())
d << "identity";
else if (m.determinant() == 1 && m(0, 0) == 1 && m(1, 1) == 1 && m(2, 2) == 1)
@@ -1562,7 +1559,7 @@ QDebug operator<<(QDebug d, const QSGOpacityNode *n)
return d;
}
d << "OpacityNode(";
- d << hex << (const void *) n << dec;
+ d << Qt::hex << (const void *) n << Qt::dec;
d << "opacity=" << n->opacity()
<< "combined=" << n->combinedOpacity()
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
@@ -1581,7 +1578,7 @@ QDebug operator<<(QDebug d, const QSGRootNode *n)
return d;
}
QDebugStateSaver saver(d);
- d << "RootNode" << hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
+ d << "RootNode" << Qt::hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
#endif
@@ -1614,8 +1611,8 @@ QDebug operator<<(QDebug d, const QSGNode *n)
d << static_cast<const QSGOpacityNode *>(n);
break;
case QSGNode::RenderNodeType:
- d << "RenderNode(" << hex << (const void *) n << dec
- << "flags=" << (int) n->flags() << dec
+ d << "RenderNode(" << Qt::hex << (const void *) n << Qt::dec
+ << "flags=" << (int) n->flags() << Qt::dec
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
@@ -1623,8 +1620,8 @@ QDebug operator<<(QDebug d, const QSGNode *n)
d << ')';
break;
default:
- d << "Node(" << hex << (const void *) n << dec
- << "flags=" << (int) n->flags() << dec
+ d << "Node(" << Qt::hex << (const void *) n << Qt::dec
+ << "flags=" << (int) n->flags() << Qt::dec
<< (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index cb677de030..5a7faed5e0 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -146,7 +146,7 @@ public:
QT_DEPRECATED void clearDirty() { }
void markDirty(DirtyState bits);
- QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
+ QT_DEPRECATED DirtyState dirtyState() const { return { }; }
virtual bool isSubtreeBlocked() const;
diff --git a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
index 6c2ff0b176..9282b6c308 100644
--- a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp
@@ -202,7 +202,7 @@ void OpenGLVisualizer::visualizeChanges(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = {};
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 7af932eeb5..90090e1cc0 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -45,6 +45,7 @@
# include <QtGui/QOpenGLFunctions>
#endif
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <QtCore/QElapsedTimer>
@@ -221,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
if (!rootNode())
return;
+ Q_TRACE_SCOPE(QSG_renderScene);
m_is_rendering = true;
@@ -235,11 +237,14 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
m_bindable = &bindable;
preprocess();
+ Q_TRACE(QSG_binding_entry);
bindable.bind();
if (profileFrames)
bindTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_binding_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererBinding);
+ Q_TRACE(QSG_render_entry);
#if QT_CONFIG(opengl)
// Sanity check that attribute registers are disabled
@@ -259,6 +264,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
render();
if (profileFrames)
renderTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererRender);
@@ -305,6 +311,8 @@ void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
void QSGRenderer::preprocess()
{
+ Q_TRACE(QSG_preprocess_entry);
+
m_is_preprocessing = true;
QSGRootNode *root = rootNode();
@@ -331,13 +339,16 @@ void QSGRenderer::preprocess()
bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
if (profileFrames)
preprocessTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_preprocess_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererPreprocess);
+ Q_TRACE(QSG_update_entry);
nodeUpdater()->updateStates(root);
if (profileFrames)
updatePassTime = frameTimer.nsecsElapsed();
+ Q_TRACE(QSG_update_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererUpdate);
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 2892f2f966..45ad49475f 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -77,6 +77,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
: m_matrix(nullptr)
, m_clip_list(nullptr)
, m_opacity(1)
+ , m_needsExternalRendering(true)
+ , m_prepareCallback(nullptr)
{
}
@@ -131,7 +133,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate()
*/
QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
{
- return nullptr;
+ return {};
}
/*!
@@ -311,7 +313,7 @@ void QSGRenderNode::releaseResources()
*/
QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
{
- return nullptr;
+ return {};
}
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode_p.h b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
index 5c42e55689..534d630f15 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
@@ -51,12 +51,14 @@
// We mean it.
//
+#include <QtQuick/private/qtquickglobal_p.h>
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgrendernode.h>
+#include <functional>
QT_BEGIN_NAMESPACE
-class QSGRenderNodePrivate
+class Q_QUICK_PRIVATE_EXPORT QSGRenderNodePrivate
{
public:
QSGRenderNodePrivate();
@@ -66,6 +68,11 @@ public:
const QMatrix4x4 *m_matrix;
const QSGClipNode *m_clip_list;
qreal m_opacity;
+
+ // ### Qt 6: change this into a value for flags()
+ bool m_needsExternalRendering;
+ // ### Qt 6: change this into a virtual prepare() function
+ std::function<void()> m_prepareCallback;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
index 38d4c4440f..a0131a3f67 100644
--- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp
@@ -400,7 +400,7 @@ void RhiVisualizer::ChangeVis::gather(Node *n)
// This is because many changes don't propegate their dirty state to the
// parent so the node updater will not unset these states. They are
// not used for anything so, unsetting it should have no side effects.
- n->dirtyState = nullptr;
+ n->dirtyState = { };
}
SHADOWNODE_TRAVERSE(n) {
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index 58b42e4094..418aaca605 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -317,6 +317,34 @@ static void qt_debug_remove_texture(QSGTexture* texture)
\since 5.9
*/
+/*!
+ \class QSGTexture::NativeTexture
+ \brief Contains information about the underlying native resources of a texture.
+ \since 5.15
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::object
+ \brief a pointer to the native object handle.
+
+ With OpenGL, the native handle is a GLuint value, so \c object is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \c
+ object is a pointer to a VkImage. With Direct3D 11 and Metal \c
+ object is a pointer to a ID3D11Texture2D or MTLTexture pointer, respectively.
+
+ \note Pay attention to the fact that \a object is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+ */
+
+/*!
+ \variable QSGTexture::NativeTexture::layout
+ \brief Specifies the current image layout for APIs like Vulkan.
+
+ For Vulkan, \c layout contains a \c VkImageLayout value.
+ */
+
+
#ifndef QT_NO_DEBUG
Q_QUICK_PRIVATE_EXPORT void qsg_set_material_failure();
#endif
@@ -721,6 +749,28 @@ void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUp
}
/*!
+ \return the platform-specific texture data for this texture.
+
+ \note This is only available when running the graphics API independent
+ rendering path of the scene graph. Use textureId() otherwise.
+
+ Returns an empty result (\c object is null) if there is no available
+ underlying native texture.
+
+ \since 5.15
+ \sa QQuickWindow::createTextureFromNativeObject()
+ */
+QSGTexture::NativeTexture QSGTexture::nativeTexture() const
+{
+ Q_D(const QSGTexture);
+ if (auto *tex = d->rhiTexture()) {
+ auto nativeTexture = tex->nativeTexture();
+ return {nativeTexture.object, nativeTexture.layout};
+ }
+ return {};
+}
+
+/*!
\internal
*/
void QSGTexture::setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates)
@@ -792,11 +842,15 @@ void QSGTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *res
/*!
\fn bool QSGDynamicTexture::updateTexture()
- Call this function to explicitly update the dynamic texture. Calling bind() will bind
- the content that was previously updated.
+ Call this function to explicitly update the dynamic texture.
The function returns true if the texture was changed as a resul of the update; otherwise
returns false.
+
+ \note This function is typically called from QQuickItem::updatePaintNode()
+ or QSGNode::preprocess(), meaning during the \c{synchronization} or the
+ \c{node preprocessing} phases of the scenegraph. Calling it at other times
+ is discouraged and can lead to unexpected behavior.
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h
index 2efdd8b7c3..207ef52f4e 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.h
+++ b/src/quick/scenegraph/coreapi/qsgtexture.h
@@ -80,7 +80,13 @@ public:
Anisotropy16x
};
+ struct NativeTexture {
+ const void *object;
+ int layout;
+ };
+
virtual int textureId() const = 0; // ### Qt 6: remove
+ NativeTexture nativeTexture() const;
virtual QSize textureSize() const = 0;
virtual bool hasAlphaChannel() const = 0;
virtual bool hasMipmaps() const = 0;
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index f7b07d724a..eab0369be7 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -50,6 +50,8 @@
#include <private/qquickprofiler_p.h>
#include <QElapsedTimer>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
static QElapsedTimer qsg_render_timer;
@@ -169,10 +171,13 @@ void QSGDistanceFieldGlyphCache::update()
if (m_pendingGlyphs.isEmpty())
return;
+ Q_TRACE_SCOPE(QSGDistanceFieldGlyphCache_update, m_pendingGlyphs.size());
+
bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled();
if (profileFrames)
qsg_render_timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_entry);
QList<QDistanceField> distanceFields;
const int pendingGlyphsSize = m_pendingGlyphs.size();
@@ -189,8 +194,11 @@ void QSGDistanceFieldGlyphCache::update()
int count = m_pendingGlyphs.size();
if (profileFrames)
renderTime = qsg_render_timer.nsecsElapsed();
+
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphRender);
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_entry);
m_pendingGlyphs.reset();
@@ -210,6 +218,7 @@ void QSGDistanceFieldGlyphCache::update()
int(renderTime / 1000000),
int((now - (renderTime / 1000000))));
}
+ Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_exit);
Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
QQuickProfiler::SceneGraphAdaptationLayerGlyphStore,
(qint64)count);
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 6baee33b53..1db49feb5d 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -57,8 +57,10 @@
#include <QtCore/qrect.h>
#include <QtGui/qbrush.h>
#include <QtGui/qcolor.h>
+#include <QtGui/qpainterpath.h>
#include <QtCore/qsharedpointer.h>
#include <QtGui/qglyphrun.h>
+#include <QtGui/qpainterpath.h>
#include <QtCore/qurl.h>
#include <private/qfontengine_p.h>
#include <QtGui/private/qdatabuffer_p.h>
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 17eb1e312c..e3c951e5ed 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -341,9 +341,10 @@ void QSGRenderContext::invalidate()
{
}
-void QSGRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
Q_UNUSED(devicePixelRatio);
+ Q_UNUSED(cb);
}
void QSGRenderContext::beginNextFrame(QSGRenderer *renderer,
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 244bcfabd1..d389420907 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -174,7 +174,7 @@ public:
using RenderPassCallback = void (*)(void *);
- virtual void prepareSync(qreal devicePixelRatio);
+ virtual void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb);
virtual void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index 66add51c55..7dfb8488ae 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -87,7 +87,6 @@ struct QSGAdaptationBackendData
};
QSGAdaptationBackendData::QSGAdaptationBackendData()
- : flags(nullptr)
{
// Fill in the table with the built-in adaptations.
builtIns.append(new QSGSoftwareAdaptation);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 2bf4a83a8e..1d18caa0b4 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -200,9 +200,14 @@ void QSGDefaultRenderContext::invalidate()
emit invalidated();
}
-void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio)
+void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb)
{
m_currentDevicePixelRatio = devicePixelRatio;
+
+ // we store the command buffer already here, in case there is something in
+ // an updatePaintNode() implementation that leads to needing it (for
+ // example, an updateTexture() call on a QSGRhiLayer)
+ m_currentFrameCommandBuffer = cb;
}
static QBasicMutex qsg_framerender_mutex;
@@ -237,14 +242,12 @@ void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRende
RenderPassCallback mainPassRecordingEnd,
void *callbackUserData)
{
- Q_ASSERT(!m_currentFrameCommandBuffer);
-
renderer->setRenderTarget(rt);
renderer->setRenderPassDescriptor(rp);
renderer->setCommandBuffer(cb);
renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
- m_currentFrameCommandBuffer = cb;
+ m_currentFrameCommandBuffer = cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called
m_currentFrameRenderPass = rp;
}
@@ -364,7 +367,7 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader());
p->link();
if (!p->isLinked())
- qWarning() << "shader compilation failed:" << endl << p->log();
+ qWarning() << "shader compilation failed:" << Qt::endl << p->log();
} else {
shader->compile();
}
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 2fdb3a48dd..97ed681f9a 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -104,7 +104,7 @@ public:
void initialize(const QSGRenderContext::InitParams *params) override;
void invalidate() override;
- void prepareSync(qreal devicePixelRatio) override;
+ void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) override;
void beginNextFrame(QSGRenderer *renderer,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index f609055677..94f15b55d4 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -60,6 +60,7 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
#include <private/qsgrhishadereffectnode_p.h>
@@ -195,8 +196,16 @@ public:
bool eventFilter(QObject *watched, QEvent *event) override;
struct WindowData {
+ WindowData()
+ : updatePending(false),
+ grabOnly(false),
+ rhiDeviceLost(false),
+ rhiDoomed(false)
+ { }
bool updatePending : 1;
bool grabOnly : 1;
+ bool rhiDeviceLost : 1;
+ bool rhiDoomed : 1;
};
QHash<QQuickWindow *, WindowData> m_windows;
@@ -316,15 +325,19 @@ void QSGRenderLoop::setInstance(QSGRenderLoop *instance)
s_instance = instance;
}
-void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window,
- bool isEs)
+void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window)
{
QString translatedMessage;
QString untranslatedMessage;
- QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ if (QSGRhiSupport::instance()->isRhiEnabled()) {
+ QQuickWindowPrivate::rhiCreationFailureMessage(QSGRhiSupport::instance()->rhiBackendName(),
&translatedMessage,
- &untranslatedMessage,
- isEs);
+ &untranslatedMessage);
+ } else {
+ QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(),
+ &translatedMessage,
+ &untranslatedMessage);
+ }
// If there is a slot connected to the error signal, emit it and leave it to
// the application to do something with the message. If nothing is connected,
// show a message on our own and terminate.
@@ -362,10 +375,7 @@ QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop()
void QSGGuiThreadRenderLoop::show(QQuickWindow *window)
{
- WindowData data;
- data.updatePending = false;
- data.grabOnly = false;
- m_windows[window] = data;
+ m_windows[window] = WindowData();
maybeUpdate(window);
}
@@ -451,8 +461,10 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
rc->invalidate();
- for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it)
+ for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) {
releaseSwapchain(it.key());
+ it->rhiDeviceLost = true;
+ }
delete rhi;
rhi = nullptr;
@@ -508,6 +520,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool enableRhi = rhiSupport->isRhiEnabled();
if (enableRhi && !rhi) {
+ // This block below handles both the initial QRhi initialization and
+ // also the subsequent reinitialization attempts after a device lost
+ // (reset) situation.
+
+ if (data.rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
+
if (!offscreenSurface)
offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
@@ -517,6 +536,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi);
+ data.rhiDeviceLost = false;
+
current = true;
rhi->makeThreadLocalNativeContextCurrent();
@@ -533,7 +554,11 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
rcParams.maybeSurface = window;
cd->context->initialize(&rcParams);
} else {
- handleContextCreationFailure(window, false);
+ if (!data.rhiDeviceLost) {
+ data.rhiDoomed = true;
+ handleContextCreationFailure(window);
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
}
} else if (!enableRhi && !gl) {
gl = new QOpenGLContext();
@@ -542,10 +567,9 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (qt_gl_global_share_context())
gl->setShareContext(qt_gl_global_share_context());
if (!gl->create()) {
- const bool isEs = gl->isOpenGLES();
delete gl;
gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
} else {
if (!offscreenSurface) {
offscreenSurface = new QOffscreenSurface;
@@ -619,7 +643,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
i++;
}
- // Check for context loss.
+ // Check for context loss. (legacy GL only)
if (!current && !rhi && !gl->isValid()) {
for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) {
QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key());
@@ -657,20 +681,25 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
return;
}
+ Q_TRACE_SCOPE(QSG_renderWindow);
QElapsedTimer renderTimer;
qint64 renderTime = 0, syncTime = 0, polishTime = 0;
bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled();
if (profileFrames)
renderTimer.start();
+ Q_TRACE(QSG_polishItems_entry);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
cd->polishItems();
if (profileFrames)
polishTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -725,15 +754,20 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
cd->renderSceneGraph(window->size(), effectiveOutputSize);
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
if (data.grabOnly) {
const bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
@@ -747,7 +781,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
const bool needsPresent = alsoSwap && window->isVisible();
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
+ QRhi::EndFrameFlags flags;
if (!needsPresent)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
@@ -767,6 +801,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
qint64 swapTime = 0;
if (profileFrames)
swapTime = renderTimer.nsecsElapsed();
+
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 02d0b84de1..9fd0ab02f5 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -112,12 +112,11 @@ public:
static void cleanup();
+ void handleContextCreationFailure(QQuickWindow *window);
+
Q_SIGNALS:
void timeToIncubate();
-protected:
- void handleContextCreationFailure(QQuickWindow *window, bool isEs);
-
private:
static QSGRenderLoop *s_instance;
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index 757410eded..952279a3ff 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -388,7 +388,7 @@ void QSGRhiLayer::grab()
m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
m_mirrorVertical ? m_rect.height() : -m_rect.height());
}
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0;
+ QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (!m_rhi->isYUpInNDC())
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
m_renderer->setProjectionMatrixToRect(mirrored, matrixFlags);
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index 6f6544548c..e86dae7c09 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -136,7 +136,7 @@ void QSGRhiShaderLinker::linkTextureSubRects()
// texture binding point.
for (Constant &c : m_constants) {
if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
- if (c.value.type() == QVariant::ByteArray) {
+ if (c.value.userType() == QMetaType::QByteArray) {
const QByteArray name = c.value.toByteArray();
if (!m_samplerNameMap.contains(name))
qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", name.constData());
@@ -270,7 +270,7 @@ bool QSGRhiShaderEffectMaterialShader::updateUniformData(RenderState &state, QSG
memcpy(dst, f, sizeof(f));
} else if (c.specialType == QSGShaderEffectNode::VariableData::None) {
changed = true;
- switch (int(c.value.type())) {
+ switch (int(c.value.userType())) {
case QMetaType::QColor: {
const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value));
const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) };
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index e2945879b1..2bf70ddec6 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -38,7 +38,10 @@
****************************************************************************/
#include "qsgrhisupport_p.h"
-#include "qsgdefaultrendercontext_p.h"
+#include "qsgcontext_p.h"
+#if QT_CONFIG(opengl)
+# include "qsgdefaultrendercontext_p.h"
+#endif
#include <QtGui/qwindow.h>
#if QT_CONFIG(vulkan)
@@ -157,9 +160,11 @@ void QSGRhiSupport::applySettings()
} else if (rhiBackend == QByteArrayLiteral("null")) {
m_rhiBackend = QRhi::Null;
} else {
+ if (!rhiBackend.isEmpty())
+ qWarning("Unknown key \"%s\" for QSG_RHI_BACKEND, falling back to default backend.", qPrintable(rhiBackend));
#if defined(Q_OS_WIN)
m_rhiBackend = QRhi::D3D11;
-#elif defined(Q_OS_DARWIN)
+#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS)
m_rhiBackend = QRhi::Metal;
#else
m_rhiBackend = QRhi::OpenGLES2;
@@ -185,29 +190,10 @@ void QSGRhiSupport::applySettings()
if (m_killDeviceFrameCount > 0 && m_rhiBackend == QRhi::D3D11)
qDebug("Graphics device will be reset every %d frames", m_killDeviceFrameCount);
- const char *backendName = "unknown";
- switch (m_rhiBackend) {
- case QRhi::Null:
- backendName = "Null";
- break;
- case QRhi::Vulkan:
- backendName = "Vulkan";
- break;
- case QRhi::OpenGLES2:
- backendName = "OpenGL";
- break;
- case QRhi::D3D11:
- backendName = "D3D11";
- break;
- case QRhi::Metal:
- backendName = "Metal";
- break;
- default:
- break;
- }
+ const QString backendName = rhiBackendName();
qCDebug(QSG_LOG_INFO,
"Using QRhi with backend %s\n graphics API debug/validation layers: %d\n QRhi profiling and debug markers: %d",
- backendName, m_debugLayer, m_profile);
+ qPrintable(backendName), m_debugLayer, m_profile);
if (m_preferSoftwareRenderer)
qCDebug(QSG_LOG_INFO, "Prioritizing software renderers");
}
@@ -247,6 +233,27 @@ QSGRhiSupport *QSGRhiSupport::instance()
return inst;
}
+QString QSGRhiSupport::rhiBackendName() const
+{
+ if (m_enableRhi) {
+ switch (m_rhiBackend) {
+ case QRhi::Null:
+ return QLatin1String("Null");
+ case QRhi::Vulkan:
+ return QLatin1String("Vulkan");
+ case QRhi::OpenGLES2:
+ return QLatin1String("OpenGL");
+ case QRhi::D3D11:
+ return QLatin1String("D3D11");
+ case QRhi::Metal:
+ return QLatin1String("Metal");
+ default:
+ return QLatin1String("Unknown");
+ }
+ }
+ return QLatin1String("Unknown (RHI not enabled)");
+}
+
QSGRendererInterface::GraphicsApi QSGRhiSupport::graphicsApi() const
{
if (!m_enableRhi)
@@ -350,7 +357,7 @@ static const void *qsgrhi_d3d11_rifResource(QSGRendererInterface::Resource res,
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, const QRhiNativeHandles *nat,
const QRhiNativeHandles *cbNat)
{
@@ -379,9 +386,15 @@ static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, co
}
#endif
-const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const QSGDefaultRenderContext *rc)
+const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res,
+ const QSGDefaultRenderContext *rc)
{
+#if QT_CONFIG(opengl)
QRhi *rhi = rc->rhi();
+#else
+ Q_UNUSED(rc)
+ QRhi *rhi = nullptr;
+#endif
if (res == QSGRendererInterface::RhiResource || !rhi)
return rhi;
@@ -408,7 +421,7 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const
case QRhi::D3D11:
return qsgrhi_d3d11_rifResource(res, nat);
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
case QRhi::Metal:
{
QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer();
@@ -469,7 +482,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
QRhi *rhi = nullptr;
- QRhi::Flags flags = 0;
+ QRhi::Flags flags;
if (isProfilingRequested())
flags |= QRhi::EnableProfiling | QRhi::EnableDebugMarkers;
if (isSoftwareRendererRequested())
@@ -513,7 +526,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf
rhi = QRhi::create(backend, &rhiParams, flags);
}
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (backend == QRhi::Metal) {
QRhiMetalInitParams rhiParams;
rhi = QRhi::create(backend, &rhiParams, flags);
@@ -576,7 +589,7 @@ void QSGRhiProfileConnection::initialize(QRhi *rhi)
profPort = 30667;
qCDebug(QSG_LOG_INFO, "Sending RHI profiling output to %s:%d", qPrintable(profHost), profPort);
m_profConn.reset(new QTcpSocket);
- QObject::connect(m_profConn.data(), QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), m_profConn.data(),
+ QObject::connect(m_profConn.data(), &QAbstractSocket::errorOccurred, m_profConn.data(),
[this](QAbstractSocket::SocketError socketError) { qWarning(" RHI profiler error: %d (%s)",
socketError, qPrintable(m_profConn->errorString())); });
m_profConn->connectToHost(profHost, profPort);
diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h
index d008ecd0af..0a95a09ad2 100644
--- a/src/quick/scenegraph/qsgrhisupport_p.h
+++ b/src/quick/scenegraph/qsgrhisupport_p.h
@@ -70,7 +70,7 @@
#include <QtGui/private/qrhid3d11_p.h>
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
#include <QtGui/private/qrhimetal_p.h>
#endif
@@ -109,6 +109,7 @@ public:
bool isRhiEnabled() const { return m_enableRhi; }
QRhi::Implementation rhiBackend() const { return m_rhiBackend; }
+ QString rhiBackendName() const;
QSGRendererInterface::GraphicsApi graphicsApi() const;
bool isDebugLayerRequested() const { return m_debugLayer; }
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index dc1f97de54..9b288029b4 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -70,6 +70,8 @@
#include <private/qsgrhishadereffectnode_p.h>
#include <private/qsgdefaultrendercontext_p.h>
+#include <qtquick_tracepoints_p.h>
+
/*
Overall design:
@@ -368,6 +370,9 @@ public:
QSize windowSize;
float dpr = 1;
int rhiSampleCount = 1;
+ bool rhiDeviceLost = false;
+ bool rhiDoomed = false;
+ bool guiNotifiedAboutRhiFailure = false;
// Local event queue stuff...
bool stopEventProcessing;
@@ -622,13 +627,15 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
sgrc->initialize(&rcParams);
}
}
- } else {
+ } else if (rhi) {
// With the rhi making the (OpenGL) context current serves only one
// purpose: to enable external OpenGL rendering connected to one of
// the QQuickWindow signals (beforeSynchronizing, beforeRendering,
// etc.) to function like it did on the direct OpenGL path. For our
// own rendering this call would not be necessary.
rhi->makeThreadLocalNativeContextCurrent();
+ } else {
+ current = false;
}
if (current) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -653,6 +660,11 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab)
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted");
}
+ // Two special cases: For grabs we do not care about blocking the gui
+ // (main) thread. When this is from an expose, we will keep locked until
+ // the frame is rendered (submitted), so in that case waking happens later
+ // in syncAndRender(). Otherwise, wake now and let the main thread go on
+ // while we render.
if (!inExpose && !inGrab) {
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui");
waitCondition.wakeOne();
@@ -669,6 +681,7 @@ void QSGRenderThread::handleDeviceLoss()
QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown();
sgrc->invalidate();
wm->releaseSwapchain(window);
+ rhiDeviceLost = true;
delete rhi;
rhi = nullptr;
}
@@ -680,7 +693,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
sinceLastTime = threadTimer.nsecsElapsed();
threadTimer.start();
}
+ Q_TRACE_SCOPE(QSG_syncAndRender);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
+ Q_TRACE(QSG_sync_entry);
QElapsedTimer waitTimer;
waitTimer.start();
@@ -693,8 +708,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
const bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage;
const bool syncRequested = (pendingUpdate & SyncRequest) || grabImage;
const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;
- pendingUpdate = 0;
const bool grabRequested = grabImage != nullptr;
+ if (!grabRequested)
+ pendingUpdate = 0;
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
// Begin the frame before syncing -> sync is where we may invoke
@@ -745,13 +761,11 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)));
// Before returning we need to ensure the same wake up logic that
// would have happened if beginFrame() had suceeded.
- if (exposeRequested) {
+ if (syncRequested && !grabRequested) {
+ // Lock like sync() would do. Note that exposeRequested always includes syncRequested.
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui");
- waitCondition.wakeOne();
- mutex.unlock();
- } else if (syncRequested && !grabRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui like sync would do");
mutex.lock();
+ // Go ahead with waking because we will return right after this.
waitCondition.wakeOne();
mutex.unlock();
}
@@ -767,33 +781,46 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
syncTime = threadTimer.nsecsElapsed();
#endif
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync);
- if (!syncResultedInChanges && !repaintRequested && sgrc->isValid() && !grabImage) {
- if (gl || !rhi->isRecordingFrame()) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
- int waitTime = vsyncDelta - (int) waitTimer.elapsed();
- if (waitTime > 0)
- msleep(waitTime);
- return;
- }
+ if (!syncResultedInChanges
+ && !repaintRequested
+ && !(pendingUpdate & RepaintRequest) // may have been set in sync()
+ && sgrc->isValid()
+ && !grabRequested
+ && (gl || (rhi && !rhi->isRecordingFrame())))
+ {
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
+ int waitTime = vsyncDelta - (int) waitTimer.elapsed();
+ if (waitTime > 0)
+ msleep(waitTime);
+ return;
}
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
+ Q_TRACE(QSG_render_entry);
- if (animatorDriver->isRunning() && !grabImage) {
+ // RepaintRequest may have been set in pendingUpdate in an
+ // updatePaintNode() invoked from sync(). We are about to do a repaint
+ // right now, so reset the flag. (bits other than RepaintRequest cannot
+ // be set in pendingUpdate at this point)
+ if (!grabRequested)
+ pendingUpdate = 0;
+
+ if (animatorDriver->isRunning() && !grabRequested) {
d->animationController->lock();
animatorDriver->advance();
d->animationController->unlock();
}
bool current = true;
- if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) {
+ if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0 && (gl || rhi)) {
if (gl)
current = gl->makeCurrent(window);
- else if (rhi)
+ else
rhi->makeThreadLocalNativeContextCurrent();
} else {
current = false;
@@ -811,21 +838,23 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
if (profileFrames)
renderTime = threadTimer.nsecsElapsed();
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
// With the rhi grabs can only be done by adding a readback and then
// blocking in a real frame. The legacy GL path never gets here with
// grabs as it rather invokes sync/render directly without going
// through syncAndRender().
- if (grabImage) {
+ if (grabRequested) {
Q_ASSERT(rhi && !gl && cd->swapchain);
*grabImage = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain);
}
if (cd->swapchain) {
- QRhi::EndFrameFlags flags = 0;
- if (grabImage)
+ QRhi::EndFrameFlags flags;
+ if (grabRequested)
flags |= QRhi::SkipPresent;
QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags);
if (frameResult != QRhi::FrameOpSuccess) {
@@ -841,12 +870,13 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
gl->swapBuffers(window);
}
- if (!grabImage)
+ if (!grabRequested)
d->fireFrameSwapped();
-
} else {
+ Q_TRACE(QSG_render_exit);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
+ Q_TRACE(QSG_swap_entry);
qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render");
}
@@ -858,7 +888,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
// has started rendering with a bad window, causing makeCurrent to
// fail or if the window has a bad size.
if (exposeRequested) {
- qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose");
+ // With expose sync() did not wake gui, do it now.
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after expose");
waitCondition.wakeOne();
mutex.unlock();
}
@@ -870,7 +901,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
int((renderTime - syncTime) / 1000000),
int(threadTimer.elapsed() - renderTime / 1000000));
-
+ Q_TRACE(QSG_swap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSwap);
@@ -912,14 +943,21 @@ void QSGRenderThread::processEventsAndWaitForMore()
void QSGRenderThread::ensureRhi()
{
if (!rhi) {
+ if (rhiDoomed) // no repeated attempts if the initial attempt failed
+ return;
QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
rhi = rhiSupport->createRhi(window, offscreenSurface);
if (rhi) {
+ rhiDeviceLost = false;
rhiSampleCount = rhiSupport->chooseSampleCountForWindowWithRhi(window, rhi);
if (rhiSupport->isProfilingRequested())
QSGRhiProfileConnection::instance()->initialize(rhi); // ### this breaks down with multiple windows
} else {
- qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ if (!rhiDeviceLost) {
+ rhiDoomed = true;
+ qWarning("Failed to create QRhi on the render thread; scenegraph is not functional");
+ }
+ // otherwise no error, will retry on a subsequent rendering attempt
return;
}
}
@@ -975,9 +1013,24 @@ void QSGRenderThread::run()
if (window) {
if (enableRhi) {
+
ensureRhi();
- if (rhi)
- syncAndRender();
+
+ // We absolutely have to syncAndRender() here, even when QRhi
+ // failed to initialize otherwise the gui thread will be left
+ // in a blocked state. It is up to syncAndRender() to
+ // gracefully skip all graphics stuff when rhi is null.
+
+ syncAndRender();
+
+ // Now we can do something about rhi init failures. (reinit
+ // failure after device reset does not count)
+ if (rhiDoomed && !guiNotifiedAboutRhiFailure) {
+ guiNotifiedAboutRhiFailure = true;
+ QEvent *e = new QEvent(QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure));
+ QCoreApplication::postEvent(window, e);
+ }
+
} else {
if (!sgrc->openglContext() && windowSize.width() > 0 && windowSize.height() > 0 && gl->makeCurrent(window)) {
QSGDefaultRenderContext::InitParams rcParams;
@@ -1282,10 +1335,9 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
w->thread->gl->setFormat(w->window->requestedFormat());
w->thread->gl->setScreen(w->window->screen());
if (!w->thread->gl->create()) {
- const bool isEs = w->thread->gl->isOpenGLES();
delete w->thread->gl;
w->thread->gl = nullptr;
- handleContextCreationFailure(w->window, isEs);
+ handleContextCreationFailure(w->window);
return;
}
@@ -1508,7 +1560,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
return;
}
-
+ Q_TRACE_SCOPE(QSG_polishAndSync);
QElapsedTimer timer;
qint64 polishTime = 0;
qint64 waitTime = 0;
@@ -1517,14 +1569,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
timer.start();
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
+ Q_TRACE(QSG_polishItems_entry);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
if (profileFrames)
polishTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncPolish);
+ Q_TRACE(QSG_wait_entry);
w->updateDuringSync = false;
@@ -1539,8 +1594,11 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync");
if (profileFrames)
waitTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_wait_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncWait);
+ Q_TRACE(QSG_sync_entry);
+
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
@@ -1548,8 +1606,10 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
if (profileFrames)
syncTime = timer.nsecsElapsed();
+ Q_TRACE(QSG_sync_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncSync);
+ Q_TRACE(QSG_animations_entry);
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations");
@@ -1570,6 +1630,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
<< " - (on Gui thread) " << window;
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 5b48b86568..20d7c4557f 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -60,6 +60,8 @@
#include <private/qquickopenglshadereffectnode_p.h>
#endif
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
// Single-threaded render loop with a custom animation driver. Like a
@@ -180,10 +182,9 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
m_gl->setShareContext(qt_gl_global_share_context());
bool created = m_gl->create();
if (!created) {
- const bool isEs = m_gl->isOpenGLES();
delete m_gl;
m_gl = nullptr;
- handleContextCreationFailure(window, isEs);
+ handleContextCreationFailure(window);
return;
}
@@ -393,6 +394,7 @@ bool QSGWindowsRenderLoop::event(QEvent *event)
void QSGWindowsRenderLoop::render()
{
RLDEBUG("render");
+ Q_TRACE(QSG_render_entry);
bool rendered = false;
for (const WindowData &wd : qAsConst(m_windows)) {
if (wd.pendingUpdate) {
@@ -407,10 +409,13 @@ void QSGWindowsRenderLoop::render()
QThread::msleep(m_vsyncDelta);
}
+ Q_TRACE(QSG_render_exit);
+
if (m_animationDriver->isRunning()) {
RLDEBUG("advancing animations");
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations);
+ Q_TRACE(QSG_animations_entry);
m_animationDriver->advance();
RLDEBUG("animations advanced");
@@ -418,6 +423,7 @@ void QSGWindowsRenderLoop::render()
"animations ticked in %dms",
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
+ Q_TRACE(QSG_animations_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1);
// It is not given that animations triggered another maybeUpdate()
@@ -476,15 +482,20 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
if (!windowData(window))
return;
+ Q_TRACE_SCOPE(QSG_renderWindow);
+
QSG_LOG_TIME_SAMPLE(time_start);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
+ Q_TRACE(QSG_polishItems_entry);
RLDEBUG(" - polishing");
d->polishItems();
QSG_LOG_TIME_SAMPLE(time_polished);
+ Q_TRACE(QSG_polishItems_exit);
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphPolishPolish);
+ Q_TRACE(QSG_sync_entry);
emit window->afterAnimating();
@@ -492,17 +503,22 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
d->syncSceneGraph();
if (lastDirtyWindow)
m_rc->endSync();
+ Q_TRACE(QSG_sync_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
QQuickProfiler::SceneGraphRenderLoopSync);
+ Q_TRACE(QSG_render_entry);
RLDEBUG(" - rendering");
d->renderSceneGraph(window->size());
+ Q_TRACE(QSG_render_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered,
QQuickProfiler::SceneGraphRenderLoopRender);
+ Q_TRACE(QSG_swap_entry);
RLDEBUG(" - swapping");
if (!d->customRenderStage || !d->customRenderStage->swap())
m_gl->swapBuffers(window);
+ Q_TRACE(QSG_swap_exit);
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped,
QQuickProfiler::SceneGraphRenderLoopSwap);
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 56d97226fb..b12f57d8ef 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -53,7 +53,6 @@ HEADERS += \
$$PWD/util/qsgengine.h \
$$PWD/util/qsgengine_p.h \
$$PWD/util/qsgplaintexture_p.h \
- $$PWD/util/qsgrhinativetextureimporter_p.h \
$$PWD/util/qsgsimplerectnode.h \
$$PWD/util/qsgsimpletexturenode.h \
$$PWD/util/qsgtextureprovider.h \
@@ -70,7 +69,6 @@ SOURCES += \
$$PWD/util/qsgareaallocator.cpp \
$$PWD/util/qsgengine.cpp \
$$PWD/util/qsgplaintexture.cpp \
- $$PWD/util/qsgrhinativetextureimporter.cpp \
$$PWD/util/qsgsimplerectnode.cpp \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtextureprovider.cpp \
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
index b16da4d76a..c493996375 100644
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
index 1a12a35b49..3f8489bfe6 100644
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
index 2d0d23d813..f721207325 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
index 65d9af4736..93ac0124be 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
index 5753794649..33de256615 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
index 6026960d68..018f5aa07e 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
index 451ccbac5b..f64d7ac315 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
index 41ebc12abf..31f870df23 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
index 0c37ccb6ed..df7ef28add 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
index b92235eec3..a90beea1b3 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
index 28ba15e3de..a219eb5800 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
index 2877ab92db..0cfdfed5a9 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
index 2e6085aa39..a3998ad695 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
index a528c667fd..62ffe0385e 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
index e83de529e6..3f23fa0da1 100644
--- a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
index 81c51321bb..82e302baa2 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
index 6bf01658a1..39281bbda5 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
index 4a9ac900a6..8ca627e6c1 100644
--- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
index 76c2459edf..b05b62e968 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
index 7bfa7ccd4a..92dc0bd710 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
index 8f8304fb49..3303ddec7f 100644
--- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
index 0b4554568b..785527811a 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
index 2872af0200..eec3bf66b0 100644
--- a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
index 5ab92fecca..c1e81f4163 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
index 96746e6b0d..b8d38bdff4 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
index 6e6b1ab6c2..7e26f3775e 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
index 4b08ee2ce4..16046468c2 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
index 4a8c646a21..9365ce95c4 100644
--- a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
index f99cdf1176..8a30f3eae6 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
index 59c4104a2c..1f187b05ac 100644
--- a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
index ffaecbb56c..780486ca29 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
index b7715d4dd5..76d03d4ff7 100644
--- a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
index 45d5bc14ee..2a33d577c7 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
index b55f881734..c77612a31a 100644
--- a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
index 6ae7a51f7a..b0b13a1d5a 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
index ce2ed3c5b3..3c091ad73e 100644
--- a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
index 66ebc5f827..b0461a686c 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
index d57d92bbe6..18e4685d21 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
index 9dd4137072..3d9b5a0bdd 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
index b16da4d76a..cfae9575da 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
index 99082297bf..2ea425e1c0 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.frag.qsb b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
index 3f4aa3713c..47c75b1e78 100644
--- a/src/quick/scenegraph/shaders_ng/texture.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/texture.vert.qsb b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
index bf0bc7d9fa..0301a7bfa0 100644
--- a/src/quick/scenegraph/shaders_ng/texture.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/texture.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
index 93965a55dd..8a30f3eae6 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
index 98abe4ef6f..95787f647b 100644
--- a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
index eadad927dc..f45b7b4488 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
index 7ba27cb4b5..acb29bb0fd 100644
--- a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
+++ b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb
Binary files differ
diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp
index 4880d98871..aec981871b 100644
--- a/src/quick/scenegraph/util/qsgengine.cpp
+++ b/src/quick/scenegraph/util/qsgengine.cpp
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\class QSGEngine
@@ -58,6 +59,8 @@ QT_BEGIN_NAMESPACE
\inmodule QtQuick
\since 5.4
+ \deprecated
+
A QSGEngine can be used to render a tree of QSGNode directly on a QWindow
or QOpenGLFramebufferObject without any integration with QML, QQuickWindow
or QQuickItem and the convenience that they provide.
@@ -285,6 +288,8 @@ QSGNinePatchNode *QSGEngine::createNinePatchNode() const
return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createNinePatchNode() : nullptr;
}
+#endif
+
QT_END_NAMESPACE
#include "moc_qsgengine.cpp"
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index c5a59b47e7..f00b7a0b6f 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -54,8 +54,7 @@ class QSGRectangleNode;
class QSGImageNode;
class QSGNinePatchNode;
-// ### Qt 6: Remove or redesign.
-
+#if QT_DEPRECATED_SINCE(5, 15)
class Q_QUICK_EXPORT QSGEngine : public QObject
{
Q_OBJECT
@@ -73,6 +72,7 @@ public:
explicit QSGEngine(QObject *parent = nullptr);
~QSGEngine() override;
+ QT_DEPRECATED_X("QSGEngine is going to be removed in Qt 6.0. Use QQuickRenderControl instead.")
void initialize(QOpenGLContext *context);
void invalidate();
@@ -84,6 +84,7 @@ public:
QSGImageNode *createImageNode() const;
QSGNinePatchNode *createNinePatchNode() const;
};
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgengine_p.h b/src/quick/scenegraph/util/qsgengine_p.h
index c5b5c695bd..662c32d3d9 100644
--- a/src/quick/scenegraph/util/qsgengine_p.h
+++ b/src/quick/scenegraph/util/qsgengine_p.h
@@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE
class QSGContext;
class QSGRenderContext;
+#if QT_DEPRECATED_SINCE(5, 15)
class QSGEnginePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QSGEngine)
@@ -69,6 +70,7 @@ public:
QScopedPointer<QSGContext> sgContext;
QScopedPointer<QSGRenderContext> sgRenderContext;
};
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
index 75a874424a..18c72286d1 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
@@ -59,6 +59,8 @@
#include <private/qquickprofiler_p.h>
+#include <qtquick_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
#ifndef GL_BGRA
@@ -250,14 +252,17 @@ void AtlasBase::bind(QSGTexture::Filtering filtering)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
uploadPendingTexture(i);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp
index fdebe03494..f00918bb4e 100644
--- a/src/quick/scenegraph/util/qsgplaintexture.cpp
+++ b/src/quick/scenegraph/util/qsgplaintexture.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qsgplaintexture_p.h"
-#include "qsgrhinativetextureimporter_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <qmath.h>
#include <private/qquickprofiler_p.h>
@@ -53,6 +52,8 @@
#endif
#include <QtGui/private/qrhi_p.h>
+#include <qtquick_tracepoints_p.h>
+
#if QT_CONFIG(opengl)
static QElapsedTimer qsg_renderer_timer;
#endif
@@ -150,9 +151,11 @@ void QSGPlainTexture::setTextureId(int id) // legacy (GL-only)
void QSGPlainTexture::bind() // legacy (GL-only)
{
#if QT_CONFIG(opengl)
+ Q_TRACE_SCOPE(QSG_texture_prepare);
QOpenGLContext *context = QOpenGLContext::currentContext();
QOpenGLFunctions *funcs = context->functions();
if (!m_dirty_texture) {
+ Q_TRACE_SCOPE(QSG_texture_bind);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
if (mipmapFiltering() != QSGTexture::None && !m_mipmaps_generated) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -174,6 +177,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
if (m_image.isNull()) {
if (m_texture_id && m_owns_texture) {
+ Q_TRACE_SCOPE(QSG_texture_delete);
funcs->glDeleteTextures(1, &m_texture_id);
qCDebug(QSG_LOG_TIME_TEXTURE, "plain texture deleted in %dms - %dx%d",
(int) qsg_renderer_timer.elapsed(),
@@ -189,6 +193,8 @@ void QSGPlainTexture::bind() // legacy (GL-only)
return;
}
+ Q_TRACE(QSG_texture_bind_entry);
+
if (m_texture_id == 0)
funcs->glGenTextures(1, &m_texture_id);
funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
@@ -196,8 +202,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 bindTime = 0;
if (profileFrames)
bindTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_bind_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareBind);
+ Q_TRACE(QSG_texture_upload_entry);
// ### TODO: check for out-of-memory situations...
@@ -232,8 +240,10 @@ void QSGPlainTexture::bind() // legacy (GL-only)
qint64 uploadTime = 0;
if (profileFrames)
uploadTime = qsg_renderer_timer.nsecsElapsed();
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
+ Q_TRACE(QSG_texture_mipmap_entry);
if (mipmapFiltering() != QSGTexture::None) {
funcs->glGenerateMipmap(GL_TEXTURE_2D);
@@ -252,6 +262,7 @@ void QSGPlainTexture::bind() // legacy (GL-only)
int((mipmapTime - uploadTime)/1000000),
m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : "");
}
+ Q_TRACE(QSG_texture_mipmap_exit);
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareMipmap);
@@ -281,14 +292,14 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native
{
Q_UNUSED(type);
- QRhiTexture::Flags flags = 0;
+ QRhiTexture::Flags flags;
if (mipmap)
flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
QRhiTexture *t = rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags);
// ownership of the native object is never taken
- QSGRhiNativeTextureImporter::buildWrapper(rhi, t, nativeObjectPtr, nativeLayout);
+ t->buildFrom({nativeObjectPtr, nativeLayout});
setTexture(t);
}
@@ -421,7 +432,7 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch
}
if (!q->m_texture) {
- QRhiTexture::Flags f = 0;
+ QRhiTexture::Flags f;
if (hasMipMaps)
f |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips;
diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
index 3dc1f5f526..6b5f1aec4f 100644
--- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp
@@ -49,6 +49,9 @@
#include <private/qquickprofiler_p.h>
#include <private/qsgdefaultrendercontext_p.h>
#include <private/qsgtexture_p.h>
+
+#include <qtquick_tracepoints_p.h>
+
#if 0
#include <private/qsgcompressedtexture_p.h>
#include <private/qsgcompressedatlastexture_p.h>
@@ -197,14 +200,17 @@ void AtlasBase::updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates)
if (profileFrames)
qsg_renderer_timer.start();
+ Q_TRACE_SCOPE(QSG_texture_prepare);
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
// Skip bind, convert, swizzle; they're irrelevant
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+ Q_TRACE(QSG_texture_upload_entry);
enqueueTextureUpload(t, resourceUpdates);
+ Q_TRACE(QSG_texture_upload_exit);
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
QQuickProfiler::SceneGraphTexturePrepareUpload);
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
deleted file mode 100644
index 7a7c19f587..0000000000
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgrhinativetextureimporter_p.h"
-#include <private/qsgrhisupport_p.h> // to get all the relevant qrhi headers
-
-QT_BEGIN_NAMESPACE
-
-void QSGRhiNativeTextureImporter::buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout)
-{
-#if !QT_CONFIG(vulkan)
- Q_UNUSED(nativeLayout);
-#endif
-#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
- Q_UNUSED(nativeObjectPtr);
-#endif
-
- switch (rhi->backend()) {
- case QRhi::OpenGLES2:
- {
-#if QT_CONFIG(opengl)
- QRhiGles2TextureNativeHandles h;
- h.texture = *reinterpret_cast<const uint *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Vulkan:
- {
-#if QT_CONFIG(vulkan)
- QRhiVulkanTextureNativeHandles h;
- h.image = *reinterpret_cast<const VkImage *>(nativeObjectPtr);
- h.layout = VkImageLayout(nativeLayout);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::D3D11:
- {
-#ifdef Q_OS_WIN
- QRhiD3D11TextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Metal:
- {
-#ifdef Q_OS_DARWIN
- QRhiMetalTextureNativeHandles h;
- h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr);
- t->buildFrom(&h);
-#endif
- }
- break;
- case QRhi::Null:
- t->build();
- break;
- default:
- qWarning("QSGRhiNativeTextureImporter: encountered an unsupported QRhi backend (%d)",
- int(rhi->backend()));
- t->build();
- break;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index 1064caccc7..4bbc2b17ba 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -46,6 +46,8 @@
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
+ \deprecated
+
\warning This utility class is only functional when running with the legacy
OpenGL renderer of the Qt Quick scenegraph. Its usage is not recommended in
new application code.
@@ -234,6 +236,8 @@
/*!
\class QSGSimpleMaterial
+ \deprecated
+
\inmodule QtQuick
\ingroup qtquick-scenegraph-materials
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
index 79180ca8e2..78cd05f2d8 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ b/src/quick/scenegraph/util/qsgsimplematerial.h
@@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 15)
+
template <typename State>
class QSGSimpleMaterialShader : public QSGMaterialShader
{
@@ -77,6 +79,7 @@ public:
void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
+ QT_DEPRECATED_X("QSGSimpleMaterialShader is going to be removed in Qt 6.0. Use QSGMaterialShader instead.")
virtual void updateState(const State *newState, const State *oldState) = 0;
virtual void resolveUniforms() {}
@@ -139,12 +142,14 @@ class QSGSimpleMaterial : public QSGMaterial
{
public:
#ifndef Q_CLANG_QDOC
+ QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func)
: m_state(aState)
, m_func(func)
{
}
+ QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.")
QSGSimpleMaterial(PtrShaderCreateFunc func)
: m_func(func)
{
@@ -213,6 +218,8 @@ Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderS
updateState(ns, old);
}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index fe5b372da8..e5e25d141b 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -176,11 +176,8 @@ void QQuickAbstractAnimationPrivate::commence()
animationInstance = new QQuickAnimatorProxyJob(animationInstance, q);
animationInstance->addAnimationChangeListener(this, QAbstractAnimationJob::Completion);
}
+ emit q->started();
animationInstance->start();
- if (animationInstance->isStopped()) {
- running = false;
- emit q->stopped();
- }
}
}
@@ -213,8 +210,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
It is only triggered for top-level, standalone animations. It will not be
triggered for animations in a Behavior or Transition, or animations
that are part of an animation group.
-
- The corresponding handler is \c onStarted.
*/
/*!
@@ -230,8 +225,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
If \l alwaysRunToEnd is true, this signal will not be emitted until the animation
has completed its current iteration.
-
- The corresponding handler is \c onStopped.
*/
/*!
@@ -250,8 +243,6 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
If \l alwaysRunToEnd is true, this signal will not be emitted until the
animation has completed its current iteration.
- The corresponding handler is \c onFinished.
-
\sa stopped(), started(), running
*/
@@ -293,10 +284,8 @@ void QQuickAbstractAnimation::setRunning(bool r)
d->animationInstance->setLoopCount(d->animationInstance->currentLoop() + d->loopCount);
supressStart = true; //we want the animation to continue, rather than restart
}
- if (!supressStart) {
+ if (!supressStart)
d->commence();
- emit started();
- }
} else {
if (d->paused) {
d->paused = false; //reset paused state to false when stopped
@@ -314,7 +303,16 @@ void QQuickAbstractAnimation::setRunning(bool r)
}
}
- emit runningChanged(d->running);
+
+ if (r == d->running) {
+ // This might happen if we start an animation with 0 duration: This will result in that
+ // commence() will emit started(), and then when it starts it will call setCurrentTime(0),
+ // (which is both start and end time of the animation), so it will also end up calling
+ // setRunning(false) (recursively) and stop the animation.
+ // Therefore, the state of d->running will in that case be different than r if we are back in
+ // the root stack frame of the recursive calls to setRunning()
+ emit runningChanged(d->running);
+ }
}
/*!
@@ -490,7 +488,7 @@ QQuickAnimationGroup *QQuickAbstractAnimation::group() const
return d->group;
}
-void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
+void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g, int index)
{
Q_D(QQuickAbstractAnimation);
if (d->group == g)
@@ -500,8 +498,12 @@ void QQuickAbstractAnimation::setGroup(QQuickAnimationGroup *g)
d->group = g;
- if (d->group && !d->group->d_func()->animations.contains(this))
- d->group->d_func()->animations.append(this);
+ if (d->group && !d->group->d_func()->animations.contains(this)) {
+ if (index >= 0)
+ d->group->d_func()->animations.insert(index, this);
+ else
+ d->group->d_func()->animations.append(this);
+ }
}
/*!
@@ -903,7 +905,7 @@ void QActionAnimation::updateState(State newState, State oldState)
void QActionAnimation::debugAnimation(QDebug d) const
{
- d << "ActionAnimation(" << hex << (const void *) this << dec << ")";
+ d << "ActionAnimation(" << Qt::hex << (const void *) this << Qt::dec << ")";
if (animAction) {
int indentLevel = 1;
@@ -1170,7 +1172,7 @@ void QQuickPropertyAction::setProperties(const QString &p)
QQmlListProperty<QObject> QQuickPropertyAction::targets()
{
Q_D(QQuickPropertyAction);
- return QQmlListProperty<QObject>(this, d->targets);
+ return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@@ -1182,7 +1184,7 @@ QQmlListProperty<QObject> QQuickPropertyAction::targets()
QQmlListProperty<QObject> QQuickPropertyAction::exclude()
{
Q_D(QQuickPropertyAction);
- return QQmlListProperty<QObject>(this, d->exclude);
+ return QQmlListProperty<QObject>(this, &(d->exclude));
}
/*!
@@ -1722,6 +1724,20 @@ void QQuickAnimationGroupPrivate::append_animation(QQmlListProperty<QQuickAbstra
a->setGroup(q);
}
+QQuickAbstractAnimation *QQuickAnimationGroupPrivate::at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index)
+{
+ if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
+ return q->d_func()->animations.at(index);
+ return nullptr;
+}
+
+int QQuickAnimationGroupPrivate::count_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
+{
+ if (auto q = qmlobject_cast<QQuickAnimationGroup *>(list->object))
+ return q->d_func()->animations.count();
+ return 0;
+}
+
void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
{
QQuickAnimationGroup *q = qobject_cast<QQuickAnimationGroup *>(list->object);
@@ -1733,6 +1749,23 @@ void QQuickAnimationGroupPrivate::clear_animation(QQmlListProperty<QQuickAbstrac
}
}
+void QQuickAnimationGroupPrivate::replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list,
+ int i, QQuickAbstractAnimation *a)
+{
+ if (auto *q = qmlobject_cast<QQuickAnimationGroup *>(list->object)) {
+ if (QQuickAbstractAnimation *anim = q->d_func()->animations.at(i))
+ anim->setGroup(nullptr);
+ if (a)
+ a->setGroup(q, i);
+ }
+}
+
+void QQuickAnimationGroupPrivate::removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list)
+{
+ if (auto *q = qobject_cast<QQuickAnimationGroup *>(list->object))
+ q->d_func()->animations.last()->setGroup(nullptr);
+}
+
QQuickAnimationGroup::~QQuickAnimationGroup()
{
Q_D(QQuickAnimationGroup);
@@ -1744,10 +1777,14 @@ QQuickAnimationGroup::~QQuickAnimationGroup()
QQmlListProperty<QQuickAbstractAnimation> QQuickAnimationGroup::animations()
{
Q_D(QQuickAnimationGroup);
- QQmlListProperty<QQuickAbstractAnimation> list(this, d->animations);
- list.append = &QQuickAnimationGroupPrivate::append_animation;
- list.clear = &QQuickAnimationGroupPrivate::clear_animation;
- return list;
+ return QQmlListProperty<QQuickAbstractAnimation>(
+ this, &(d->animations),
+ &QQuickAnimationGroupPrivate::append_animation,
+ &QQuickAnimationGroupPrivate::count_animation,
+ &QQuickAnimationGroupPrivate::at_animation,
+ &QQuickAnimationGroupPrivate::clear_animation,
+ &QQuickAnimationGroupPrivate::replace_animation,
+ &QQuickAnimationGroupPrivate::removeLast_animation);
}
/*!
@@ -1927,20 +1964,20 @@ QAbstractAnimationJob* QQuickParallelAnimation::transition(QQuickStateActions &a
//convert a variant from string type to another animatable type
void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type)
{
- if (variant.userType() != QVariant::String) {
+ if (variant.userType() != QMetaType::QString) {
variant.convert(type);
return;
}
switch (type) {
- case QVariant::Rect:
- case QVariant::RectF:
- case QVariant::Point:
- case QVariant::PointF:
- case QVariant::Size:
- case QVariant::SizeF:
- case QVariant::Color:
- case QVariant::Vector3D:
+ case QMetaType::QRect:
+ case QMetaType::QRectF:
+ case QMetaType::QPoint:
+ case QMetaType::QPointF:
+ case QMetaType::QSize:
+ case QMetaType::QSizeF:
+ case QMetaType::QColor:
+ case QMetaType::QVector3D:
{
bool ok = false;
variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok);
@@ -1996,7 +2033,7 @@ void QQuickBulkValueAnimator::topLevelAnimationLoopChanged()
void QQuickBulkValueAnimator::debugAnimation(QDebug d) const
{
- d << "BulkValueAnimation(" << hex << (const void *) this << dec << ")" << "duration:" << duration();
+ d << "BulkValueAnimation(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << duration();
if (animValue) {
int indentLevel = 1;
@@ -2533,7 +2570,7 @@ void QQuickPropertyAnimation::setProperties(const QString &prop)
QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
{
Q_D(QQuickPropertyAnimation);
- return QQmlListProperty<QObject>(this, d->targets);
+ return QQmlListProperty<QObject>(this, &(d->targets));
}
/*!
@@ -2544,7 +2581,7 @@ QQmlListProperty<QObject> QQuickPropertyAnimation::targets()
QQmlListProperty<QObject> QQuickPropertyAnimation::exclude()
{
Q_D(QQuickPropertyAnimation);
- return QQmlListProperty<QObject>(this, d->exclude);
+ return QQmlListProperty<QObject>(this, &(d->exclude));
}
void QQuickAnimationPropertyUpdater::setValue(qreal v)
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index 746cb938bd..7bad9d50c4 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -80,6 +80,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAbstractAnimation : public QObject, public QQ
Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopCountChanged)
Q_CLASSINFO("DefaultMethod", "start()")
+ QML_NAMED_ELEMENT(Animation)
+ QML_UNCREATABLE("Animation is an abstract class")
+
public:
enum ThreadingModel {
GuiThread,
@@ -108,7 +111,7 @@ public:
void setCurrentTime(int);
QQuickAnimationGroup *group() const;
- void setGroup(QQuickAnimationGroup *);
+ void setGroup(QQuickAnimationGroup *, int index = -1);
void setDefaultTarget(const QQmlProperty &);
void setDisableUserControl();
@@ -165,6 +168,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPauseAnimation : public QQuickAbstractAnimati
Q_DECLARE_PRIVATE(QQuickPauseAnimation)
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
+ QML_NAMED_ELEMENT(PauseAnimation)
public:
QQuickPauseAnimation(QObject *parent=nullptr);
@@ -191,6 +195,7 @@ class QQuickScriptAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName)
+ QML_NAMED_ELEMENT(ScriptAction)
public:
QQuickScriptAction(QObject *parent=nullptr);
@@ -221,6 +226,7 @@ class QQuickPropertyAction : public QQuickAbstractAnimation
Q_PROPERTY(QQmlListProperty<QObject> targets READ targets)
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PropertyAction)
public:
QQuickPropertyAction(QObject *parent=nullptr);
@@ -269,6 +275,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyAnimation : public QQuickAbstractAnim
Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged)
Q_PROPERTY(QQmlListProperty<QObject> targets READ targets)
Q_PROPERTY(QQmlListProperty<QObject> exclude READ exclude)
+ QML_NAMED_ELEMENT(PropertyAnimation)
public:
QQuickPropertyAnimation(QObject *parent=nullptr);
@@ -324,6 +331,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickColorAnimation : public QQuickPropertyAnimati
Q_DECLARE_PRIVATE(QQuickPropertyAnimation)
Q_PROPERTY(QColor from READ from WRITE setFrom)
Q_PROPERTY(QColor to READ to WRITE setTo)
+ QML_NAMED_ELEMENT(ColorAnimation)
public:
QQuickColorAnimation(QObject *parent=nullptr);
@@ -343,6 +351,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
+ QML_NAMED_ELEMENT(NumberAnimation)
public:
QQuickNumberAnimation(QObject *parent=nullptr);
@@ -368,6 +377,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim
Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged)
+ QML_NAMED_ELEMENT(Vector3dAnimation)
public:
QQuickVector3dAnimation(QObject *parent=nullptr);
@@ -389,6 +399,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
+ QML_NAMED_ELEMENT(RotationAnimation)
public:
QQuickRotationAnimation(QObject *parent=nullptr);
@@ -433,6 +444,7 @@ class QQuickSequentialAnimation : public QQuickAnimationGroup
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
+ QML_NAMED_ELEMENT(SequentialAnimation)
public:
QQuickSequentialAnimation(QObject *parent=nullptr);
@@ -450,6 +462,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickParallelAnimation : public QQuickAnimationGro
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickAnimationGroup)
+ QML_NAMED_ELEMENT(ParallelAnimation)
public:
QQuickParallelAnimation(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index c20ec65c24..8d23242b68 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -256,7 +256,12 @@ public:
: QQuickAbstractAnimationPrivate() {}
static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *role);
+ static QQuickAbstractAnimation *at_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index);
+ static int count_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
static void clear_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
+ static void replace_animation(QQmlListProperty<QQuickAbstractAnimation> *list, int index,
+ QQuickAbstractAnimation *role);
+ static void removeLast_animation(QQmlListProperty<QQuickAbstractAnimation> *list);
QList<QQuickAbstractAnimation *> animations;
};
diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h
index d9ce377060..da6df6038a 100644
--- a/src/quick/util/qquickanimationcontroller_p.h
+++ b/src/quick/util/qquickanimationcontroller_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlP
Q_DECLARE_PRIVATE(QQuickAnimationController)
Q_CLASSINFO("DefaultProperty", "animation")
+ QML_NAMED_ELEMENT(AnimationController)
Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation NOTIFY animationChanged)
diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h
index 511cecda7f..9f7aaafcb0 100644
--- a/src/quick/util/qquickanimator_p.h
+++ b/src/quick/util/qquickanimator_p.h
@@ -69,6 +69,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimator : public QQuickAbstractAnimation
Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
+ QML_NAMED_ELEMENT(Animator)
+ QML_ADDED_IN_MINOR_VERSION(2)
+ QML_UNCREATABLE("Animator is an abstract class")
+
public:
QQuickItem *targetItem() const;
void setTargetItem(QQuickItem *target);
@@ -109,6 +113,8 @@ class QQuickScaleAnimatorPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickScaleAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(ScaleAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickScaleAnimator(QObject *parent = nullptr);
protected:
@@ -119,6 +125,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickXAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(XAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickXAnimator(QObject *parent = nullptr);
protected:
@@ -129,6 +137,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickYAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(YAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickYAnimator(QObject *parent = nullptr);
protected:
@@ -139,6 +149,8 @@ protected:
class Q_QUICK_PRIVATE_EXPORT QQuickOpacityAnimator : public QQuickAnimator
{
Q_OBJECT
+ QML_NAMED_ELEMENT(OpacityAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickOpacityAnimator(QObject *parent = nullptr);
protected:
@@ -152,6 +164,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimator : public QQuickAnimator
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickRotationAnimator)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
+ QML_NAMED_ELEMENT(RotationAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
enum RotationDirection { Numerical, Shortest, Clockwise, Counterclockwise };
@@ -177,6 +191,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickUniformAnimator)
Q_PROPERTY(QString uniform READ uniform WRITE setUniform NOTIFY uniformChanged)
+ QML_NAMED_ELEMENT(UniformAnimator)
+ QML_ADDED_IN_MINOR_VERSION(2)
public:
QQuickUniformAnimator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 84480ddd18..767be96403 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -184,7 +184,7 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState,
void QQuickAnimatorProxyJob::debugAnimation(QDebug d) const
{
- d << "QuickAnimatorProxyJob("<< hex << (const void *) this << dec
+ d << "QuickAnimatorProxyJob("<< Qt::hex << (const void *) this << Qt::dec
<< "state:" << state() << "duration:" << duration()
<< "proxying: (" << job() << ')';
}
@@ -266,7 +266,7 @@ QQuickAnimatorJob::QQuickAnimatorJob()
void QQuickAnimatorJob::debugAnimation(QDebug d) const
{
- d << "QuickAnimatorJob(" << hex << (const void *) this << dec
+ d << "QuickAnimatorJob(" << Qt::hex << (const void *) this << Qt::dec
<< ") state:" << state() << "duration:" << duration()
<< "target:" << m_target << "value:" << m_value;
}
diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h
index 66a33489e4..b0eb6fa604 100644
--- a/src/quick/util/qquickapplication_p.h
+++ b/src/quick/util/qquickapplication_p.h
@@ -71,6 +71,9 @@ class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QQmlListProperty<QQuickScreenInfo> screens READ screens NOTIFY screensChanged)
+ QML_NAMED_ELEMENT(Application)
+ QML_UNCREATABLE("Application is an abstract class.")
+
public:
explicit QQuickApplication(QObject *parent = nullptr);
virtual ~QQuickApplication();
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index eee8562a2a..ceda5589b2 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -185,6 +185,80 @@ QVariant QQuickBehavior::targetValue() const
return d->targetValue;
}
+/*!
+ \readonly
+ \qmlpropertygroup QtQuick::Behavior::targetProperty
+ \qmlproperty string QtQuick::Behavior::targetProperty.name
+ \qmlproperty Object QtQuick::Behavior::targetProperty.object
+
+ \table
+ \header
+ \li Property
+ \li Description
+ \row
+ \li name
+ \li This property holds the name of the property being controlled by this Behavior.
+ \row
+ \li object
+ \li This property holds the object of the property being controlled by this Behavior.
+ \endtable
+
+ This property can be used to define custom behaviors based on the name or the object of
+ the property being controlled.
+
+ The following example defines a Behavior fading out and fading in its target object
+ when the property it controls changes:
+ \qml
+ // FadeBehavior.qml
+ import QtQuick 2.15
+
+ Behavior {
+ id: root
+ property Item fadeTarget: targetProperty.object
+ SequentialAnimation {
+ NumberAnimation {
+ target: root.fadeTarget
+ property: "opacity"
+ to: 0
+ easing.type: Easing.InQuad
+ }
+ PropertyAction { } // actually change the controlled property between the 2 other animations
+ NumberAnimation {
+ target: root.fadeTarget
+ property: "opacity"
+ to: 1
+ easing.type: Easing.OutQuad
+ }
+ }
+ }
+ \endqml
+
+ This can be used to animate a text when it changes:
+ \qml
+ import QtQuick 2.15
+
+ Text {
+ id: root
+ property int counter
+ text: counter
+ FadeBehavior on text {}
+ Timer {
+ running: true
+ repeat: true
+ interval: 1000
+ onTriggered: ++root.counter
+ }
+ }
+ \endqml
+
+ \since QtQuick 2.15
+*/
+QQmlProperty QQuickBehavior::targetProperty() const
+{
+ Q_D(const QQuickBehavior);
+ return d->property;
+}
+
void QQuickBehavior::write(const QVariant &value)
{
Q_D(QQuickBehavior);
@@ -265,6 +339,8 @@ void QQuickBehavior::setTarget(const QQmlProperty &property)
if (finalizedIdx < 0)
finalizedIdx = metaObject()->indexOfSlot("componentFinalized()");
engPriv->registerFinalizeCallback(this, finalizedIdx);
+
+ Q_EMIT targetPropertyChanged();
}
void QQuickBehavior::componentFinalized()
diff --git a/src/quick/util/qquickbehavior_p.h b/src/quick/util/qquickbehavior_p.h
index 80a51d77af..a57a26d822 100644
--- a/src/quick/util/qquickbehavior_p.h
+++ b/src/quick/util/qquickbehavior_p.h
@@ -70,7 +70,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBehavior : public QObject, public QQmlPropert
Q_PROPERTY(QQuickAbstractAnimation *animation READ animation WRITE setAnimation)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(QVariant targetValue READ targetValue NOTIFY targetValueChanged REVISION 13)
+ Q_PROPERTY(QQmlProperty targetProperty READ targetProperty NOTIFY targetPropertyChanged REVISION 15)
Q_CLASSINFO("DeferredPropertyNames", "animation")
+ QML_NAMED_ELEMENT(Behavior)
public:
QQuickBehavior(QObject *parent=nullptr);
@@ -87,9 +89,12 @@ public:
QVariant targetValue() const;
+ QQmlProperty targetProperty() const;
+
Q_SIGNALS:
void enabledChanged();
void targetValueChanged();
+ void targetPropertyChanged();
private Q_SLOTS:
void componentFinalized();
diff --git a/src/quick/util/qquickboundaryrule.cpp b/src/quick/util/qquickboundaryrule.cpp
deleted file mode 100644
index 3558c8bfa0..0000000000
--- a/src/quick/util/qquickboundaryrule.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickboundaryrule_p.h"
-
-#include <qqmlcontext.h>
-#include <qqmlinfo.h>
-#include <private/qqmlproperty_p.h>
-#include <private/qqmlengine_p.h>
-#include <private/qobject_p.h>
-#include <private/qquickanimation_p_p.h>
-#include <QtCore/qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcBR, "qt.quick.boundaryrule")
-
-class QQuickBoundaryReturnJob;
-class QQuickBoundaryRulePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickBoundaryRule)
-public:
- QQuickBoundaryRulePrivate() {}
-
- QQmlProperty property;
- QEasingCurve easing = QEasingCurve(QEasingCurve::OutQuad);
- QQuickBoundaryReturnJob *returnAnimationJob = nullptr;
- // read-only properties, updated on each write()
- qreal targetValue = 0; // after easing was applied
- qreal peakOvershoot = 0;
- qreal currentOvershoot = 0;
- // settable properties
- qreal minimum = 0;
- qreal maximum = 0;
- qreal minimumOvershoot = 0;
- qreal maximumOvershoot = 0;
- qreal overshootScale = 0.5;
- int returnDuration = 100;
- QQuickBoundaryRule::OvershootFilter overshootFilter = QQuickBoundaryRule::OvershootFilter::None;
- bool enabled = true;
- bool finalized = false;
-
- qreal easedOvershoot(qreal overshootingValue);
- void resetOvershoot();
-};
-
-class QQuickBoundaryReturnJob : public QAbstractAnimationJob
-{
-public:
- QQuickBoundaryReturnJob(QQuickBoundaryRulePrivate *br, qreal to)
- : QAbstractAnimationJob()
- , boundaryRule(br)
- , fromValue(br->targetValue)
- , toValue(to) {}
-
- int duration() const override { return boundaryRule->returnDuration; }
-
- void updateCurrentTime(int) override;
-
- void updateState(QAbstractAnimationJob::State newState,
- QAbstractAnimationJob::State oldState) override;
-
- QQuickBoundaryRulePrivate *boundaryRule;
- qreal fromValue; // snapshot of initial value from which we're returning
- qreal toValue; // target property value to which we're returning
-};
-
-void QQuickBoundaryReturnJob::updateCurrentTime(int t)
-{
- // The easing property tells how to behave when the property is being
- // externally manipulated beyond the bounds. During returnToBounds()
- // we run it in reverse, by reversing time.
- qreal progress = (duration() - t) / qreal(duration());
- qreal easingValue = boundaryRule->easing.valueForProgress(progress);
- qreal delta = qAbs(fromValue - toValue) * easingValue;
- qreal value = (fromValue > toValue ? toValue + delta : toValue - delta);
- qCDebug(lcBR) << t << "ms" << qRound(progress * 100) << "% easing" << easingValue << "->" << value;
- QQmlPropertyPrivate::write(boundaryRule->property, value,
- QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
-}
-
-void QQuickBoundaryReturnJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState)
-{
- Q_UNUSED(oldState)
- if (newState == QAbstractAnimationJob::Stopped) {
- qCDebug(lcBR) << "return animation done";
- boundaryRule->resetOvershoot();
- boundaryRule->returnAnimationJob = nullptr;
- delete this;
- }
-}
-
-/*!
- \qmltype BoundaryRule
- \instantiates QQuickBoundaryRule
- \inqmlmodule Qt.labs.animation
- \ingroup qtquick-transitions-animations
- \ingroup qtquick-interceptors
- \brief Defines a restriction on the range of values that can be set on a numeric property.
- \since 5.14
-
- A BoundaryRule defines the range of values that a particular property is
- allowed to have. When an out-of-range value would otherwise be set,
- it applies "resistance" via an easing curve.
-
- For example, the following BoundaryRule prevents DragHandler from dragging
- the Rectangle too far:
-
- \snippet qml/boundaryRule.qml 0
-
- Note that a property cannot have more than one assigned BoundaryRule.
-
- \sa {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation#Behaviors}{Behavior example}, {Qt QML}
-*/
-
-QQuickBoundaryRule::QQuickBoundaryRule(QObject *parent)
- : QObject(*(new QQuickBoundaryRulePrivate), parent)
- , QQmlPropertyValueInterceptor()
-{
-}
-
-QQuickBoundaryRule::~QQuickBoundaryRule()
-{
- Q_D(QQuickBoundaryRule);
- // stop any running animation and
- // prevent QQuickBoundaryReturnJob::updateState() from accessing QQuickBoundaryRulePrivate
- delete d->returnAnimationJob;
-}
-
-/*!
- \qmlproperty bool QtQuick::BoundaryRule::enabled
-
- This property holds whether the rule will be enforced when the tracked
- property changes value.
-
- By default a BoundaryRule is enabled.
-*/
-bool QQuickBoundaryRule::enabled() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->enabled;
-}
-
-void QQuickBoundaryRule::setEnabled(bool enabled)
-{
- Q_D(QQuickBoundaryRule);
- if (d->enabled == enabled)
- return;
- d->enabled = enabled;
- emit enabledChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::minimum
-
- This property holds the smallest unconstrained value that the property is
- allowed to have. If the property is set to a smaller value, it will be
- constrained by \l easing and \l minimumOvershoot.
-
- The default is \c 0.
-*/
-qreal QQuickBoundaryRule::minimum() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->minimum;
-}
-
-void QQuickBoundaryRule::setMinimum(qreal minimum)
-{
- Q_D(QQuickBoundaryRule);
- if (qFuzzyCompare(d->minimum, minimum))
- return;
- d->minimum = minimum;
- emit minimumChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::minimumOvershoot
-
- This property holds the amount that the property is allowed to be
- less than \l minimum. Whenever the value is less than \l minimum
- and greater than \c {minimum - minimumOvershoot}, it is constrained
- by the \l easing curve. When the value attempts to go under
- \c {minimum - minimumOvershoots} there is a hard stop.
-
- The default is \c 0.
-*/
-qreal QQuickBoundaryRule::minimumOvershoot() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->minimumOvershoot;
-}
-
-void QQuickBoundaryRule::setMinimumOvershoot(qreal minimumOvershoot)
-{
- Q_D(QQuickBoundaryRule);
- if (qFuzzyCompare(d->minimumOvershoot, minimumOvershoot))
- return;
- d->minimumOvershoot = minimumOvershoot;
- emit minimumOvershootChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::maximum
-
- This property holds the largest unconstrained value that the property is
- allowed to have. If the property is set to a larger value, it will be
- constrained by \l easing and \l maximumOvershoot.
-
- The default is \c 1.
-*/
-qreal QQuickBoundaryRule::maximum() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->maximum;
-}
-
-void QQuickBoundaryRule::setMaximum(qreal maximum)
-{
- Q_D(QQuickBoundaryRule);
- if (qFuzzyCompare(d->maximum, maximum))
- return;
- d->maximum = maximum;
- emit maximumChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::maximumOvershoot
-
- This property holds the amount that the property is allowed to be
- more than \l maximum. Whenever the value is greater than \l maximum
- and less than \c {maximum + maximumOvershoot}, it is constrained
- by the \l easing curve. When the value attempts to exceed
- \c {maximum + maximumOvershoot} there is a hard stop.
-
- The default is 0.
-*/
-qreal QQuickBoundaryRule::maximumOvershoot() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->maximumOvershoot;
-}
-
-void QQuickBoundaryRule::setMaximumOvershoot(qreal maximumOvershoot)
-{
- Q_D(QQuickBoundaryRule);
- if (qFuzzyCompare(d->maximumOvershoot, maximumOvershoot))
- return;
- d->maximumOvershoot = maximumOvershoot;
- emit maximumOvershootChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::overshootScale
-
- This property holds the amount by which the \l easing is scaled during the
- overshoot condition. For example if an Item is restricted from moving more
- than 100 pixels beyond some limit, and the user (by means of some Input
- Handler) is trying to drag it 100 pixels past the limit, if overshootScale
- is set to 1, the user will succeed: the only effect of the easing curve is
- to change the rate at which the item moves from overshoot 0 to overshoot
- 100. But if it is set to 0.5, the BoundaryRule provides resistance such
- that when the user tries to move 100 pixels, the Item will only move 50
- pixels; and the easing curve modulates the rate of movement such that it
- may move in sync with the user's attempted movement at the beginning, and
- then slows down, depending on the shape of the easing curve.
-
- The default is 0.5.
-*/
-qreal QQuickBoundaryRule::overshootScale() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->overshootScale;
-}
-
-void QQuickBoundaryRule::setOvershootScale(qreal overshootScale)
-{
- Q_D(QQuickBoundaryRule);
- if (qFuzzyCompare(d->overshootScale, overshootScale))
- return;
- d->overshootScale = overshootScale;
- emit overshootScaleChanged();
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::currentOvershoot
-
- This property holds the amount by which the most recently set value of the
- intercepted property exceeds \l maximum or is less than \l minimum.
-
- It is positive if the property value exceeds \l maximum, negative if the
- property value is less than \l minimum, or 0 if the property value is
- within both boundaries.
-*/
-qreal QQuickBoundaryRule::currentOvershoot() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->currentOvershoot;
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::peakOvershoot
-
- This property holds the most-positive or most-negative value of
- \l currentOvershoot that has been seen, until \l returnToBounds() is called.
-
- This can be useful when the intercepted property value is known to
- fluctuate, and you want to find and react to the maximum amount of
- overshoot rather than to the fluctuations.
-
- \sa overshootFilter
-*/
-qreal QQuickBoundaryRule::peakOvershoot() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->peakOvershoot;
-}
-
-/*!
- \qmlproperty enum QtQuick::BoundaryRule::overshootFilter
-
- This property specifies the aggregation function that will be applied to
- the intercepted property value.
-
- If this is set to \c BoundaryRule.None (the default), the intercepted
- property will hold a value whose overshoot is limited to \l currentOvershoot.
- If this is set to \c BoundaryRule.Peak, the intercepted property will hold
- a value whose overshoot is limited to \l peakOvershoot.
-*/
-QQuickBoundaryRule::OvershootFilter QQuickBoundaryRule::overshootFilter() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->overshootFilter;
-}
-
-void QQuickBoundaryRule::setOvershootFilter(OvershootFilter overshootFilter)
-{
- Q_D(QQuickBoundaryRule);
- if (d->overshootFilter == overshootFilter)
- return;
- d->overshootFilter = overshootFilter;
- emit overshootFilterChanged();
-}
-
-/*!
- \qmlmethod bool QtQuick::BoundaryRule::returnToBounds
-
- Returns the intercepted property to a value between \l minimum and
- \l maximum, such that \l currentOvershoot and \l peakOvershoot are both
- zero. This will be animated if \l returnDuration is greater than zero.
-
- Returns true if the value needed to be adjusted, or false if it was already
- within bounds.
-*/
-bool QQuickBoundaryRule::returnToBounds()
-{
- Q_D(QQuickBoundaryRule);
- if (d->returnAnimationJob) {
- qCDebug(lcBR) << "animation already in progress";
- return true;
- }
- if (currentOvershoot() > 0) {
- if (d->returnDuration > 0)
- d->returnAnimationJob = new QQuickBoundaryReturnJob(d, maximum());
- else
- write(maximum());
- } else if (currentOvershoot() < 0) {
- if (d->returnDuration > 0)
- d->returnAnimationJob = new QQuickBoundaryReturnJob(d, minimum());
- else
- write(minimum());
- } else {
- return false;
- }
- if (d->returnAnimationJob) {
- qCDebug(lcBR) << "animating from" << d->returnAnimationJob->fromValue << "to" << d->returnAnimationJob->toValue;
- d->returnAnimationJob->start();
- } else {
- d->resetOvershoot();
- qCDebug(lcBR) << "returned to" << d->property.read();
- }
- return true;
-}
-
-/*!
- \qmlproperty qreal QtQuick::BoundaryRule::easing
-
- This property holds the easing curve to be applied in overshoot mode
- (whenever the \l minimum or \l maximum constraint is violated, while
- the value is still within the respective overshoot range).
-
- The default easing curve is \l QEasingCurve::OutQuad.
-*/
-QEasingCurve QQuickBoundaryRule::easing() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->easing;
-}
-
-void QQuickBoundaryRule::setEasing(const QEasingCurve &easing)
-{
- Q_D(QQuickBoundaryRule);
- if (d->easing == easing)
- return;
- d->easing = easing;
- emit easingChanged();
-}
-
-/*!
- \qmlproperty int QtQuick::BoundaryRule::returnDuration
-
- This property holds the amount of time in milliseconds that
- \l returnToBounds() will take to return the target property to the nearest bound.
- If it is set to 0, returnToBounds() will set the property immediately
- rather than creating an animation job.
-
- The default is 100 ms.
-*/
-int QQuickBoundaryRule::returnDuration() const
-{
- Q_D(const QQuickBoundaryRule);
- return d->returnDuration;
-}
-
-void QQuickBoundaryRule::setReturnDuration(int duration)
-{
- Q_D(QQuickBoundaryRule);
- if (d->returnDuration == duration)
- return;
- d->returnDuration = duration;
- emit returnDurationChanged();
-}
-
-void QQuickBoundaryRule::write(const QVariant &value)
-{
- bool conversionOk = false;
- qreal rValue = value.toReal(&conversionOk);
- if (!conversionOk) {
- qWarning() << "BoundaryRule doesn't work with non-numeric values:" << value;
- return;
- }
- Q_D(QQuickBoundaryRule);
- bool bypass = !d->enabled || !d->finalized || QQmlEnginePrivate::designerMode();
- if (bypass) {
- QQmlPropertyPrivate::write(d->property, value,
- QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
- return;
- }
-
- qmlExecuteDeferred(this);
- d->targetValue = d->easedOvershoot(rValue);
- QQmlPropertyPrivate::write(d->property, d->targetValue,
- QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding);
-}
-
-void QQuickBoundaryRule::setTarget(const QQmlProperty &property)
-{
- Q_D(QQuickBoundaryRule);
- d->property = property;
-
- QQmlEnginePrivate *engPriv = QQmlEnginePrivate::get(qmlEngine(this));
- static int finalizedIdx = -1;
- if (finalizedIdx < 0)
- finalizedIdx = metaObject()->indexOfSlot("componentFinalized()");
- engPriv->registerFinalizeCallback(this, finalizedIdx);
-}
-
-void QQuickBoundaryRule::componentFinalized()
-{
- Q_D(QQuickBoundaryRule);
- d->finalized = true;
-}
-
-/*!
- \internal
- Given that something is trying to set the target property to \a value,
- this function applies the easing curve and returns the value that the
- property should actually get instead.
-*/
-qreal QQuickBoundaryRulePrivate::easedOvershoot(qreal value)
-{
- qreal ret = value;
- Q_Q(QQuickBoundaryRule);
- if (value > maximum) {
- qreal overshootWas = currentOvershoot;
- currentOvershoot = value - maximum;
- if (!qFuzzyCompare(overshootWas, currentOvershoot))
- emit q->currentOvershootChanged();
- overshootWas = peakOvershoot;
- peakOvershoot = qMax(currentOvershoot, peakOvershoot);
- if (!qFuzzyCompare(overshootWas, peakOvershoot))
- emit q->peakOvershootChanged();
- ret = maximum + maximumOvershoot * easing.valueForProgress(
- (overshootFilter == QQuickBoundaryRule::OvershootFilter::Peak ? peakOvershoot : currentOvershoot)
- * overshootScale / maximumOvershoot);
- qCDebug(lcBR).nospace() << value << " overshoots maximum " << maximum << " by "
- << currentOvershoot << " (peak " << peakOvershoot << "): eased to " << ret;
- } else if (value < minimum) {
- qreal overshootWas = currentOvershoot;
- currentOvershoot = value - minimum;
- if (!qFuzzyCompare(overshootWas, currentOvershoot))
- emit q->currentOvershootChanged();
- overshootWas = peakOvershoot;
- peakOvershoot = qMin(currentOvershoot, peakOvershoot);
- if (!qFuzzyCompare(overshootWas, peakOvershoot))
- emit q->peakOvershootChanged();
- ret = minimum - minimumOvershoot * easing.valueForProgress(
- -(overshootFilter == QQuickBoundaryRule::OvershootFilter::Peak ? peakOvershoot : currentOvershoot)
- * overshootScale / minimumOvershoot);
- qCDebug(lcBR).nospace() << value << " overshoots minimum " << minimum << " by "
- << currentOvershoot << " (peak " << peakOvershoot << "): eased to " << ret;
- } else {
- resetOvershoot();
- }
- return ret;
-}
-
-/*!
- \internal
- Resets the currentOvershoot and peakOvershoot
- properties to zero.
-*/
-void QQuickBoundaryRulePrivate::resetOvershoot()
-{
- Q_Q(QQuickBoundaryRule);
- if (!qFuzzyCompare(peakOvershoot, 0)) {
- peakOvershoot = 0;
- emit q->peakOvershootChanged();
- }
- if (!qFuzzyCompare(currentOvershoot, 0)) {
- currentOvershoot = 0;
- emit q->currentOvershootChanged();
- }
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qquickboundaryrule_p.cpp"
diff --git a/src/quick/util/qquickboundaryrule_p.h b/src/quick/util/qquickboundaryrule_p.h
deleted file mode 100644
index 3325b675c5..0000000000
--- a/src/quick/util/qquickboundaryrule_p.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKBOUNDARYRULE_H
-#define QQUICKBOUNDARYRULE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtquickglobal_p.h>
-
-#include <private/qqmlpropertyvalueinterceptor_p.h>
-#include <qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickAbstractAnimation;
-class QQuickBoundaryRulePrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickBoundaryRule : public QObject, public QQmlPropertyValueInterceptor
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QQuickBoundaryRule)
-
- Q_INTERFACES(QQmlPropertyValueInterceptor)
- Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
- Q_PROPERTY(qreal minimumOvershoot READ minimumOvershoot WRITE setMinimumOvershoot NOTIFY minimumOvershootChanged)
- Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
- Q_PROPERTY(qreal maximumOvershoot READ maximumOvershoot WRITE setMaximumOvershoot NOTIFY maximumOvershootChanged)
- Q_PROPERTY(qreal overshootScale READ overshootScale WRITE setOvershootScale NOTIFY overshootScaleChanged)
- Q_PROPERTY(qreal currentOvershoot READ currentOvershoot NOTIFY currentOvershootChanged)
- Q_PROPERTY(qreal peakOvershoot READ peakOvershoot NOTIFY peakOvershootChanged)
- Q_PROPERTY(OvershootFilter overshootFilter READ overshootFilter WRITE setOvershootFilter NOTIFY overshootFilterChanged)
- Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
- Q_PROPERTY(int returnDuration READ returnDuration WRITE setReturnDuration NOTIFY returnDurationChanged)
-
-public:
- enum OvershootFilter {
- None,
- Peak
- };
- Q_ENUM(OvershootFilter)
-
- QQuickBoundaryRule(QObject *parent=nullptr);
- ~QQuickBoundaryRule();
-
- void setTarget(const QQmlProperty &) override;
- void write(const QVariant &value) override;
-
- bool enabled() const;
- void setEnabled(bool enabled);
-
- qreal minimum() const;
- void setMinimum(qreal minimum);
- qreal minimumOvershoot() const;
- void setMinimumOvershoot(qreal minimum);
-
- qreal maximum() const;
- void setMaximum(qreal maximum);
- qreal maximumOvershoot() const;
- void setMaximumOvershoot(qreal maximum);
-
- qreal overshootScale() const;
- void setOvershootScale(qreal scale);
-
- qreal currentOvershoot() const;
- qreal peakOvershoot() const;
-
- OvershootFilter overshootFilter() const;
- void setOvershootFilter(OvershootFilter overshootFilter);
-
- Q_INVOKABLE bool returnToBounds();
-
- QEasingCurve easing() const;
- void setEasing(const QEasingCurve &easing);
-
- int returnDuration() const;
- void setReturnDuration(int duration);
-
-Q_SIGNALS:
- void enabledChanged();
- void minimumChanged();
- void minimumOvershootChanged();
- void maximumChanged();
- void maximumOvershootChanged();
- void overshootScaleChanged();
- void currentOvershootChanged();
- void peakOvershootChanged();
- void overshootFilterChanged();
- void easingChanged();
- void returnDurationChanged();
-
-private Q_SLOTS:
- void componentFinalized();
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickBoundaryRule)
-
-#endif // QQUICKBOUNDARYRULE_H
diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h
index 8d277f7cf7..e849c52a35 100644
--- a/src/quick/util/qquickfontloader_p.h
+++ b/src/quick/util/qquickfontloader_p.h
@@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ QML_NAMED_ELEMENT(FontLoader)
public:
enum Status { Null = 0, Ready, Loading, Error };
diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h
index db2b7b6796..ee6d679649 100644
--- a/src/quick/util/qquickfontmetrics_p.h
+++ b/src/quick/util/qquickfontmetrics_p.h
@@ -79,6 +79,8 @@ class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject
Q_PROPERTY(qreal overlinePosition READ overlinePosition NOTIFY fontChanged)
Q_PROPERTY(qreal strikeOutPosition READ strikeOutPosition NOTIFY fontChanged)
Q_PROPERTY(qreal lineWidth READ lineWidth NOTIFY fontChanged)
+ QML_NAMED_ELEMENT(FontMetrics)
+ QML_ADDED_IN_MINOR_VERSION(4)
public:
explicit QQuickFontMetrics(QObject *parent = nullptr);
~QQuickFontMetrics();
diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h b/src/quick/util/qquickforeignutils_p.h
index e811109a94..7e51bc4f82 100644
--- a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h
+++ b/src/quick/util/qquickforeignutils_p.h
@@ -37,8 +37,22 @@
**
****************************************************************************/
-#ifndef QSGRHINATIVETEXTUREIMPORTER_P_H
-#define QSGRHINATIVETEXTUREIMPORTER_P_H
+#ifndef QTQUICKFOREIGN_P_H
+#define QTQUICKFOREIGN_P_H
+
+#include <qtquickglobal_p.h>
+
+#if QT_CONFIG(im)
+#include <QtGui/qinputmethod.h>
+#endif
+#if QT_CONFIG(validator)
+#include <QtGui/qvalidator.h>
+#endif
+#if QT_CONFIG(shortcut)
+#include <QtGui/qkeysequence.h>
+#endif
+
+#include <QtQml/qqml.h>
//
// W A R N I N G
@@ -51,20 +65,56 @@
// We mean it.
//
-#include <QtQuick/private/qtquickglobal_p.h>
-
QT_BEGIN_NAMESPACE
-class QRhi;
-class QRhiTexture;
+#if QT_CONFIG(validator)
+struct QValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QValidator)
+ QML_ANONYMOUS
+};
+
+struct QRegExpValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QRegExpValidator)
+ QML_NAMED_ELEMENT(RegExpValidator)
+};
+
+#if QT_CONFIG(regularexpression)
+struct QRegularExpressionValidatorForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QRegularExpressionValidator)
+ QML_NAMED_ELEMENT(RegularExpressionValidator)
+ QML_ADDED_IN_MINOR_VERSION(14)
+};
+#endif // QT_CONFIG(regularexpression)
+
+#endif // QT_CONFIG(validator)
+
+#if QT_CONFIG(im)
+struct QInputMethodForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QInputMethod)
+ QML_NAMED_ELEMENT(InputMethod)
+ QML_UNCREATABLE("InputMethod is an abstract class.")
+};
+#endif // QT_CONFIG(im)
-class QSGRhiNativeTextureImporter
+#if QT_CONFIG(shortcut)
+struct QKeySequenceForeign
{
-public:
- static void buildWrapper(QRhi *rhi, QRhiTexture *t,
- const void *nativeObjectPtr, int nativeLayout);
+ Q_GADGET
+ QML_FOREIGN(QKeySequence)
+ QML_NAMED_ELEMENT(StandardKey)
+ QML_ADDED_IN_MINOR_VERSION(2)
+ QML_UNCREATABLE("Cannot create an instance of StandardKey.")
};
+#endif // QT_CONFIG(shortcut)
QT_END_NAMESPACE
-#endif // QSGRHINATIVETEXTUREIMPORTER_P_H
+#endif // QTQUICKFOREIGN_P_H
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 527274e6be..70256e202e 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -273,6 +273,52 @@ public:
return QMatrix4x4();
}
+ static QColorSpace colorSpaceFromObject(const QV4::Value &object, QV4::ExecutionEngine *v4, bool *ok)
+ {
+ if (ok)
+ *ok = false;
+ QColorSpace retn;
+ QV4::Scope scope(v4);
+ QV4::ScopedObject obj(scope, object);
+ if (!obj) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+
+ QV4::ScopedString s(scope);
+
+ QV4::ScopedValue vName(scope, obj->get((s = v4->newString(QStringLiteral("namedColorSpace")))));
+ if (vName->isInt32()) {
+ if (ok)
+ *ok = true;
+ return QColorSpace((QColorSpace::NamedColorSpace)vName->toInt32());
+ }
+
+ QV4::ScopedValue vPri(scope, obj->get((s = v4->newString(QStringLiteral("primaries")))));
+ QV4::ScopedValue vTra(scope, obj->get((s = v4->newString(QStringLiteral("transferFunction")))));
+ if (!vPri->isInt32() || !vTra->isInt32()) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+
+ QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri->integerValue());
+ QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra->integerValue());
+ float gamma = 0.0f;
+ if (tra == QColorSpace::TransferFunction::Gamma) {
+ QV4::ScopedValue vGam(scope, obj->get((s = v4->newString(QStringLiteral("gamma")))));
+ if (!vGam->isNumber()) {
+ if (ok)
+ *ok = false;
+ return retn;
+ }
+ gamma = vGam->toNumber();
+ }
+ if (ok) *ok = true;
+ return QColorSpace(pri, tra, gamma);
+ }
+
static QFont fontFromObject(const QV4::Value &object, QV4::ExecutionEngine *v4, bool *ok)
{
if (ok)
@@ -402,6 +448,8 @@ public:
switch (type) {
case QMetaType::QColor:
return &QQuickColorValueType::staticMetaObject;
+ case QMetaType::QColorSpace:
+ return &QQuickColorSpaceValueType::staticMetaObject;
case QMetaType::QFont:
return &QQuickFontValueType::staticMetaObject;
case QMetaType::QVector2D:
@@ -427,6 +475,9 @@ public:
case QMetaType::QColor:
dst.setValue<QColor>(QColor());
return true;
+ case QMetaType::QColorSpace:
+ dst.setValue<QColorSpace>(QColorSpace());
+ return true;
case QMetaType::QFont:
dst.setValue<QFont>(QFont());
return true;
@@ -647,6 +698,9 @@ public:
#endif
bool ok = false;
switch (type) {
+ case QMetaType::QColorSpace:
+ *v = QVariant::fromValue(colorSpaceFromObject(object, v4, &ok));
+ break;
case QMetaType::QFont:
*v = QVariant::fromValue(fontFromObject(object, v4, &ok));
break;
@@ -669,6 +723,8 @@ public:
switch (type) {
case QMetaType::QColor:
return typedEqual<QColor>(lhs, rhs);
+ case QMetaType::QColorSpace:
+ return typedEqual<QColorSpace>(lhs, rhs);
case QMetaType::QFont:
return typedEqual<QFont>(lhs, rhs);
case QMetaType::QVector2D:
@@ -719,7 +775,7 @@ public:
bool typedRead(const QVariant& src, int dstType, void *dst)
{
T *dstT = reinterpret_cast<T *>(dst);
- if (src.type() == static_cast<uint>(dstType)) {
+ if (src.userType() == dstType) {
*dstT = src.value<T>();
} else {
*dstT = T();
@@ -732,6 +788,8 @@ public:
switch (dstType) {
case QMetaType::QColor:
return typedRead<QColor>(src, dstType, dst);
+ case QMetaType::QColorSpace:
+ return typedRead<QColorSpace>(src, dstType, dst);
case QMetaType::QFont:
return typedRead<QFont>(src, dstType, dst);
case QMetaType::QVector2D:
@@ -766,6 +824,8 @@ public:
switch (type) {
case QMetaType::QColor:
return typedWrite<QColor>(src, dst);
+ case QMetaType::QColorSpace:
+ return typedWrite<QColorSpace>(src, dst);
case QMetaType::QFont:
return typedWrite<QFont>(src, dst);
case QMetaType::QVector2D:
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index ebcca77f17..80873e2ad5 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -43,6 +43,7 @@
#include "qquickpixmapcache_p.h"
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
+#include <QtGui/qcolorspace.h>
QT_BEGIN_NAMESPACE
@@ -291,7 +292,7 @@ void QQuickImageResponse::cancel()
\image imageprovider.png
See the \l {imageprovider}{Image Provider Example} for the complete implementation.
- Note that the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
+ Note that the example registers the provider via a \l{QQmlEngineExtensionPlugin}{plugin}
instead of registering it in the application \c main() function as shown above.
@@ -510,6 +511,7 @@ public:
{
}
+ QColorSpace targetColorSpace;
QQuickImageProviderOptions::AutoTransform autoTransform = QQuickImageProviderOptions::UsePluginDefaultTransform;
bool preserveAspectRatioCrop = false;
bool preserveAspectRatioFit = false;
@@ -558,7 +560,8 @@ bool QQuickImageProviderOptions::operator==(const QQuickImageProviderOptions &ot
{
return d->autoTransform == other.d->autoTransform &&
d->preserveAspectRatioCrop == other.d->preserveAspectRatioCrop &&
- d->preserveAspectRatioFit == other.d->preserveAspectRatioFit;
+ d->preserveAspectRatioFit == other.d->preserveAspectRatioFit &&
+ d->targetColorSpace == other.d->targetColorSpace;
}
/*!
@@ -602,6 +605,19 @@ void QQuickImageProviderOptions::setPreserveAspectRatioFit(bool preserveAspectRa
d->preserveAspectRatioFit = preserveAspectRatioFit;
}
+/*!
+ Returns the color space the image provider should return the image in.
+*/
+QColorSpace QQuickImageProviderOptions::targetColorSpace() const
+{
+ return d->targetColorSpace;
+}
+
+void QQuickImageProviderOptions::setTargetColorSpace(const QColorSpace &colorSpace)
+{
+ d->targetColorSpace = colorSpace;
+}
+
QQuickImageProviderWithOptions::QQuickImageProviderWithOptions(ImageType type, Flags flags)
: QQuickAsyncImageProvider()
{
@@ -672,17 +688,17 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const
return res;
const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit();
- const bool formatIsSvg = (format == "svg" || format == "svgz");
+ const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf");
- if (!preserveAspectCropOrFit && formatIsSvg && !requestedSize.isEmpty())
+ if (!preserveAspectCropOrFit && formatIsScalable && !requestedSize.isEmpty())
return requestedSize;
qreal ratio = 0.0;
- if (requestedSize.width() && (preserveAspectCropOrFit || formatIsSvg ||
+ if (requestedSize.width() && (preserveAspectCropOrFit || formatIsScalable ||
requestedSize.width() < originalSize.width())) {
ratio = qreal(requestedSize.width()) / originalSize.width();
}
- if (requestedSize.height() && (preserveAspectCropOrFit || formatIsSvg ||
+ if (requestedSize.height() && (preserveAspectCropOrFit || formatIsScalable ||
requestedSize.height() < originalSize.height())) {
qreal hr = qreal(requestedSize.height()) / originalSize.height();
if (ratio == 0.0)
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 24b22f00c1..74ee52b1d3 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -301,6 +301,8 @@ void QQuickPath::pathElements_append(QQmlListProperty<QQuickPathElement> *proper
QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement);
if (curve)
d->_pathCurves.append(curve);
+ else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement))
+ d->_pathTexts.append(text);
else {
QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement);
if (attribute && !d->_attributes.contains(attribute->name()))
@@ -329,6 +331,7 @@ void QQuickPath::pathElements_clear(QQmlListProperty<QQuickPathElement> *propert
d->_pathElements.clear();
d->_pathCurves.clear();
d->_pointCache.clear();
+ d->_pathTexts.clear();
}
void QQuickPath::interpolate(int idx, const QString &name, qreal value)
@@ -478,6 +481,8 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
point.values[percentString] = percent->value();
interpolate(attributePoints, attributePoints.count() - 1, percentString, percent->value());
usesPercent = true;
+ } else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) {
+ text->addToPath(path);
}
}
@@ -547,6 +552,9 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint
++index;
}
+ for (QQuickPathText *text : qAsConst(d->_pathTexts))
+ text->addToPath(path);
+
if (closed) {
QPointF end = path.currentPosition();
*closed = startX == end.x() && startY == end.y();
@@ -593,6 +601,8 @@ void QQuickPath::gatherAttributes()
for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) {
if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement))
d->_pathCurves.append(curve);
+ else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement))
+ d->_pathTexts.append(text);
else if (QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement))
attributes.insert(attribute->name());
}
@@ -2415,7 +2425,7 @@ QVariant QQuickPathPolyline::path() const
void QQuickPathPolyline::setPath(const QVariant &path)
{
- if (path.type() == QVariant::PolygonF) {
+ if (path.userType() == QMetaType::QPolygonF) {
setPath(path.value<QPolygonF>());
} else if (path.canConvert<QVector<QPointF>>()) {
setPath(path.value<QVector<QPointF>>());
@@ -2431,7 +2441,7 @@ void QQuickPathPolyline::setPath(const QVariant &path)
pathList.append(v.toPointF());
setPath(pathList);
} else {
- qWarning() << "PathPolyline: path of type" << path.type() << "not supported";
+ qWarning() << "PathPolyline: path of type" << path.userType() << "not supported";
}
}
@@ -2583,7 +2593,7 @@ void QQuickPathMultiline::setPaths(const QVariant &paths)
}
setPaths(pathsList);
} else {
- qWarning() << "PathMultiline: paths of type" << paths.type() << "not supported";
+ qWarning() << "PathMultiline: paths of type" << paths.userType() << "not supported";
setPaths(QVector<QVector<QPointF>>());
}
}
@@ -2619,6 +2629,219 @@ void QQuickPathMultiline::addToPath(QPainterPath &path, const QQuickPathData &)
}
}
+/*!
+ \qmltype PathText
+ \instantiates QQuickPathText
+ \inqmlmodule QtQuick
+ \ingroup qtquick-animation-paths
+ \brief Defines a string in a specified font.
+ \since QtQuick 2.15
+
+ This element defines the shape of a specified string in a specified font. The text's
+ baseline will be translated to the x and y coordinates, and the outlines from the font
+ will be added to the path accordingly.
+
+ \qml
+ PathText {
+ x: 0
+ y: font.pixelSize
+ font.family: "Arial"
+ font.pixelSize: 100
+ text: "Foobar"
+ }
+ \endqml
+
+ \sa Path, QPainterPath::setFillRule, PathPolyline, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg, PathMove
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::x
+
+ The horizontal position of the PathText's baseline.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::y
+
+ The vertical position of the PathText's baseline.
+
+ \note This property refers to the position of the baseline of the text, not the top of its bounding box. This may
+ cause some confusion, e.g. when using the PathText with Qt Quick Shapes. See \l FontMetrics for information on how to
+ get the ascent of a font, which can be used to translate the text into the expected position.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::text
+
+ The text for which this PathText should contain the outlines.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::font.family
+
+ Sets the family name of the font.
+
+ The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
+ If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
+ If the family isn't available a family will be set using the font matching algorithm.
+*/
+
+/*!
+ \qmlproperty string QtQuick::PathText::font.styleName
+
+ Sets the style name of the font.
+
+ The style name is case insensitive. If set, the font will be matched against style name instead
+ of the font properties \l font.weight, \l font.bold and \l font.italic.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.bold
+
+ Sets whether the font weight is bold.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick::PathText::font.weight
+
+ Sets the font's weight.
+
+ The weight can be one of:
+ \list
+ \li Font.Thin
+ \li Font.Light
+ \li Font.ExtraLight
+ \li Font.Normal - the default
+ \li Font.Medium
+ \li Font.DemiBold
+ \li Font.Bold
+ \li Font.ExtraBold
+ \li Font.Black
+ \endlist
+
+ \qml
+ PathText { text: "Hello"; font.weight: Font.DemiBold }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.italic
+
+ Sets whether the font has an italic style.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.underline
+
+ Sets whether the text is underlined.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.strikeout
+
+ Sets whether the font has a strikeout style.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.pointSize
+
+ Sets the font size in points. The point size must be greater than zero.
+*/
+
+/*!
+ \qmlproperty int QtQuick::PathText::font.pixelSize
+
+ Sets the font size in pixels.
+
+ Using this function makes the font device dependent.
+ Use \c pointSize to set the size of the font in a device independent manner.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.letterSpacing
+
+ Sets the letter spacing for the font.
+
+ Letter spacing changes the default spacing between individual letters in the font.
+ A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathText::font.wordSpacing
+
+ Sets the word spacing for the font.
+
+ Word spacing changes the default spacing between individual words.
+ A positive value increases the word spacing by a corresponding amount of pixels,
+ while a negative value decreases the inter-word spacing accordingly.
+*/
+
+/*!
+ \qmlproperty enumeration QtQuick::PathText::font.capitalization
+
+ Sets the capitalization for the text.
+
+ \list
+ \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
+ \li Font.AllUppercase - This alters the text to be rendered in all uppercase type.
+ \li Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+ \li Font.SmallCaps - This alters the text to be rendered in small-caps type.
+ \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+ \endlist
+
+ \qml
+ PathText { text: "Hello"; font.capitalization: Font.AllLowercase }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.kerning
+
+ Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
+ improve performance when creating or changing the text, at the expense of some cosmetic
+ features. The default value is true.
+
+ \qml
+ PathText { text: "OATS FLAVOUR WAY"; font.kerning: false }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PathText::font.preferShaping
+
+ Sometimes, a font will apply complex rules to a set of characters in order to
+ display them correctly. In some writing systems, such as Brahmic scripts, this is
+ required in order for the text to be legible, but in e.g. Latin script, it is merely
+ a cosmetic feature. Setting the \c preferShaping property to false will disable all
+ such features when they are not required, which will improve performance in most cases.
+
+ The default value is true.
+
+ \qml
+ PathText { text: "Some text"; font.preferShaping: false }
+ \endqml
+*/
+
+void QQuickPathText::updatePath() const
+{
+ if (!_path.isEmpty())
+ return;
+
+ _path.addText(0.0, 0.0, _font, _text);
+
+ // Account for distance from baseline to top, since addText() takes baseline position
+ QRectF brect = _path.boundingRect();
+ _path.translate(_x, _y - brect.y());
+}
+
+void QQuickPathText::addToPath(QPainterPath &path)
+{
+ if (_text.isEmpty())
+ return;
+ updatePath();
+ path.addPath(_path);
+}
+
QT_END_NAMESPACE
#include "moc_qquickpath_p.cpp"
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index 5987ae8f35..159c46d13c 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -63,6 +63,7 @@ QT_REQUIRE_CONFIG(quick_path);
#include <QtCore/QObject>
#include <QtGui/QPainterPath>
+#include <QtGui/QFont>
QT_BEGIN_NAMESPACE
@@ -77,6 +78,7 @@ struct QQuickPathData
class Q_QUICK_PRIVATE_EXPORT QQuickPathElement : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickPathElement(QObject *parent=nullptr) : QObject(parent) {}
Q_SIGNALS:
@@ -89,6 +91,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAttribute : public QQuickPathElement
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PathAttribute)
public:
QQuickPathAttribute(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -116,6 +119,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickCurve : public QQuickPathElement
Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
Q_PROPERTY(qreal relativeX READ relativeX WRITE setRelativeX NOTIFY relativeXChanged)
Q_PROPERTY(qreal relativeY READ relativeY WRITE setRelativeY NOTIFY relativeYChanged)
+ QML_ANONYMOUS
public:
QQuickCurve(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -153,6 +157,7 @@ private:
class Q_QUICK_PRIVATE_EXPORT QQuickPathLine : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathLine)
public:
QQuickPathLine(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -162,6 +167,8 @@ public:
class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathMove)
+ QML_ADDED_IN_MINOR_VERSION(9)
public:
QQuickPathMove(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -176,6 +183,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve
Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY controlYChanged)
Q_PROPERTY(qreal relativeControlX READ relativeControlX WRITE setRelativeControlX NOTIFY relativeControlXChanged)
Q_PROPERTY(qreal relativeControlY READ relativeControlY WRITE setRelativeControlY NOTIFY relativeControlYChanged)
+
+ QML_NAMED_ELEMENT(PathQuad)
public:
QQuickPathQuad(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -220,6 +229,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathCubic : public QQuickCurve
Q_PROPERTY(qreal relativeControl1Y READ relativeControl1Y WRITE setRelativeControl1Y NOTIFY relativeControl1YChanged)
Q_PROPERTY(qreal relativeControl2X READ relativeControl2X WRITE setRelativeControl2X NOTIFY relativeControl2XChanged)
Q_PROPERTY(qreal relativeControl2Y READ relativeControl2Y WRITE setRelativeControl2Y NOTIFY relativeControl2YChanged)
+ QML_NAMED_ELEMENT(PathCubic)
public:
QQuickPathCubic(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -277,6 +287,7 @@ private:
class Q_QUICK_PRIVATE_EXPORT QQuickPathCatmullRomCurve : public QQuickCurve
{
Q_OBJECT
+ QML_NAMED_ELEMENT(PathCurve)
public:
QQuickPathCatmullRomCurve(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -291,6 +302,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve
Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 9)
+ QML_NAMED_ELEMENT(PathArc)
public:
QQuickPathArc(QObject *parent=nullptr)
@@ -342,6 +354,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve
Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged)
Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged)
+ QML_NAMED_ELEMENT(PathAngleArc)
+ QML_ADDED_IN_MINOR_VERSION(11)
+
public:
QQuickPathAngleArc(QObject *parent=nullptr)
: QQuickCurve(parent) {}
@@ -392,6 +407,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve
{
Q_OBJECT
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+ QML_NAMED_ELEMENT(PathSvg)
public:
QQuickPathSvg(QObject *parent=nullptr) : QQuickCurve(parent) {}
@@ -411,6 +427,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPercent : public QQuickPathElement
{
Q_OBJECT
Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ QML_NAMED_ELEMENT(PathPercent)
public:
QQuickPathPercent(QObject *parent=nullptr) : QQuickPathElement(parent) {}
@@ -429,6 +446,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathPolyline : public QQuickCurve
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant path READ path WRITE setPath NOTIFY pathChanged)
+ QML_NAMED_ELEMENT(PathPolyline)
+ QML_ADDED_IN_MINOR_VERSION(14)
public:
QQuickPathPolyline(QObject *parent=nullptr);
@@ -451,6 +470,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathMultiline : public QQuickCurve
Q_OBJECT
Q_PROPERTY(QPointF start READ start NOTIFY startChanged)
Q_PROPERTY(QVariant paths READ paths WRITE setPaths NOTIFY pathsChanged)
+ QML_NAMED_ELEMENT(PathMultiline)
+ QML_ADDED_IN_MINOR_VERSION(14)
public:
QQuickPathMultiline(QObject *parent=nullptr);
@@ -493,6 +514,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPath : public QObject, public QQmlParserStatu
Q_PROPERTY(bool closed READ isClosed NOTIFY changed)
Q_PROPERTY(QSizeF scale READ scale WRITE setScale NOTIFY scaleChanged REVISION 14)
Q_CLASSINFO("DefaultProperty", "pathElements")
+ QML_NAMED_ELEMENT(Path)
Q_INTERFACES(QQmlParserStatus)
public:
QQuickPath(QObject *parent=nullptr);
@@ -577,6 +599,106 @@ public:
static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr);
};
+class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
+ Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
+ Q_PROPERTY(qreal width READ width NOTIFY changed)
+ Q_PROPERTY(qreal height READ height NOTIFY changed)
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+ QML_NAMED_ELEMENT(PathText)
+ QML_ADDED_IN_MINOR_VERSION(15)
+public:
+ QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent)
+ {
+ connect(this, &QQuickPathText::xChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::yChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::textChanged, this, &QQuickPathElement::changed);
+ connect(this, &QQuickPathText::fontChanged, this, &QQuickPathElement::changed);
+
+ connect(this, &QQuickPathElement::changed, this, &QQuickPathText::invalidate);
+ }
+
+ void addToPath(QPainterPath &path);
+
+ qreal x() const { return _x; }
+ qreal y() const { return _y; }
+ QString text() const { return _text; }
+ QFont font() const { return _font; }
+
+ void setX(qreal x)
+ {
+ if (qFuzzyCompare(_x, x))
+ return;
+
+ _x = x;
+ Q_EMIT xChanged();
+ }
+
+ void setY(qreal y)
+ {
+ if (qFuzzyCompare(_y, y))
+ return;
+
+ _y = y;
+ Q_EMIT yChanged();
+ }
+
+ void setText(const QString &text)
+ {
+ if (text == _text)
+ return;
+
+ _text = text;
+ Q_EMIT textChanged();
+ }
+
+ void setFont(const QFont &font)
+ {
+ if (font == _font)
+ return;
+
+ _font = font;
+ Q_EMIT fontChanged();
+ }
+
+ qreal width() const
+ {
+ updatePath();
+ return _path.boundingRect().width();
+ }
+
+ qreal height() const
+ {
+ updatePath();
+ return _path.boundingRect().height();
+ }
+
+Q_SIGNALS:
+ void xChanged();
+ void yChanged();
+ void textChanged();
+ void fontChanged();
+
+private Q_SLOTS:
+ void invalidate()
+ {
+ _path.clear();
+ }
+
+private:
+ void updatePath() const;
+
+ QString _text;
+ qreal _x = qreal(0.0);
+ qreal _y = qreal(0.0);
+ QFont _font;
+
+ mutable QPainterPath _path;
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickPathElement)
@@ -593,5 +715,6 @@ QML_DECLARE_TYPE(QQuickPathSvg)
QML_DECLARE_TYPE(QQuickPathPercent)
QML_DECLARE_TYPE(QQuickPathPolyline)
QML_DECLARE_TYPE(QQuickPath)
+QML_DECLARE_TYPE(QQuickPathText)
#endif // QQUICKPATH_H
diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h
index e26001ec77..5505b876c1 100644
--- a/src/quick/util/qquickpath_p_p.h
+++ b/src/quick/util/qquickpath_p_p.h
@@ -80,6 +80,7 @@ public:
QList<QQuickPath::AttributePoint> _attributePoints;
QStringList _attributes;
QList<QQuickCurve*> _pathCurves;
+ QList<QQuickPathText*> _pathTexts;
mutable QQuickCachedBezier prevBez;
QQmlNullableValue<qreal> startX;
QQmlNullableValue<qreal> startY;
diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h
index 60a9ff2e22..440ea06841 100644
--- a/src/quick/util/qquickpathinterpolator_p.h
+++ b/src/quick/util/qquickpathinterpolator_p.h
@@ -69,6 +69,7 @@ class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject
Q_PROPERTY(qreal x READ x NOTIFY xChanged)
Q_PROPERTY(qreal y READ y NOTIFY yChanged)
Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
+ QML_NAMED_ELEMENT(PathInterpolator)
public:
explicit QQuickPathInterpolator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index e1b30f2b2c..d96ebe70b2 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -86,6 +86,8 @@ QT_BEGIN_NAMESPACE
const QLatin1String QQuickPixmap::itemGrabberScheme = QLatin1String("itemgrabber");
+Q_LOGGING_CATEGORY(lcImg, "qt.quick.image")
+
#ifndef QT_NO_DEBUG
static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif
@@ -137,6 +139,7 @@ public:
QQuickPixmapData *data;
QQmlEngine *engineForReader; // always access reader inside readerMutex
+ QRect requestRegion;
QSize requestSize;
QUrl url;
@@ -240,9 +243,10 @@ public:
class QQuickPixmapData
{
public:
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QQuickImageProviderOptions &po, const QString &e)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QRect &r, const QSize &rs,
+ const QQuickImageProviderOptions &po, const QString &e)
: refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Error),
- url(u), errorString(e), requestSize(s),
+ url(u), errorString(e), requestRegion(r), requestSize(rs),
providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -250,9 +254,10 @@ public:
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QRect &r, const QSize &s, const QQuickImageProviderOptions &po,
+ QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
: refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Loading),
- url(u), requestSize(r),
+ url(u), requestRegion(r), requestSize(s),
providerOptions(po), appliedTransform(aTransform),
textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr),
nextUnreferenced(nullptr)
@@ -261,9 +266,10 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
- const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
+ const QSize &s, const QRect &r, const QSize &rs, const QQuickImageProviderOptions &po,
+ QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
: refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Ready),
- url(u), implicitSize(s), requestSize(r),
+ url(u), implicitSize(s), requestRegion(r), requestSize(rs),
providerOptions(po), appliedTransform(aTransform),
textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
@@ -308,9 +314,11 @@ public:
QUrl url;
QString errorString;
QSize implicitSize;
+ QRect requestRegion;
QSize requestSize;
QQuickImageProviderOptions providerOptions;
QQuickImageProviderOptions::AutoTransform appliedTransform;
+ QColorSpace targetColorSpace;
QQuickTextureFactory *textureFactory;
@@ -399,7 +407,7 @@ static void maybeRemoveAlpha(QImage *image)
}
static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount,
- const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
+ const QRect &requestRegion, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0)
{
QImageReader imgio(dev);
@@ -417,14 +425,25 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions);
if (scSize.isValid())
imgio.setScaledSize(scSize);
+ if (!requestRegion.isNull())
+ imgio.setScaledClipRect(requestRegion);
+ const QSize originalSize = imgio.size();
+ qCDebug(lcImg) << url << "frame" << frame << "of" << imgio.imageCount()
+ << "requestRegion" << requestRegion << "QImageReader size" << originalSize << "-> scSize" << scSize;
if (impsize)
- *impsize = imgio.size();
+ *impsize = originalSize;
if (imgio.read(image)) {
maybeRemoveAlpha(image);
if (impsize && impsize->width() < 0)
*impsize = image->size();
+ if (providerOptions.targetColorSpace().isValid()) {
+ if (image->colorSpace().isValid())
+ image->convertToColorSpace(providerOptions.targetColorSpace());
+ else
+ image->setColorSpace(providerOptions.targetColorSpace());
+ }
return true;
} else {
if (errorString)
@@ -568,7 +587,8 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
buff.open(QIODevice::ReadOnly);
int frameCount;
int const frame = job->data ? job->data->frame : 0;
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, frame))
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount,
+ job->requestRegion, job->requestSize, job->providerOptions, nullptr, frame))
error = QQuickPixmapReply::Decoding;
else if (job->data)
job->data->frameCount = frameCount;
@@ -884,7 +904,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
} else {
int frameCount;
int const frame = runningJob->data ? runningJob->data->frame : 0;
- if ( !readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, frame)) {
+ if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestRegion, runningJob->requestSize,
+ runningJob->providerOptions, nullptr, frame)) {
errorCode = QQuickPixmapReply::Loading;
if (f.fileName() != localFile)
errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
@@ -997,6 +1018,7 @@ class QQuickPixmapKey
{
public:
const QUrl *url;
+ const QRect *region;
const QSize *size;
int frame;
QQuickImageProviderOptions options;
@@ -1004,12 +1026,20 @@ public:
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options && lhs.frame == rhs.frame;
+ return *lhs.url == *rhs.url &&
+ *lhs.region == *rhs.region &&
+ *lhs.size == *rhs.size &&
+ lhs.frame == rhs.frame &&
+ lhs.options == rhs.options;
}
inline uint qHash(const QQuickPixmapKey &key)
{
- return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^
+ (key.region->x()*29) ^ (key.region->y()*31) ^ (key.options.autoTransform() * 0x5c5c5c5c);
+ // key.region.width() and height() are not included, because the hash function should be simple,
+ // and they are more likely to be held constant for some batches of images
+ // (e.g. tiles, or repeatedly cropping to the same viewport at different positions).
}
class QQuickPixmapStore : public QObject
@@ -1176,7 +1206,8 @@ void QQuickPixmap::purgeCache()
}
QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d)
-: data(d), engineForReader(nullptr), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0)
+ : data(d), engineForReader(nullptr), requestRegion(d->requestRegion), requestSize(d->requestSize),
+ url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0)
{
if (finishedIndex == -1) {
finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex();
@@ -1271,7 +1302,7 @@ void QQuickPixmapData::release()
void QQuickPixmapData::addToCache()
{
if (!inCache) {
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1282,7 +1313,7 @@ void QQuickPixmapData::addToCache()
void QQuickPixmapData::removeFromCache()
{
if (inCache) {
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
pixmapStore()->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1290,7 +1321,9 @@ void QQuickPixmapData::removeFromCache()
}
}
-static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
+static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url,
+ const QRect &requestRegion, const QSize &requestSize,
+ const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
{
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
@@ -1305,7 +1338,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
switch (imageType) {
case QQuickImageProvider::Invalid:
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions,
QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()));
case QQuickImageProvider::Texture:
{
@@ -1313,7 +1346,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestTexture(imageId(url), &readSize, requestSize);
if (texture) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestRegion, requestSize,
+ providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1324,7 +1358,9 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image),
+ readSize, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1334,7 +1370,9 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
: provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()),
+ readSize, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
}
break;
}
@@ -1346,7 +1384,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
}
// provider has bad image type, or provider returned null image
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions,
QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString()));
}
@@ -1364,7 +1402,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QQuickTextureFactory *factory = texReader.read();
if (factory) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
+ return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestRegion, requestSize,
+ providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
} else {
errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
if (f.fileName() != localFile)
@@ -1374,9 +1413,10 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QImage image;
QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
int frameCount;
- if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestSize, providerOptions, &appliedTransform, frame)) {
+ if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestRegion, requestSize, providerOptions, &appliedTransform, frame)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform, frame, frameCount);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestRegion, requestSize,
+ providerOptions, appliedTransform, frame, frameCount);
} else if (f.fileName() != localFile) {
errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
}
@@ -1384,12 +1424,13 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
} else {
errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
}
- return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions, errorString);
+ return new QQuickPixmapData(declarativePixmap, url, requestRegion, requestSize, providerOptions, errorString);
}
struct QQuickPixmapNull {
QUrl url;
+ QRect region;
QSize size;
};
Q_GLOBAL_STATIC(QQuickPixmapNull, nullPixmap);
@@ -1405,15 +1446,16 @@ QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url)
load(engine, url);
}
-QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &size)
+QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QRect &region, const QSize &size)
: d(nullptr)
{
- load(engine, url, size);
+ load(engine, url, region, size);
}
QQuickPixmap::QQuickPixmap(const QUrl &url, const QImage &image)
{
- d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize(), QQuickImageProviderOptions(), QQuickImageProviderOptions::UsePluginDefaultTransform);
+ d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QRect(), QSize(),
+ QQuickImageProviderOptions(), QQuickImageProviderOptions::UsePluginDefaultTransform);
d->addToCache();
}
@@ -1486,6 +1528,14 @@ const QSize &QQuickPixmap::requestSize() const
return nullPixmap()->size;
}
+const QRect &QQuickPixmap::requestRegion() const
+{
+ if (d)
+ return d->requestRegion;
+ else
+ return nullPixmap()->region;
+}
+
QQuickImageProviderOptions::AutoTransform QQuickPixmap::autoTransform() const
{
if (d)
@@ -1561,25 +1611,26 @@ QRect QQuickPixmap::rect() const
void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url)
{
- load(engine, url, QSize(), QQuickPixmap::Cache);
+ load(engine, url, QRect(), QSize(), QQuickPixmap::Cache);
}
void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, QQuickPixmap::Options options)
{
- load(engine, url, QSize(), options);
+ load(engine, url, QRect(), QSize(), options);
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &size)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize)
{
- load(engine, url, size, QQuickPixmap::Cache);
+ load(engine, url, requestRegion, requestSize, QQuickPixmap::Cache);
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize, QQuickPixmap::Options options)
{
- load(engine, url, requestSize, options, QQuickImageProviderOptions());
+ load(engine, url, requestRegion, requestSize, options, QQuickImageProviderOptions());
}
-void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
{
if (d) {
d->declarativePixmaps.remove(this);
@@ -1587,7 +1638,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
d = nullptr;
}
- QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
QQuickPixmapStore *store = pixmapStore();
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
@@ -1596,10 +1647,11 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
// cached version. Unless it's an itemgrabber url, since the cache is used to pass
// the result between QQuickItemGrabResult and QQuickImage.
if (url.scheme() == itemGrabberScheme) {
- QSize dummy;
- if (requestSize != dummy)
+ QRect dummyRegion;
+ QSize dummySize;
+ if (requestSize != dummySize)
qWarning() << "Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.";
- const QQuickPixmapKey grabberKey = { &url, &dummy, 0, QQuickImageProviderOptions() };
+ const QQuickPixmapKey grabberKey = { &url, &dummyRegion, &dummySize, 0, QQuickImageProviderOptions() };
iter = store->m_cache.find(grabberKey);
} else if (options & QQuickPixmap::Cache)
iter = store->m_cache.find(key);
@@ -1621,7 +1673,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, frame, &ok);
+ d = createPixmapDataSync(this, engine, url, requestRegion, requestSize, providerOptions, frame, &ok);
if (ok) {
PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
if (options & QQuickPixmap::Cache)
@@ -1638,7 +1690,8 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
return;
- d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
+ d = new QQuickPixmapData(this, url, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
if (options & QQuickPixmap::Cache)
d->addToCache();
@@ -1672,9 +1725,10 @@ void QQuickPixmap::clear(QObject *obj)
}
}
-bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
+bool QQuickPixmap::isCached(const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ const int frame, const QQuickImageProviderOptions &options)
{
- QQuickPixmapKey key = { &url, &requestSize, frame, options };
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, options };
QQuickPixmapStore *store = pixmapStore();
return store->m_cache.contains(key);
@@ -1720,6 +1774,13 @@ bool QQuickPixmap::connectDownloadProgress(QObject *object, int method)
return QMetaObject::connect(d->reply, QQuickPixmapReply::downloadProgressIndex, object, method);
}
+QColorSpace QQuickPixmap::colorSpace() const
+{
+ if (!d || !d->textureFactory)
+ return QColorSpace();
+ return d->textureFactory->image().colorSpace();
+}
+
QT_END_NAMESPACE
#include <qquickpixmapcache.moc>
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index ab5d391fa2..93dec63e94 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -117,6 +117,9 @@ public:
bool preserveAspectRatioFit() const;
void setPreserveAspectRatioFit(bool preserveAspectRatioFit);
+ QColorSpace targetColorSpace() const;
+ void setTargetColorSpace(const QColorSpace &colorSpace);
+
private:
QSharedDataPointer<QQuickImageProviderOptionsPrivate> d;
};
@@ -127,7 +130,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPixmap
public:
QQuickPixmap();
QQuickPixmap(QQmlEngine *, const QUrl &);
- QQuickPixmap(QQmlEngine *, const QUrl &, const QSize &);
+ QQuickPixmap(QQmlEngine *, const QUrl &, const QRect &region, const QSize &);
QQuickPixmap(const QUrl &, const QImage &image);
~QQuickPixmap();
@@ -148,6 +151,7 @@ public:
QString error() const;
const QUrl &url() const;
const QSize &implicitSize() const;
+ const QRect &requestRegion() const;
const QSize &requestSize() const;
QQuickImageProviderOptions::AutoTransform autoTransform() const;
int frameCount() const;
@@ -155,6 +159,8 @@ public:
void setImage(const QImage &);
void setPixmap(const QQuickPixmap &other);
+ QColorSpace colorSpace() const;
+
QQuickTextureFactory *textureFactory() const;
QRect rect() const;
@@ -163,9 +169,10 @@ public:
void load(QQmlEngine *, const QUrl &);
void load(QQmlEngine *, const QUrl &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options);
- void load(QQmlEngine *, const QUrl &, const QSize &, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize, QQuickPixmap::Options options);
+ void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize,
+ QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1);
void clear();
void clear(QObject *);
@@ -176,7 +183,8 @@ public:
bool connectDownloadProgress(QObject *, int);
static void purgeCache();
- static bool isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options);
+ static bool isCached(const QUrl &url, const QRect &requestRegion, const QSize &requestSize,
+ const int frame, const QQuickImageProviderOptions &options);
static const QLatin1String itemGrabberScheme;
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 82a6ebffac..27a00420af 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -65,6 +65,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPropertyChanges : public QQuickStateOperation
Q_PROPERTY(QObject *target READ object WRITE setObject)
Q_PROPERTY(bool restoreEntryValues READ restoreEntryValues WRITE setRestoreEntryValues)
Q_PROPERTY(bool explicit READ isExplicit WRITE setIsExplicit)
+ QML_NAMED_ELEMENT(PropertyChanges)
+
public:
QQuickPropertyChanges();
~QQuickPropertyChanges();
@@ -107,6 +109,11 @@ public:
void applyBindings(QObject *obj, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
};
+template<>
+inline QQmlCustomParser *qmlCreateCustomParser<QQuickPropertyChanges>()
+{
+ return new QQuickPropertyChangesParser;
+}
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp
index 5d227b4613..8e135b4624 100644
--- a/src/quick/util/qquickshortcut.cpp
+++ b/src/quick/util/qquickshortcut.cpp
@@ -80,16 +80,12 @@
/*! \qmlsignal QtQuick::Shortcut::activated()
This signal is emitted when the shortcut is activated.
-
- The corresponding handler is \c onActivated.
*/
/*! \qmlsignal QtQuick::Shortcut::activatedAmbiguously()
This signal is emitted when the shortcut is activated ambigously,
meaning that it matches the start of more than one shortcut.
-
- The corresponding handler is \c onActivatedAmbiguously.
*/
static bool qQuickShortcutContextMatcher(QObject *obj, Qt::ShortcutContext context)
@@ -130,7 +126,7 @@ QT_BEGIN_NAMESPACE
static QKeySequence valueToKeySequence(const QVariant &value)
{
- if (value.type() == QVariant::Int)
+ if (value.userType() == QMetaType::Int)
return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
return QKeySequence::fromString(value.toString());
}
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index 712cca7696..0e66a38e75 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qvariant.h>
#include <QtGui/qkeysequence.h>
#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -72,6 +73,8 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
+ QML_NAMED_ELEMENT(Shortcut)
+ QML_ADDED_IN_MINOR_VERSION(5)
public:
explicit QQuickShortcut(QObject *parent = nullptr);
diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp
index bae57172d1..254b1af0a2 100644
--- a/src/quick/util/qquicksmoothedanimation.cpp
+++ b/src/quick/util/qquicksmoothedanimation.cpp
@@ -313,7 +313,7 @@ void QSmoothedAnimation::init()
void QSmoothedAnimation::debugAnimation(QDebug d) const
{
- d << "SmoothedAnimationJob(" << hex << (const void *) this << dec << ")" << "duration:" << userDuration
+ d << "SmoothedAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << userDuration
<< "velocity:" << velocity << "target:" << target.object() << "property:" << target.name()
<< "to:" << to << "current velocity:" << trackVelocity;
}
diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h
index 7bceba387c..d7e637446d 100644
--- a/src/quick/util/qquicksmoothedanimation_p.h
+++ b/src/quick/util/qquicksmoothedanimation_p.h
@@ -68,6 +68,7 @@ class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation
Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged)
Q_PROPERTY(ReversingMode reversingMode READ reversingMode WRITE setReversingMode NOTIFY reversingModeChanged)
Q_PROPERTY(qreal maximumEasingTime READ maximumEasingTime WRITE setMaximumEasingTime NOTIFY maximumEasingTimeChanged)
+ QML_NAMED_ELEMENT(SmoothedAnimation)
public:
enum ReversingMode { Eased, Immediate, Sync };
diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp
index 9012d20f9a..6f03d24750 100644
--- a/src/quick/util/qquickspringanimation.cpp
+++ b/src/quick/util/qquickspringanimation.cpp
@@ -319,7 +319,7 @@ void QSpringAnimation::updateState(QAbstractAnimationJob::State newState, QAbstr
void QSpringAnimation::debugAnimation(QDebug d) const
{
- d << "SpringAnimationJob(" << hex << (const void *) this << dec << ")" << "velocity:" << maxVelocity
+ d << "SpringAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "velocity:" << maxVelocity
<< "spring:" << spring << "damping:" << damping << "epsilon:" << epsilon << "modulus:" << modulus
<< "mass:" << mass << "target:" << target.object() << "property:" << target.name()
<< "to:" << to << "current velocity:" << velocity;
diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h
index 2014a4311a..771b746622 100644
--- a/src/quick/util/qquickspringanimation_p.h
+++ b/src/quick/util/qquickspringanimation_p.h
@@ -71,6 +71,7 @@ class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation
Q_PROPERTY(qreal epsilon READ epsilon WRITE setEpsilon)
Q_PROPERTY(qreal modulus READ modulus WRITE setModulus NOTIFY modulusChanged)
Q_PROPERTY(qreal mass READ mass WRITE setMass NOTIFY massChanged)
+ QML_NAMED_ELEMENT(SpringAnimation)
public:
QQuickSpringAnimation(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index c106528f45..71ab1f4d62 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -267,9 +267,13 @@ void QQuickState::setExtends(const QString &extends)
QQmlListProperty<QQuickStateOperation> QQuickState::changes()
{
Q_D(QQuickState);
- return QQmlListProperty<QQuickStateOperation>(this, &d->operations, QQuickStatePrivate::operations_append,
- QQuickStatePrivate::operations_count, QQuickStatePrivate::operations_at,
- QQuickStatePrivate::operations_clear);
+ return QQmlListProperty<QQuickStateOperation>(this, &d->operations,
+ QQuickStatePrivate::operations_append,
+ QQuickStatePrivate::operations_count,
+ QQuickStatePrivate::operations_at,
+ QQuickStatePrivate::operations_clear,
+ QQuickStatePrivate::operations_replace,
+ QQuickStatePrivate::operations_removeLast);
}
int QQuickState::operationCount() const
diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h
index 576ba9834c..af49bb1c2f 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -125,6 +125,7 @@ class QQuickStateOperationPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickStateOperation : public QObject
{
Q_OBJECT
+ QML_ANONYMOUS
public:
QQuickStateOperation(QObject *parent = nullptr)
: QObject(parent) {}
@@ -157,6 +158,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickState : public QObject
Q_PROPERTY(QQmlListProperty<QQuickStateOperation> changes READ changes)
Q_CLASSINFO("DefaultProperty", "changes")
Q_CLASSINFO("DeferredPropertyNames", "changes")
+ QML_NAMED_ELEMENT(State)
public:
QQuickState(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index 2fa5321165..ae4ed291b5 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -244,6 +244,23 @@ public:
QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
return list->at(index);
}
+ static void operations_replace(QQmlListProperty<QQuickStateOperation> *prop, int index,
+ QQuickStateOperation *op) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ auto &guard = list->at(index);
+ if (guard.object() == op) {
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ } else {
+ list->at(index)->setState(nullptr);
+ op->setState(qobject_cast<QQuickState*>(prop->object));
+ list->replace(index, OperationGuard(op, list));
+ }
+ }
+ static void operations_removeLast(QQmlListProperty<QQuickStateOperation> *prop) {
+ QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data);
+ list->last()->setState(nullptr);
+ list->removeLast();
+ }
QQuickTransitionManager transitionManager;
diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h
index ff509a7cf5..931baaca4e 100644
--- a/src/quick/util/qquickstatechangescript_p.h
+++ b/src/quick/util/qquickstatechangescript_p.h
@@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, p
Q_PROPERTY(QQmlScriptString script READ script WRITE setScript)
Q_PROPERTY(QString name READ name WRITE setName)
+ QML_NAMED_ELEMENT(StateChangeScript)
public:
QQuickStateChangeScript(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 46e7d62fc1..2109aafc10 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -70,6 +70,8 @@ public:
static int count_state(QQmlListProperty<QQuickState> *list);
static QQuickState *at_state(QQmlListProperty<QQuickState> *list, int index);
static void clear_states(QQmlListProperty<QQuickState> *list);
+ static void replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state);
+ static void removeLast_states(QQmlListProperty<QQuickState> *list);
static void append_transition(QQmlListProperty<QQuickTransition> *list, QQuickTransition *state);
static int count_transitions(QQmlListProperty<QQuickTransition> *list);
@@ -163,10 +165,13 @@ QList<QQuickState *> QQuickStateGroup::states() const
QQmlListProperty<QQuickState> QQuickStateGroup::statesProperty()
{
Q_D(QQuickStateGroup);
- return QQmlListProperty<QQuickState>(this, &d->states, &QQuickStateGroupPrivate::append_state,
- &QQuickStateGroupPrivate::count_state,
- &QQuickStateGroupPrivate::at_state,
- &QQuickStateGroupPrivate::clear_states);
+ return QQmlListProperty<QQuickState>(this, &d->states,
+ &QQuickStateGroupPrivate::append_state,
+ &QQuickStateGroupPrivate::count_state,
+ &QQuickStateGroupPrivate::at_state,
+ &QQuickStateGroupPrivate::clear_states,
+ &QQuickStateGroupPrivate::replace_states,
+ &QQuickStateGroupPrivate::removeLast_states);
}
void QQuickStateGroupPrivate::append_state(QQmlListProperty<QQuickState> *list, QQuickState *state)
@@ -201,6 +206,29 @@ void QQuickStateGroupPrivate::clear_states(QQmlListProperty<QQuickState> *list)
_this->d_func()->states.clear();
}
+void QQuickStateGroupPrivate::replace_states(QQmlListProperty<QQuickState> *list, int index, QQuickState *state)
+{
+ auto *self = qobject_cast<QQuickStateGroup *>(list->object);
+ auto *d = self->d_func();
+ auto *oldState = d->states.at(index);
+ if (oldState != state) {
+ oldState->setStateGroup(nullptr);
+ state->setStateGroup(self);
+ d->states.replace(index, state);
+ if (d->currentState == oldState->name())
+ d->setCurrentStateInternal(state->name(), true);
+ }
+}
+
+void QQuickStateGroupPrivate::removeLast_states(QQmlListProperty<QQuickState> *list)
+{
+ auto *d = qobject_cast<QQuickStateGroup *>(list->object)->d_func();
+ if (d->currentState == d->states.last()->name())
+ d->setCurrentStateInternal(d->states.length() > 1 ? d->states.first()->name() : QString(), true);
+ d->states.last()->setStateGroup(nullptr);
+ d->states.removeLast();
+}
+
/*!
\qmlproperty list<Transition> QtQuick::StateGroup::transitions
This property holds a list of transitions defined by the state group.
diff --git a/src/quick/util/qquickstategroup_p.h b/src/quick/util/qquickstategroup_p.h
index 7235066d99..11a0c5f442 100644
--- a/src/quick/util/qquickstategroup_p.h
+++ b/src/quick/util/qquickstategroup_p.h
@@ -65,6 +65,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickStateGroup : public QObject, public QQmlParse
Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
Q_PROPERTY(QQmlListProperty<QQuickState> states READ statesProperty DESIGNABLE false)
Q_PROPERTY(QQmlListProperty<QQuickTransition> transitions READ transitionsProperty DESIGNABLE false)
+ QML_NAMED_ELEMENT(StateGroup)
public:
QQuickStateGroup(QObject * = nullptr);
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 7d545cdb2f..660852ba83 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -89,8 +89,8 @@ public:
QQmlContext *context,
bool preloadImages,
bool *fontSizeModified)
- : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(true), nbImages(0), updateImagePositions(false)
- , preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
+ : text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl),
+ fontSizeModified(fontSizeModified), context(context), preloadImages(preloadImages)
{
}
@@ -122,15 +122,15 @@ public:
QFont baseFont;
QStack<List> listStack;
QUrl baseUrl;
- bool hasNewLine;
- int nbImages;
- bool updateImagePositions;
- bool preFormat;
- bool prependSpace;
- bool hasSpace;
- bool preloadImages;
bool *fontSizeModified;
QQmlContext *context;
+ int nbImages = 0;
+ bool hasNewLine = true;
+ bool updateImagePositions = false;
+ bool preFormat = false;
+ bool prependSpace = false;
+ bool hasSpace = true;
+ bool preloadImages;
static const QChar lessThan;
static const QChar greaterThan;
@@ -706,7 +706,7 @@ void QQuickStyledTextPrivate::parseImageAttributes(const QChar *&ch, const QStri
// to avoid a relayout later on.
QUrl url = baseUrl.resolved(image->url);
if (url.isLocalFile()) {
- image->pix = new QQuickPixmap(context->engine(), url, image->size);
+ image->pix = new QQuickPixmap(context->engine(), url, QRect(), image->size);
if (image->pix && image->pix->isReady()) {
image->size = image->pix->implicitSize();
} else {
diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h
index 9a3a520ed1..c6d9fc2604 100644
--- a/src/quick/util/qquicksystempalette_p.h
+++ b/src/quick/util/qquicksystempalette_p.h
@@ -79,6 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject
Q_PROPERTY(QColor shadow READ shadow NOTIFY paletteChanged)
Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged)
Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged)
+ QML_NAMED_ELEMENT(SystemPalette)
public:
QQuickSystemPalette(QObject *parent=nullptr);
diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h
index 4fb6741996..a1d64e3d0a 100644
--- a/src/quick/util/qquicktextmetrics_p.h
+++ b/src/quick/util/qquicktextmetrics_p.h
@@ -74,6 +74,8 @@ class Q_AUTOTEST_EXPORT QQuickTextMetrics : public QObject
Q_PROPERTY(QString elidedText READ elidedText NOTIFY metricsChanged FINAL)
Q_PROPERTY(Qt::TextElideMode elide READ elide WRITE setElide NOTIFY elideChanged FINAL)
Q_PROPERTY(qreal elideWidth READ elideWidth WRITE setElideWidth NOTIFY elideWidthChanged FINAL)
+ QML_NAMED_ELEMENT(TextMetrics)
+ QML_ADDED_IN_MINOR_VERSION(4)
public:
explicit QQuickTextMetrics(QObject *parent = 0);
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index ac9f75979e..7ec7c827eb 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -723,7 +723,7 @@ void QQuickTimeLine::updateCurrentTime(int v)
void QQuickTimeLine::debugAnimation(QDebug d) const
{
- d << "QuickTimeLine(" << hex << (const void *) this << dec << ")";
+ d << "QuickTimeLine(" << Qt::hex << (const void *) this << Qt::dec << ")";
}
bool operator<(const QPair<int, Update> &lhs,
diff --git a/src/quick/util/qquicktimeline_p_p.h b/src/quick/util/qquicktimeline_p_p.h
index abb5369b7b..fc5bd15ed1 100644
--- a/src/quick/util/qquicktimeline_p_p.h
+++ b/src/quick/util/qquicktimeline_p_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/QObject>
+#include <private/qtquickglobal_p.h>
#include "private/qabstractanimationjob_p.h"
QT_BEGIN_NAMESPACE
@@ -61,7 +62,7 @@ class QQuickTimeLineValue;
class QQuickTimeLineCallback;
struct QQuickTimeLinePrivate;
class QQuickTimeLineObject;
-class Q_AUTOTEST_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
+class Q_QUICK_PRIVATE_EXPORT QQuickTimeLine : public QObject, QAbstractAnimationJob
{
Q_OBJECT
public:
diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h
index c7d06b8832..6e45143126 100644
--- a/src/quick/util/qquicktransition_p.h
+++ b/src/quick/util/qquicktransition_p.h
@@ -103,6 +103,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTransition : public QObject
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_CLASSINFO("DefaultProperty", "animations")
Q_CLASSINFO("DeferredPropertyNames", "animations")
+ QML_NAMED_ELEMENT(Transition)
public:
QQuickTransition(QObject *parent=nullptr);
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
deleted file mode 100644
index 93b6599506..0000000000
--- a/src/quick/util/qquickutilmodule.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickutilmodule_p.h"
-#include "qquickanimation_p.h"
-#include "qquickanimation_p_p.h"
-#include "qquickbehavior_p.h"
-#include "qquicksmoothedanimation_p.h"
-#include "qquickfontloader_p.h"
-#include "qquickfontmetrics_p.h"
-#include "qquickpropertychanges_p.h"
-#include "qquickspringanimation_p.h"
-#include "qquickstategroup_p.h"
-#include "qquickstatechangescript_p.h"
-#include "qquickstate_p.h"
-#include "qquickstate_p_p.h"
-#include "qquicksystempalette_p.h"
-#include "qquicktextmetrics_p.h"
-#include "qquicktransition_p.h"
-#include "qquickanimator_p.h"
-#if QT_CONFIG(shortcut)
-#include "qquickshortcut_p.h"
-#endif
-#include "qquickvalidator_p.h"
-#include <qqmlinfo.h>
-#include <private/qqmltypenotavailable_p.h>
-#include <private/qquickanimationcontroller_p.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/QInputMethod>
-#include <QtGui/QKeySequence>
-
-#if QT_CONFIG(shortcut)
-Q_DECLARE_METATYPE(QKeySequence::StandardKey)
-#endif
-
-void QQuickUtilModule::defineModule()
-{
-#if QT_CONFIG(im)
- qmlRegisterUncreatableType<QInputMethod>("QtQuick",2,0,"InputMethod",
- QInputMethod::tr("InputMethod is an abstract class"));
-#endif
- qmlRegisterUncreatableType<QQuickAbstractAnimation>("QtQuick",2,0,"Animation",QQuickAbstractAnimation::tr("Animation is an abstract class"));
-
- qmlRegisterType<QQuickBehavior>("QtQuick",2,0,"Behavior");
- qmlRegisterType<QQuickColorAnimation>("QtQuick",2,0,"ColorAnimation");
- qmlRegisterType<QQuickSmoothedAnimation>("QtQuick",2,0,"SmoothedAnimation");
- qmlRegisterType<QQuickFontLoader>("QtQuick",2,0,"FontLoader");
- qmlRegisterType<QQuickNumberAnimation>("QtQuick",2,0,"NumberAnimation");
- qmlRegisterType<QQuickParallelAnimation>("QtQuick",2,0,"ParallelAnimation");
- qmlRegisterType<QQuickPauseAnimation>("QtQuick",2,0,"PauseAnimation");
- qmlRegisterType<QQuickPropertyAction>("QtQuick",2,0,"PropertyAction");
- qmlRegisterType<QQuickPropertyAnimation>("QtQuick",2,0,"PropertyAnimation");
- qmlRegisterType<QQuickRotationAnimation>("QtQuick",2,0,"RotationAnimation");
- qmlRegisterType<QQuickScriptAction>("QtQuick",2,0,"ScriptAction");
- qmlRegisterType<QQuickSequentialAnimation>("QtQuick",2,0,"SequentialAnimation");
- qmlRegisterType<QQuickSpringAnimation>("QtQuick",2,0,"SpringAnimation");
- qmlRegisterType<QQuickAnimationController>("QtQuick",2,0,"AnimationController");
- qmlRegisterType<QQuickStateChangeScript>("QtQuick",2,0,"StateChangeScript");
- qmlRegisterType<QQuickStateGroup>("QtQuick",2,0,"StateGroup");
- qmlRegisterType<QQuickState>("QtQuick",2,0,"State");
- qmlRegisterType<QQuickSystemPalette>("QtQuick",2,0,"SystemPalette");
- qmlRegisterType<QQuickTransition>("QtQuick",2,0,"Transition");
- qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
-
-#if QT_CONFIG(validator)
- qmlRegisterAnonymousType<QValidator>("QtQuick", 2);
- qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
- qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
- qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
-#if QT_CONFIG(regularexpression)
- qmlRegisterType<QRegularExpressionValidator>("QtQuick", 2, 14, "RegularExpressionValidator");
-#endif
-#endif
-
- qmlRegisterUncreatableType<QQuickAnimator>("QtQuick", 2, 2, "Animator", QQuickAbstractAnimation::tr("Animator is an abstract class"));
- qmlRegisterType<QQuickXAnimator>("QtQuick", 2, 2, "XAnimator");
- qmlRegisterType<QQuickYAnimator>("QtQuick", 2, 2, "YAnimator");
- qmlRegisterType<QQuickScaleAnimator>("QtQuick", 2, 2, "ScaleAnimator");
- qmlRegisterType<QQuickRotationAnimator>("QtQuick", 2, 2, "RotationAnimator");
- qmlRegisterType<QQuickOpacityAnimator>("QtQuick", 2, 2, "OpacityAnimator");
-#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
- qmlRegisterType<QQuickUniformAnimator>("QtQuick", 2, 2, "UniformAnimator");
-#endif
- qmlRegisterAnonymousType<QQuickStateOperation>("QtQuick", 2);
-
- qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser);
-
-#if QT_CONFIG(shortcut)
- qRegisterMetaType<QKeySequence::StandardKey>();
- qmlRegisterUncreatableType<QKeySequence, 2>("QtQuick", 2, 2, "StandardKey", QStringLiteral("Cannot create an instance of StandardKey."));
-#endif
-
- qmlRegisterType<QQuickFontMetrics>("QtQuick", 2, 4, "FontMetrics");
- qmlRegisterType<QQuickTextMetrics>("QtQuick", 2, 4, "TextMetrics");
-
-#if QT_CONFIG(shortcut)
- qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
- qmlRegisterType<QQuickShortcut,6>("QtQuick", 2, 6, "Shortcut");
-
- qmlRegisterType<QQuickShortcut,9>("QtQuick", 2, 9, "Shortcut");
-#endif
-
- qmlRegisterUncreatableType<QQuickAbstractAnimation, 12>("QtQuick", 2, 12, "Animation",
- QQuickAbstractAnimation::tr("Animation is an abstract class"));
- // 5.13
- qmlRegisterType<QQuickBehavior, 13>("QtQuick", 2, 13, "Behavior");
-}
diff --git a/src/quick/util/qquickutilmodule_p.h b/src/quick/util/qquickutilmodule_p.h
deleted file mode 100644
index b03eeddede..0000000000
--- a/src/quick/util/qquickutilmodule_p.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKUTILMODULE_H
-#define QQUICKUTILMODULE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickUtilModule
-{
-public:
- static void defineModule();
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKUTILMODULE_H
diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h
index 9212efa044..a0dc2cd5ba 100644
--- a/src/quick/util/qquickvalidator_p.h
+++ b/src/quick/util/qquickvalidator_p.h
@@ -61,6 +61,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
{
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+ QML_NAMED_ELEMENT(IntValidator)
public:
QQuickIntValidator(QObject *parent = nullptr);
@@ -76,6 +77,7 @@ class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
{
Q_OBJECT
Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+ QML_NAMED_ELEMENT(DoubleValidator)
public:
QQuickDoubleValidator(QObject *parent = nullptr);
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 0af29aed1c..395385fa0d 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -41,6 +41,7 @@
#include <qtquickglobal.h>
#include <private/qqmlvaluetype_p.h>
+#include <private/qcolorspace_p.h>
#include <private/qfont_p.h>
@@ -50,7 +51,6 @@ namespace QQuickValueTypes {
void registerValueTypes()
{
QQmlValueTypeFactory::registerValueTypes("QtQuick", 2, 0);
- qmlRegisterValueTypeEnums<QQuickFontValueType>("QtQuick", 2, 0, "Font");
}
}
@@ -785,6 +785,47 @@ void QQuickFontValueType::setPreferShaping(bool enable)
v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() | QFont::PreferNoShaping));
}
+QQuickColorSpaceValueType::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
+{
+ if (const auto *p = QColorSpacePrivate::get(v))
+ return (QQuickColorSpaceValueType::NamedColorSpace)p->namedColorSpace;
+ return QQuickColorSpaceValueType::Unknown;
+}
+void QQuickColorSpaceValueType::setNamedColorSpace(QQuickColorSpaceValueType::NamedColorSpace namedColorSpace)
+{
+ v = { (QColorSpace::NamedColorSpace)namedColorSpace };
+}
+
+QQuickColorSpaceValueType::Primaries QQuickColorSpaceValueType::primaries() const noexcept
+{
+ return (QQuickColorSpaceValueType::Primaries)v.primaries();
+}
+
+void QQuickColorSpaceValueType::setPrimaries(QQuickColorSpaceValueType::Primaries primariesId)
+{
+ v.setPrimaries((QColorSpace::Primaries)primariesId);
+}
+
+QQuickColorSpaceValueType::TransferFunction QQuickColorSpaceValueType::transferFunction() const noexcept
+{
+ return (QQuickColorSpaceValueType::TransferFunction)v.transferFunction();
+}
+
+void QQuickColorSpaceValueType::setTransferFunction(QQuickColorSpaceValueType::TransferFunction transferFunction)
+{
+ v.setTransferFunction((QColorSpace::TransferFunction)transferFunction, v.gamma());
+}
+
+float QQuickColorSpaceValueType::gamma() const noexcept
+{
+ return v.gamma();
+}
+
+void QQuickColorSpaceValueType::setGamma(float gamma)
+{
+ v.setTransferFunction(v.transferFunction(), gamma);
+}
+
QT_END_NAMESPACE
#include "moc_qquickvaluetypes_p.cpp"
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 4305006f91..638fdd2773 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -56,6 +56,7 @@
#include <private/qqmlvaluetype_p.h>
#include <QtGui/QColor>
+#include <QtGui/QColorSpace>
#include <QtGui/QVector2D>
#include <QtGui/QVector3D>
#include <QtGui/QVector4D>
@@ -328,6 +329,9 @@ class QQuickFontValueType
Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
+ QML_NAMED_ELEMENT(Font)
+ QML_UNCREATABLE("Element is not creatable.")
+
public:
enum FontWeight { Thin = QFont::Thin,
ExtraLight = QFont::ExtraLight,
@@ -405,6 +409,58 @@ public:
void setPreferShaping(bool b);
};
+class QQuickColorSpaceValueType
+{
+ QColorSpace v;
+ Q_GADGET
+
+ Q_PROPERTY(NamedColorSpace namedColorSpace READ namedColorSpace WRITE setNamedColorSpace FINAL)
+ Q_PROPERTY(Primaries primaries READ primaries WRITE setPrimaries FINAL)
+ Q_PROPERTY(TransferFunction transferFunction READ transferFunction WRITE setTransferFunction FINAL)
+ Q_PROPERTY(float gamma READ gamma WRITE setGamma FINAL)
+
+ QML_NAMED_ELEMENT(ColorSpace)
+ QML_ADDED_IN_MINOR_VERSION(15)
+ Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
+
+public:
+ enum NamedColorSpace {
+ Unknown = 0,
+ SRgb,
+ SRgbLinear,
+ AdobeRgb,
+ DisplayP3,
+ ProPhotoRgb
+ };
+ Q_ENUM(NamedColorSpace)
+
+ enum class Primaries {
+ Custom = 0,
+ SRgb,
+ AdobeRgb,
+ DciP3D65,
+ ProPhotoRgb
+ };
+ Q_ENUM(Primaries)
+ enum class TransferFunction {
+ Custom = 0,
+ Linear,
+ Gamma,
+ SRgb,
+ ProPhotoRgb
+ };
+ Q_ENUM(TransferFunction)
+
+ NamedColorSpace namedColorSpace() const noexcept;
+ void setNamedColorSpace(NamedColorSpace namedColorSpace);
+ Primaries primaries() const noexcept;
+ void setPrimaries(Primaries primariesId);
+ TransferFunction transferFunction() const noexcept;
+ void setTransferFunction(TransferFunction transferFunction);
+ float gamma() const noexcept;
+ void setGamma(float gamma);
+};
+
QT_END_NAMESPACE
#endif // QQUICKVALUETYPES_P_H
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 63d995e34c..f61a967959 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -1,6 +1,5 @@
SOURCES += \
$$PWD/qquickapplication.cpp\
- $$PWD/qquickutilmodule.cpp\
$$PWD/qquickanimation.cpp \
$$PWD/qquicksystempalette.cpp \
$$PWD/qquickspringanimation.cpp \
@@ -15,7 +14,6 @@ SOURCES += \
$$PWD/qquicktimeline.cpp \
$$PWD/qquickpixmapcache.cpp \
$$PWD/qquickbehavior.cpp \
- $$PWD/qquickboundaryrule.cpp \
$$PWD/qquickfontloader.cpp \
$$PWD/qquickstyledtext.cpp \
$$PWD/qquickimageprovider.cpp \
@@ -33,7 +31,6 @@ qtConfig(qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
- $$PWD/qquickutilmodule_p.h\
$$PWD/qquickanimation_p.h \
$$PWD/qquickanimation_p_p.h \
$$PWD/qquicksystempalette_p.h \
@@ -51,7 +48,6 @@ HEADERS += \
$$PWD/qquicktimeline_p_p.h \
$$PWD/qquickpixmapcache_p.h \
$$PWD/qquickbehavior_p.h \
- $$PWD/qquickboundaryrule_p.h \
$$PWD/qquickfontloader_p.h \
$$PWD/qquickstyledtext_p.h \
$$PWD/qquickimageprovider.h \
@@ -65,7 +61,8 @@ HEADERS += \
$$PWD/qquickprofiler_p.h \
$$PWD/qquickfontmetrics_p.h \
$$PWD/qquicktextmetrics_p.h \
- $$PWD/qquickvalidator_p.h
+ $$PWD/qquickvalidator_p.h \
+ $$PWD/qquickforeignutils_p.h
qtConfig(shortcut) {
SOURCES += \