aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/controls/qquicktextfield.cpp71
-rw-r--r--src/controls/qquicktextfield_p.h6
-rw-r--r--tests/auto/controls/data/tst_textfield.qml52
3 files changed, 128 insertions, 1 deletions
diff --git a/src/controls/qquicktextfield.cpp b/src/controls/qquicktextfield.cpp
index 694e3f5d..de6840bd 100644
--- a/src/controls/qquicktextfield.cpp
+++ b/src/controls/qquicktextfield.cpp
@@ -36,10 +36,12 @@
#include "qquicktextfield_p.h"
+#include <QtCore/qbasictimer.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQuick/private/qquickclipnode_p.h>
#include <QtQuick/private/qquicktextinput_p_p.h>
+#include <QtQuick/private/qquickevents_p_p.h>
QT_BEGIN_NAMESPACE
@@ -72,17 +74,32 @@ QT_BEGIN_NAMESPACE
\sa TextArea, {Customizing TextField}
*/
+/*!
+ \qmlsignal QtQuickControls2::TextField::pressAndHold(MouseEvent mouse)
+
+ This signal is emitted when there is a long press (the delay depends on the platform plugin).
+ The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
+ position of the press, and which button is pressed.
+*/
+
class QQuickTextFieldPrivate : public QQuickTextInputPrivate
{
Q_DECLARE_PUBLIC(QQuickTextField)
public:
- QQuickTextFieldPrivate() : background(Q_NULLPTR), placeholder(Q_NULLPTR) { }
+ QQuickTextFieldPrivate()
+ : background(Q_NULLPTR)
+ , placeholder(Q_NULLPTR)
+ , longPress(false)
+ { }
void resizeBackground();
+ bool isPressAndHoldConnected();
QQuickItem *background;
QQuickText *placeholder;
+ QBasicTimer pressAndHoldTimer;
+ bool longPress;
};
void QQuickTextFieldPrivate::resizeBackground()
@@ -101,6 +118,12 @@ void QQuickTextFieldPrivate::resizeBackground()
}
}
+bool QQuickTextFieldPrivate::isPressAndHoldConnected()
+{
+ Q_Q(QQuickTextField);
+ IS_SIGNAL_CONNECTED(q, QQuickTextField, pressAndHold, (QQuickMouseEvent *));
+}
+
QQuickTextField::QQuickTextField(QQuickItem *parent) :
QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
{
@@ -193,4 +216,50 @@ QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
return clipNode;
}
+void QQuickTextField::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QQuickTextField);
+ d->longPress = false;
+ if (Qt::LeftButton == (event->buttons() & Qt::LeftButton))
+ d->pressAndHoldTimer.start(QGuiApplication::styleHints()->mousePressAndHoldInterval(), this);
+ else
+ d->pressAndHoldTimer.stop();
+ QQuickTextInput::mousePressEvent(event);
+}
+
+void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickTextField);
+ if (qAbs(int(event->localPos().x() - d->pressPos.x())) > QGuiApplication::styleHints()->startDragDistance())
+ d->pressAndHoldTimer.stop();
+ if (!d->pressAndHoldTimer.isActive())
+ QQuickTextInput::mouseMoveEvent(event);
+}
+
+void QQuickTextField::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QQuickTextField);
+ if (!d->longPress) {
+ d->pressAndHoldTimer.stop();
+ QQuickTextInput::mouseReleaseEvent(event);
+ }
+}
+
+void QQuickTextField::timerEvent(QTimerEvent *event)
+{
+ Q_D(QQuickTextField);
+ if (event->timerId() == d->pressAndHoldTimer.timerId()) {
+ d->pressAndHoldTimer.stop();
+ d->longPress = true;
+ QQuickMouseEvent me(d->pressPos.x(), d->pressPos.y(), Qt::LeftButton, Qt::LeftButton,
+ QGuiApplication::keyboardModifiers(), false/*isClick*/, true/*wasHeld*/);
+ me.setAccepted(d->isPressAndHoldConnected());
+ emit pressAndHold(&me);
+ if (!me.isAccepted())
+ d->longPress = false;
+ } else {
+ QQuickTextInput::timerEvent(event);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/controls/qquicktextfield_p.h b/src/controls/qquicktextfield_p.h
index 41d39316..1cc7ffe4 100644
--- a/src/controls/qquicktextfield_p.h
+++ b/src/controls/qquicktextfield_p.h
@@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE
class QQuickText;
class QQuickTextFieldPrivate;
+class QQuickMouseEvent;
class Q_QUICKCONTROLS_EXPORT QQuickTextField : public QQuickTextInput
{
@@ -75,10 +76,15 @@ public:
Q_SIGNALS:
void backgroundChanged();
void placeholderChanged();
+ void pressAndHold(QQuickMouseEvent *mouse);
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QQuickTextField)
diff --git a/tests/auto/controls/data/tst_textfield.qml b/tests/auto/controls/data/tst_textfield.qml
index 4a55ef97..9ce325b3 100644
--- a/tests/auto/controls/data/tst_textfield.qml
+++ b/tests/auto/controls/data/tst_textfield.qml
@@ -60,4 +60,56 @@ TestCase {
verify(control)
control.destroy()
}
+
+ SignalSpy {
+ id: pressAndHoldSpy
+ signalName: "pressAndHold"
+ }
+
+ function test_pressAndHold() {
+ var control = textField.createObject(testCase)
+ control.width = 200
+ pressAndHoldSpy.target = control
+
+ mouseClick(control)
+ compare(pressAndHoldSpy.count, 0)
+ var interval = Qt.styleHints.mousePressAndHoldInterval
+
+ // Short press duration => nothing happens
+ mousePress(control)
+ wait(interval * 0.3)
+ mouseRelease(control)
+ compare(pressAndHoldSpy.count, 0)
+
+ // Long enough press duration => signal emitted
+ mousePress(control, 10, 10)
+ // Add 10% extra time to allow the control to
+ // receive the timer event before we come back here
+ wait(interval * 1.1)
+ compare(pressAndHoldSpy.count, 1)
+ mouseRelease(control)
+ compare(pressAndHoldSpy.count, 1)
+
+ // Long enough, but move in between => nothing happens
+ pressAndHoldSpy.clear()
+ mousePress(control)
+ wait(interval * 0.6)
+ mouseMove(control, 5, 5, Qt.LeftButton)
+ wait(interval * 0.6)
+ compare(pressAndHoldSpy.count, 0)
+ mouseRelease(control)
+ compare(pressAndHoldSpy.count, 0)
+
+ // Long enough, but 2nd press in between => nothing happens
+ pressAndHoldSpy.clear()
+ mousePress(control, 10, 10)
+ wait(interval * 0.6)
+ mousePress(control, 10, 10, Qt.RightButton)
+ wait(interval * 0.6)
+ compare(pressAndHoldSpy.count, 0)
+ mouseRelease(control, 10, 10, Qt.LeftButton|Qt.RightButton)
+ compare(pressAndHoldSpy.count, 0)
+
+ control.destroy()
+ }
}