aboutsummaryrefslogtreecommitdiffstats
path: root/src/controls
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>2015-09-15 11:40:43 +0200
committerGabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>2015-09-15 13:25:52 +0000
commitb47ac20e368dce3bbf89bc724600703cd33cb168 (patch)
treeb8b3ef1eb6afe4f9c78ccfcaa5925db2a1536fb6 /src/controls
parent175dc7d516740a8964a859e4d7b5daaf41ef98d0 (diff)
Ensure press-and-hold event keeps selection
This concerns TextField and TextArea. It is an almost universal UX pattern on touch platforms where the user long presses to pop the context menu up. In many cases the context menu is used for copy and cut operations, which means that poping it up should keep the selection. The implementation works by not forwarding the initial mouse press event to the parent class until we're sure it's not going to be a long press. If the long press timer is cancelled for any reason, we will then send the delayed mouse press event to the parent class followed by whichever event triggered the cancellation. Auto-tests refactored and updated. Change-Id: If3aa8075f07a80929f4bd723895d9599bf8d169e Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src/controls')
-rw-r--r--src/controls/qquickpressandholdhelper.cpp25
-rw-r--r--src/controls/qquickpressandholdhelper_p.h4
-rw-r--r--src/controls/qquicktextarea.cpp22
-rw-r--r--src/controls/qquicktextfield.cpp22
4 files changed, 64 insertions, 9 deletions
diff --git a/src/controls/qquickpressandholdhelper.cpp b/src/controls/qquickpressandholdhelper.cpp
index 088a402b..38cd871c 100644
--- a/src/controls/qquickpressandholdhelper.cpp
+++ b/src/controls/qquickpressandholdhelper.cpp
@@ -45,17 +45,22 @@
QT_BEGIN_NAMESPACE
QQuickPressAndHoldHelper::QQuickPressAndHoldHelper()
- : control(Q_NULLPTR), longPress(false), pressAndHoldSignalIndex(-1)
+ : control(Q_NULLPTR)
+ , longPress(false)
+ , pressAndHoldSignalIndex(-1)
+ , delayedMousePressEvent(Q_NULLPTR)
{ }
void QQuickPressAndHoldHelper::mousePressEvent(QMouseEvent *event)
{
longPress = false;
pressPos = event->localPos();
- if (Qt::LeftButton == (event->buttons() & Qt::LeftButton))
+ if (Qt::LeftButton == (event->buttons() & Qt::LeftButton)) {
timer.start(QGuiApplication::styleHints()->mousePressAndHoldInterval(), control);
- else
+ delayedMousePressEvent = new QMouseEvent(event->type(), event->pos(), event->button(), event->buttons(), event->modifiers());
+ } else {
timer.stop();
+ }
}
void QQuickPressAndHoldHelper::mouseMoveEvent(QMouseEvent *event)
@@ -73,6 +78,7 @@ void QQuickPressAndHoldHelper::mouseReleaseEvent(QMouseEvent *)
void QQuickPressAndHoldHelper::timerEvent(QTimerEvent *)
{
timer.stop();
+ clearDelayedMouseEvent();
if (pressAndHoldSignalIndex == -1)
pressAndHoldSignalIndex = control->metaObject()->indexOfSignal("pressAndHold(QQuickMouseEvent*)");
@@ -92,4 +98,17 @@ void QQuickPressAndHoldHelper::timerEvent(QTimerEvent *)
}
}
+void QQuickPressAndHoldHelper::clearDelayedMouseEvent()
+{
+ if (delayedMousePressEvent) {
+ delete delayedMousePressEvent;
+ delayedMousePressEvent = 0;
+ }
+}
+
+bool QQuickPressAndHoldHelper::isActive()
+{
+ return !(timer.isActive() || longPress);
+}
+
QT_END_NAMESPACE
diff --git a/src/controls/qquickpressandholdhelper_p.h b/src/controls/qquickpressandholdhelper_p.h
index 6c0dc5ae..0ac84494 100644
--- a/src/controls/qquickpressandholdhelper_p.h
+++ b/src/controls/qquickpressandholdhelper_p.h
@@ -55,11 +55,15 @@ struct QQuickPressAndHoldHelper
void mouseReleaseEvent(QMouseEvent *event);
void timerEvent(QTimerEvent *event);
+ void clearDelayedMouseEvent();
+ bool isActive();
+
QQuickItem *control;
QBasicTimer timer;
QPointF pressPos;
bool longPress;
int pressAndHoldSignalIndex;
+ QMouseEvent *delayedMousePressEvent;
};
QT_END_NAMESPACE
diff --git a/src/controls/qquicktextarea.cpp b/src/controls/qquicktextarea.cpp
index 5427358b..d46702e2 100644
--- a/src/controls/qquicktextarea.cpp
+++ b/src/controls/qquicktextarea.cpp
@@ -260,23 +260,39 @@ void QQuickTextArea::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickTextArea);
d->pressAndHoldHelper.mousePressEvent(event);
- QQuickTextEdit::mousePressEvent(event);
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextEdit::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
+ QQuickTextEdit::mousePressEvent(event);
+ }
}
void QQuickTextArea::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickTextArea);
d->pressAndHoldHelper.mouseMoveEvent(event);
- if (!d->pressAndHoldHelper.timer.isActive())
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextEdit::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
QQuickTextEdit::mouseMoveEvent(event);
+ }
}
void QQuickTextArea::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickTextArea);
d->pressAndHoldHelper.mouseReleaseEvent(event);
- if (!d->pressAndHoldHelper.longPress)
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextEdit::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
QQuickTextEdit::mouseReleaseEvent(event);
+ }
}
void QQuickTextArea::timerEvent(QTimerEvent *event)
diff --git a/src/controls/qquicktextfield.cpp b/src/controls/qquicktextfield.cpp
index cf8f24a2..7cf5f3c1 100644
--- a/src/controls/qquicktextfield.cpp
+++ b/src/controls/qquicktextfield.cpp
@@ -292,23 +292,39 @@ void QQuickTextField::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickTextField);
d->pressAndHoldHelper.mousePressEvent(event);
- QQuickTextInput::mousePressEvent(event);
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextInput::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
+ QQuickTextInput::mousePressEvent(event);
+ }
}
void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickTextField);
d->pressAndHoldHelper.mouseMoveEvent(event);
- if (!d->pressAndHoldHelper.timer.isActive())
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextInput::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
QQuickTextInput::mouseMoveEvent(event);
+ }
}
void QQuickTextField::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickTextField);
d->pressAndHoldHelper.mouseReleaseEvent(event);
- if (!d->pressAndHoldHelper.longPress)
+ if (d->pressAndHoldHelper.isActive()) {
+ if (d->pressAndHoldHelper.delayedMousePressEvent) {
+ QQuickTextInput::mousePressEvent(d->pressAndHoldHelper.delayedMousePressEvent);
+ d->pressAndHoldHelper.clearDelayedMouseEvent();
+ }
QQuickTextInput::mouseReleaseEvent(event);
+ }
}
void QQuickTextField::timerEvent(QTimerEvent *event)