From cb78d5c91ed33543a8e7fe7717f74f95834e4cc3 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 18 Oct 2016 18:45:49 +0200 Subject: TapHandler: add gesturePolicy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now it behaved as if this was set to DragThreshold: give up on the tap as soon as you are clearly dragging rather than tapping. But that's not what is normally wanted when building a Button control, for example. So provide 3 options: give up past the drag threshold, when the pointer goes outside the bounds, or when it's released outside the bounds. The longPressThreshold also constrains all three cases: holding (or dragging) for too long will not result in an immediate cancellation, but it also will not be a tap gesture. Change-Id: I95aec978e783892b55371391a27642751d91d9ff Reviewed-by: Jan Arve Sæther --- tests/manual/pointer/content/FlashAnimation.qml | 57 ++++++++++++++ tests/manual/pointer/content/MultiButton.qml | 85 +++++++++++++++++++++ tests/manual/pointer/content/Slider.qml | 19 ++++- tests/manual/pointer/main.qml | 1 + tests/manual/pointer/multibuttons.qml | 95 ++++++++++++++++++++++++ tests/manual/pointer/qml.qrc | 6 ++ tests/manual/pointer/resources/balloon.png | Bin 0 -> 3759 bytes tests/manual/pointer/resources/fighter.png | Bin 0 -> 9669 bytes tests/manual/pointer/resources/missile.png | Bin 0 -> 2305 bytes tests/manual/pointer/resources/mixer-knob.png | Bin 8555 -> 7821 bytes tests/manual/pointer/tapHandler.qml | 29 ++++++++ 11 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 tests/manual/pointer/content/FlashAnimation.qml create mode 100644 tests/manual/pointer/content/MultiButton.qml create mode 100644 tests/manual/pointer/multibuttons.qml create mode 100644 tests/manual/pointer/resources/balloon.png create mode 100644 tests/manual/pointer/resources/fighter.png create mode 100644 tests/manual/pointer/resources/missile.png (limited to 'tests') diff --git a/tests/manual/pointer/content/FlashAnimation.qml b/tests/manual/pointer/content/FlashAnimation.qml new file mode 100644 index 0000000000..b628255a3d --- /dev/null +++ b/tests/manual/pointer/content/FlashAnimation.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests 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.0 + +SequentialAnimation { + id: tapFlash + running: false + PropertyAction { value: false } + PauseAnimation { duration: 100 } + PropertyAction { value: true } + PauseAnimation { duration: 100 } + PropertyAction { value: false } + PauseAnimation { duration: 100 } + PropertyAction { value: true } + PauseAnimation { duration: 100 } + PropertyAction { value: false } + PauseAnimation { duration: 100 } + PropertyAction { value: true } +} diff --git a/tests/manual/pointer/content/MultiButton.qml b/tests/manual/pointer/content/MultiButton.qml new file mode 100644 index 0000000000..5b31e9ebd0 --- /dev/null +++ b/tests/manual/pointer/content/MultiButton.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests 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.8 +import Qt.labs.handlers 1.0 + +Rectangle { + id: root + property alias label: label.text + property alias pressed: tap.isPressed + property bool checked: false + property alias gesturePolicy: tap.gesturePolicy + signal tapped + + width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0 + border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true + + gradient: Gradient { + GradientStop { position: 0.0; color: tap.isPressed ? "#b8b5b2" : "#efebe7" } + GradientStop { position: 1.0; color: "#b8b5b2" } + } + + TapHandler { + id: tap + objectName: label.text + onTapped: { + tapFlash.start() + root.tapped + } + } + + Text { + id: label + font.pointSize: 14 + text: "Button" + anchors.centerIn: parent + } + + Rectangle { + anchors.fill: parent + color: "transparent" + border.width: 2; radius: root.radius; antialiasing: true + opacity: tapFlash.running ? 1 : 0 + FlashAnimation on visible { + id: tapFlash + } + } +} diff --git a/tests/manual/pointer/content/Slider.qml b/tests/manual/pointer/content/Slider.qml index cd52dfac80..a1decf8c4b 100644 --- a/tests/manual/pointer/content/Slider.qml +++ b/tests/manual/pointer/content/Slider.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -46,6 +46,9 @@ Item { property int value: 50 property int maximumValue: 99 property alias label: label.text + property alias tapEnabled: tap.enabled + property alias pressed: tap.isPressed + signal tapped Rectangle { id: slot @@ -70,7 +73,10 @@ Item { anchors.horizontalCenterOffset: 1 radius: 5 color: "#4400FFFF" - opacity: dragHandler.active ? 1 : 0 + opacity: dragHandler.active || tapFlash.running ? 1 : 0 + FlashAnimation on visible { + id: tapFlash + } } Image { id: knob @@ -90,6 +96,15 @@ Item { yAxis.minimum: slot.y yAxis.maximum: slot.height + slot.y - knob.height } + TapHandler { + id: tap + objectName: label.text + gesturePolicy: TapHandler.DragThreshold + onTapped: { + tapFlash.start() + root.tapped + } + } } Text { diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml index b06d3cf155..a71490d23b 100644 --- a/tests/manual/pointer/main.qml +++ b/tests/manual/pointer/main.qml @@ -60,6 +60,7 @@ Window { addExample("fake Flickable", "implementation of a simplified Flickable using only Items, DragHandler and MomentumAnimation", Qt.resolvedUrl("fakeFlickable.qml")) addExample("photo surface", "re-implementation of the existing photo surface demo using Handlers", Qt.resolvedUrl("photosurface.qml")) addExample("tap", "TapHandler: device-agnostic tap/click detection for buttons", Qt.resolvedUrl("tapHandler.qml")) + addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml")) } } } diff --git a/tests/manual/pointer/multibuttons.qml b/tests/manual/pointer/multibuttons.qml new file mode 100644 index 0000000000..16d2f191e7 --- /dev/null +++ b/tests/manual/pointer/multibuttons.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests 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.0 +import QtQuick.Particles 2.0 +import QtQuick.Layouts 1.0 +import Qt.labs.handlers 1.0 +import "content" + +Item { + width: 800 + height: 800 + ColumnLayout { + anchors.right: parent.right + spacing: 20 + Text { text: "protagonist"; font.pointSize: 12 } + MultiButton { + id: balloonsButton + label: "Launch Balloons" + Layout.fillWidth: true + gesturePolicy: TapHandler.DragThreshold + } + Text { text: "the goons"; font.pointSize: 12 } + MultiButton { + id: missilesButton + label: "Launch Missiles" + Layout.fillWidth: true + gesturePolicy: TapHandler.WithinBounds + } + MultiButton { + id: fightersButton + label: "Launch Fighters" + Layout.fillWidth: true + gesturePolicy: TapHandler.ReleaseWithinBounds + } + } + ParticleSystem { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 150 + ImageParticle { source: "resources/balloon.png" } + Emitter { anchors.bottom: parent.bottom; enabled: balloonsButton.pressed; lifeSpan: 5000; size: 64 + maximumEmitted: 99 + emitRate: 50; velocity: PointDirection { x: 10; y: -150; yVariation: 30; xVariation: 50 } } } + ParticleSystem { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + ImageParticle { source: "resources/fighter.png" } + Emitter { anchors.bottom: parent.bottom; enabled: fightersButton.pressed; lifeSpan: 15000; size: 204 + emitRate: 3; velocity: PointDirection { x: -1000; y: -250; yVariation: 150; xVariation: 50 } } } + ParticleSystem { + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 100 + ImageParticle { source: "resources/missile.png"; autoRotation: true; rotation: 90 } + Emitter { anchors.bottom: parent.bottom; enabled: missilesButton.pressed; lifeSpan: 5000; size: 128 + emitRate: 10; velocity: PointDirection { x: -200; y: -350; yVariation: 200; xVariation: 100 } } } +} diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc index 4535a26802..4113974d46 100644 --- a/tests/manual/pointer/qml.qrc +++ b/tests/manual/pointer/qml.qrc @@ -6,16 +6,22 @@ joystick.qml map.qml mixer.qml + multibuttons.qml photosurface.qml pinchHandler.qml singlePointHandlerProperties.qml tapHandler.qml content/FakeFlickable.qml + content/FlashAnimation.qml content/MomentumAnimation.qml + content/MultiButton.qml content/Slider.qml resources/arrowhead.png + resources/balloon.png + resources/fighter.png resources/grabbing-location.svg resources/map.svgz + resources/missile.png resources/mixer-knob.png resources/mouse.png resources/mouse_left.png diff --git a/tests/manual/pointer/resources/balloon.png b/tests/manual/pointer/resources/balloon.png new file mode 100644 index 0000000000..6476facc49 Binary files /dev/null and b/tests/manual/pointer/resources/balloon.png differ diff --git a/tests/manual/pointer/resources/fighter.png b/tests/manual/pointer/resources/fighter.png new file mode 100644 index 0000000000..2acee43cba Binary files /dev/null and b/tests/manual/pointer/resources/fighter.png differ diff --git a/tests/manual/pointer/resources/missile.png b/tests/manual/pointer/resources/missile.png new file mode 100644 index 0000000000..72c02d1fb9 Binary files /dev/null and b/tests/manual/pointer/resources/missile.png differ diff --git a/tests/manual/pointer/resources/mixer-knob.png b/tests/manual/pointer/resources/mixer-knob.png index 02cc9fc72b..b7d42ee3bd 100644 Binary files a/tests/manual/pointer/resources/mixer-knob.png and b/tests/manual/pointer/resources/mixer-knob.png differ diff --git a/tests/manual/pointer/tapHandler.qml b/tests/manual/pointer/tapHandler.qml index f2a454fb80..2e45b1c369 100644 --- a/tests/manual/pointer/tapHandler.qml +++ b/tests/manual/pointer/tapHandler.qml @@ -57,6 +57,9 @@ Item { acceptedButtons: (leftAllowedCB.checked ? Qt.LeftButton : Qt.NoButton) | (middleAllowedCB.checked ? Qt.MiddleButton : Qt.NoButton) | (rightAllowedCB.checked ? Qt.RightButton : Qt.NoButton) + gesturePolicy: (policyDragThresholdCB.checked ? TapHandler.DragThreshold : + policyWithinBoundsCB.checked ? TapHandler.WithinBounds : + TapHandler.ReleaseWithinBounds) onPressedButtonsChanged: switch (pressedButtons) { case Qt.MiddleButton: borderBlink.blinkColor = "orange"; break; case Qt.RightButton: borderBlink.blinkColor = "magenta"; break; @@ -141,5 +144,31 @@ Item { id: rightAllowedCB text: "right click" } + Text { text: " gesture policy:"; anchors.verticalCenter: leftAllowedCB.verticalCenter } + Examples.CheckBox { + id: policyDragThresholdCB + text: "drag threshold" + onCheckedChanged: if (checked) { + policyWithinBoundsCB.checked = false; + policyReleaseWithinBoundsCB.checked = false; + } + } + Examples.CheckBox { + id: policyWithinBoundsCB + text: "within bounds" + onCheckedChanged: if (checked) { + policyDragThresholdCB.checked = false; + policyReleaseWithinBoundsCB.checked = false; + } + } + Examples.CheckBox { + id: policyReleaseWithinBoundsCB + checked: true + text: "release within bounds" + onCheckedChanged: if (checked) { + policyDragThresholdCB.checked = false; + policyWithinBoundsCB.checked = false; + } + } } } -- cgit v1.2.3