TapHandler: add gesturePolicy
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 <jan-arve.saether@qt.io>
This commit is contained in:
parent
5c639a07fd
commit
cb78d5c91e
|
@ -58,23 +58,19 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
|
|||
|
||||
TapHandler is a handler for taps on a touchscreen or clicks on a mouse.
|
||||
|
||||
It requires that any movement between the press and release remains
|
||||
less than the drag threshold for a single tap, and less than
|
||||
QPlatformTheme::MouseDoubleClickDistance for multi-tap gestures
|
||||
(double-tap, triple-tap, etc.) with the mouse, or 10 pixels with touch.
|
||||
It also requires that the time between press and release remains
|
||||
less than QStyleHints::mouseDoubleClickInterval() for a single tap,
|
||||
and that the time from one press/release sequence to the next remains
|
||||
less than QStyleHints::mouseDoubleClickInterval() for multi-tap gestures.
|
||||
|
||||
Detection of a valid tap gesture depends on \l gesturePolicy.
|
||||
Note that buttons (such as QPushButton) are often implemented not to care
|
||||
whether the press and release occur close together: if you press the button
|
||||
and then change your mind, you need to drag all the way off the edge of the
|
||||
button in order to cancel the click. If you want to achieve such behavior,
|
||||
it's enough to use a PointerHandler and consider the button clicked on
|
||||
every \l {QQuickPointerHandler:}{released} event. But TapHandler requires
|
||||
that the events occur close together in both space and time, which is anyway
|
||||
necessary to detect double clicks or multi-click gestures.
|
||||
button in order to cancel the click. Therefore the default
|
||||
\l gesturePolicy is \l ReleaseWithinBounds. If you want to require
|
||||
that the press and release are close together in both space and time,
|
||||
set it to \l DragThreshold.
|
||||
|
||||
For multi-tap gestures (double-tap, triple-tap etc.), the distance moved
|
||||
must not exceed QPlatformTheme::MouseDoubleClickDistance with mouse and
|
||||
QPlatformTheme::TouchDoubleTapDistance with touch, and the time between
|
||||
taps must not exceed QStyleHints::mouseDoubleClickInterval().
|
||||
|
||||
\sa MouseArea
|
||||
*/
|
||||
|
@ -82,6 +78,7 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
|
|||
QQuickTapHandler::QQuickTapHandler(QObject *parent)
|
||||
: QQuickPointerSingleHandler(parent)
|
||||
, m_pressed(false)
|
||||
, m_gesturePolicy(ReleaseWithinBounds)
|
||||
, m_tapCount(0)
|
||||
, m_longPressThreshold(-1)
|
||||
, m_lastTapTimestamp(0.0)
|
||||
|
@ -102,15 +99,46 @@ QQuickTapHandler::~QQuickTapHandler()
|
|||
{
|
||||
}
|
||||
|
||||
static bool dragOverThreshold(QQuickEventPoint *point)
|
||||
{
|
||||
QPointF delta = point->scenePos() - point->scenePressPos();
|
||||
return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
|
||||
QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
|
||||
}
|
||||
|
||||
bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
|
||||
{
|
||||
if (point->state() == QQuickEventPoint::Pressed && parentContains(point))
|
||||
return true;
|
||||
// If the user has not dragged too far, it could be a tap.
|
||||
// If the user has not violated any constraint, it could be a tap.
|
||||
// Otherwise we want to give up the grab so that a competing handler
|
||||
// (e.g. DragHandler) gets a chance to take over.
|
||||
// Don't forget to emit released in case of a cancel.
|
||||
return !point->isDraggedOverThreshold();
|
||||
bool ret = false;
|
||||
switch (point->state()) {
|
||||
case QQuickEventPoint::Pressed:
|
||||
case QQuickEventPoint::Released:
|
||||
ret = parentContains(point);
|
||||
break;
|
||||
default: // update or stationary
|
||||
switch (m_gesturePolicy) {
|
||||
case DragThreshold:
|
||||
ret = !dragOverThreshold(point);
|
||||
break;
|
||||
case WithinBounds:
|
||||
ret = parentContains(point);
|
||||
break;
|
||||
case ReleaseWithinBounds:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// If this is the grabber, returning false from this function will
|
||||
// cancel the grab, so handleGrabCancel() and setPressed(false) will be called.
|
||||
// But when m_gesturePolicy is DragThreshold, we don't grab, but
|
||||
// we still don't want to be pressed anymore.
|
||||
if (!ret)
|
||||
setPressed(false, true, point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QQuickTapHandler::handleEventPoint(QQuickEventPoint *point)
|
||||
|
@ -134,7 +162,7 @@ void QQuickTapHandler::handleEventPoint(QQuickEventPoint *point)
|
|||
The time in seconds that an event point must be pressed in order to
|
||||
trigger a long press gesture and emit the \l longPressed() signal.
|
||||
If the point is released before this time limit, a tap can be detected
|
||||
if the other constraints are satisfied. The default value is
|
||||
if the \l gesturePolicy constraint is satisfied. The default value is
|
||||
QStyleHints::mousePressAndHoldInterval() converted to seconds.
|
||||
*/
|
||||
qreal QQuickTapHandler::longPressThreshold() const
|
||||
|
@ -165,6 +193,54 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty gesturePolicy
|
||||
|
||||
The spatial constraint for a tap or long press gesture to be recognized,
|
||||
in addition to the constraint that the release must occur before
|
||||
\l longPressThreshold has elapsed. If these constraints are not satisfied,
|
||||
the \l tapped signal is not emitted, and \l tapCount is not incremented.
|
||||
If the spatial constraint is violated, \l isPressed transitions immediately
|
||||
from true to false, regardless of the time held.
|
||||
|
||||
\c DragThreshold means that the event point must not move significantly.
|
||||
If the mouse, finger or stylus moves past the system-wide drag threshold
|
||||
(QStyleHints::startDragDistance), the tap gesture is canceled, even if
|
||||
the button or finger is still pressed. This policy can be useful whenever
|
||||
TapHandler needs to cooperate with other pointer handlers (for example
|
||||
\l DragHandler), because in this case TapHandler will never grab.
|
||||
|
||||
\c WithinBounds means that if the event point leaves the bounds of the
|
||||
\l target item, the tap gesture is canceled. The TapHandler will grab on
|
||||
press, but release the grab as soon as the boundary constraint is no
|
||||
longer satisfied.
|
||||
|
||||
\c ReleaseWithinBounds (the default value) means that at the time of release
|
||||
(the mouse button is released or the finger is lifted), if the event point
|
||||
is outside the bounds of the \l target item, a tap gesture is not
|
||||
recognized. This is the default value, because it corresponds to typical
|
||||
button behavior: you can cancel a click by dragging outside the button, and
|
||||
you can also change your mind by dragging back inside the button before
|
||||
release. Note that it's necessary for TapHandler to grab on press and
|
||||
retain it until release (greedy grab) in order to detect this gesture.
|
||||
*/
|
||||
void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy)
|
||||
{
|
||||
if (m_gesturePolicy == gesturePolicy)
|
||||
return;
|
||||
|
||||
m_gesturePolicy = gesturePolicy;
|
||||
emit gesturePolicyChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty pressed
|
||||
|
||||
This property will be true whenever the mouse or touch point is pressed,
|
||||
and any movement since the press is compliant with the current
|
||||
\l gesturePolicy. When the event point is released or the policy is
|
||||
violated, pressed will change to false.
|
||||
*/
|
||||
void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *point)
|
||||
{
|
||||
if (m_pressed != press) {
|
||||
|
@ -173,6 +249,8 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *poi
|
|||
m_longPressTimer.start(longPressThresholdMilliseconds(), this);
|
||||
else
|
||||
m_longPressTimer.stop();
|
||||
if (m_gesturePolicy != DragThreshold)
|
||||
setGrab(point, press);
|
||||
if (!cancel && !press && point->timeHeld() < longPressThreshold()) {
|
||||
// Assuming here that pointerEvent()->timestamp() is in ms.
|
||||
qreal ts = point->pointerEvent()->timestamp() / 1000.0;
|
||||
|
|
|
@ -64,8 +64,16 @@ class Q_AUTOTEST_EXPORT QQuickTapHandler : public QQuickPointerSingleHandler
|
|||
Q_PROPERTY(bool isPressed READ isPressed NOTIFY pressedChanged)
|
||||
Q_PROPERTY(int tapCount READ tapCount NOTIFY tapCountChanged)
|
||||
Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged)
|
||||
Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged)
|
||||
|
||||
public:
|
||||
enum GesturePolicy {
|
||||
DragThreshold,
|
||||
WithinBounds,
|
||||
ReleaseWithinBounds
|
||||
};
|
||||
Q_ENUM(GesturePolicy)
|
||||
|
||||
QQuickTapHandler(QObject *parent = 0);
|
||||
~QQuickTapHandler();
|
||||
|
||||
|
@ -79,10 +87,14 @@ public:
|
|||
qreal longPressThreshold() const;
|
||||
void setLongPressThreshold(qreal longPressThreshold);
|
||||
|
||||
GesturePolicy gesturePolicy() const { return m_gesturePolicy; }
|
||||
void setGesturePolicy(GesturePolicy gesturePolicy);
|
||||
|
||||
Q_SIGNALS:
|
||||
void pressedChanged();
|
||||
void tapCountChanged();
|
||||
void longPressThresholdChanged();
|
||||
void gesturePolicyChanged();
|
||||
void tapped(QQuickEventPoint *point);
|
||||
void longPressed();
|
||||
|
||||
|
@ -96,13 +108,13 @@ private:
|
|||
|
||||
private:
|
||||
bool m_pressed;
|
||||
GesturePolicy m_gesturePolicy;
|
||||
int m_tapCount;
|
||||
int m_longPressThreshold;
|
||||
QBasicTimer m_longPressTimer;
|
||||
QPointF m_lastTapPos;
|
||||
qreal m_lastTapTimestamp;
|
||||
|
||||
static qreal m_tapInterval;
|
||||
static qreal m_multiTapInterval;
|
||||
static int m_mouseMultiClickDistanceSquared;
|
||||
static int m_touchMultiTapDistanceSquared;
|
||||
|
|
|
@ -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 }
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 } } }
|
||||
}
|
|
@ -6,16 +6,22 @@
|
|||
<file>joystick.qml</file>
|
||||
<file>map.qml</file>
|
||||
<file>mixer.qml</file>
|
||||
<file>multibuttons.qml</file>
|
||||
<file>photosurface.qml</file>
|
||||
<file>pinchHandler.qml</file>
|
||||
<file>singlePointHandlerProperties.qml</file>
|
||||
<file>tapHandler.qml</file>
|
||||
<file>content/FakeFlickable.qml</file>
|
||||
<file>content/FlashAnimation.qml</file>
|
||||
<file>content/MomentumAnimation.qml</file>
|
||||
<file>content/MultiButton.qml</file>
|
||||
<file>content/Slider.qml</file>
|
||||
<file>resources/arrowhead.png</file>
|
||||
<file>resources/balloon.png</file>
|
||||
<file>resources/fighter.png</file>
|
||||
<file>resources/grabbing-location.svg</file>
|
||||
<file>resources/map.svgz</file>
|
||||
<file>resources/missile.png</file>
|
||||
<file>resources/mixer-knob.png</file>
|
||||
<file>resources/mouse.png</file>
|
||||
<file>resources/mouse_left.png</file>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 7.6 KiB |
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue