aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickdrag.cpp25
-rw-r--r--src/quick/items/qquickdrag_p.h9
-rw-r--r--src/quick/items/qquickmousearea.cpp12
-rw-r--r--src/quick/items/qquickwindow.cpp4
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp70
6 files changed, 112 insertions, 10 deletions
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 0ae26cb5c3..166b40aaf2 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -45,11 +45,12 @@
#include <QtQuick/private/qquickevents_p_p.h>
#include <private/qquickitemchangelistener_p.h>
#include <private/qv8engine_p.h>
-#include <QtCore/qcoreapplication.h>
#include <QtCore/qmimedata.h>
#include <QtQml/qqmlinfo.h>
#include <QtGui/qdrag.h>
#include <QtGui/qevent.h>
+#include <QtGui/qstylehints.h>
+#include <QtGui/qguiapplication.h>
#ifndef QT_NO_DRAGANDDROP
@@ -785,7 +786,8 @@ void QQuickDragAttached::startDrag(QQmlV4Function *args)
QQuickDrag::QQuickDrag(QObject *parent)
: QObject(parent), _target(0), _axis(XAndYAxis), _xmin(-FLT_MAX),
-_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
+_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false),
+ _threshold(qApp->styleHints()->startDragDistance())
{
}
@@ -879,6 +881,25 @@ void QQuickDrag::setYmax(qreal m)
emit maximumYChanged();
}
+
+qreal QQuickDrag::threshold() const
+{
+ return _threshold;
+}
+
+void QQuickDrag::setThreshold(qreal value)
+{
+ if (_threshold != value) {
+ _threshold = value;
+ emit thresholdChanged();
+ }
+}
+
+void QQuickDrag::resetThreshold()
+{
+ setThreshold(qApp->styleHints()->startDragDistance());
+}
+
bool QQuickDrag::active() const
{
return _active;
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 098fcc61b9..22829350fe 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -157,6 +157,9 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged)
+ // Note, threshold was added in QtQuick 2.2 but REVISION is not supported (or needed) for grouped
+ // properties See QTBUG-33179
+ Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold)
//### consider drag and drop
public:
@@ -182,6 +185,10 @@ public:
qreal ymax() const;
void setYmax(qreal);
+ qreal threshold() const;
+ void setThreshold(qreal);
+ void resetThreshold();
+
bool active() const;
void setActive(bool);
@@ -199,6 +206,7 @@ Q_SIGNALS:
void maximumYChanged();
void activeChanged();
void filterChildrenChanged();
+ void thresholdChanged();
private:
QQuickItem *_target;
@@ -209,6 +217,7 @@ private:
qreal _ymax;
bool _active : 1;
bool _filterChildren: 1;
+ qreal _threshold;
Q_DISABLE_COPY(QQuickDrag)
};
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 8a73a5d73d..39f07f2afd 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -48,10 +48,7 @@
#include <private/qqmldata_p.h>
#include <QtGui/private/qguiapplication_p.h>
-
#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
#include <float.h>
@@ -695,8 +692,8 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
d->drag->target()->setPosition(dragPos);
if (!keepMouseGrab()
- && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event)
- || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event))) {
+ && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
+ || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold()))) {
setKeepMouseGrab(true);
d->stealMouse = true;
d->startScene = event->windowPos();
@@ -1189,6 +1186,7 @@ void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
\qmlproperty real QtQuick2::MouseArea::drag.minimumY
\qmlproperty real QtQuick2::MouseArea::drag.maximumY
\qmlproperty bool QtQuick2::MouseArea::drag.filterChildren
+ \qmlproperty real QtQuick2::MouseArea::drag.threshold
\c drag provides a convenient way to make an item draggable.
@@ -1213,6 +1211,10 @@ void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This
enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
+ \c drag.threshold determines the threshold in pixels of when the drag operation should
+ start. By default this is bound to a platform dependent value. This property was added in
+ Qt Quick 2.2.
+
\snippet qml/mousearea/mouseareadragfilter.qml dragfilter
*/
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index c8bc026868..513c3da0a2 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2077,13 +2077,13 @@ bool QQuickWindowPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem
return false;
}
-bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event)
+bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold)
{
QStyleHints *styleHints = qApp->styleHints();
int caps = QGuiApplicationPrivate::mouseEventCaps(event);
bool dragVelocityLimitAvailable = (caps & QTouchDevice::Velocity)
&& styleHints->startDragVelocity();
- bool overThreshold = qAbs(d) > styleHints->startDragDistance();
+ bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
if (dragVelocityLimitAvailable) {
QVector2D velocityVec = QGuiApplicationPrivate::mouseEventVelocity(event);
qreal velocity = axis == Qt::XAxis ? velocityVec.x() : velocityVec.y();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 12925cbbca..e29ceb521f 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -221,7 +221,7 @@ public:
static bool defaultAlphaBuffer;
- static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event);
+ static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index de1c12097b..0c0b51d9c2 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -86,6 +86,7 @@ private slots:
void resetDrag();
void dragging_data() { acceptedButton_data(); }
void dragging();
+ void dragThreshold();
void invalidDrag_data() { rejectedButton_data(); }
void invalidDrag();
void setDragOnPressed();
@@ -235,6 +236,20 @@ void tst_QQuickMouseArea::dragProperties()
drag->setFilterChildren(true);
QCOMPARE(filterChildrenSpy.count(), 1);
+
+ // threshold
+ QCOMPARE(int(drag->threshold()), qApp->styleHints()->startDragDistance());
+ QSignalSpy thresholdSpy(drag, SIGNAL(thresholdChanged()));
+ drag->setThreshold(0.0);
+ QCOMPARE(drag->threshold(), 0.0);
+ QCOMPARE(thresholdSpy.count(), 1);
+ drag->setThreshold(99);
+ QCOMPARE(thresholdSpy.count(), 2);
+ drag->setThreshold(99);
+ QCOMPARE(thresholdSpy.count(), 2);
+ drag->resetThreshold();
+ QCOMPARE(int(drag->threshold()), qApp->styleHints()->startDragDistance());
+ QCOMPARE(thresholdSpy.count(), 3);
}
void tst_QQuickMouseArea::resetDrag()
@@ -318,6 +333,61 @@ void tst_QQuickMouseArea::dragging()
QCOMPARE(blackRect->y(), 61.0);
}
+
+void tst_QQuickMouseArea::dragThreshold()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("dragging.qml"), true, &errorMessage), errorMessage.constData());
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject() != 0);
+
+ QQuickMouseArea *mouseRegion = window.rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+ QQuickDrag *drag = mouseRegion->drag();
+
+ drag->setThreshold(5);
+
+ mouseRegion->setAcceptedButtons(Qt::LeftButton);
+ QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+ QVERIFY(blackRect == drag->target());
+ QVERIFY(!drag->active());
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QVERIFY(!drag->active());
+ QCOMPARE(blackRect->x(), 50.0);
+ QCOMPARE(blackRect->y(), 50.0);
+ QTest::mouseMove(&window, QPoint(100, 102), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 100), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 104), 50);
+ QTest::mouseMove(&window, QPoint(100, 105), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 106), 50);
+ QTest::mouseMove(&window, QPoint(100, 108), 50);
+ QVERIFY(drag->active());
+ QTest::mouseMove(&window, QPoint(100, 116), 50);
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QTRY_VERIFY(drag->active());
+ QTRY_COMPARE(blackRect->x(), 50.0);
+ QTRY_COMPARE(blackRect->y(), 66.0);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(122,122));
+ QTRY_VERIFY(!drag->active());
+
+ // Immediate drag threshold
+ drag->setThreshold(0);
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 123), 50);
+ QVERIFY(drag->active());
+ QTest::mouseMove(&window, QPoint(100, 124), 50);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100, 124));
+ QTRY_VERIFY(!drag->active());
+ drag->resetThreshold();
+}
void tst_QQuickMouseArea::invalidDrag()
{
QFETCH(Qt::MouseButtons, acceptedButtons);