aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/controls/Drawer.qml2
-rw-r--r--src/imports/controls/controls.pro3
-rw-r--r--src/imports/controls/doc/doc.pri7
-rw-r--r--src/imports/controls/doc/images/qtquickcontrols2-control.pngbin34588 -> 22234 bytes
-rw-r--r--src/imports/controls/doc/images/qtquickcontrols2-control.svg392
-rw-r--r--src/imports/controls/material/Drawer.qml2
-rw-r--r--src/imports/controls/universal/Drawer.qml2
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp6
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h1
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp90
-rw-r--r--src/quicktemplates2/qquickbutton.cpp17
-rw-r--r--src/quicktemplates2/qquickcheckbox.cpp6
-rw-r--r--src/quicktemplates2/qquickcheckdelegate.cpp13
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp6
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp130
-rw-r--r--src/quicktemplates2/qquickdial.cpp17
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp101
-rw-r--r--src/quicktemplates2/qquickdrawer_p.h2
-rw-r--r--src/quicktemplates2/qquickdrawer_p_p.h3
-rw-r--r--src/quicktemplates2/qquickframe.cpp4
-rw-r--r--src/quicktemplates2/qquickgroupbox.cpp11
-rw-r--r--src/quicktemplates2/qquickmenu.cpp42
-rw-r--r--src/quicktemplates2/qquickmenuitem.cpp35
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp20
-rw-r--r--src/quicktemplates2/qquickoverlay_p_p.h1
-rw-r--r--src/quicktemplates2/qquickpage.cpp47
-rw-r--r--src/quicktemplates2/qquickpopup.cpp116
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h7
-rw-r--r--src/quicktemplates2/qquickswitch.cpp147
-rw-r--r--src/quicktemplates2/qquickswitch_p.h8
-rw-r--r--src/quicktemplates2/qquickswitchdelegate.cpp65
-rw-r--r--src/quicktemplates2/qquickswitchdelegate_p.h7
-rw-r--r--tests/auto/applicationwindow/tst_applicationwindow.cpp4
-rw-r--r--tests/auto/controls/data/tst_control.qml6
-rw-r--r--tests/auto/controls/data/tst_drawer.qml1
-rw-r--r--tests/auto/controls/data/tst_popup.qml90
-rw-r--r--tests/auto/controls/data/tst_switch.qml127
-rw-r--r--tests/auto/controls/data/tst_switchdelegate.qml216
-rw-r--r--tests/auto/drawer/BLACKLIST2
-rw-r--r--tests/auto/drawer/data/header.qml57
-rw-r--r--tests/auto/drawer/data/reposition.qml58
-rw-r--r--tests/auto/drawer/tst_drawer.cpp137
42 files changed, 1737 insertions, 271 deletions
diff --git a/src/imports/controls/Drawer.qml b/src/imports/controls/Drawer.qml
index 4b4ea8c0..eca9b949 100644
--- a/src/imports/controls/Drawer.qml
+++ b/src/imports/controls/Drawer.qml
@@ -42,6 +42,8 @@ import QtQuick.Templates 2.1 as T
T.Drawer {
id: control
+ parent: T.ApplicationWindow.overlay
+
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
diff --git a/src/imports/controls/controls.pro b/src/imports/controls/controls.pro
index 999245c8..9e8a3c27 100644
--- a/src/imports/controls/controls.pro
+++ b/src/imports/controls/controls.pro
@@ -7,8 +7,6 @@ QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
-QMAKE_DOCS = $$PWD/doc/qtquickcontrols2.qdocconf
-
OTHER_FILES += \
qmldir
@@ -20,6 +18,7 @@ RESOURCES += \
include(controls.pri)
!static: include(designer/designer.pri)
+include(doc/doc.pri)
qtquickcompiler {
qmlfiles.prefix = /qt-project.org/imports/QtQuick/Controls.2
diff --git a/src/imports/controls/doc/doc.pri b/src/imports/controls/doc/doc.pri
new file mode 100644
index 00000000..8eaccbed
--- /dev/null
+++ b/src/imports/controls/doc/doc.pri
@@ -0,0 +1,7 @@
+QMAKE_DOCS = $$PWD/qtquickcontrols2.qdocconf
+
+OTHER_FILES += \
+ $$files($$PWD/snippets/*.qml) \
+ $$files($$PWD/src/*.qdoc) \
+ $$files($$PWD/src/calendar/*.qdoc) \
+ $$files($$PWD/src/templates/*.qdoc)
diff --git a/src/imports/controls/doc/images/qtquickcontrols2-control.png b/src/imports/controls/doc/images/qtquickcontrols2-control.png
index 28fcb742..26babc9f 100644
--- a/src/imports/controls/doc/images/qtquickcontrols2-control.png
+++ b/src/imports/controls/doc/images/qtquickcontrols2-control.png
Binary files differ
diff --git a/src/imports/controls/doc/images/qtquickcontrols2-control.svg b/src/imports/controls/doc/images/qtquickcontrols2-control.svg
new file mode 100644
index 00000000..b0ffae7c
--- /dev/null
+++ b/src/imports/controls/doc/images/qtquickcontrols2-control.svg
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="679.31317"
+ height="357.84125"
+ viewBox="0 0 679.31314 357.84124"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="qtquickcontrols2-control.svg"
+ inkscape:export-filename="/home/mitch/Dropbox/qtquickcontrols2-control.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4327"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(0.8,0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInL"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4318"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(-0.8,-0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4191"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4212"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6,-0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInL-2"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4318-4"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(-0.8,-0.8)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL-9"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4327-1"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(0.8,0.8)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInL-3"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4318-9"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(-0.8,-0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL-0"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4327-5"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(0.8,0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInL-9"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4318-2"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(-0.8,-0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL-1"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4327-2"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="scale(0.8,0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="370.99138"
+ inkscape:cy="234.56612"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="3742"
+ inkscape:window-height="2124"
+ inkscape:window-x="98"
+ inkscape:window-y="36"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(91.482322,-255.11685)">
+ <rect
+ style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4136"
+ width="564.41473"
+ height="248.82799"
+ x="-30.289024"
+ y="321.69858" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138"
+ style="font-style:normal;font-weight:normal;font-size:15.41801071px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(1.1690183,0,0,1.1690183,19.800223,-141.31953)"><flowRegion
+ id="flowRegion4140"><rect
+ id="rect4142"
+ width="129.78784"
+ height="31.668232"
+ x="-34.519978"
+ y="400.22751"
+ style="font-size:15.41801071px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara4144"
+ style="font-size:20.55734825px;fill:#000000">Background</flowPara><flowPara
+ id="flowPara4146" /></flowRoot> <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:27.60000038;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.58381503"
+ id="rect4148"
+ width="464.22452"
+ height="165.94499"
+ x="18.895706"
+ y="364.74274" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6"
+ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,144.03104,146.23557)"><flowRegion
+ id="flowRegion4140-6"><rect
+ id="rect4142-6"
+ width="334.36047"
+ height="80.812172"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:40px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara4146-6">Content item</flowPara></flowRoot> <path
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.04880464;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL);marker-end:url(#TriangleOutL)"
+ d="m 27.018805,516.90108 0,-133.62042"
+ id="path4179"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.93839902;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2);marker-end:url(#TriangleOutL-9)"
+ d="m 26.776662,538.68728 451.028788,0"
+ id="path4179-7"
+ inkscape:connector-curvature="0" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2"
+ style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,10.003309,144.31674)"><flowRegion
+ id="flowRegion4140-6-6"><rect
+ id="rect4142-6-1"
+ width="117.17769"
+ height="101.01524"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:20px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara9732"
+ style="font-size:17.5px;fill:#000000">Available height</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2-7"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,10.811464,253.07573)"><flowRegion
+ id="flowRegion4140-6-6-4"><rect
+ id="rect4142-6-1-4"
+ width="252.53812"
+ height="61.619293"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ style="font-size:17.5px;fill:#000000"
+ id="flowPara10048">Available width</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-1"
+ style="font-style:normal;font-weight:normal;font-size:25px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,210.99354,300.96896)"><flowRegion
+ id="flowRegion4140-6-9"><rect
+ id="rect4142-6-0"
+ width="270.72089"
+ height="68.690361"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:25px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara4146-6-2"
+ style="font-size:17.5px">Width</flowPara></flowRoot> <path
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.90119678;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-3);marker-end:url(#TriangleOutL-0)"
+ d="m -26.522148,583.27143 557.292688,0"
+ id="path4179-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.9011969;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9);marker-end:url(#TriangleOutL-1)"
+ d="m -43.461661,566.30584 0,-239.7552"
+ id="path4179-9"
+ inkscape:connector-curvature="0" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-1-7"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,-112.00353,150.83655)"><flowRegion
+ id="flowRegion4140-6-9-7"><rect
+ id="rect4142-6-0-5"
+ width="270.72089"
+ height="68.690361"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara4146-6-2-9"
+ style="font-size:17.5px;fill:#000000">Height</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-3"
+ style="font-style:normal;font-weight:normal;font-size:60px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,156.72375,-24.786365)"><flowRegion
+ id="flowRegion4140-6-67"><rect
+ id="rect4142-6-5"
+ width="334.36047"
+ height="80.812172"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:60px;fill:#000000" /></flowRegion><flowPara
+ id="flowPara4146-6-3">Control</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2-7-5"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,186.57489,257.45801)"><flowRegion
+ id="flowRegion4140-6-6-4-6"><rect
+ id="rect4142-6-1-4-2"
+ width="252.53812"
+ height="61.619293"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ style="font-size:17.5px;fill:#000000"
+ id="flowPara10048-9">Bottom padding</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2-7-5-1"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,193.9747,48.798368)"><flowRegion
+ id="flowRegion4140-6-6-4-6-2"><rect
+ id="rect4142-6-1-4-2-7"
+ width="252.53812"
+ height="61.619293"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ style="font-size:17.5px;fill:#000000"
+ id="flowPara10048-9-0">Top padding</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2-7-5-9"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,457.80767,148.11921)"><flowRegion
+ id="flowRegion4140-6-6-4-6-3"><rect
+ id="rect4142-6-1-4-2-6"
+ width="81.109558"
+ height="93.762154"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ style="font-size:17.5px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#000000"
+ id="flowPara4386">Right padding</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot4138-6-2-7-5-9-2"
+ style="font-style:normal;font-weight:normal;font-size:17.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ transform="matrix(0.6007979,0,0,0.6007979,-54.735211,151.06168)"><flowRegion
+ id="flowRegion4140-6-6-4-6-3-5"><rect
+ id="rect4142-6-1-4-2-6-4"
+ width="81.109558"
+ height="93.762154"
+ x="42.426407"
+ y="481.62601"
+ style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara
+ style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#000000"
+ id="flowPara4386-0">Left padding</flowPara></flowRoot> </g>
+</svg>
diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml
index e0b698e2..efb394d1 100644
--- a/src/imports/controls/material/Drawer.qml
+++ b/src/imports/controls/material/Drawer.qml
@@ -42,6 +42,8 @@ import QtQuick.Controls.Material.impl 2.1
T.Drawer {
id: control
+ parent: T.ApplicationWindow.overlay
+
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
diff --git a/src/imports/controls/universal/Drawer.qml b/src/imports/controls/universal/Drawer.qml
index 1ce73f41..c3dece6e 100644
--- a/src/imports/controls/universal/Drawer.qml
+++ b/src/imports/controls/universal/Drawer.qml
@@ -41,6 +41,8 @@ import QtQuick.Controls.Universal 2.1
T.Drawer {
id: control
+ parent: T.ApplicationWindow.overlay
+
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 9c840493..f2442cb7 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -105,7 +105,7 @@ static const int AUTO_REPEAT_INTERVAL = 100;
*/
QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() :
- down(false), explicitDown(false), pressed(false), checked(false), checkable(false),
+ down(false), explicitDown(false), pressed(false), keepPressed(false), checked(false), checkable(false),
autoExclusive(false), autoRepeat(false), wasHeld(false),
holdTimer(0), delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), indicator(nullptr), group(nullptr)
{
@@ -525,7 +525,7 @@ void QQuickAbstractButton::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::mouseMoveEvent(event);
- setPressed(contains(event->pos()));
+ setPressed(d->keepPressed || contains(event->pos()));
if (d->autoRepeat)
d->stopPressRepeat();
@@ -540,7 +540,7 @@ void QQuickAbstractButton::mouseReleaseEvent(QMouseEvent *event)
bool wasPressed = d->pressed;
setPressed(false);
- if (contains(event->pos()))
+ if (d->keepPressed || contains(event->pos()))
nextCheckState();
if (wasPressed) {
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index a7d4d6c2..688ad804 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -82,6 +82,7 @@ public:
bool down;
bool explicitDown;
bool pressed;
+ bool keepPressed;
bool checked;
bool checkable;
bool autoExclusive;
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index 7f466fd7..7fb406c1 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -443,7 +443,7 @@ QQuickItem *QQuickApplicationWindow::contentItem() const
The difference between \l Window::activeFocusItem and ApplicationWindow::activeFocusControl
is that the former may point to a building block of a control, whereas the latter points
to the enclosing control. For example, when SpinBox has focus, activeFocusItem points to
- the editor and acticeFocusControl to the SpinBox itself.
+ the editor and activeFocusControl to the SpinBox itself.
\sa Window::activeFocusItem
*/
@@ -622,47 +622,49 @@ public:
void windowChange(QQuickWindow *wnd);
- QQuickApplicationWindow *window;
+ QQuickWindow *window;
};
void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd)
{
Q_Q(QQuickApplicationWindowAttached);
- if (window && !QQuickApplicationWindowPrivate::get(window))
- window = nullptr; // being deleted (QTBUG-52731)
+ if (window == wnd)
+ return;
- QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd);
- if (window != newWindow) {
- QQuickApplicationWindow *oldWindow = window;
- if (oldWindow) {
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged,
- q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged,
- q, &QQuickApplicationWindowAttached::headerChanged);
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged,
- q, &QQuickApplicationWindowAttached::footerChanged);
- }
- if (newWindow) {
- QObject::connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged,
- q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
- QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged,
- q, &QQuickApplicationWindowAttached::headerChanged);
- QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged,
- q, &QQuickApplicationWindowAttached::footerChanged);
- }
+ QQuickApplicationWindow *oldWindow = qobject_cast<QQuickApplicationWindow *>(window);
+ if (oldWindow && !QQuickApplicationWindowPrivate::get(oldWindow))
+ oldWindow = nullptr; // being deleted (QTBUG-52731)
+
+ if (oldWindow) {
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged,
+ q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged,
+ q, &QQuickApplicationWindowAttached::headerChanged);
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged,
+ q, &QQuickApplicationWindowAttached::footerChanged);
+ }
- window = newWindow;
- emit q->windowChanged();
- emit q->contentItemChanged();
- emit q->overlayChanged();
-
- if ((oldWindow && oldWindow->activeFocusControl()) || (newWindow && newWindow->activeFocusControl()))
- emit q->activeFocusControlChanged();
- if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header()))
- emit q->headerChanged();
- if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer()))
- emit q->footerChanged();
+ QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd);
+ if (newWindow) {
+ QObject::connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged,
+ q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
+ QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged,
+ q, &QQuickApplicationWindowAttached::headerChanged);
+ QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged,
+ q, &QQuickApplicationWindowAttached::footerChanged);
}
+
+ window = wnd;
+ emit q->windowChanged();
+ emit q->contentItemChanged();
+ emit q->overlayChanged();
+
+ if ((oldWindow && oldWindow->activeFocusControl()) || (newWindow && newWindow->activeFocusControl()))
+ emit q->activeFocusControlChanged();
+ if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header()))
+ emit q->headerChanged();
+ if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer()))
+ emit q->footerChanged();
}
QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent)
@@ -698,7 +700,7 @@ QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent
QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window;
+ return qobject_cast<QQuickApplicationWindow *>(d->window);
}
/*!
@@ -711,7 +713,9 @@ QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const
QQuickItem *QQuickApplicationWindowAttached::contentItem() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->contentItem() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->contentItem();
+ return nullptr;
}
/*!
@@ -728,7 +732,9 @@ QQuickItem *QQuickApplicationWindowAttached::contentItem() const
QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->activeFocusControl() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->activeFocusControl();
+ return nullptr;
}
/*!
@@ -742,7 +748,9 @@ QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const
QQuickItem *QQuickApplicationWindowAttached::header() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->header() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->header();
+ return nullptr;
}
/*!
@@ -756,7 +764,9 @@ QQuickItem *QQuickApplicationWindowAttached::header() const
QQuickItem *QQuickApplicationWindowAttached::footer() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->footer() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->footer();
+ return nullptr;
}
/*!
@@ -769,7 +779,7 @@ QQuickItem *QQuickApplicationWindowAttached::footer() const
QQuickOverlay *QQuickApplicationWindowAttached::overlay() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->overlay() : nullptr;
+ return QQuickOverlay::overlay(d->window);
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickbutton.cpp b/src/quicktemplates2/qquickbutton.cpp
index 19310713..591c4316 100644
--- a/src/quicktemplates2/qquickbutton.cpp
+++ b/src/quicktemplates2/qquickbutton.cpp
@@ -110,6 +110,17 @@ QQuickButton::QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent) :
\qmlproperty bool QtQuick.Controls::Button::checkable
This property holds whether the button is checkable.
+
+ A checkable button toggles between checked (on) and unchecked (off) when
+ the user clicks on it or presses the space bar while the button has active
+ focus.
+
+ Setting \l {AbstractButton::}{checked} to \c true forces this property to
+ \c true.
+
+ The default value is \c false.
+
+ \sa CheckBox, Switch
*/
void QQuickButton::checkableChange()
@@ -120,8 +131,10 @@ void QQuickButton::checkableChange()
/*!
\qmlproperty bool QtQuick.Controls::Button::autoRepeat
- This property holds whether the button repeats pressed(), released()
- and clicked() signals while the button is pressed and held down.
+ This property holds whether the button repeats
+ \l {AbstractButton::}{pressed()}, \l {AbstractButton::}{released()}
+ and \l {AbstractButton::}{clicked()} signals while the button is pressed
+ and held down.
The default value is \c false.
*/
diff --git a/src/quicktemplates2/qquickcheckbox.cpp b/src/quicktemplates2/qquickcheckbox.cpp
index 1daf69dc..a777c2b4 100644
--- a/src/quicktemplates2/qquickcheckbox.cpp
+++ b/src/quicktemplates2/qquickcheckbox.cpp
@@ -52,9 +52,11 @@ QT_BEGIN_NAMESPACE
CheckBox presents an option button that can be toggled on (checked) or
off (unchecked). Check boxes are typically used to select one or more
- options from a set of options.
+ options from a set of options. For larger sets of options, such as those
+ in a list, consider using \l CheckDelegate instead.
- The state of the checkbox can be set with the \l {AbstractButton::}{checked} property.
+ CheckBox inherits its API from \l AbstractButton. For instance, the
+ state of the checkbox can be set with the \l {AbstractButton::}{checked} property.
In addition to the checked and unchecked states, there is a third state:
partially checked. The partially checked state can be enabled using the
diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp
index 09be5d60..249aaa95 100644
--- a/src/quicktemplates2/qquickcheckdelegate.cpp
+++ b/src/quicktemplates2/qquickcheckdelegate.cpp
@@ -54,9 +54,14 @@ QT_BEGIN_NAMESPACE
CheckDelegate presents an item delegate that can be toggled on (checked) or
off (unchecked). Check delegates are typically used to select one or more
- options from a set of options.
-
- The state of the check delegate can be set with the
+ options from a set of options in a list. For smaller sets of options, or
+ for options that need to be uniquely identifiable, consider using
+ \l CheckBox instead.
+
+ CheckDelegate inherits its API from \l ItemDelegate, which is inherited
+ from AbstractButton. For instance, you can set \l {AbstractButton::text}{text},
+ and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton
+ API. The state of the check delegate can be set with the
\l {AbstractButton::}{checked} property.
In addition to the checked and unchecked states, there is a third state:
@@ -75,7 +80,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- \sa {Customizing CheckDelegate}, {Delegate Controls}
+ \sa {Customizing CheckDelegate}, {Delegate Controls}, CheckBox
*/
class QQuickCheckDelegatePrivate : public QQuickItemDelegatePrivate
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index 31a92b5d..d9859b7d 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -55,9 +55,11 @@ QT_BEGIN_NAMESPACE
\section2 Using Containers
- Container provides an API to \l {addItem}{add}, \l {insertItem}{insert},
+ Typically, items are statically declared as children of Container, but it
+ is also possible to \l {addItem}{add}, \l {insertItem}{insert},
\l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The
- items in a container can be accessed using \l itemAt() or \l contentChildren.
+ items in a container can be accessed using \l itemAt() or
+ \l contentChildren.
Most containers have the concept of a "current" item. The current item is
specified via the \l currentIndex property, and can be accessed using the
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 642e2e72..518255dd 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -70,8 +70,26 @@ QT_BEGIN_NAMESPACE
events from the window system, and paints a representation of itself on
the screen.
+ \section1 Control Layout
+
+ The following diagram illustrates the layout of a typical control:
+
\image qtquickcontrols2-control.png
+ The \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} of a control
+ are typically based on the implicit sizes of the background and the content
+ item plus any \l {Control::}{padding}. These properties determine how large
+ the control will be when no explicit \l {Item::}{width} or
+ \l {Item::}{height} is specified.
+
+ The \l {Control::}{background} item fills the entire width and height of the
+ control, unless an explicit size has been given for it.
+
+ The geometry of the \l {Control::}{contentItem} is determined by the
+ padding.
+
+ \section1 Event Handling
+
All controls, except non-interactive indicators, do not let clicks and
touches through to items below them. For example, if \l Pane is used as the
\l {ApplicationWindow::}{header} or \l {ApplicationWindow::}{footer} of
@@ -397,6 +415,10 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
Q_D(QQuickControl);
QQuickItem::itemChange(change, value);
switch (change) {
+ case ItemVisibleHasChanged:
+ if (!value.boolValue)
+ setHovered(false);
+ break;
case ItemParentHasChanged:
if (value.item) {
d->resolveFont();
@@ -432,6 +454,22 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
Control propagates explicit font properties from parent to children. If you change a specific
property on a control's font, that property propagates to all of the control's children,
overriding any system defaults for that property.
+
+ \code
+ Page {
+ font.family: "Courier"
+
+ Column {
+ Label {
+ text: qsTr("This will use Courier...")
+ }
+
+ Switch {
+ text: qsTr("... and so will this")
+ }
+ }
+ }
+ \endcode
*/
QFont QQuickControl::font() const
{
@@ -458,9 +496,10 @@ void QQuickControl::resetFont()
\qmlproperty real QtQuick.Controls::Control::availableWidth
\readonly
- This property holds the width available after deducting horizontal padding.
+ This property holds the width available to the \l contentItem after
+ deducting horizontal padding from the \l {Item::}{width} of the control.
- \sa padding, leftPadding, rightPadding
+ \sa {Control Layout}, padding, leftPadding, rightPadding
*/
qreal QQuickControl::availableWidth() const
{
@@ -471,9 +510,10 @@ qreal QQuickControl::availableWidth() const
\qmlproperty real QtQuick.Controls::Control::availableHeight
\readonly
- This property holds the height available after deducting vertical padding.
+ This property holds the height available to the \l contentItem after
+ deducting vertical padding from the \l {Item::}{height} of the control.
- \sa padding, topPadding, bottomPadding
+ \sa {Control Layout}, padding, topPadding, bottomPadding
*/
qreal QQuickControl::availableHeight() const
{
@@ -485,7 +525,19 @@ qreal QQuickControl::availableHeight() const
This property holds the default padding.
- \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
+ Padding adds a space between each edge of the content item and the
+ background item, effectively controlling the size of the content item. To
+ specify a padding value for a specific edge of the control, set its
+ relevant property:
+
+ \list
+ \li \l {Control::}{leftPadding}
+ \li \l {Control::}{rightPadding}
+ \li \l {Control::}{topPadding}
+ \li \l {Control::}{bottomPadding}
+ \endlist
+
+ \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
*/
qreal QQuickControl::padding() const
{
@@ -527,7 +579,7 @@ void QQuickControl::resetPadding()
This property holds the top padding.
- \sa padding, bottomPadding, availableHeight
+ \sa {Control Layout}, padding, bottomPadding, availableHeight
*/
qreal QQuickControl::topPadding() const
{
@@ -554,7 +606,7 @@ void QQuickControl::resetTopPadding()
This property holds the left padding.
- \sa padding, rightPadding, availableWidth
+ \sa {Control Layout}, padding, rightPadding, availableWidth
*/
qreal QQuickControl::leftPadding() const
{
@@ -581,7 +633,7 @@ void QQuickControl::resetLeftPadding()
This property holds the right padding.
- \sa padding, leftPadding, availableWidth
+ \sa {Control Layout}, padding, leftPadding, availableWidth
*/
qreal QQuickControl::rightPadding() const
{
@@ -608,7 +660,7 @@ void QQuickControl::resetRightPadding()
This property holds the bottom padding.
- \sa padding, topPadding, availableHeight
+ \sa {Control Layout}, padding, topPadding, availableHeight
*/
qreal QQuickControl::bottomPadding() const
{
@@ -634,6 +686,12 @@ void QQuickControl::resetBottomPadding()
\qmlproperty real QtQuick.Controls::Control::spacing
This property holds the spacing.
+
+ Spacing is useful for controls that have multiple or repetitive building
+ blocks. For example, some styles use spacing to determine the distance
+ between the text and indicator of \l CheckBox. Spacing is not enforced by
+ Control, so each style may interpret it differently, and some may ignore it
+ altogether.
*/
qreal QQuickControl::spacing() const
{
@@ -766,9 +824,11 @@ void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
This property holds whether the control is mirrored.
This property is provided for convenience. A control is considered mirrored
- when its visual layout direction is right-to-left.
+ when its visual layout direction is right-to-left; that is, when using a
+ right-to-left locale or when \l {LayoutMirroring::enabled}{LayoutMirroring.enabled}
+ is \c true.
- \sa locale, {LayoutMirroring}{LayoutMirroring}
+ \sa locale, {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces}
*/
bool QQuickControl::isMirrored() const
{
@@ -917,6 +977,10 @@ void QQuickControl::setHoverEnabled(bool enabled)
\qmlproperty bool QtQuick.Controls::Control::wheelEnabled
This property determines whether the control handles wheel events. The default value is \c false.
+
+ \note Care must be taken when enabling wheel events for controls within scrollable items such
+ as \l Flickable, as the control will consume the events and hence interrupt scrolling of the
+ Flickable.
*/
bool QQuickControl::isWheelEnabled() const
{
@@ -939,9 +1003,30 @@ void QQuickControl::setWheelEnabled(bool enabled)
This property holds the background item.
+ \code
+ Button {
+ id: control
+ text: qsTr("Button")
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ opacity: enabled ? 1 : 0.3
+ color: control.down ? "#d0d0d0" : "#e0e0e0"
+ }
+ }
+ \endcode
+
\note If the background item has no explicit size specified, it automatically
follows the control's size. In most cases, there is no need to specify
width or height for a background item.
+
+ \note Most controls use the implicit size of the background item to calculate
+ the implicit size of the control itself. If you replace the background item
+ with a custom one, you should also consider providing a sensible implicit
+ size for it (unless it is an item like \l Image which has its own implicit
+ size).
+
+ \sa {Control Layout}
*/
QQuickItem *QQuickControl::background() const
{
@@ -972,7 +1057,28 @@ void QQuickControl::setBackground(QQuickItem *background)
This property holds the visual content item.
- \note The content item is automatically resized inside the \l padding of the control.
+ \note The content item is automatically resized to fit within the
+ \l padding of the control.
+
+ \note Most controls use the implicit size of the content item to calculate
+ the implicit size of the control itself. If you replace the content item
+ with a custom one, you should also consider providing a sensible implicit
+ size for it (unless it is an item like \l Text which has its own implicit
+ size).
+
+ \code
+ Button {
+ id: control
+ text: qsTr("Button")
+ contentItem: Label {
+ text: control.text
+ font: control.font
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ \endcode
+
+ \sa {Control Layout}, padding
*/
QQuickItem *QQuickControl::contentItem() const
{
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 3b096255..48d02faa 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -300,6 +300,8 @@ qreal QQuickDial::position() const
Like the \l position property, angle is continuously updated while the
handle is dragged.
+ The range is from \c -140 degrees to \c 140 degrees.
+
\sa position
*/
qreal QQuickDial::angle() const
@@ -311,7 +313,18 @@ qreal QQuickDial::angle() const
/*!
\qmlproperty real QtQuick.Controls::Dial::stepSize
- This property holds the step size. The default value is \c 0.0.
+ This property holds the step size.
+
+ The step size determines the amount by which the dial's value
+ is increased and decreased when interacted with via the keyboard.
+ For example, a step size of \c 0.2, will result in the dial's
+ value increasing and decreasing in increments of \c 0.2.
+
+ The step size is only respected for touch and mouse interaction
+ when \l snapMode is set to a value other than \c Dial.NoSnap.
+
+ The default value is \c 0.0, which results in an effective step
+ size of \c 0.1 for keyboard interaction.
\sa snapMode, increase(), decrease()
*/
@@ -460,7 +473,7 @@ void QQuickDial::decrease()
}
/*!
- \qmlproperty component QtQuick.Controls::Dial::handle
+ \qmlproperty Item QtQuick.Controls::Dial::handle
This property holds the handle of the dial.
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index 4c9fbb62..bc1636de 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -69,6 +69,54 @@ QT_BEGIN_NAMESPACE
of the window.
\endtable
+ \code
+ import QtQuick 2.7
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ id: window
+ visible: true
+
+ Drawer {
+ id: drawer
+ width: 0.66 * window.width
+ height: window.height
+ }
+ }
+ \endcode
+
+ Drawer is a special type of popup that resides at one of the window \l {edge}{edges}.
+ By default, Drawer re-parents itself to the window \l {ApplicationWindow::}{overlay},
+ and therefore operates on window coordinates. It is also possible to manually set the
+ \l {Popup::}{parent} to something else to make the drawer operate in a specific
+ coordinate space.
+
+ Drawer can be configured to cover only part of its window edge. The following example
+ illustrates how Drawer can be positioned to appear below a window header:
+
+ \code
+ import QtQuick 2.7
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ id: window
+ visible: true
+
+ header: ToolBar { }
+
+ Drawer {
+ y: header.height
+ width: window.width * 0.6
+ height: window.height - header.height
+ }
+ }
+ \endcode
+
+ The \l position property determines how much of the drawer is visible, as
+ a value between \c 0.0 and \c 1.0. It is not possible to set the x-coordinate
+ (or horizontal margins) of a drawer at the left or right window edge, or the
+ y-coordinate (or vertical margins) of a drawer at the top or bottom window edge.
+
In the image above, the application's contents are \e "pushed" across the
screen. This is achieved by applying a translation to the contents:
@@ -117,6 +165,7 @@ QQuickDrawerPrivate::QQuickDrawerPrivate()
: edge(Qt::LeftEdge), offset(0), position(0),
dragMargin(QGuiApplication::styleHints()->startDragDistance())
{
+ setEdge(Qt::LeftEdge);
}
qreal QQuickDrawerPrivate::positionAt(const QPointF &point) const
@@ -161,6 +210,27 @@ void QQuickDrawerPrivate::reposition()
popupItem->setY(window->height() - position * popupItem->height());
break;
}
+
+ QQuickPopupPrivate::reposition();
+}
+
+void QQuickDrawerPrivate::resizeOverlay()
+{
+ if (!dimmer || !window)
+ return;
+
+ QRectF geometry(0, 0, window->width(), window->height());
+
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
+ geometry.setY(popupItem->y());
+ geometry.setHeight(popupItem->height());
+ } else {
+ geometry.setX(popupItem->x());
+ geometry.setWidth(popupItem->width());
+ }
+
+ dimmer->setPosition(geometry.topLeft());
+ dimmer->setSize(geometry.size());
}
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int threshold = -1)
@@ -309,6 +379,12 @@ bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *ev
Q_Q(QQuickDrawer);
Q_UNUSED(item);
+ // Don't react to synthesized mouse move events at INF,INF coordinates.
+ // QQuickWindowPrivate::translateTouchToMouse() uses them to clear hover
+ // on touch release (QTBUG-55995).
+ if (qIsInf(event->screenPos().x()) || qIsInf(event->screenPos().y()))
+ return true;
+
const QPointF movePoint = event->windowPos();
if (grabMouse(event)) {
@@ -374,6 +450,22 @@ bool QQuickDrawerPrivate::prepareExitTransition()
return QQuickPopupPrivate::prepareExitTransition();
}
+void QQuickDrawerPrivate::setEdge(Qt::Edge e)
+{
+ edge = e;
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
+ allowVerticalMove = true;
+ allowVerticalResize = true;
+ allowHorizontalMove = false;
+ allowHorizontalResize = false;
+ } else {
+ allowVerticalMove = false;
+ allowVerticalResize = false;
+ allowHorizontalMove = true;
+ allowHorizontalResize = true;
+ }
+}
+
QQuickDrawer::QQuickDrawer(QObject *parent) :
QQuickPopup(*(new QQuickDrawerPrivate), parent)
{
@@ -406,7 +498,7 @@ void QQuickDrawer::setEdge(Qt::Edge edge)
if (d->edge == edge)
return;
- d->edge = edge;
+ d->setEdge(edge);
if (isComponentComplete())
d->reposition();
emit edgeChanged();
@@ -531,4 +623,11 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event)
}
}
+void QQuickDrawer::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickDrawer);
+ QQuickPopup::geometryChanged(newGeometry, oldGeometry);
+ d->resizeOverlay();
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h
index e694e27b..bada1344 100644
--- a/src/quicktemplates2/qquickdrawer_p.h
+++ b/src/quicktemplates2/qquickdrawer_p.h
@@ -87,6 +87,8 @@ protected:
void mouseUngrabEvent() override;
bool overlayEvent(QQuickItem *item, QEvent *event) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
private:
Q_DISABLE_COPY(QQuickDrawer)
Q_DECLARE_PRIVATE(QQuickDrawer)
diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h
index f14c36dd..b7555c3e 100644
--- a/src/quicktemplates2/qquickdrawer_p_p.h
+++ b/src/quicktemplates2/qquickdrawer_p_p.h
@@ -68,6 +68,7 @@ public:
qreal positionAt(const QPointF &point) const;
void reposition() override;
+ void resizeOverlay() override;
bool startDrag(QQuickWindow *window, QMouseEvent *event);
bool grabMouse(QMouseEvent *event);
@@ -80,6 +81,8 @@ public:
bool prepareEnterTransition() override;
bool prepareExitTransition() override;
+ void setEdge(Qt::Edge edge);
+
Qt::Edge edge;
qreal offset;
qreal position;
diff --git a/src/quicktemplates2/qquickframe.cpp b/src/quicktemplates2/qquickframe.cpp
index 2f2a5497..bcc387c1 100644
--- a/src/quicktemplates2/qquickframe.cpp
+++ b/src/quicktemplates2/qquickframe.cpp
@@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE
or a \l ColumnLayout.
Items declared as children of a Frame are automatically parented to the
- Frame's contentItem. Items created dynamically need to be explicitly
- parented to the contentItem.
+ Frame's \l {Control::}{contentItem}. Items created dynamically need to be
+ explicitly parented to the contentItem.
If only a single item is used within a Frame, it will resize to fit the
implicit size of its contained item. This makes it particularly suitable
diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp
index 45fe406f..27c325ef 100644
--- a/src/quicktemplates2/qquickgroupbox.cpp
+++ b/src/quicktemplates2/qquickgroupbox.cpp
@@ -48,10 +48,10 @@ QT_BEGIN_NAMESPACE
\inqmlmodule QtQuick.Controls
\since 5.7
\ingroup qtquickcontrols2-containers
- \brief A frame with a logical group of controls.
+ \brief A logical group of controls within a titled visual frame.
GroupBox is used to layout a logical group of controls together, within
- a titled visual frame. GroupBox does not provide a layout of its own, but
+ a \l {title}{titled} visual frame. GroupBox does not provide a layout of its own, but
requires you to position its contents, for instance by creating a \l RowLayout
or a \l ColumnLayout.
@@ -75,8 +75,8 @@ QT_BEGIN_NAMESPACE
\image qtquickcontrols2-groupbox-checkable.png
It is a common pattern to enable or disable the groupbox's children when
- its checkbox is toggled on or off, but it is the application that decides
- on the behavior of the groupbox.
+ its checkbox is toggled on or off, but it is up to the application to decide
+ on the behavior of the checkbox.
\snippet qtquickcontrols2-groupbox-checkable.qml 1
@@ -101,6 +101,9 @@ QQuickGroupBox::QQuickGroupBox(QQuickItem *parent) :
\qmlproperty string QtQuick.Controls::GroupBox::title
This property holds the title.
+
+ The title is typically displayed above the groupbox to
+ summarize its contents.
*/
QString QQuickGroupBox::title() const
{
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index b8522668..bf37f801 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -89,6 +89,15 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ Typically, menu items are statically declared as children of the menu, but
+ Menu also provides API to \l {addItem}{add}, \l {insertItem}{insert},
+ \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The
+ items in a menu can be accessed using \l itemAt() or
+ \l {Popup::}{contentChildren}.
+
+ Although \l {MenuItem}{MenuItems} are most commonly used with Menu, it can
+ contain any type of item.
+
\sa {Customizing Menu}, {Menu Controls}, {Popup Controls}
*/
@@ -350,7 +359,7 @@ void QQuickMenu::moveItem(int from, int to)
/*!
\qmlmethod void QtQuick.Controls::Menu::removeItem(int index)
- Removes an item at \a index.
+ Removes the item at \a index.
\note The ownership of the item is transferred to the caller.
*/
@@ -372,8 +381,20 @@ void QQuickMenu::removeItem(int index)
This property holds the model used to display menu items.
- By default, the model is an \l ObjectModel, in order to allow declaring
- menu items as children of the menu.
+ The content model is provided for visualization purposes. It can be assigned
+ as a model to a content item that presents the contents of the menu.
+
+ \code
+ Menu {
+ id: menu
+ contentItem: ListView {
+ model: menu.contentModel
+ }
+ }
+ \endcode
+
+ The model allows menu items to be statically declared as children of the
+ menu.
*/
QVariant QQuickMenu::contentModel() const
{
@@ -387,7 +408,14 @@ QVariant QQuickMenu::contentModel() const
This property holds the list of content data.
- \sa Item::data
+ The list contains all objects that have been declared in QML as children
+ of the menu, and also items that have been dynamically added or
+ inserted using the \l addItem() and \l insertItem() methods, respectively.
+
+ \note Unlike \c contentChildren, \c contentData does include non-visual QML
+ objects. It is not re-ordered when items are inserted or moved.
+
+ \sa Item::data, contentChildren
*/
QQmlListProperty<QObject> QQuickMenu::contentData()
{
@@ -402,9 +430,11 @@ QQmlListProperty<QObject> QQuickMenu::contentData()
/*!
\qmlproperty string QtQuick.Controls::Menu::title
- Title for the menu as a submenu or in a menubar.
+ This property holds the title for the menu.
- Its value defaults to an empty string.
+ The title of a menu is often displayed in the text of a menu item when the
+ menu is a submenu, and in the text of a tool button when it is in a
+ menubar.
*/
QString QQuickMenu::title() const
{
diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp
index 35942f92..902889b0 100644
--- a/src/quicktemplates2/qquickmenuitem.cpp
+++ b/src/quicktemplates2/qquickmenuitem.cpp
@@ -52,26 +52,30 @@ QT_BEGIN_NAMESPACE
\brief A menu item within a Menu.
MenuItem is a convenience type that implements the AbstractButton API,
- providing an easy way to respond to menu items being clicked, for example.
+ providing a familiar way to respond to menu items being \l triggered, for
+ example.
\code
Button {
id: fileButton
text: "File"
onClicked: menu.open()
- }
- Menu {
- id: menu
- anchor.target: fileButton
- MenuItem {
- text: "New..."
- }
- MenuItem {
- text: "Open..."
- }
- MenuItem {
- text: "Save"
+ Menu {
+ id: menu
+
+ MenuItem {
+ text: "New..."
+ onTriggered: document.reset()
+ }
+ MenuItem {
+ text: "Open..."
+ onTriggered: openDialog.open()
+ }
+ MenuItem {
+ text: "Save"
+ onTriggered: saveDialog.open()
+ }
}
}
\endcode
@@ -110,6 +114,11 @@ QQuickMenuItem::QQuickMenuItem(QQuickItem *parent) :
\qmlproperty bool QtQuick.Controls::MenuItem::checkable
This property holds whether the menu item is checkable.
+
+ A checkable menu item toggles between checked (on) and unchecked (off) when
+ the user clicks on it or interacts with it via the keyboard.
+
+ \sa {AbstractButton::}{checked}
*/
void QQuickMenuItem::checkableChange()
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index ccae4da6..9bdc9135 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -113,7 +113,7 @@ void QQuickOverlayPrivate::createOverlay(QQuickPopup *popup)
QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
if (!p->dimmer)
p->dimmer = createDimmer(popup->isModal() ? modal : modeless, popup, q);
- resizeOverlay(popup);
+ p->resizeOverlay();
}
void QQuickOverlayPrivate::destroyOverlay(QQuickPopup *popup)
@@ -126,16 +126,6 @@ void QQuickOverlayPrivate::destroyOverlay(QQuickPopup *popup)
}
}
-void QQuickOverlayPrivate::resizeOverlay(QQuickPopup *popup)
-{
- Q_Q(QQuickOverlay);
- QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
- if (p->dimmer) {
- p->dimmer->setWidth(q->width());
- p->dimmer->setHeight(q->height());
- }
-}
-
void QQuickOverlayPrivate::toggleOverlay()
{
Q_Q(QQuickOverlay);
@@ -320,7 +310,7 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old
Q_D(QQuickOverlay);
QQuickItem::geometryChanged(newGeometry, oldGeometry);
for (QQuickPopup *popup : qAsConst(d->allPopups))
- d->resizeOverlay(popup);
+ QQuickPopupPrivate::get(popup)->resizeOverlay();
}
void QQuickOverlay::mousePressEvent(QMouseEvent *event)
@@ -404,7 +394,11 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
switch (event->type()) {
case QEvent::MouseButtonPress:
emit pressed();
- return popup->overlayEvent(item, event);
+ if (popup->overlayEvent(item, event)) {
+ d->mouseGrabberPopup = popup;
+ return true;
+ }
+ break;
case QEvent::MouseMove:
return popup->overlayEvent(item, event);
case QEvent::MouseButtonRelease:
diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h
index db005555..ef142f1b 100644
--- a/src/quicktemplates2/qquickoverlay_p_p.h
+++ b/src/quicktemplates2/qquickoverlay_p_p.h
@@ -78,7 +78,6 @@ public:
void createOverlay(QQuickPopup *popup);
void destroyOverlay(QQuickPopup *popup);
- void resizeOverlay(QQuickPopup *popup);
void toggleOverlay();
QVector<QQuickPopup *> stackingOrderPopups() const;
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 4304c4fb..54e79fbe 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -104,6 +104,37 @@ QQuickPage::QQuickPage(QQuickItem *parent) :
\qmlproperty string QtQuick.Controls::Page::title
This property holds the page title.
+
+ The title is often displayed at the top of a page to give
+ the user context about the page they are viewing.
+
+ \code
+ ApplicationWindow {
+ visible: true
+ width: 400
+ height: 400
+
+ header: Label {
+ text: view.currentItem.title
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ SwipeView {
+ id: view
+ anchors.fill: parent
+
+ Page {
+ title: qsTr("Home")
+ }
+ Page {
+ title: qsTr("Discover")
+ }
+ Page {
+ title: qsTr("Activity")
+ }
+ }
+ }
+ \endcode
*/
QString QQuickPage::title() const
@@ -183,7 +214,13 @@ void QQuickPage::setFooter(QQuickItem *footer)
This property holds the list of content data.
- \sa Item::data
+ The list contains all objects that have been declared in QML as children
+ of the container.
+
+ \note Unlike \c contentChildren, \c contentData does include non-visual QML
+ objects.
+
+ \sa Item::data, contentChildren
*/
QQmlListProperty<QObject> QQuickPage::contentData()
{
@@ -200,7 +237,13 @@ QQmlListProperty<QObject> QQuickPage::contentData()
This property holds the list of content children.
- \sa Item::children
+ The list contains all items that have been declared in QML as children
+ of the page.
+
+ \note Unlike \c contentData, \c contentChildren does not include non-visual
+ QML objects.
+
+ \sa Item::children, contentData
*/
QQmlListProperty<QQuickItem> QQuickPage::contentChildren()
{
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 4143ee3f..1a5310bf 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -125,12 +125,18 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, hasDim(false)
, visible(false)
, complete(false)
+ , hasWidth(false)
+ , hasHeight(false)
, hasTopMargin(false)
, hasLeftMargin(false)
, hasRightMargin(false)
, hasBottomMargin(false)
, allowVerticalFlip(false)
, allowHorizontalFlip(false)
+ , allowVerticalMove(true)
+ , allowHorizontalMove(true)
+ , allowVerticalResize(true)
+ , allowHorizontalResize(true)
, hadActiveFocusBeforeExitTransition(false)
, x(0)
, y(0)
@@ -587,13 +593,19 @@ void QQuickPopupPrivate::reposition()
bool widthAdjusted = false;
bool heightAdjusted = false;
- QRectF rect(x, y, iw > 0 ? iw : w, ih > 0 ? ih : h);
+ QRectF rect(allowHorizontalMove ? x : popupItem->x(),
+ allowVerticalMove ? y : popupItem->y(),
+ !hasWidth && iw > 0 ? iw : w,
+ !hasHeight && ih > 0 ? ih : h);
if (parentItem) {
rect = parentItem->mapRectToScene(rect);
if (window) {
const QMarginsF margins = getMargins();
- const QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(margins);
+ const QRectF bounds(qMax<qreal>(0.0, margins.left()),
+ qMax<qreal>(0.0, margins.top()),
+ window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()),
+ window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
// if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
if (allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
@@ -610,31 +622,39 @@ void QQuickPopupPrivate::reposition()
}
// push inside the margins if specified
- if (margins.top() >= 0 && rect.top() < bounds.top())
- rect.moveTop(margins.top());
- if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
- rect.moveBottom(bounds.bottom());
- if (margins.left() >= 0 && rect.left() < bounds.left())
- rect.moveLeft(margins.left());
- if (margins.right() >= 0 && rect.right() > bounds.right())
- rect.moveRight(bounds.right());
+ if (allowVerticalMove) {
+ if (margins.top() >= 0 && rect.top() < bounds.top())
+ rect.moveTop(margins.top());
+ if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
+ rect.moveBottom(bounds.bottom());
+ }
+ if (allowHorizontalMove) {
+ if (margins.left() >= 0 && rect.left() < bounds.left())
+ rect.moveLeft(margins.left());
+ if (margins.right() >= 0 && rect.right() > bounds.right())
+ rect.moveRight(bounds.right());
+ }
if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
// neither the flipped or pushed geometry fits inside the window, choose
// whichever side (left vs. right) fits larger part of the popup
- if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
- rect.moveLeft(bounds.left());
- else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
- rect.moveRight(bounds.right());
+ if (allowHorizontalMove && allowHorizontalFlip) {
+ if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
+ rect.moveLeft(bounds.left());
+ else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
+ rect.moveRight(bounds.right());
+ }
// as a last resort, adjust the width to fit the window
- if (rect.left() < bounds.left()) {
- rect.setLeft(bounds.left());
- widthAdjusted = true;
- }
- if (rect.right() > bounds.right()) {
- rect.setRight(bounds.right());
- widthAdjusted = true;
+ if (allowHorizontalResize) {
+ if (rect.left() < bounds.left()) {
+ rect.setLeft(bounds.left());
+ widthAdjusted = true;
+ }
+ if (rect.right() > bounds.right()) {
+ rect.setRight(bounds.right());
+ widthAdjusted = true;
+ }
}
} else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right()
&& iw != w) {
@@ -646,19 +666,23 @@ void QQuickPopupPrivate::reposition()
if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
// neither the flipped or pushed geometry fits inside the window, choose
// whichever side (above vs. below) fits larger part of the popup
- if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
- rect.moveTop(bounds.top());
- else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
- rect.moveBottom(bounds.bottom());
+ if (allowVerticalMove && allowVerticalFlip) {
+ if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
+ rect.moveTop(bounds.top());
+ else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
+ rect.moveBottom(bounds.bottom());
+ }
// as a last resort, adjust the height to fit the window
- if (rect.top() < bounds.top()) {
- rect.setTop(bounds.top());
- heightAdjusted = true;
- }
- if (rect.bottom() > bounds.bottom()) {
- rect.setBottom(bounds.bottom());
- heightAdjusted = true;
+ if (allowVerticalResize) {
+ if (rect.top() < bounds.top()) {
+ rect.setTop(bounds.top());
+ heightAdjusted = true;
+ }
+ if (rect.bottom() > bounds.bottom()) {
+ rect.setBottom(bounds.bottom());
+ heightAdjusted = true;
+ }
}
} else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom()
&& ih != h) {
@@ -681,12 +705,22 @@ void QQuickPopupPrivate::reposition()
emit q->yChanged();
}
- if (widthAdjusted && rect.width() > 0)
+ if (!hasWidth && widthAdjusted && rect.width() > 0)
popupItem->setWidth(rect.width());
- if (heightAdjusted && rect.height() > 0)
+ if (!hasHeight && heightAdjusted && rect.height() > 0)
popupItem->setHeight(rect.height());
}
+void QQuickPopupPrivate::resizeOverlay()
+{
+ if (!dimmer)
+ return;
+
+ qreal w = window ? window->width() : 0;
+ qreal h = window ? window->height() : 0;
+ dimmer->setSize(QSizeF(w, h));
+}
+
void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
{
if (item == m_parentItem)
@@ -907,13 +941,20 @@ qreal QQuickPopup::width() const
void QQuickPopup::setWidth(qreal width)
{
Q_D(QQuickPopup);
+ d->hasWidth = true;
d->popupItem->setWidth(width);
}
void QQuickPopup::resetWidth()
{
Q_D(QQuickPopup);
+ if (!d->hasWidth)
+ return;
+
+ d->hasWidth = false;
d->popupItem->resetWidth();
+ if (d->popupItem->isVisible())
+ d->reposition();
}
/*!
@@ -930,13 +971,20 @@ qreal QQuickPopup::height() const
void QQuickPopup::setHeight(qreal height)
{
Q_D(QQuickPopup);
+ d->hasHeight = true;
d->popupItem->setHeight(height);
}
void QQuickPopup::resetHeight()
{
Q_D(QQuickPopup);
+ if (!d->hasHeight)
+ return;
+
+ d->hasHeight = false;
d->popupItem->resetHeight();
+ if (d->popupItem->isVisible())
+ d->reposition();
}
/*!
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 93039287..4ad8d171 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -157,6 +157,7 @@ public:
void init();
bool tryClose(QQuickItem *item, QMouseEvent *event);
virtual void reposition();
+ virtual void resizeOverlay();
virtual bool prepareEnterTransition();
virtual bool prepareExitTransition();
@@ -183,12 +184,18 @@ public:
bool hasDim;
bool visible;
bool complete;
+ bool hasWidth;
+ bool hasHeight;
bool hasTopMargin;
bool hasLeftMargin;
bool hasRightMargin;
bool hasBottomMargin;
bool allowVerticalFlip;
bool allowHorizontalFlip;
+ bool allowVerticalMove;
+ bool allowHorizontalMove;
+ bool allowVerticalResize;
+ bool allowHorizontalResize;
bool hadActiveFocusBeforeExitTransition;
qreal x;
qreal y;
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp
index 37ae53f0..a7d17e86 100644
--- a/src/quicktemplates2/qquickswitch.cpp
+++ b/src/quicktemplates2/qquickswitch.cpp
@@ -90,103 +90,28 @@ class QQuickSwitchPrivate : public QQuickAbstractButtonPrivate
public:
QQuickSwitchPrivate() : position(0) { }
- void updatePosition();
- qreal positionAt(const QPoint &point) const;
-
- bool handleMousePressEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseUngrabEvent(QQuickItem *child);
+ qreal positionAt(const QPointF &point) const;
qreal position;
- QPoint pressPoint;
};
-void QQuickSwitchPrivate::updatePosition()
-{
- Q_Q(QQuickSwitch);
- q->setPosition(checked ? 1.0 : 0.0);
-}
-
-qreal QQuickSwitchPrivate::positionAt(const QPoint &point) const
+qreal QQuickSwitchPrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickSwitch);
- qreal pos = point.x() / indicator->width();
+ qreal pos = 0.0;
+ if (indicator)
+ pos = indicator->mapFromItem(q, point).x() / indicator->width();
if (q->isMirrored())
return 1.0 - pos;
return pos;
}
-bool QQuickSwitchPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = event->pos();
- q->setPressed(true);
- emit q->pressed();
- event->accept();
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if (!child->keepMouseGrab())
- child->setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(event->pos().x() - pressPoint.x(), Qt::XAxis, event));
- if (child->keepMouseGrab()) {
- q->setPosition(positionAt(event->pos()));
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = QPoint();
- q->setPressed(false);
- if (child->keepMouseGrab()) {
- bool wasChecked = checked;
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- child->setKeepMouseGrab(false);
- if (wasChecked != checked) {
- emit q->released();
- emit q->clicked();
- }
- event->accept();
- } else {
- q->toggle();
- emit q->released();
- emit q->clicked();
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseUngrabEvent(QQuickItem *child)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- pressPoint = QPoint();
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- q->setPressed(false);
- return true;
-}
-
QQuickSwitch::QQuickSwitch(QQuickItem *parent) :
QQuickAbstractButton(*(new QQuickSwitchPrivate), parent)
{
+ Q_D(QQuickSwitch);
+ d->keepPressed = true;
setCheckable(true);
- setFiltersChildMouseEvents(true);
- QObjectPrivate::connect(this, &QQuickAbstractButton::checkedChanged, d_func(), &QQuickSwitchPrivate::updatePosition);
}
/*!
@@ -227,30 +152,56 @@ qreal QQuickSwitch::visualPosition() const
return d->position;
}
+void QQuickSwitch::mousePressEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mousePressEvent(event);
+}
+
+void QQuickSwitch::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSwitch);
+ QQuickAbstractButton::mouseMoveEvent(event);
+
+ const QPointF movePoint = event->localPos();
+ if (!keepMouseGrab()) {
+ // don't start dragging the handle unless the initial press was at the indicator,
+ // or the drag has reached the indicator area. this prevents unnatural jumps when
+ // dragging far outside the indicator.
+ const qreal pressPos = d->positionAt(d->pressPoint);
+ const qreal movePos = d->positionAt(movePoint);
+ if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0))
+ setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event));
+ }
+
+ if (keepMouseGrab())
+ setPosition(d->positionAt(movePoint));
+}
+
+void QQuickSwitch::mouseReleaseEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mouseReleaseEvent(event);
+ setKeepMouseGrab(false);
+}
+
void QQuickSwitch::mirrorChange()
{
QQuickAbstractButton::mirrorChange();
emit visualPositionChanged();
}
-bool QQuickSwitch::childMouseEventFilter(QQuickItem *child, QEvent *event)
+void QQuickSwitch::nextCheckState()
{
Q_D(QQuickSwitch);
- if (child == indicator()) {
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- return d->handleMousePressEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseMove:
- return d->handleMouseMoveEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseButtonRelease:
- return d->handleMouseReleaseEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::UngrabMouse:
- return d->handleMouseUngrabEvent(child);
- default:
- return false;
- }
- }
- return false;
+ if (keepMouseGrab())
+ setChecked(d->position > 0.5);
+ else
+ QQuickAbstractButton::nextCheckState();
+}
+
+void QQuickSwitch::checkStateSet()
+{
+ Q_D(QQuickSwitch);
+ setPosition(d->checked ? 1.0 : 0.0);
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickswitch_p.h b/src/quicktemplates2/qquickswitch_p.h
index fa92e9f3..27a065b4 100644
--- a/src/quicktemplates2/qquickswitch_p.h
+++ b/src/quicktemplates2/qquickswitch_p.h
@@ -73,8 +73,14 @@ Q_SIGNALS:
void visualPositionChanged();
protected:
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
void mirrorChange() override;
- bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
+
+ void nextCheckState() override;
+ void checkStateSet() override;
private:
Q_DISABLE_COPY(QQuickSwitch)
diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp
index fbdae418..62b677e5 100644
--- a/src/quicktemplates2/qquickswitchdelegate.cpp
+++ b/src/quicktemplates2/qquickswitchdelegate.cpp
@@ -80,22 +80,17 @@ public:
{
}
- void updatePosition();
- qreal positionAt(const QPoint &point) const;
+ qreal positionAt(const QPointF &point) const;
qreal position;
};
-void QQuickSwitchDelegatePrivate::updatePosition()
-{
- Q_Q(QQuickSwitchDelegate);
- q->setPosition(checked ? 1.0 : 0.0);
-}
-
-qreal QQuickSwitchDelegatePrivate::positionAt(const QPoint &point) const
+qreal QQuickSwitchDelegatePrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickSwitchDelegate);
- qreal pos = point.x() / indicator->width();
+ qreal pos = 0.0;
+ if (indicator)
+ pos = indicator->mapFromItem(q, point).x() / indicator->width();
if (q->isMirrored())
return 1.0 - pos;
return pos;
@@ -104,9 +99,9 @@ qreal QQuickSwitchDelegatePrivate::positionAt(const QPoint &point) const
QQuickSwitchDelegate::QQuickSwitchDelegate(QQuickItem *parent) :
QQuickItemDelegate(*(new QQuickSwitchDelegatePrivate), parent)
{
+ Q_D(QQuickSwitchDelegate);
+ d->keepPressed = true;
setCheckable(true);
-
- QObjectPrivate::connect(this, &QQuickAbstractButton::checkedChanged, d_func(), &QQuickSwitchDelegatePrivate::updatePosition);
}
/*!
@@ -147,6 +142,37 @@ qreal QQuickSwitchDelegate::visualPosition() const
return d->position;
}
+void QQuickSwitchDelegate::mousePressEvent(QMouseEvent *event)
+{
+ QQuickItemDelegate::mousePressEvent(event);
+}
+
+void QQuickSwitchDelegate::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSwitchDelegate);
+ QQuickItemDelegate::mouseMoveEvent(event);
+
+ const QPointF movePoint = event->localPos();
+ if (!keepMouseGrab()) {
+ // don't start dragging the handle unless the initial press was at the indicator,
+ // or the drag has reached the indicator area. this prevents unnatural jumps when
+ // dragging far outside the indicator.
+ const qreal pressPos = d->positionAt(d->pressPoint);
+ const qreal movePos = d->positionAt(movePoint);
+ if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0))
+ setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event));
+ }
+
+ if (keepMouseGrab())
+ setPosition(d->positionAt(movePoint));
+}
+
+void QQuickSwitchDelegate::mouseReleaseEvent(QMouseEvent *event)
+{
+ QQuickItemDelegate::mouseReleaseEvent(event);
+ setKeepMouseGrab(false);
+}
+
QFont QQuickSwitchDelegate::defaultFont() const
{
return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont);
@@ -158,4 +184,19 @@ void QQuickSwitchDelegate::mirrorChange()
emit visualPositionChanged();
}
+void QQuickSwitchDelegate::nextCheckState()
+{
+ Q_D(QQuickSwitchDelegate);
+ if (keepMouseGrab())
+ setChecked(d->position > 0.5);
+ else
+ QQuickItemDelegate::nextCheckState();
+}
+
+void QQuickSwitchDelegate::checkStateSet()
+{
+ Q_D(QQuickSwitchDelegate);
+ setPosition(d->checked ? 1.0 : 0.0);
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickswitchdelegate_p.h b/src/quicktemplates2/qquickswitchdelegate_p.h
index 5126f643..c0cc21ac 100644
--- a/src/quicktemplates2/qquickswitchdelegate_p.h
+++ b/src/quicktemplates2/qquickswitchdelegate_p.h
@@ -73,9 +73,16 @@ Q_SIGNALS:
void visualPositionChanged();
protected:
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
QFont defaultFont() const override;
void mirrorChange() override;
+ void nextCheckState() override;
+ void checkStateSet() override;
+
private:
Q_DISABLE_COPY(QQuickSwitchDelegate)
Q_DECLARE_PRIVATE(QQuickSwitchDelegate)
diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp
index b712075f..fb7f96b8 100644
--- a/tests/auto/applicationwindow/tst_applicationwindow.cpp
+++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp
@@ -318,7 +318,7 @@ void tst_applicationwindow::attachedProperties()
QVERIFY(!childWindowControl->property("attached_activeFocusControl").value<QQuickItem *>());
QVERIFY(!childWindowControl->property("attached_header").value<QQuickItem *>());
QVERIFY(!childWindowControl->property("attached_footer").value<QQuickItem *>());
- QVERIFY(!childWindowControl->property("attached_overlay").value<QQuickItem *>());
+ QCOMPARE(childWindowControl->property("attached_overlay").value<QQuickItem *>(), QQuickOverlay::overlay(childWindow));
QQuickItem *childWindowItem = object->property("childWindowItem").value<QQuickItem *>();
QVERIFY(childWindowItem);
@@ -327,7 +327,7 @@ void tst_applicationwindow::attachedProperties()
QVERIFY(!childWindowItem->property("attached_activeFocusControl").value<QQuickItem *>());
QVERIFY(!childWindowItem->property("attached_header").value<QQuickItem *>());
QVERIFY(!childWindowItem->property("attached_footer").value<QQuickItem *>());
- QVERIFY(!childWindowItem->property("attached_overlay").value<QQuickItem *>());
+ QCOMPARE(childWindowItem->property("attached_overlay").value<QQuickItem *>(), QQuickOverlay::overlay(childWindow));
QObject *childWindowObject = object->property("childWindowObject").value<QObject *>();
QVERIFY(childWindowObject);
diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml
index 0061440b..dc84ff93 100644
--- a/tests/auto/controls/data/tst_control.qml
+++ b/tests/auto/controls/data/tst_control.qml
@@ -880,6 +880,12 @@ TestCase {
mouseMove(control, -10, -10)
compare(control.hovered, false)
+ mouseMove(control, control.width / 2, control.height / 2)
+ compare(control.hovered, true)
+
+ control.visible = false
+ compare(control.hovered, false)
+
control.destroy()
}
diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml
index bfa8dd10..2e1f32dc 100644
--- a/tests/auto/controls/data/tst_drawer.qml
+++ b/tests/auto/controls/data/tst_drawer.qml
@@ -60,6 +60,7 @@ TestCase {
compare(control.edge, Qt.LeftEdge)
compare(control.position, 0.0)
compare(control.dragMargin, Qt.styleHints.startDragDistance)
+ compare(control.parent, ApplicationWindow.overlay)
control.destroy()
}
diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml
index a86e800e..5609d47f 100644
--- a/tests/auto/controls/data/tst_popup.qml
+++ b/tests/auto/controls/data/tst_popup.qml
@@ -355,6 +355,48 @@ TestCase {
control.destroy()
}
+ function test_resetSize() {
+ var control = popupControl.createObject(testCase, {visible: true, margins: 0})
+ verify(control)
+
+ control.width = control.implicitWidth = testCase.width + 10
+ control.height = control.implicitHeight = testCase.height + 10
+
+ compare(control.width, testCase.width + 10)
+ compare(control.height, testCase.height + 10)
+
+ control.width = undefined
+ control.height = undefined
+ compare(control.width, testCase.width)
+ compare(control.height, testCase.height)
+
+ control.destroy()
+ }
+
+ function test_negativeMargins() {
+ var control = popupControl.createObject(testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height})
+ verify(control)
+
+ control.open()
+ verify(control.visible)
+
+ compare(control.x, 0)
+ compare(control.y, 0)
+
+ compare(control.margins, -1)
+ compare(control.topMargin, -1)
+ compare(control.leftMargin, -1)
+ compare(control.rightMargin, -1)
+ compare(control.bottomMargin, -1)
+
+ control.x = -10
+ control.y = -10
+ compare(control.x, 0)
+ compare(control.y, 0)
+
+ control.destroy()
+ }
+
function test_margins() {
var control = popupControl.createObject(testCase, {width: 100, height: 100})
verify(control)
@@ -975,14 +1017,52 @@ TestCase {
var control = popupControl.createObject(testCase)
verify(control)
- control.width = 200
- control.height = 200
-
control.open()
waitForRendering(control.contentItem)
- compare(control.width, 200)
- compare(control.height, 200)
+ // implicit size of the content
+ control.contentItem.implicitWidth = 10
+ compare(control.implicitWidth, 10 + control.leftPadding + control.rightPadding)
+ compare(control.width, control.implicitWidth)
+ compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding)
+
+ control.contentItem.implicitHeight = 20
+ compare(control.implicitHeight, 20 + control.topPadding + control.bottomPadding)
+ compare(control.height, control.implicitHeight)
+ compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding)
+
+ // implicit size of the popup
+ control.implicitWidth = 30
+ compare(control.implicitWidth, 30)
+ compare(control.width, 30)
+ compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding)
+
+ control.implicitHeight = 40
+ compare(control.implicitHeight, 40)
+ compare(control.height, 40)
+ compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding)
+
+ // set explicit size
+ control.width = 50
+ compare(control.implicitWidth, 30)
+ compare(control.width, 50)
+ compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding)
+
+ control.height = 60
+ compare(control.implicitHeight, 40)
+ compare(control.height, 60)
+ compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding)
+
+ // reset explicit size
+ control.width = undefined
+ compare(control.implicitWidth, 30)
+ compare(control.width, 30)
+ compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding)
+
+ control.height = undefined
+ compare(control.implicitHeight, 40)
+ compare(control.height, 40)
+ compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding)
control.destroy()
}
diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml
index 6c145fc1..f3843cf7 100644
--- a/tests/auto/controls/data/tst_switch.qml
+++ b/tests/auto/controls/data/tst_switch.qml
@@ -95,6 +95,29 @@ TestCase {
control.destroy()
}
+ function test_pressed_data() {
+ return [
+ { tag: "indicator", x: 15 },
+ { tag: "background", x: 5 }
+ ]
+ }
+
+ function test_pressed(data) {
+ var control = swtch.createObject(testCase, {padding: 10})
+ verify(control)
+
+ // stays pressed when dragged outside
+ compare(control.pressed, false)
+ mousePress(control, data.x, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ mouseMove(control, -1, control.height / 2)
+ compare(control.pressed, true)
+ mouseRelease(control, -1, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, false)
+
+ control.destroy()
+ }
+
function test_mouse() {
var control = swtch.createObject(testCase)
verify(control)
@@ -177,6 +200,110 @@ TestCase {
control.destroy()
}
+ function test_drag() {
+ var control = swtch.createObject(testCase, {leftPadding: 100, rightPadding: 100})
+ verify(control)
+
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+
+ // press-drag-release inside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control.indicator, 0)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control.indicator, control.width)
+ compare(control.position, 1.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control.indicator, control.indicator.width)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // press-drag-release outside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
+ mousePress(control, 0)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width / 2)
+ compare(control.position, 0.5)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.leftPadding)
+ compare(control.position, 0.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // press-drag-release from and to outside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control, control.width)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width / 2)
+ compare(control.position, 0.5)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 1.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ control.destroy()
+ }
+
function test_keys() {
var control = swtch.createObject(testCase)
verify(control)
diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml
index 2d5c6089..4a5d711f 100644
--- a/tests/auto/controls/data/tst_switchdelegate.qml
+++ b/tests/auto/controls/data/tst_switchdelegate.qml
@@ -55,6 +55,13 @@ TestCase {
SwitchDelegate {}
}
+ Component {
+ id: signalSequenceSpy
+ SignalSequenceSpy {
+ signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"]
+ }
+ }
+
// TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here?
function test_defaults() {
@@ -83,4 +90,213 @@ TestCase {
compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset);
control.destroy();
}
+
+ function test_pressed_data() {
+ return [
+ { tag: "indicator", x: 15 },
+ { tag: "background", x: 5 }
+ ]
+ }
+
+ function test_pressed(data) {
+ var control = switchDelegate.createObject(testCase, {padding: 10})
+ verify(control)
+
+ // stays pressed when dragged outside
+ compare(control.pressed, false)
+ mousePress(control, data.x, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ mouseMove(control, -1, control.height / 2)
+ compare(control.pressed, true)
+ mouseRelease(control, -1, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, false)
+
+ control.destroy()
+ }
+
+ function test_mouse() {
+ var control = switchDelegate.createObject(testCase)
+ verify(control)
+
+ // check
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ verify(spy.success)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // uncheck
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
+ mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ verify(spy.success)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // release on the right
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ verify(spy.success)
+ mouseMove(control, control.width * 2, control.height / 2, 0, Qt.LeftButton)
+ compare(control.pressed, true)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // release on the left
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
+ mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton)
+ compare(control.pressed, true)
+ verify(spy.success)
+ mouseMove(control, -control.width, control.height / 2, 0, Qt.LeftButton)
+ compare(control.pressed, true)
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
+ mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // right button
+ spy.expectedSequence = []
+ mousePress(control, control.width / 2, control.height / 2, Qt.RightButton)
+ compare(control.pressed, false)
+ verify(spy.success)
+ mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ control.destroy()
+ }
+
+ function test_drag() {
+ var control = switchDelegate.createObject(testCase, {leftPadding: 100, rightPadding: 100})
+ verify(control)
+
+ var spy = signalSequenceSpy.createObject(control, {target: control})
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+
+ // press-drag-release inside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control.indicator, 0)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control.indicator, control.width)
+ compare(control.position, 1.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control.indicator, control.indicator.width)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // press-drag-release outside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }],
+ "pressed"]
+ mousePress(control, 0)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width / 2)
+ compare(control.position, 0.5)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.leftPadding)
+ compare(control.position, 0.0)
+ compare(control.checked, true)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }],
+ ["checkedChanged", { "pressed": false, "checked": false }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ // press-drag-release from and to outside the indicator
+ spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }],
+ "pressed"]
+ mousePress(control, control.width)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+ verify(spy.success)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 0.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width / 2)
+ compare(control.position, 0.5)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ mouseMove(control, control.width - control.rightPadding)
+ compare(control.position, 1.0)
+ compare(control.checked, false)
+ compare(control.pressed, true)
+
+ spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }],
+ ["checkedChanged", { "pressed": false, "checked": true }],
+ "released",
+ "clicked"]
+ mouseRelease(control, control.width)
+ compare(control.position, 1.0)
+ compare(control.checked, true)
+ compare(control.pressed, false)
+ verify(spy.success)
+
+ control.destroy()
+ }
}
diff --git a/tests/auto/drawer/BLACKLIST b/tests/auto/drawer/BLACKLIST
new file mode 100644
index 00000000..1b06b49c
--- /dev/null
+++ b/tests/auto/drawer/BLACKLIST
@@ -0,0 +1,2 @@
+[touch]
+windows
diff --git a/tests/auto/drawer/data/header.qml b/tests/auto/drawer/data/header.qml
new file mode 100644
index 00000000..9a352ffc
--- /dev/null
+++ b/tests/auto/drawer/data/header.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.6
+import QtQuick.Controls 2.0
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias drawer: drawer
+
+ header: ToolBar { }
+
+ Drawer {
+ id: drawer
+ width: 200
+ height: parent.height
+ }
+}
diff --git a/tests/auto/drawer/data/reposition.qml b/tests/auto/drawer/data/reposition.qml
new file mode 100644
index 00000000..abaec5ae
--- /dev/null
+++ b/tests/auto/drawer/data/reposition.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.6
+import QtQuick.Controls 2.0
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias drawer: drawer
+
+ header: Item { implicitHeight: 50 }
+ footer: Item { implicitHeight: 50 }
+
+ Drawer {
+ id: drawer
+ width: parent.width / 2
+ implicitHeight: parent.height
+ }
+}
diff --git a/tests/auto/drawer/tst_drawer.cpp b/tests/auto/drawer/tst_drawer.cpp
index 8b02e95c..1ded5bf4 100644
--- a/tests/auto/drawer/tst_drawer.cpp
+++ b/tests/auto/drawer/tst_drawer.cpp
@@ -40,9 +40,13 @@
#include "../shared/visualtestutil.h"
#include <QtGui/qstylehints.h>
+#include <QtGui/qtouchdevice.h>
#include <QtGui/qguiapplication.h>
+#include <QtGui/qpa/qwindowsysteminterface.h>
+#include <QtQuick/private/qquickwindow_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
#include <QtQuickTemplates2/private/qquickoverlay_p.h>
+#include <QtQuickTemplates2/private/qquickpopup_p_p.h>
#include <QtQuickTemplates2/private/qquickdrawer_p.h>
#include <QtQuickTemplates2/private/qquickbutton_p.h>
#include <QtQuickTemplates2/private/qquickslider_p.h>
@@ -66,6 +70,7 @@ private slots:
void dragMargin();
void reposition();
+ void header();
void hover_data();
void hover();
@@ -74,6 +79,9 @@ private slots:
void wheel();
void multiple();
+
+ void touch_data();
+ void touch();
};
void tst_Drawer::visible_data()
@@ -323,27 +331,88 @@ void tst_Drawer::dragMargin()
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - rightDistance, drawer->height() / 2));
}
+static QRectF geometry(const QQuickItem *item)
+{
+ return QRectF(item->x(), item->y(), item->width(), item->height());
+}
+
void tst_Drawer::reposition()
{
- QQuickApplicationHelper helper(this, QStringLiteral("applicationwindow.qml"));
+ QQuickApplicationHelper helper(this, QStringLiteral("reposition.qml"));
QQuickApplicationWindow *window = helper.appWindow;
window->show();
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window));
- QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>();
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
QVERIFY(drawer);
- drawer->setEdge(Qt::RightEdge);
+ QQuickItem *popupItem = drawer->popupItem();
+ QVERIFY(popupItem);
drawer->open();
- QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width());
+ QQuickItem *dimmer = QQuickPopupPrivate::get(drawer)->dimmer;
+ QVERIFY(dimmer);
+
+ QCOMPARE(geometry(dimmer), QRectF(0, 0, window->width(), window->height()));
+ QTRY_COMPARE(geometry(popupItem), QRectF(0, 0, window->width() / 2, window->height()));
+
+ drawer->setY(100);
+ QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100));
+ QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height() - 100));
+
+ drawer->setHeight(window->height());
+ QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height()));
+ QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height()));
+
+ drawer->resetHeight();
+ QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100));
+ QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2, window->height() - 100));
+
+ drawer->setParentItem(window->contentItem());
+ QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150));
+ QCOMPARE(geometry(popupItem), QRectF(0, 150, window->width() / 2, window->height() - 150));
+
+ drawer->setEdge(Qt::RightEdge);
+ QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150));
+ QTRY_COMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150));
window->setWidth(window->width() + 100);
- QTRY_COMPARE(drawer->popupItem()->x(), window->width() - drawer->width());
+ QTRY_COMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150));
+ QCOMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2, window->height() - 150));
drawer->close();
- QTRY_COMPARE(drawer->popupItem()->x(), static_cast<qreal>(window->width()));
+ QTRY_COMPARE(geometry(popupItem), QRectF(window->width(), 150, window->width() / 2, window->height() - 150));
+}
+
+void tst_Drawer::header()
+{
+ QQuickApplicationHelper helper(this, QStringLiteral("header.qml"));
+
+ QQuickApplicationWindow *window = helper.appWindow;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickItem *content = window->contentItem();
+ QVERIFY(content);
+
+ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
+ QVERIFY(overlay);
+
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
+ QVERIFY(drawer);
+ QQuickItem *popupItem = drawer->popupItem();
+
+ drawer->open();
+ QVERIFY(drawer->isVisible());
+
+ QCOMPARE(drawer->parentItem(), overlay);
+ QCOMPARE(drawer->height(), overlay->height());
+ QCOMPARE(popupItem->height(), overlay->height());
+
+ drawer->setParentItem(content);
+ QCOMPARE(drawer->parentItem(), content);
+ QCOMPARE(drawer->height(), content->height());
+ QCOMPARE(popupItem->height(), content->height());
}
void tst_Drawer::hover_data()
@@ -615,6 +684,58 @@ void tst_Drawer::multiple()
QCOMPARE(leftDrawer->position(), 0.0);
}
+void tst_Drawer::touch_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("Window") << "window.qml";
+ QTest::newRow("ApplicationWindow") << "applicationwindow.qml";
+}
+
+void tst_Drawer::touch()
+{
+ QFETCH(QString, source);
+ QQuickApplicationHelper helper(this, source);
+
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>();
+ QVERIFY(drawer);
+
+ struct TouchDeviceDeleter
+ {
+ static inline void cleanup(QTouchDevice *device)
+ {
+ QWindowSystemInterface::unregisterTouchDevice(device);
+ delete device;
+ }
+ };
+
+ QScopedPointer<QTouchDevice, TouchDeviceDeleter> device(new QTouchDevice);
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device.data());
+
+ // drag to open
+ QTest::touchEvent(window, device.data()).press(0, QPoint(0, 100));
+ QTest::touchEvent(window, device.data()).move(0, QPoint(100, 100));
+ QTRY_COMPARE(drawer->position(), 0.5);
+ QTest::touchEvent(window, device.data()).release(0, QPoint(100, 100));
+ QTRY_COMPARE(drawer->position(), 1.0);
+
+ // drag to close
+ QTest::touchEvent(window, device.data()).press(0, QPoint(300, 100));
+ QTest::touchEvent(window, device.data()).move(0, QPoint(300 - drawer->dragMargin(), 100));
+ for (int x = 300; x > 100; x -= 10) {
+ QTest::touchEvent(window, device.data()).move(0, QPoint(x, 100));
+ QQuickWindowPrivate::get(window)->flushFrameSynchronousEvents();
+ }
+ QTest::touchEvent(window, device.data()).move(0, QPoint(100, 100));
+ QTRY_COMPARE(drawer->position(), 0.5);
+ QTest::touchEvent(window, device.data()).release(0, QPoint(100, 100));
+ QTRY_COMPARE(drawer->position(), 0.0);
+}
+
QTEST_MAIN(tst_Drawer)
#include "tst_drawer.moc"