diff options
Diffstat (limited to 'tests/manual')
-rw-r--r-- | tests/manual/pointer/content/CheckBox.qml | 44 | ||||
-rw-r--r-- | tests/manual/pointer/content/TextBox.qml | 50 | ||||
-rw-r--r-- | tests/manual/pointer/inputinspector.cpp | 197 | ||||
-rw-r--r-- | tests/manual/pointer/inputinspector.h | 79 | ||||
-rw-r--r-- | tests/manual/pointer/main.cpp | 6 | ||||
-rw-r--r-- | tests/manual/pointer/main.qml | 29 | ||||
-rw-r--r-- | tests/manual/pointer/pointer.pro | 5 | ||||
-rw-r--r-- | tests/manual/pointer/pointerDrag.qml | 219 | ||||
-rw-r--r-- | tests/manual/pointer/qml.qrc | 3 |
9 files changed, 628 insertions, 4 deletions
diff --git a/tests/manual/pointer/content/CheckBox.qml b/tests/manual/pointer/content/CheckBox.qml new file mode 100644 index 0000000000..477be56f05 --- /dev/null +++ b/tests/manual/pointer/content/CheckBox.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 +import Qt.labs.handlers 1.0 + +Row { + id: root + property bool checked : false + property string label : "CheckBox" + Rectangle { + width: 10; height: 10 + color: root.checked ? "#202020" : "transparent" + border.color: "black" + TapHandler { + onTapped: root.checked = !root.checked + } + } + Text { text: root.label } +} diff --git a/tests/manual/pointer/content/TextBox.qml b/tests/manual/pointer/content/TextBox.qml new file mode 100644 index 0000000000..0fbfaf02e3 --- /dev/null +++ b/tests/manual/pointer/content/TextBox.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + id: r1 + radius: 10 + border.color: "black" + border.width: 4 + property string label + implicitHeight: txt.implicitHeight + 12 + implicitWidth: txt.implicitWidth+ 12 + color: "#c0c0c0" + + function queryColor(pressed) { + return pressed ? "#ff4040" : "#c0c0c0" + } + + Text { + id: txt + y: 6 + anchors.horizontalCenter: parent.horizontalCenter + text: parent.label + } +} diff --git a/tests/manual/pointer/inputinspector.cpp b/tests/manual/pointer/inputinspector.cpp new file mode 100644 index 0000000000..82d814b848 --- /dev/null +++ b/tests/manual/pointer/inputinspector.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "inputinspector.h" +#include <QtQuick/QQuickWindow> +#include <QtQuick/QQuickItem> +#include <QtQuick/private/qquickpointerhandler_p.h> +#include <QtCore/QSet> + +static const int timerInterval = 100; + +InputInspector::InputInspector(QObject *parent) : QObject(parent) +{ +} + +InputInspector::~InputInspector() +{ + m_window = nullptr; + killTimer(m_timerId); +} + +QString InputInspector::mouseGrabber() const +{ + QString name; + if (m_window) { + if (QQuickItem *grabber = m_window->mouseGrabberItem()) { + name = objectIdentifier(grabber); + } else { + name = QLatin1String("no grabber"); + } + } else { + name = "ERROR: need a source window"; + } + return name; +} + +QString InputInspector::passiveGrabbers() const +{ + return vectorStringJoin(passiveGrabbers_helper()); +} + +QString InputInspector::exclusiveGrabbers() const +{ + return vectorStringJoin(exclusiveGrabbers_helper()); +} + +QString InputInspector::vectorStringJoin(const QVector<QObject*> &arr) const +{ + QString res; + for (QObject* obj: arr) { + if (!res.isEmpty()) + res += QLatin1String(" , "); + res += objectIdentifier(obj); + } + res.prepend(QLatin1String("[")); + res += QLatin1String("]"); + return res; +} + +QQuickWindow *InputInspector::source() const +{ + return m_window; +} + +void InputInspector::setSource(QQuickWindow *window) +{ + m_window = window; + if (m_window && !m_timerId) + m_timerId = startTimer(timerInterval); + emit sourceChanged(); +} + +void InputInspector::update() +{ + const QString mouseGrabberName = mouseGrabber(); + if (lastState.mouseGrabber != mouseGrabberName) { + emit mouseGrabberChanged(); + lastState.mouseGrabber = mouseGrabberName; + } + + const QString tempPassiveGrabbers = passiveGrabbers(); + if (lastState.passiveGrabbers != tempPassiveGrabbers) { + emit passiveGrabbersChanged(); + lastState.passiveGrabbers = tempPassiveGrabbers; + } + + const QString tempExclusiveGrabbers = exclusiveGrabbers(); + if (lastState.exclusiveGrabbers != tempExclusiveGrabbers) { + emit exclusiveGrabbersChanged(); + lastState.exclusiveGrabbers = tempExclusiveGrabbers; + } +} + +void InputInspector::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_timerId) + update(); +} + +QQuickPointerDevice *InputInspector::pointerDevice() const +{ + QQuickPointerDevice *device = QQuickPointerDevice::touchDevices().value(0); + if (!device) + device = QQuickPointerDevice::genericMouseDevice(); + return device; +} + +QVector<QObject*> InputInspector::passiveGrabbers_helper(int pointId /*= 0*/) const +{ + QVector<QObject*> result; + QSet<QObject*> visited; + QQuickPointerDevice *device = pointerDevice(); + if (device && source()) { + QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(source()); + QQuickPointerEvent *pointerEvent = winPriv->pointerEventInstance(device); + if (pointerEvent) { + for (int i = 0; i < pointerEvent->pointCount(); ++i) { + QQuickEventPoint *eventPoint = pointerEvent->point(i); + QVector<QPointer <QQuickPointerHandler> > passives = eventPoint->passiveGrabbers(); + if (!pointId || eventPoint->pointId() == pointId) { + for (auto it = passives.constBegin(); it != passives.constEnd(); ++it) { + QObject *handler = it->data(); + if (!visited.contains(handler)) { + result << it->data(); + visited << handler; + } + } + } + } + } + } + return result; +} + +QVector<QObject*> InputInspector::exclusiveGrabbers_helper(int pointId /*= 0*/) const +{ + QVector<QObject*> result; + QSet<QObject*> visited; + QQuickPointerDevice *device = pointerDevice(); + if (device && source()) { + QQuickWindowPrivate *winPriv = QQuickWindowPrivate::get(source()); + QQuickPointerEvent *pointerEvent = winPriv->pointerEventInstance(device); + if (pointerEvent) { + for (int i = 0; i < pointerEvent->pointCount(); ++i) { + QQuickEventPoint *eventPoint = pointerEvent->point(i); + if (!pointId || eventPoint->pointId() == pointId) { + if (QObject *exclusiveGrabber = eventPoint->exclusiveGrabber()) { + if (!visited.contains(exclusiveGrabber)) { + result << exclusiveGrabber; + visited << exclusiveGrabber; + } + } + } + } + } + } + return result; +} + +QString InputInspector::objectIdentifier(QObject *o) +{ + QString name; + name = o->objectName(); + if (name.isEmpty()) + name = o->property("text").toString(); + if (name.isEmpty()) + name = o->metaObject()->className(); + if (name.isEmpty()) + name = QLatin1String("unknown"); + + return name; +} diff --git a/tests/manual/pointer/inputinspector.h b/tests/manual/pointer/inputinspector.h new file mode 100644 index 0000000000..66a053d0c3 --- /dev/null +++ b/tests/manual/pointer/inputinspector.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INPUTINSPECTOR_H +#define INPUTINSPECTOR_H + +#include <QObject> +class QQuickWindow; +class QQuickPointerHandler; +class QQuickPointerDevice; + +class InputInspector : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString mouseGrabber READ mouseGrabber NOTIFY mouseGrabberChanged) + Q_PROPERTY(QString passiveGrabbers READ passiveGrabbers NOTIFY passiveGrabbersChanged) + Q_PROPERTY(QString exclusiveGrabbers READ exclusiveGrabbers NOTIFY exclusiveGrabbersChanged) + Q_PROPERTY(QQuickWindow * source READ source WRITE setSource NOTIFY sourceChanged) +public: + explicit InputInspector(QObject *parent = nullptr); + ~InputInspector(); + QString mouseGrabber() const; + QString passiveGrabbers() const; + QString exclusiveGrabbers() const; + QQuickWindow *source() const; + void setSource(QQuickWindow *window); + + void timerEvent(QTimerEvent *event); + Q_INVOKABLE void update(); + +signals: + void mouseGrabberChanged(); + void passiveGrabbersChanged(); + void exclusiveGrabbersChanged(); + void sourceChanged(); +private: + QVector<QObject*> passiveGrabbers_helper(int pointId = 0) const; + QVector<QObject*> exclusiveGrabbers_helper(int pointId = 0) const; + static QString objectIdentifier(QObject *o); + QQuickPointerDevice *pointerDevice() const; + QString vectorStringJoin(const QVector<QObject*> &arr) const; + +private: + mutable struct LastState { + QString mouseGrabber; + QString passiveGrabbers; + QString exclusiveGrabbers; + } lastState; + + QQuickWindow *m_window = nullptr; + int m_timerId = 0; +}; + +#endif // INPUTINSPECTOR_H diff --git a/tests/manual/pointer/main.cpp b/tests/manual/pointer/main.cpp index 97d8422b69..43ad182a76 100644 --- a/tests/manual/pointer/main.cpp +++ b/tests/manual/pointer/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -29,14 +29,18 @@ #include <QQmlApplicationEngine> #include <QQuickItem> #include <QQuickWindow> +#include "inputinspector.h" int main(int argc, char *argv[]) { QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); + qmlRegisterType<InputInspector>("org.qtproject.Test", 1, 0, "InputInspector"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; if (!app.arguments().isEmpty()) { QQuickWindow * win = static_cast<QQuickWindow *>(engine.rootObjects().first()); auto lastArg = app.arguments().last(); diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml index a50bfc3872..bd9097c517 100644 --- a/tests/manual/pointer/main.qml +++ b/tests/manual/pointer/main.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the manual tests of the Qt Toolkit. @@ -28,11 +28,14 @@ import QtQuick 2.8 import QtQuick.Window 2.2 +import QtQuick.Layouts 1.2 import Qt.labs.handlers 1.0 +import org.qtproject.Test 1.0 import "qrc:/quick/shared/" as Examples import "content" Window { + id: window width: 800 height: 600 visible: true @@ -53,6 +56,7 @@ Window { 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")) addExample("flickable with Handlers", "Flickable with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickableWithHandlers.qml")) + addExample("tap and drag", "Flickable with all possible combinations of TapHandler and DragHandler children", Qt.resolvedUrl("pointerDrag.qml")) } } Item { @@ -70,5 +74,28 @@ Window { TouchpointFeedbackSprite { } MouseFeedbackSprite { } + + InputInspector { + id: inspector + source: window + } + + Rectangle { + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.margins: 4 + radius: 5 + width: Math.max(grid.implicitWidth, 400) + implicitHeight: grid.implicitHeight + color: "#40404080" + GridLayout { + id: grid + width: parent.width + columns: 3 + Text { text: "mouseGrabber" } Text { text: inspector.mouseGrabber } Item { Layout.fillWidth: true } + Text { text: "passiveGrabbers" } Text { text: inspector.passiveGrabbers } Item { Layout.fillWidth: true } + Text { text: "exclusiveGrabbers" } Text { text: inspector.exclusiveGrabbers } Item { Layout.fillWidth: true } + } + } } } diff --git a/tests/manual/pointer/pointer.pro b/tests/manual/pointer/pointer.pro index 79044a102e..43fddbd459 100644 --- a/tests/manual/pointer/pointer.pro +++ b/tests/manual/pointer/pointer.pro @@ -1,7 +1,8 @@ TEMPLATE = app -QT += qml quick svg +QT += qml quick quick-private svg -SOURCES += main.cpp +SOURCES += main.cpp inputinspector.cpp +HEADERS += inputinspector.h RESOURCES += qml.qrc ../../../examples/quick/shared/quick_shared.qrc diff --git a/tests/manual/pointer/pointerDrag.qml b/tests/manual/pointer/pointerDrag.qml new file mode 100644 index 0000000000..f3fbe66339 --- /dev/null +++ b/tests/manual/pointer/pointerDrag.qml @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.handlers 1.0 +import "content" + +Rectangle { + id: root + width: 600; height: 480; color: "#f0f0f0" + + property int globalGesturePolicy : TapHandler.DragThreshold + + Flickable { + id: flick + anchors.fill: parent + contentHeight: 600 + contentWidth: 1000 + objectName: "Flick" + + Repeater { + model: flick.contentHeight/200 + Rectangle { + width: flick.contentWidth + height: 101 + x: 0 + y: index * 200 + border.color: "#808080" + border.width: 1 + color: "transparent" + } + } + + Repeater { + model: flick.contentWidth/200 + Rectangle { + width: 101 + height: flick.contentHeight + x: index * 200 + y: 0 + border.color: "#808080" + border.width: 1 + color: "transparent" + } + } + + TextBox { + x: 0; y: 0 + width: 100; height: 100 + label: "DragHandler" + objectName: "dragSquircle1" + DragHandler { + + } + } + + TextBox { + x: 100; y: 0 + width: 100; height: 100 + label: "TapHandler" + color: queryColor(tap1.pressed) + + TapHandler { + id: tap1 + gesturePolicy: root.globalGesturePolicy + } + } + + TextBox { + x: 200; y: 0 + width: 100; height: 100 + label: "TapHandler\nDragHandler" + color: queryColor(tap2.pressed) + TapHandler { + id: tap2 + gesturePolicy: root.globalGesturePolicy + } + DragHandler { } + } + + TextBox { + x: 300; y: 0 + width: 100; height: 100 + label: "DragHandler\nTapHandler" + color: queryColor(tap3.pressed) + DragHandler { } + TapHandler { + id: tap3 + gesturePolicy: root.globalGesturePolicy + } + } + + TextBox { + x: 400; y: 0 + width: 100; height: 100 + label: "DragHandler" + DragHandler { } + + TextBox { + label: "TapHandler" + x: (parent.width - width)/2 + y: 60 + color: queryColor(tap4.pressed) + TapHandler { + id: tap4 + gesturePolicy: root.globalGesturePolicy + } + } + } + + TextBox { + objectName: "dragSquircle5" + x: 500; y: 0 + width: 100; height: 100 + label: "TapHandler" + color: queryColor(tap5.pressed) + CheckBox { + id: ckGreedyDrag + x: 10 + anchors.bottom: dragRect5.top + label: " Greedy ↓" + checked: true + } + TapHandler { + id: tap5 + gesturePolicy: root.globalGesturePolicy + } + + TextBox { + id: dragRect5 + objectName: "dragRect5" + label: "DragHandler" + x: (parent.width - width)/2 + y: 60 + DragHandler { + grabPermissions: ckGreedyDrag ? DragHandler.CanTakeOverFromAnything : + DragHandler.CanTakeOverFromItems | DragHandler.CanTakeOverFromHandlersOfDifferentType | DragHandler.ApprovesTakeOverByAnything + } + } + } + + + TextBox { + x: 0; y: 100 + width: 100; height: 100 + label: "No MouseArea" + + TextBox { + objectName: "dragRect01" + label: "DragHandler" + x: (parent.width - width)/2 + y: 60 + DragHandler { } + } + } + + TextBox { + id: r2 + label: "MouseArea" + x: 100; y: 100 + width: 100; height: 100 + + MouseArea { + id: ma + enabled: ckEnabled.checked + drag.target: ckDrag.checked ? r2 : undefined + drag.threshold: ckExtendDragThreshold.checked ? 50 : undefined + anchors.fill: parent + } + Column { + anchors.bottom: parent.bottom + anchors.bottomMargin: 10 + x: 10 + CheckBox { + id: ckEnabled + label: " Enabled" + checked: true + } + + CheckBox { + id: ckDrag + label: " Drag" + checked: true + } + + CheckBox { + id: ckExtendDragThreshold + label: " Extend threshold" + checked: false + } + } + } + } +} diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc index f9d600b16c..11f64e156e 100644 --- a/tests/manual/pointer/qml.qrc +++ b/tests/manual/pointer/qml.qrc @@ -10,8 +10,10 @@ <file>multibuttons.qml</file> <file>photosurface.qml</file> <file>pinchHandler.qml</file> + <file>pointerDrag.qml</file> <file>singlePointHandlerProperties.qml</file> <file>tapHandler.qml</file> + <file>content/CheckBox.qml</file> <file>content/FakeFlickable.qml</file> <file>content/FlashAnimation.qml</file> <file>content/MomentumAnimation.qml</file> @@ -23,6 +25,7 @@ <file>content/ScrollBar.qml</file> <file>content/Slider.qml</file> <file>content/TapHandlerButton.qml</file> + <file>content/TextBox.qml</file> <file>content/TouchpointFeedbackSprite.qml</file> <file>resources/arrowhead.png</file> <file>resources/balloon.png</file> |