aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2016-07-07 14:02:54 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2017-09-29 05:17:22 +0000
commita4439d6baf6996fd018575f5ed752b4d4429f92a (patch)
tree2e6ce4d50dc5020b27f36080164058bf40048d23 /src
parent8ebe8f6eeb798918486e1e9124a567dd90deff23 (diff)
improve documentation of the PointerHandler base classes and index
also QQuickPointerEvent and QQuickPointerDevice Change-Id: I8bdb7c26cf6a5775a77dbf748c47c170270c5fff Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/doc/images/pointDistanceThreshold.pngbin0 -> 8661 bytes
-rw-r--r--src/quick/doc/images/pointDistanceThreshold.svg217
-rw-r--r--src/quick/doc/images/touchpoint-metrics.svg580
-rw-r--r--src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc73
-rw-r--r--src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc44
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp40
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler.cpp118
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp80
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp232
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp3
-rw-r--r--src/quick/items/qquickevents.cpp363
-rw-r--r--src/quick/items/qquickevents_p_p.h1
12 files changed, 1705 insertions, 46 deletions
diff --git a/src/quick/doc/images/pointDistanceThreshold.png b/src/quick/doc/images/pointDistanceThreshold.png
new file mode 100644
index 0000000000..c883f5f8a1
--- /dev/null
+++ b/src/quick/doc/images/pointDistanceThreshold.png
Binary files differ
diff --git a/src/quick/doc/images/pointDistanceThreshold.svg b/src/quick/doc/images/pointDistanceThreshold.svg
new file mode 100644
index 0000000000..30d04e0df6
--- /dev/null
+++ b/src/quick/doc/images/pointDistanceThreshold.svg
@@ -0,0 +1,217 @@
+<?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"
+ id="svg6318"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+ viewBox="0 0 249.99999 100"
+ version="1.1"
+ sodipodi:docname="pointDistanceThreshold.svg"
+ width="250"
+ height="100"
+ inkscape:export-filename="/home/rutledge/dev/qt510/qtdeclarative/src/quick/doc/images/pointDistanceThreshold.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <title
+ id="title892">pointDistanceThreshold</title>
+ <defs
+ id="defs20">
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker1145"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mstart">
+ <path
+ inkscape:connector-curvature="0"
+ transform="scale(0.6)"
+ 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"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path1143" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5708"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5710"
+ 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)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5656"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path5658"
+ 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)"
+ 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="path4267"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4264"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="10"
+ pagecolor="#ffffff"
+ inkscape:zoom="2.1818696"
+ inkscape:window-width="3025"
+ inkscape:window-maximized="0"
+ inkscape:window-x="275"
+ showgrid="false"
+ borderopacity="1.0"
+ inkscape:current-layer="layer1"
+ inkscape:cx="-180.21887"
+ inkscape:cy="-3.6626369"
+ inkscape:window-height="2115"
+ inkscape:pageopacity="0.0"
+ inkscape:document-units="px"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <g
+ id="layer1"
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ transform="translate(14.90473,-165.12199)">
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4231"
+ width="30.622982"
+ height="41.004536"
+ x="127.52915"
+ y="204.5533"
+ ry="3.3911796"
+ transform="rotate(-6.0579549)" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006eed;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="129.10042"
+ y="218.27599"
+ id="text4234"
+ transform="rotate(-6.0579549)"><tspan
+ sodipodi:role="line"
+ id="tspan4236"
+ x="129.10042"
+ y="218.27599">Item</tspan></text>
+ <rect
+ ry="4.7313037"
+ y="196.45122"
+ x="121.42953"
+ height="57.208683"
+ width="42.822224"
+ id="rect1011"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
+ transform="rotate(-6.0579549)" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker5656)"
+ d="m 152.47483,208.41921 12.89093,-1.36808"
+ id="path1013"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path6337"
+ d="m 189.62569,349.61549 -24.29,-54.26 -12.83194,-58.84322 c -2.6119,-12.7355 2.2926,-19.07175 9.23283,-20.18303 6.94022,-1.11127 15.91617,3.00243 21.44717,11.16683 8.071,9.1465 4.33419,25.07247 11.96207,39.28935 7.62787,14.21687 15.16237,31.30787 22.85987,51.95087 l 5.2215,-4.5404 14.80555,-23.66072 -9.48553,-65.8264 -19.7978,-27.78564 -25.75599,2.46365 c -15.01523,-4.56498 -8.7269,-29.71674 14.1138,-30.8189 0,0 24.50188,-6.93892 30.57911,0.83552 6.07722,7.77444 30.208,23.27674 35.52842,29.53381 6.64558,7.81553 12.02547,67.49345 12.02547,67.49345"
+ sodipodi:nodetypes="cccscscccccccssc"
+ style="fill:#f2ecd5;fill-opacity:0.88108108;stroke:#4d4d4d;stroke-width:5.15140009;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.25098039"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path1141"
+ d="m 142.4415,209.48402 -12.89093,1.36807"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1145)" />
+ <text
+ id="text1335"
+ y="227.02623"
+ x="-37.15416"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"
+ transform="rotate(-6.0579549)"><tspan
+ y="227.02623"
+ x="-37.15416"
+ id="tspan1333"
+ sodipodi:role="line">pointDistanceThreshold</tspan></text>
+ </g>
+ <metadata
+ id="metadata19">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="https://www.gnu.org/licenses/fdl-1.3.html" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title></dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>pointDistanceThreshold</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>The Qt Company</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Shawn Rutledge</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:date>20170921</dc:date>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/quick/doc/images/touchpoint-metrics.svg b/src/quick/doc/images/touchpoint-metrics.svg
new file mode 100644
index 0000000000..cbf4cb3257
--- /dev/null
+++ b/src/quick/doc/images/touchpoint-metrics.svg
@@ -0,0 +1,580 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg6318"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+ viewBox="0 0 443.12941 596.85604"
+ version="1.1"
+ sodipodi:docname="touchpoint-metrics.svg"
+ width="443.12943"
+ height="596.85602"
+ inkscape:export-filename="/home/rutledge/dev/qt5/qtdeclarative/src/quick/doc/images/touchpoint-metrics.png"
+ inkscape:export-xdpi="90.474083"
+ inkscape:export-ydpi="90.474083">
+ <defs
+ id="defs20">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5708"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5710"
+ 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="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5656"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5658"
+ 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:isstock="true"
+ style="overflow:visible"
+ id="marker5436"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mend"
+ inkscape:collect="always">
+ <path
+ transform="scale(-0.6,-0.6)"
+ 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"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5438"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker5378"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mstart"
+ inkscape:collect="always">
+ <path
+ transform="scale(0.6,0.6)"
+ 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"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5380"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path4288"
+ 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="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path4285"
+ 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="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4267"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;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="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4264"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <filter
+ inkscape:collect="always"
+ style="color-interpolation-filters:sRGB"
+ id="filter4958-5"
+ x="-0.084455244"
+ width="1.1689105"
+ y="-0.74658436"
+ height="2.4931686">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="97.211503"
+ id="feGaussianBlur4960-1" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4317"
+ id="linearGradient5092"
+ gradientUnits="userSpaceOnUse"
+ x1="6603.8599"
+ y1="946.87665"
+ x2="6603.8599"
+ y2="-1479.8376"
+ gradientTransform="matrix(0.14148321,0,0,0.26337982,-551.07006,366.30969)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4317">
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="0"
+ id="stop4319" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.661"
+ offset="1"
+ id="stop4321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4149"
+ id="linearGradient4155-1"
+ x1="3145.3071"
+ y1="1359.6201"
+ x2="3082.0513"
+ y2="1461.0105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4149">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop4151" />
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ offset="1"
+ id="stop4153" />
+ </linearGradient>
+ </defs>
+ <title
+ id="title6969">press button</title>
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="10"
+ pagecolor="#ffffff"
+ inkscape:zoom="2.1818696"
+ inkscape:window-width="3025"
+ inkscape:window-maximized="0"
+ inkscape:window-x="275"
+ showgrid="false"
+ borderopacity="1.0"
+ inkscape:current-layer="layer1"
+ inkscape:cx="294.2435"
+ inkscape:cy="305.24727"
+ inkscape:window-height="2115"
+ inkscape:pageopacity="0.0"
+ inkscape:document-units="px"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <g
+ id="layer1"
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ transform="translate(-19.10777,28.71728)">
+ <ellipse
+ transform="matrix(0.17845239,0,0,-0.11180897,-891.75636,813.19424)"
+ ry="156.25"
+ rx="1381.25"
+ cy="2349.6123"
+ cx="6356.25"
+ id="path4860-7"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.35;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4958-5);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <g
+ id="g4433"
+ transform="matrix(0.68820663,0,0,0.68820663,5.9576757,-8.9538574)">
+ <rect
+ ry="15.802789"
+ y="-28.717279"
+ x="19.107775"
+ height="848.34637"
+ width="643.89008"
+ id="rect5025-7"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4244-3"
+ width="643.89008"
+ height="848.34637"
+ x="19.107775"
+ y="-23.449682"
+ ry="15.802789" />
+ <rect
+ ry="15.802789"
+ y="-23.449682"
+ x="19.107775"
+ height="848.34637"
+ width="643.89008"
+ id="rect4315-1"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.90399996;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient5092);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 34.910559,-23.449671 306.821051,0 315.87514,692.820621 0,139.72299 c 0,8.75475 -7.04805,15.80279 -15.80279,15.80279 l -606.893401,0 c -8.754745,0 -15.802789,-7.04804 -15.802789,-15.80279 l 0,-816.7408215 c 0,-8.7547455 7.048044,-15.8027895 15.802789,-15.8027895 z"
+ id="rect4325-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sccssssss" />
+ <rect
+ y="25.141434"
+ x="62.871906"
+ height="740.51996"
+ width="554.67615"
+ id="rect5094"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:64.19769287;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#939393;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:64.19769287;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4248-1"
+ width="520.93262"
+ height="706.77637"
+ x="79.74366"
+ y="42.013233" />
+ <g
+ id="g4779-1"
+ transform="matrix(0.33396996,0,0,0.33396996,-712.61797,319.71649)">
+ <circle
+ r="59.752544"
+ cy="1410.4148"
+ cx="3113.8386"
+ id="path4147-2"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4155-1);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ id="circle4157-9"
+ d="m 3122.5371,1358.1816 -0.8867,7.8477 a 45.109688,45.109688 0 0 1 37.2988,44.3848 45.109688,45.109688 0 0 1 -45.1113,45.1113 45.109688,45.109688 0 0 1 -45.1094,-45.1113 45.109688,45.109688 0 0 1 37.293,-44.42 l -0.8789,-7.7656 a 52.966831,52.966831 0 0 0 -44.2715,52.1856 52.966831,52.966831 0 0 0 52.9668,52.9668 52.966831,52.966831 0 0 0 52.9668,-52.9668 52.966831,52.966831 0 0 0 -44.2676,-52.2325 z"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ y="1357.4473"
+ x="3109.9236"
+ height="53.033009"
+ width="7.8286819"
+ id="rect4767-5"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000003, 1.00000003;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -93.997225,215.5841 -46.290585,0"
+ id="path4158"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4162"
+ d="m -117.94458,184.189 0,62.79019"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000006, 1.00000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <g
+ id="g4174"
+ transform="translate(-403.15923,36.297289)">
+ <ellipse
+ ry="24.954388"
+ rx="15.555983"
+ cy="178.94307"
+ cx="284.64172"
+ id="path4148"
+ style="opacity:1;fill:#e2ff8b;fill-opacity:0.25098039;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4156"
+ d="m 284.87089,179.28681 15.23922,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4160"
+ d="m 285.21463,179.28681 0,-25.4369"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <rect
+ style="opacity:1;fill:#e6e6e6;fill-opacity:1;stroke:#358e12;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4238"
+ width="321.4903"
+ height="289.082"
+ x="75.304832"
+ y="94.97757" />
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4231"
+ width="156.85616"
+ height="110.83637"
+ x="168.64072"
+ y="119.2838"
+ ry="9.1664505" />
+ <path
+ id="path6337"
+ d="m 320.3128,565.52961 -13.62,-29.96 c -45.92,-30.16 -78.8,-67.18 -98.53,-111.24 l -48.58,-108.52 c -5.2238,-25.471 19.618,-25.345 30.68,-9.0162 16.142,18.293 30.885,45.371 46.28,86.657 l 5.2215,-4.5404 -59.025,-218.39 c -4.2637,-29.243 23.814,-32.925 34.28,-12.486 l 49.717,145.07 3.6827,-2.1073 c -16.547,-46.113 32.245,-68.82 43.104,-12.947 l 2.4051,8.2164 0.63738,-0.20605 c -18.07,-41.645 26.255,-63.863 41.465,-20.253 l 3.9923,15.864 0.25639,-0.0618 c -4.7466,-31.9 24.489,-34.442 36.128,-17.563 15.213,22.024 62.049,126.67 36.323,223.39 l 14.529,64.473"
+ sodipodi:nodetypes="ccsccccccccccccccccc"
+ style="fill:#f2ecd5;fill-opacity:0.88108108;stroke:#4d4d4d;stroke-width:5.15140009;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.25098039"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4179"
+ d="m 257.62466,169.84909 -75.0045,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <ellipse
+ ry="20.747375"
+ rx="15.555983"
+ cy="210.94308"
+ cx="157.19211"
+ id="ellipse4185"
+ style="opacity:1;fill:#d2ff44;fill-opacity:0.69019608;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ transform="matrix(0.97361357,-0.228203,0.228203,0.97361357,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4187"
+ d="m 186.02082,173.21041 30.3228,-7.41015"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4189"
+ d="m 206.0817,189.77229 -9.79896,-40.5339"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4203"
+ d="m 202.70075,321.07311 -46.29058,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000003, 1.00000003;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000006, 1.00000006;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 179.88768,290.65026 0,62.79019"
+ id="path4205"
+ inkscape:connector-curvature="0" />
+ <ellipse
+ ry="24.954388"
+ rx="15.555983"
+ cy="366.34235"
+ cx="-33.562881"
+ id="ellipse4209"
+ style="opacity:1;fill:#d2ff44;fill-opacity:0.69005845;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ transform="matrix(0.82504909,-0.56506106,0.56506106,0.82504909,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4211"
+ d="m 166.58656,330.02978 25.45643,-17.62857"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4213"
+ d="M 193.54247,341.84882 165.08708,300.58218"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000005, 0.70000005;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 255.58123,156.48354 -55.13917,13.07972"
+ id="path4253"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.50683999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#Arrow2Mstart);marker-end:url(#Arrow2Mend)"
+ id="path4255"
+ sodipodi:type="arc"
+ sodipodi:cx="88.504486"
+ sodipodi:cy="192.79727"
+ sodipodi:rx="99.028755"
+ sodipodi:ry="60.303371"
+ sodipodi:start="0.0081667968"
+ sodipodi:end="0.18640007"
+ sodipodi:open="true"
+ d="m 187.52994,193.28975 a 99.028755,60.303371 0 0 1 -1.7121,10.6831"
+ inkscape:transform-center-x="-97.138756"
+ inkscape:transform-center-y="-2.1359185"
+ transform="matrix(0.99260218,-0.12141219,0.34645175,0.93806779,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5368"
+ d="m 197.32294,149.03759 -25.3509,5.88287"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.50000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker5378);marker-end:url(#marker5436)"
+ d="m 174.13381,155.92063 10.90284,37.60336"
+ id="path5370"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5650"
+ d="m 186.19518,173.42441 6.5705,28.76449"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000011;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000007, 0.70000007;stroke-dashoffset:0;stroke-opacity:1"
+ inkscape:transform-center-x="0.57875414"
+ inkscape:transform-center-y="-3.0663012" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 216.29427,166.04651 6.78267,28.89901"
+ id="path5652"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-x="11.459489"
+ inkscape:transform-center-y="17.730719" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5654"
+ d="m 193.42658,199.80678 27.98449,-7.24458"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.50000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker5656);marker-end:url(#marker5708)"
+ inkscape:transform-center-x="3.7104844"
+ inkscape:transform-center-y="53.812545" />
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#877553;stroke-width:0.49999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect6618"
+ width="32.408298"
+ height="41.563641"
+ x="184.97807"
+ y="148.72353" />
+ <rect
+ y="298.08408"
+ x="159.8698"
+ height="46.262844"
+ width="38.889957"
+ id="rect6620"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#877553;stroke-width:0.49999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="258.05429"
+ y="166.59993"
+ id="text6622"><tspan
+ sodipodi:role="line"
+ id="tspan6624"
+ x="258.05429"
+ y="166.59993">rotation</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="203.90126"
+ y="207.63615"
+ id="text6626"><tspan
+ sodipodi:role="line"
+ id="tspan6628"
+ x="203.90126"
+ y="207.63615">horizontalDiameter</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="76.891922"
+ y="180.37347"
+ id="text6630"><tspan
+ sodipodi:role="line"
+ id="tspan6632"
+ x="76.891922"
+ y="180.37347">verticalDiameter</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#877553;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="219.07135"
+ y="151.56999"
+ id="text4233"><tspan
+ sodipodi:role="line"
+ id="tspan4235"
+ x="219.07135"
+ y="151.56999">bounding box</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006eed;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="173.82605"
+ y="134.1916"
+ id="text4234"><tspan
+ sodipodi:role="line"
+ id="tspan4236"
+ x="173.82605"
+ y="134.1916">Item</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#358e12;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="81.786491"
+ y="109.88538"
+ id="text4240"><tspan
+ sodipodi:role="line"
+ id="tspan4242"
+ x="81.786491"
+ y="109.88538">Scene (Window)</tspan></text>
+ <path
+ inkscape:connector-curvature="0"
+ id="path4219"
+ d="m 261.39257,176.47248 -78.11808,18.63309"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000005, 0.70000005;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <metadata
+ id="metadata19">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="https://www.gnu.org/licenses/fdl-1.3.html" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Touch Point Metrics</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>The Qt Company</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Shawn Rutledge</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:date>20170921</dc:date>
+ <dc:description>The hand image is from https://openclipart.org/detail/192689/press-button
+The generic tablet device is from https://openclipart.org/detail/244440/computer-tablet-and-phone-vectors</dc:description>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc
new file mode 100644
index 0000000000..b17c5ab728
--- /dev/null
+++ b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtquickhandlers-index.html
+ \title Qt Quick Pointer Handlers
+ \brief A module with a set of QML elements that handle events from pointing devices in a user interface.
+
+ Qt Quick Pointer Handlers are a set of QML types used to handle events from
+ touch, mouse, and stylus devices in a UI. In contrast to event-handling
+ Items, such as \l MouseArea, Pointer Handlers require less memory and are
+ intended to be used in greater numbers: one handler per type of
+ interaction. Each Pointer Handler handles events on behalf of its \c parent
+ Item. One Item can have multiple Pointer Handlers.
+
+ The module is introduced in Qt 5.10.
+
+ \section1 Pointer Handlers
+
+ \annotatedlist pointerhandlers
+
+ \section1 Getting Started
+
+ The QML types can be imported into your application using the following import statement in your \c {.qml} file.
+
+ \code
+ import Qt.labs.handlers 1.0
+ \endcode
+
+ \section1 Key Features
+
+ Some of the key features are:
+
+ \list
+ \li Handle gestures such as tapping or dragging regardless which device it comes from
+ \li Handle gestures from different classes of devices in different ways
+ \li Each Item can have unlimited Handlers
+ \endlist
+
+ \omit TODO actual overview with snippets and stuff \endomit
+
+ \section1 Related Information
+
+ \list
+ \li \l{Qt Quick}
+ \li \l{Qt Quick Pointer Handlers Overview}
+ \li \l{Qt Quick Pointer Handlers QML Types}{Qt Quick Pointer Handlers QML Types}
+ \endlist
+*/
diff --git a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc
new file mode 100644
index 0000000000..cf87c75e8c
--- /dev/null
+++ b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmlmodule Qt.labs.handlers 1.0
+ \title Qt Quick Pointer Handlers QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for handling events from pointing devices in a user interface.
+
+ The \l{Qt Quick Pointer Handlers} module provides QML types for handling
+ events from pointing devices in a UI. These QML types work in conjunction
+ with \l{Qt Quick}.
+
+ The QML types can be imported into your application using the
+ following import statement in your .qml file.
+
+ \code
+ import Qt.labs.handlers 1.0
+ \endcode
+*/
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index 41d8b228a1..2ced136026 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -46,8 +46,17 @@
QT_BEGIN_NAMESPACE
/*!
+ \qmltype MultiPointHandler
+ \since 5.10
+ \preliminary
+ \instantiates QQuickMultiPointHandler
+ \inherits PointerDeviceHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for multi-point Pointer Events.
+
An intermediate class (not registered as a QML type)
- for the type of handler which requires and acts upon a specific number
+ for any type of handler which requires and acts upon a specific number
of multiple touchpoints.
*/
QQuickMultiPointHandler::QQuickMultiPointHandler(QObject *parent, int requiredPointCount)
@@ -99,6 +108,20 @@ QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointe
return ret;
}
+/*!
+ \qmlproperty int MultiPointHandler::requiredPointCount
+
+ The number of touchpoints that are required to activate this handler. If
+ a smaller number of touchpoints are in contact with the
+ \l {PointerHandler::parent}{parent}, they will be ignored. If a larger number
+ of touchpoints are in contact, the required number of points will be
+ chosen in the order that they are pressed, and the remaining points will
+ be ignored. Any ignored points are eligible to activate other Pointer
+ Handlers, which have different constraints, on the same Item or on other
+ Items.
+
+ The default value is 2.
+*/
void QQuickMultiPointHandler::setRequiredPointCount(int c)
{
if (m_requiredPointCount == c)
@@ -108,6 +131,21 @@ void QQuickMultiPointHandler::setRequiredPointCount(int c)
emit requiredPointCountChanged();
}
+
+/*!
+ \qmlproperty real MultiPointHandler::pointDistanceThreshold
+
+ The margin beyond the bounds of the \l {PointerHandler::parent}{parent}
+ item within which a touch point can activate this handler. For example, on
+ a PinchHandler where the \l {PointerHandler::target}{target} is also the
+ \c parent, it's useful to set this to a distance at least half the width
+ of a typical user's finger, so that if the \c parent has been scaled down
+ to a very small size, the pinch gesture is still possible.
+
+ The default value is 0.
+
+ \image pointDistanceThreshold.png
+*/
void QQuickMultiPointHandler::setPointDistanceThreshold(qreal pointDistanceThreshold)
{
if (m_pointDistanceThreshold == pointDistanceThreshold)
diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp
index dd0ff1f44c..1521b58d57 100644
--- a/src/quick/handlers/qquickpointerdevicehandler.cpp
+++ b/src/quick/handlers/qquickpointerdevicehandler.cpp
@@ -45,10 +45,19 @@
QT_BEGIN_NAMESPACE
/*!
- An intermediate class (not registered as a QML type)
- for handlers which allow filtering based on device type,
- pointer type, or device-specific buttons (such as mouse or stylus buttons).
- */
+ \qmltype PointerDeviceHandler
+ \qmlabstract
+ \since 5.10
+ \preliminary
+ \instantiates QQuickPointerDeviceHandler
+ \inherits PointerHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for pointer events with device-specific constraints.
+
+ An intermediate class (not registered as a QML type) for handlers which
+ allow filtering based on device type, pointer type, or keyboard modifiers.
+*/
QQuickPointerDeviceHandler::QQuickPointerDeviceHandler(QObject *parent)
: QQuickPointerHandler(parent)
, m_acceptedDevices(QQuickPointerDevice::AllDevices)
@@ -61,6 +70,31 @@ QQuickPointerDeviceHandler::~QQuickPointerDeviceHandler()
{
}
+/*!
+ \qmlproperty int PointerDeviceHandler::acceptedDevices
+
+ The types of pointing devices that can activate this Pointer Handler.
+
+ By default, this property is set to \l PointerDevice.AllDevices.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching devices.
+
+ For example, a control could be made to respond to mouse and stylus clicks
+ in one way, and touchscreen taps in another way, with two handlers:
+
+ \qml
+ Item {
+ TapHandler {
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ onTapped: console.log("clicked")
+ }
+ TapHandler {
+ acceptedDevices: PointerDevice.TouchScreen
+ onTapped: console.log("tapped")
+ }
+ }
+ \endqml
+*/
void QQuickPointerDeviceHandler::setAcceptedDevices(QQuickPointerDevice::DeviceTypes acceptedDevices)
{
if (m_acceptedDevices == acceptedDevices)
@@ -70,6 +104,34 @@ void QQuickPointerDeviceHandler::setAcceptedDevices(QQuickPointerDevice::DeviceT
emit acceptedDevicesChanged();
}
+/*!
+ \qmlproperty int PointerDeviceHandler::acceptedPointerTypes
+
+ The types of pointing instruments (finger, stylus, eraser, etc.)
+ that can activate this Pointer Handler.
+
+ By default, this property is set to \l PointerDevice.AllPointerTypes.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching events.
+
+ For example, a control could be made to respond to mouse, touch, and stylus clicks
+ in some way, but delete itself if tapped with an eraser tool on a graphics tablet,
+ with two handlers:
+
+ \qml
+ Rectangle {
+ id: rect
+ TapHandler {
+ acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Finger | PointerDevice.Pen
+ onTapped: console.log("clicked")
+ }
+ TapHandler {
+ acceptedPointerTypes: PointerDevice.Eraser
+ onTapped: rect.destroy()
+ }
+ }
+ \endqml
+*/
void QQuickPointerDeviceHandler::setAcceptedPointerTypes(QQuickPointerDevice::PointerTypes acceptedPointerTypes)
{
if (m_acceptedPointerTypes == acceptedPointerTypes)
@@ -80,30 +142,30 @@ void QQuickPointerDeviceHandler::setAcceptedPointerTypes(QQuickPointerDevice::Po
}
/*!
- \qmlproperty int PointerDeviceHandler::acceptedModifiers
-
- If this property is set, it will require the given keyboard modifiers to
- be pressed in order to react to pointer events, and otherwise ignore them.
-
- If this property is set to \c Qt.KeyboardModifierMask (the default value),
- then the PointerHandler ignores the modifier keys.
-
- For example, an \l [QML] Item could have two handlers of the same type,
- one of which is enabled only if the required keyboard modifiers are
- pressed:
-
- \qml
- Item {
- TapHandler {
- acceptedModifiers: Qt.ControlModifier
- onTapped: console.log("control-tapped")
- }
- TapHandler {
- acceptedModifiers: Qt.NoModifier
- onTapped: console.log("tapped")
- }
- }
- \endqml
+ \qmlproperty int PointerDeviceHandler::acceptedModifiers
+
+ If this property is set, it will require the given keyboard modifiers to
+ be pressed in order to react to pointer events, and otherwise ignore them.
+
+ If this property is set to \c Qt.KeyboardModifierMask (the default value),
+ then the PointerHandler ignores the modifier keys.
+
+ For example, an \l [QML] Item could have two handlers of the same type,
+ one of which is enabled only if the required keyboard modifiers are
+ pressed:
+
+ \qml
+ Item {
+ TapHandler {
+ acceptedModifiers: Qt.ControlModifier
+ onTapped: console.log("control-tapped")
+ }
+ TapHandler {
+ acceptedModifiers: Qt.NoModifier
+ onTapped: console.log("tapped")
+ }
+ }
+ \endqml
*/
void QQuickPointerDeviceHandler::setAcceptedModifiers(Qt::KeyboardModifiers acceptedModifiers)
{
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
index 14ce8fea03..c32bec665c 100644
--- a/src/quick/handlers/qquickpointerhandler.cpp
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -46,13 +46,16 @@ Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active")
/*!
\qmltype PointerHandler
- //! \instantiates QQuickPointerHandler
- \inqmlmodule QtQuick
+ \qmlabstract
+ \since 5.10
+ \preliminary
+ \instantiates QQuickPointerHandler
+ \inqmlmodule Qt.labs.handlers
\ingroup qtquick-handlers
- \brief Handler for pointer events.
+ \brief Abstract handler for pointer events.
- PointerHandler is a handler for pointer events regardless of source.
- They may represent events from a touch, mouse or tablet device.
+ PointerHandler is the base class handler (not registered as a QML type) for
+ pointer events without regard to source (touch, mouse or graphics tablet).
*/
QQuickPointerHandler::QQuickPointerHandler(QObject *parent)
@@ -79,7 +82,7 @@ QQuickPointerHandler::~QQuickPointerHandler()
/*!
Notification that the grab has changed in some way which is relevant to this handler.
The \a grabber (subject) will be the PointerHandler whose state is changing,
- or null if the state change regards an Item. (TODO do we have any such cases?)
+ or null if the state change regards an Item.
The \a stateChange (verb) tells what happened.
The \a point (object) is the point that was grabbed or ungrabbed.
EventPoint has the sole responsibility to call this function.
@@ -124,6 +127,22 @@ void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEv
}
}
+/*!
+ \internal
+ Acquire or give up a passive grab of the given \a point, according to the \a grab state.
+
+ Unlike the exclusive grab, multiple PointerHandlers can have passive grabs
+ simultaneously. This means that each of them will receive further events
+ when the \a point moves, and when it is finally released. Typically a
+ PointerHandler should acquire a passive grab as soon as a point is pressed,
+ if the handler's constraints do not clearly rule out any interest in that
+ point. For example, DragHandler needs a passive grab in order to watch the
+ movement of a point to see whether it will be dragged past the drag
+ threshold. When a handler is actively manipulating its \l target (that is,
+ when \l active is true), it may be able to do its work with only a passive
+ grab, or it may acquire an exclusive grab if the gesture clearly must not
+ be interpreted in another way by another handler.
+*/
void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab)
{
qCDebug(lcPointerHandlerDispatch) << point << grab;
@@ -144,6 +163,10 @@ void QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab)
point->setGrabberPointerHandler(grab ? this : nullptr, true);
}
+/*!
+ \internal
+ Cancel any existing grab of the given \a point.
+*/
void QQuickPointerHandler::cancelAllGrabs(QQuickEventPoint *point)
{
qCDebug(lcPointerHandlerDispatch) << point;
@@ -165,13 +188,10 @@ bool QQuickPointerHandler::parentContains(const QQuickEventPoint *point) const
}
/*!
- \qmlproperty bool PointerHandler::enabled
+ \qmlproperty bool QtQuick::PointerHandler::enabled
If a PointerHandler is disabled, it will reject all events
and no signals will be emitted.
-
- TODO is it too extreme not even to emit pressed/updated/released?
- or should we disable only the higher-level interpretation, in subclasses?
*/
void QQuickPointerHandler::setEnabled(bool enabled)
{
@@ -182,6 +202,17 @@ void QQuickPointerHandler::setEnabled(bool enabled)
emit enabledChanged();
}
+/*!
+ \qmlproperty Item QtQuick::PointerHandler::target
+
+ The Item which this handler will manipulate.
+
+ By default, it is the same as the \l parent: the Item within which
+ the handler is declared. However, it can sometimes be useful to set the
+ target to a different Item, in order to handle events within one item
+ but manipulate another; or to \c null, to disable the default behavior
+ and do something else instead.
+*/
void QQuickPointerHandler::setTarget(QQuickItem *target)
{
m_targetExplicitlySet = true;
@@ -225,6 +256,16 @@ bool QQuickPointerHandler::wantsPointerEvent(QQuickPointerEvent *event)
return m_enabled;
}
+/*!
+ \readonly
+ \qmlproperty bool QtQuick::PointerHandler::active
+
+ This holds true whenever this PointerHandler has taken sole responsibility
+ for handing one or more EventPoints, by successfully taking an exclusive
+ grab of those points. This means that it is keeping its properties
+ up-to-date according to the movements of those Event Points and actively
+ manipulating its \l target (if any).
+*/
void QQuickPointerHandler::setActive(bool active)
{
if (m_active != active) {
@@ -241,7 +282,8 @@ void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event)
}
/*!
- \qmlproperty Item PointerHandler::parent
+ \readonly
+ \qmlproperty Item QtQuick::PointerHandler::parent
The \l Item which is the scope of the handler; the Item in which it was declared.
The handler will handle events on behalf of this Item, which means a
@@ -249,7 +291,21 @@ void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event)
the Item's interior. Initially \l target() is the same, but target()
can be reassigned.
- \sa QQuickPointerHandler::target(), QObject::parent()
+ \sa QQuick::PointerHandler::target(), QObject::parent()
+*/
+
+/*!
+ \qmlsignal QtQuick::PointerHandler::grabChanged(EventPoint point)
+
+ This signal is emitted when this handler has acquired or relinquished a
+ passive or exclusive grab of the given \a point.
+*/
+
+/*!
+ \qmlsignal QtQuick::PointerHandler::canceled(EventPoint point)
+
+ If this handler has already grabbed the given \a point, this signal is
+ emitted when the grab is stolen by a different Pointer Handler or Item.
*/
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index 2588c4c180..dee168a8e4 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -43,6 +43,15 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH_TARGET)
/*!
+ \qmltype SinglePointHandler
+ \qmlabstract
+ \preliminary
+ \instantiates QQuickSinglePointHandler
+ \inherits PointerDeviceHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for single-point Pointer Events.
+
An intermediate class (not registered as a QML type)
for the most common handlers: those which expect only a single point.
wantsPointerEvent() will choose the first point which is inside the
@@ -203,6 +212,35 @@ void QQuickSinglePointHandler::moveTarget(QPointF pos, QQuickEventPoint *point)
m_pointInfo.m_position = target()->mapFromScene(m_pointInfo.m_scenePosition);
}
+/*!
+ \qmlproperty int QtQuick::SinglePointHandler::acceptedButtons
+
+ The mouse buttons which can activate this Pointer Handler.
+
+ By default, this property is set to \l Qt.LeftButton.
+ It can be set to an OR combination of mouse buttons, and will ignore events
+ from other buttons.
+
+ For example, a control could be made to respond to left and right clicks
+ in different ways, with two handlers:
+
+ \qml
+ Item {
+ TapHandler {
+ onTapped: console.log("left clicked")
+ }
+ TapHandler {
+ acceptedButtons: Qt.RightButton
+ onTapped: console.log("right clicked")
+ }
+ }
+ \endqml
+
+ \note Tapping on a touchscreen or tapping the stylus on a graphics tablet
+ emulates clicking the left mouse button. This behavior can be altered via
+ \l {PointerDeviceHandler::acceptedDevices}{acceptedDevices} or
+ \l {PointerDeviceHandler::acceptedPointerTypes}{acceptedPointerTypes}.
+*/
void QQuickSinglePointHandler::setAcceptedButtons(Qt::MouseButtons buttons)
{
if (m_acceptedButtons == buttons)
@@ -218,6 +256,43 @@ void QQuickSinglePointHandler::reset()
m_pointInfo.reset();
}
+/*!
+ \readonly
+ \qmlproperty HandlerPoint QtQuick::SinglePointHandler::point
+
+ The event point currently being handled. When no point is currently being
+ handled, this object is reset to default values (all coordinates are 0).
+*/
+
+/*!
+ \qmltype HandlerPoint
+ \instantiates QQuickHandlerPoint
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief An event point
+
+ A QML representation of a QQuickEventPoint.
+
+ It's possible to make bindings to properties of a \l SinglePointHandler's
+ current point. For example:
+
+ \snippet pointerHandlers/dragHandlerNullTarget.qml 0
+
+ The point is kept up-to-date when the DragHandler is actively responding to
+ an EventPoint; but when the point is released, or the current point is
+ being handled by a different handler, \c position.x and \c position.y are 0.
+
+ \note This is practically identical to QtQuick::EventPoint; however an
+ EventPoint is a long-lived QObject which is invalidated between gestures
+ and reused for subsequent event deliveries. Continuous bindings to its
+ properties are not possible, and an individual handler cannot rely on it
+ outside the period when that point is part of an active gesture which that
+ handler is handling. HandlerPoint is a Q_GADGET that the handler owns.
+ This allows you to make lifetime bindings to its properties.
+
+ \sa SinglePointHandler::point
+*/
+
QQuickHandlerPoint::QQuickHandlerPoint()
: m_id(0)
, m_rotation(0)
@@ -240,4 +315,161 @@ void QQuickHandlerPoint::reset()
m_pressedButtons = Qt::NoButton;
}
+/*!
+ \readonly
+ \qmlproperty int QtQuick::HandlerPoint::id
+ \brief The ID number of the point
+
+ During a touch gesture, from the time that the first finger is pressed
+ until the last finger is released, each touchpoint will have a unique ID
+ number. Likewise, if input from multiple devices occurs (for example
+ simultaneous mouse and touch presses), all the current event points from
+ all the devices will have unique IDs.
+
+ \note Do not assume that id numbers start at zero or that they are
+ sequential. Such an assumption is often false due to the way the underlying
+ drivers work.
+
+ \sa QTouchEvent::TouchPoint::id
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointingDeviceUniqueId QtQuick::HandlerPoint::uniqueId
+ \brief The unique ID of the point, if any
+
+ This is normally empty, because touchscreens cannot uniquely identify fingers.
+
+ On some types of touchscreens, especially those using TUIO drivers,
+ it's possible to use recognizable physical tokens (fiducial objects)
+ in addition to fingers. So if this point is a touch point, and
+ uniqueId is set, it is the identifier for such an object.
+
+ On a graphics tablet, each type of stylus or other tool often has a unique
+ ID or serial number, which can be useful to respond in different ways to
+ different tools.
+
+ Interpreting the contents of this ID requires knowledge of the hardware and
+ drivers in use.
+
+ \sa QTabletEvent::uniqueId, QtQuick::TouchPoint::uniqueId, QtQuick::EventTouchPoint::uniqueId
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::position
+ \brief The position within the \c parent Item
+
+ This is the position of the event point relative to the bounds of the \l parent.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::scenePosition
+ \brief The position within the scene
+
+ This is the position of the event point relative to the bounds of the Qt
+ Quick scene (typically the whole window).
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::pressPosition
+ \brief The pressed position within the \c parent Item
+
+ This is the position at which this point was pressed, relative to the
+ bounds of the \l parent.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::scenePressPosition
+ \brief The pressed position within the scene
+
+ This is the position at which this point was pressed, in the coordinate
+ system of the \l {Qt Quick Scene Graph}{scene graph}.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::sceneGrabPosition
+ \brief The grabbed position within the scene
+
+ If this point has been grabbed by a Pointer Handler or an Item, it means
+ that object has taken sole responsibility for handling the movement and the
+ release if this point. In that case, this is the position at which the grab
+ occurred, in the coordinate system of the \l {Qt Quick Scene Graph}{scene graph}.
+*/
+
+/*!
+ \readonly
+ \qmlproperty enum QtQuick::HandlerPoint::pressedButtons
+ \brief Which mouse or stylus buttons are currently pressed
+
+ \sa MouseArea::pressedButtons
+*/
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::HandlerPoint::velocity
+ \brief A vector representing the average speed and direction of movement
+
+ This is a velocity vector pointing in the direction of movement, in logical
+ pixels per second. It has x and y components, at least one of which will be
+ nonzero when this point is in motion. It holds the average recent velocity:
+ how fast and in which direction the event point has been moving recently.
+
+ \sa QtQuick::EventPoint::velocity, QtQuick::TouchPoint::velocity, QTouchEvent::TouchPoint::velocity
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::HandlerPoint::rotation
+
+ This property holds the rotation angle of the stylus on a graphics tablet
+ or the contact patch of a touchpoint on a touchscreen.
+
+ It is valid only with certain tablet stylus devices and touchscreens that
+ can measure the rotation angle. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::HandlerPoint::pressure
+
+ This property tells how hard the user is pressing the stylus on a graphics
+ tablet or the finger against a touchscreen, in the range from \c 0 (no
+ measurable pressure) to \c 1.0 (maximum pressure which the device can
+ measure).
+
+ It is valid only with certain tablets and touchscreens that can measure
+ pressure. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty size QtQuick::HandlerPoint::ellipseDiameters
+
+ This property holds the diameters of the contact patch, if the event
+ comes from a touchpoint and the device provides this information.
+
+ A touchpoint is modeled as an elliptical area where the finger is pressed
+ against the touchscreen. (In fact, it could also be modeled as a bitmap;
+ but in that case we expect an elliptical bounding estimate to be fitted to
+ the contact patch before the event is sent.) The harder the user presses,
+ the larger the contact patch; so, these diameters provide an alternate way
+ of detecting pressure, in case the device does not include a separate
+ pressure sensor. The ellipse is centered on \l scenePosition (\l position
+ in the PointerHandler's Item's local coordinates). The \l rotation property
+ provides the rotation of the ellipse, if known. It is expected that if the
+ \l rotation is zero, the \l {QSize::height}{height} is the larger dimension
+ (the major axis), because of the usual hand position, reaching upward or
+ outward across the surface.
+
+ If the contact patch is unknown, or the device is not a touchscreen,
+ these values will be zero.
+
+ \sa QtQuick::EventPoint::ellipseDiameters, QtQuick::TouchPoint::ellipseDiameters, QTouchEvent::TouchPoint::ellipseDiameters
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
index f99f84bdb0..e5b728db0f 100644
--- a/src/quick/handlers/qquicktaphandler.cpp
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -54,6 +54,7 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
/*!
\qmltype TapHandler
\instantiates QQuickTapHandler
+ \inherits SinglePointHandler
\inqmlmodule Qt.labs.handlers
\ingroup qtquick-handlers
\brief Handler for taps and clicks.
@@ -326,6 +327,7 @@ void QQuickTapHandler::updateTimeHeld()
/*!
\qmlproperty int TapHandler::tapCount
+ \readonly
The number of taps which have occurred within the time and space
constraints to be considered a single gesture. For example, to detect
@@ -345,6 +347,7 @@ void QQuickTapHandler::updateTimeHeld()
/*!
\qmlproperty real TapHandler::timeHeld
+ \readonly
The amount of time in seconds that a pressed point has been held, without
moving beyond the drag threshold. It will be updated at least once per
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 90e72ebde6..3011d75aa0 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -447,6 +447,84 @@ Item {
\l inverted always returns false.
*/
+/*!
+ \qmltype PointerDevice
+ \instantiates QQuickPointerDevice
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about a pointing device
+
+ A pointing device can be a mouse, a touchscreen, or a stylus on a graphics
+ tablet.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::type
+
+ This property holds the type of the pointing device.
+
+ Valid values are:
+
+ \value DeviceType.UnknownDevice
+ the device cannot be identified
+ \value DeviceType.Mouse
+ a mouse
+ \value DeviceType.TouchScreen
+ a touchscreen providing absolute coordinates
+ \value DeviceType.TouchPad
+ a trackpad or touchpad providing relative coordinates
+ \value DeviceType.Stylus
+ a pen-like device
+ \value DeviceType.Airbrush
+ a stylus with a thumbwheel to adjust
+ \l {QTabletEvent::tangentialPressure}{tangentialPressure}
+ \value DeviceType.Puck
+ a device that is similar to a flat mouse with a
+ transparent circle with cross-hairs (same as \l QTabletEvent::Puck)
+
+ \sa QTouchDevice::DeviceType
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::capabilities
+
+ This property holds a bitwise combination of the capabilities of the
+ pointing device. It tells you under which conditions events are sent,
+ and which properties of PointerEvent are expected to be valid.
+
+ Valid values are:
+
+ \value CapabilityFlag.Position
+ the \l {QtQuick::EventPoint::position}{position} and
+ \l {QtQuick::EventPoint::scenePosition}{scenePosition} properties
+ \value CapabilityFlag.Area
+ the \l {QtQuick::EventTouchPoint::ellipseDiameters}{ellipseDiameters} property
+ \value CapabilityFlag.Pressure
+ the \l {QtQuick::EventTouchPoint::pressure}{pressure} property
+ \value CapabilityFlag.Velocity
+ the \l {QtQuick::PointerEvent::velocity}{velocity} property
+ \value CapabilityFlag.Scroll
+ a \l {QtQuick::PointerDevice::DeviceType::Mouse}{Mouse} has a wheel, or the
+ operating system recognizes scroll gestures on a
+ \l {QtQuick::PointerDevice::DeviceType::TouchPad}{TouchPad}
+ \value CapabilityFlag.Hover
+ events are sent even when no button is pressed, or the finger or stylus
+ is not in contact with the surface
+ \value CapabilityFlag.Rotation
+ the \l {QtQuick::EventTouchPoint::rotation}{rotation} property
+ \value CapabilityFlag.XTilt
+ horizontal angle between a stylus and the axis perpendicular to the surface
+ \value CapabilityFlag.YTilt
+ vertical angle between a stylus and the axis perpendicular to the surface
+
+ \sa QTouchDevice::capabilities
+*/
+
typedef QHash<QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)
@@ -531,6 +609,118 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
return nullptr;
}
+/*!
+ \qmltype EventPoint
+ \qmlabstract
+ \instantiates QQuickEventPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual point within a PointerEvent
+
+ A PointerEvent contains an EventPoint for each point of contact: one corresponding
+ to the mouse cursor, or one for each finger touching a touchscreen.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::position
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the upper-left corner of the Item which has the PointerHandler.
+ If a contact patch is available from the pointing device, this point
+ represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePosition
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the scene. If a contact patch is available from the \l device,
+ this point represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePressPosition
+
+ This property holds the scene-relative position at which the press event
+ (on a touch device) or most recent change in QQuickPointerEvent::buttons()
+ (on a mouse or tablet stylus) occurred.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::sceneGrabPosition
+
+ This property holds the scene-relative position at which the EventPoint was
+ located when setGrabber() was called most recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty vector2d QtQuick::EventPoint::velocity
+
+ This property holds average recent velocity: how fast and in which
+ direction the event point has been moving recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::state
+
+ This property tells what the user is currently doing at this point.
+
+ It can be one of:
+ \value Pressed
+ The user's finger is now pressing a touchscreen, button or stylus
+ which was not pressed already
+ \value Updated
+ The touchpoint or position is being moved, with no change in pressed state
+ \value Stationary
+ The touchpoint or position is not being moved, and there is also
+ no change in pressed state
+ \value Released
+ The user's finger has now released a touch point, button or stylus
+ which was pressed
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::pointId
+
+ This property holds the ID of the event, if any.
+
+ Touchpoints have automatically-incrementing IDs: each time the user
+ presses a finger against the touchscreen, it will be a larger number.
+ In other cases, it will be -1.
+
+ \sa PointerDevice.uniqueId
+*/
+
+/*!
+ \readonly
+ \qmlproperty bool QtQuick::EventPoint::accepted
+
+ Setting \a accepted to true prevents the event from being propagated to
+ Items below the PointerHandler's Item.
+
+ Generally, if the handler acts on the mouse event, then it should be
+ accepted so that items lower in the stacking order do not also respond to
+ the same event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty real QtQuick::EventPoint::timeHeld
+
+ This property holds the amount of time that the button or touchpoint has
+ been held. It can be used to detect a "long press", and can drive an
+ animation to show progress toward activation of the "long press" action.
+*/
+
void QQuickEventPoint::reset(Qt::TouchPointState state, const QPointF &scenePos, int pointId, ulong timestamp, const QVector2D &velocity)
{
m_scenePos = scenePos;
@@ -761,10 +951,15 @@ void QQuickEventPoint::cancelAllGrabs(QQuickPointerHandler *handler)
}
/*!
- Set this point as \a accepted (true) or rejected (false).
- Accepting a point is intended to stop event propagation.
- It does not imply any kind of grab, passive or exclusive.
- TODO explain further under what conditions propagation really does stop...
+ Sets this point as \a accepted (true) or rejected (false).
+
+ During delivery of the current event to the Items in the scene, each Item
+ or Pointer Handler should accept the points for which it is taking
+ responsibility. As soon as all points within the event are accepted, event
+ propagation stops. However accepting the point does not imply any kind of
+ grab, passive or exclusive.
+
+ \sa setExclusiveGrabber, QQuickPointerHandler::setPassiveGrab, QQuickPointerHandler::setExclusiveGrab
*/
void QQuickEventPoint::setAccepted(bool accepted)
{
@@ -774,6 +969,86 @@ void QQuickEventPoint::setAccepted(bool accepted)
}
}
+
+/*!
+ \qmltype EventTouchPoint
+ \qmlabstract
+ \instantiates QQuickEventTouchPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual touch point within a PointerEvent
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointerUniqueId QtQuick::EventTouchPoint::uniqueId
+
+ This property holds the unique ID of the fiducial or stylus in use, if any.
+
+ On touchscreens that can track physical objects (such as knobs or game
+ pieces) in addition to fingers, each object usually has a unique ID.
+ Likewise, each stylus that can be used with a graphics tablet usually has a
+ unique serial number. Qt so far only supports numeric IDs. You can get the
+ actual number as uniqueId.numeric, but that is a device-specific detail.
+ In the future, there may be support for non-numeric IDs, so you should
+ not assume that the number is meaningful.
+
+ If you need to identify specific objects, your application should provide
+ UI for registering objects and mapping them to functionality: allow the
+ user to select a meaning, virtual tool, or action, prompt the user to bring
+ the object into proximity, and store a mapping from uniqueId to its
+ purpose, for example in \l Settings.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::rotation
+
+ This property holds the rotation angle of the stylus on a graphics tablet
+ or the contact patch of a touchpoint on a touchscreen.
+
+ It is valid only with certain tablet stylus devices and touchscreens that
+ can measure the rotation angle. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::pressure
+
+ This property tells how hard the user is pressing the stylus on a graphics
+ tablet or the finger against a touchscreen, in the range from \c 0 (no
+ measurable pressure) to \c 1.0 (maximum pressure which the device can
+ measure).
+
+ It is valid only with certain tablets and touchscreens that can measure
+ pressure. Otherwise, it will be \c 1.0 when pressed.
+*/
+
+/*!
+ \readonly
+ \qmlproperty size QtQuick::EventTouchPoint::ellipseDiameters
+
+ This property holds the diameters of the contact patch, if the event
+ comes from a touchpoint and the \l device provides this information.
+
+ A touchpoint is modeled as an elliptical area where the finger is pressed
+ against the touchscreen. (In fact, it could also be modeled as a bitmap; but
+ in that case we expect an elliptical bounding estimate to be fitted to the
+ contact patch before the event is sent.) The harder the user presses, the
+ larger the contact patch; so, these diameters provide an alternate way of
+ detecting pressure, in case the device does not include a separate pressure
+ sensor. The ellipse is centered on \l scenePos (\l pos in the PointerHandler's
+ Item's local coordinates). The \l rotation property provides the
+ rotation of the ellipse, if known. It is expected that if the \l rotation
+ is zero, the verticalDiameter of the ellipse is the larger one (the major axis),
+ because of the usual hand position, reaching upward or outward across the surface.
+
+ If the contact patch is unknown, or the \l device is not a touchscreen,
+ these values will be zero.
+*/
+
QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent)
: QQuickEventPoint(parent), m_rotation(0), m_pressure(0)
{}
@@ -846,6 +1121,24 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
}
/*!
+ \qmltype PointerEvent
+ \instantiates QQuickPointerEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about an event from a pointing device
+
+ A PointerEvent is an event describing contact or movement across a surface,
+ provided by a mouse, a touchpoint (single finger on a touchscreen), or a
+ stylus on a graphics tablet. The \l device property provides more
+ information about where the event came from.
+
+ \sa PointerHandler
+
+ \image touchpoint-metrics.png
+*/
+
+/*!
\internal
\class QQuickPointerEvent
@@ -859,6 +1152,68 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
dynamically create and destroy objects of this type for each event.
*/
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerEvent::button
+
+ This property holds the \l {Qt::MouseButton}{button} that caused the event,
+ if any. If the \l device does not have buttons, or the event is a hover
+ event, it will be \c Qt.NoButton.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::buttons
+
+ This property holds the combination of mouse or stylus
+ \l {Qt::MouseButton}{buttons} pressed when the event was generated. For move
+ events, this is all buttons that are pressed down. For press events, this
+ includes the button that caused the event, as well as any others that were
+ already held. For release events, this excludes the button that caused the
+ event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::modifiers
+
+ This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} flags
+ that existed immediately before the event occurred.
+
+ It contains a bitwise combination of the following flags:
+ \value Qt.NoModifier
+ No modifier key is pressed.
+ \value Qt.ShiftModifier
+ A Shift key on the keyboard is pressed.
+ \value Qt.ControlModifier
+ A Ctrl key on the keyboard is pressed.
+ \value Qt.AltModifier
+ An Alt key on the keyboard is pressed.
+ \value Qt.MetaModifier
+ A Meta key on the keyboard is pressed.
+ \value Qt.KeypadModifier
+ A keypad button is pressed.
+
+ For example, to react to a Shift key + Left mouse button click:
+ \qml
+ Item {
+ TapHandler {
+ onTapped: {
+ if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
+ doSomething();
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::PointerEvent::device
+
+ This property holds the device that generated the event.
+*/
+
QQuickPointerEvent::~QQuickPointerEvent()
{}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 2954695b1b..50c9a86b9f 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -270,7 +270,6 @@ public:
Updated = Qt::TouchPointMoved,
Stationary = Qt::TouchPointStationary,
Released = Qt::TouchPointReleased
- // Canceled = Qt::TouchPointReleased << 1 // 0x10 // TODO maybe
};
Q_DECLARE_FLAGS(States, State)
Q_FLAG(States)