Skip to content

Commit 5dcd3ed

Browse files
committed
Touch support for QtQuick2
1 parent e7fcdd4 commit 5dcd3ed

File tree

4 files changed

+317
-11
lines changed

4 files changed

+317
-11
lines changed

inc/extension_qt/quick2_view_executor.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,16 @@ class Quick2ViewCmdExecutor : public QWindowViewCmdExecutor {
8585
virtual void GetAlertMessage(std::string* text, Error** error) NOT_SUPPORTED_IMPL;
8686
virtual void SetAlertPromptText(const std::string& alert_prompt_text, Error** error) NOT_SUPPORTED_IMPL;
8787
virtual void AcceptOrDismissAlert(bool accept, Error** error) NOT_SUPPORTED_IMPL;
88-
virtual void TouchClick(const ElementId& element, Error **error) NOT_SUPPORTED_IMPL;
89-
virtual void TouchDoubleClick(const ElementId& element, Error **error) NOT_SUPPORTED_IMPL;
90-
virtual void TouchDown(const int &x, const int &y, Error **error) NOT_SUPPORTED_IMPL;
91-
virtual void TouchUp(const int &x, const int &y, Error **error) NOT_SUPPORTED_IMPL;
92-
virtual void TouchMove(const int &x, const int &y, Error **error) NOT_SUPPORTED_IMPL;
93-
virtual void TouchLongClick(const ElementId& element, Error **error) NOT_SUPPORTED_IMPL;
88+
virtual void TouchClick(const ElementId& element, Error **error);
89+
virtual void TouchDoubleClick(const ElementId& element, Error **error);
90+
virtual void TouchDown(const int &x, const int &y, Error **error);
91+
virtual void TouchUp(const int &x, const int &y, Error **error);
92+
virtual void TouchMove(const int &x, const int &y, Error **error);
93+
virtual void TouchLongClick(const ElementId& element, Error **error);
9494
virtual void TouchScroll(const int &xoffset, const int &yoffset, Error **error) NOT_SUPPORTED_IMPL;
95-
virtual void TouchScroll(const ElementId &element, const int &xoffset, const int &yoffset, Error **error) NOT_SUPPORTED_IMPL;
95+
virtual void TouchScroll(const ElementId &element, const int &xoffset, const int &yoffset, Error **error);
9696
virtual void TouchFlick(const int &xSpeed, const int &ySpeed, Error **error) NOT_SUPPORTED_IMPL;
97-
virtual void TouchFlick(const ElementId &element, const int &xoffset, const int &yoffset, const int &speed, Error **error) NOT_SUPPORTED_IMPL;
97+
virtual void TouchFlick(const ElementId &element, const int &xoffset, const int &yoffset, const int &speed, Error **error);
9898
virtual void GetPlayerState(const ElementId& element, PlayerState*, Error** error);
9999
virtual void SetPlayerState(const ElementId& element, PlayerState, Error** error);
100100
virtual void GetPlayerVolume(const ElementId& element, double*, Error** error);

inc/extension_qt/qwindow_view_executor.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#include "webdriver_error.h"
1111

1212
#include <QtCore/QDebug>
13-
#include <QtGui/QTouchDevice>
13+
#include <QtGui/QTouchEvent>
14+
#include <QtGui/QTouchDevice>
1415
#include <QtGui/QWindow>
1516

1617
namespace webdriver {
@@ -43,10 +44,12 @@ class QWindowViewCmdExecutor : public ViewCmdExecutor {
4344
QRect ConvertRectToQRect(const Rect &rect);
4445
QPoint ConvertPointToQPoint(const Point &p);
4546
Qt::MouseButton ConvertMouseButtonToQtMouseButton(MouseButton button);
46-
47-
QTouchDevice touchDevice;
47+
QTouchEvent::TouchPoint createTouchPoint(Qt::TouchPointState state, QPointF &point, QVector2D velocity = QVector2D());
48+
QTouchEvent* createSimpleTouchEvent(QEvent::Type eventType, Qt::TouchPointStates touchPointStates, QPointF &point, QVector2D velocity = QVector2D());
49+
QTouchEvent* createTouchEvent(QEvent::Type eventType, Qt::TouchPointStates touchPointStates, const QList<QTouchEvent::TouchPoint> &touchPoints);
4850

4951
private:
52+
QTouchDevice touchDevice;
5053
DISALLOW_COPY_AND_ASSIGN(QWindowViewCmdExecutor);
5154
};
5255

src/webdriver/extension_qt/quick2_view_executor.cc

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919

2020
#include <QtCore/QBuffer>
2121
#include <QtCore/QDebug>
22+
#include <QtCore/QTimer>
2223
#include <QtGui/QGuiApplication>
2324
#include <QtQml/QQmlExpression>
2425
#include <QtQml/QQmlEngine>
26+
#include <QtGui/QStyleHints>
2527

2628
#include "third_party/pugixml/pugixml.hpp"
2729

@@ -1027,6 +1029,269 @@ void Quick2ViewCmdExecutor::GetPlaybackSpeed(const ElementId &element, double *s
10271029
positionValue->GetAsDouble(speed);
10281030
}
10291031

1032+
void Quick2ViewCmdExecutor::TouchClick(const ElementId& element, Error **error)
1033+
{
1034+
QQuickView* view = getView(view_id_, error);
1035+
if (NULL == view)
1036+
return;
1037+
1038+
Point location(0,0);
1039+
1040+
// calculate the half of the element size and translate by it.
1041+
Size size;
1042+
GetElementSize(element, &size, error);
1043+
if (*error)
1044+
return;
1045+
1046+
location.Offset(size.width() / 2, size.height() / 2);
1047+
1048+
QPointF point = ConvertPointToQPoint(location);
1049+
1050+
QQuickItem* pItem = getElement(element, error);
1051+
if (*error)
1052+
return;
1053+
1054+
point = pItem->mapToScene(point);
1055+
1056+
QTouchEvent *touchBeginEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, point);
1057+
QTouchEvent *touchEndEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, point);
1058+
1059+
QGuiApplication::postEvent(view, touchBeginEvent);
1060+
QGuiApplication::postEvent(view, touchEndEvent);
1061+
1062+
QGuiApplication::processEvents();
1063+
}
1064+
1065+
void Quick2ViewCmdExecutor::TouchDoubleClick(const ElementId& element, Error **error)
1066+
{
1067+
QQuickView* view = getView(view_id_, error);
1068+
if (NULL == view)
1069+
return;
1070+
1071+
Point location(0,0);
1072+
1073+
// calculate the half of the element size and translate by it.
1074+
Size size;
1075+
GetElementSize(element, &size, error);
1076+
if (*error)
1077+
return;
1078+
1079+
location.Offset(size.width() / 2, size.height() / 2);
1080+
1081+
QPointF point = ConvertPointToQPoint(location);
1082+
1083+
QQuickItem* pItem = getElement(element, error);
1084+
if (*error)
1085+
return;
1086+
1087+
point = pItem->mapToScene(point);
1088+
1089+
QTouchEvent *touchBeginEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, point);
1090+
QTouchEvent *touchEndEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, point);
1091+
QTouchEvent *touchBeginEvent2 = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, point);
1092+
QTouchEvent *touchEndEvent2 = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, point);
1093+
1094+
QGuiApplication::postEvent(view, touchBeginEvent);
1095+
QGuiApplication::postEvent(view, touchEndEvent);
1096+
QGuiApplication::postEvent(view, touchBeginEvent2);
1097+
QGuiApplication::postEvent(view, touchEndEvent2);
1098+
1099+
1100+
QGuiApplication::processEvents();
1101+
}
1102+
1103+
void Quick2ViewCmdExecutor::TouchDown(const int &x, const int &y, Error **error)
1104+
{
1105+
QQuickView* view = getView(view_id_, error);
1106+
if (NULL == view)
1107+
return;
1108+
1109+
QPointF point = ConvertPointToQPoint(Point(x, y));
1110+
1111+
QTouchEvent *touchBeginEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, point);
1112+
1113+
QGuiApplication::postEvent(view, touchBeginEvent);
1114+
1115+
QGuiApplication::processEvents();
1116+
}
1117+
1118+
void Quick2ViewCmdExecutor::TouchUp(const int &x, const int &y, Error **error)
1119+
{
1120+
QQuickView* view = getView(view_id_, error);
1121+
if (NULL == view)
1122+
return;
1123+
1124+
QPointF point = ConvertPointToQPoint(Point(x, y));
1125+
1126+
QTouchEvent *touchEndEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, point);
1127+
1128+
QGuiApplication::postEvent(view, touchEndEvent);
1129+
1130+
QGuiApplication::processEvents();
1131+
}
1132+
1133+
void Quick2ViewCmdExecutor::TouchMove(const int &x, const int &y, Error **error)
1134+
{
1135+
QQuickView* view = getView(view_id_, error);
1136+
if (NULL == view)
1137+
return;
1138+
1139+
QPointF point = ConvertPointToQPoint(Point(x, y));
1140+
1141+
QTouchEvent *touchMoveEvent = createSimpleTouchEvent(QEvent::TouchUpdate, Qt::TouchPointMoved, point);
1142+
1143+
QGuiApplication::postEvent(view, touchMoveEvent);
1144+
1145+
QGuiApplication::processEvents();
1146+
}
1147+
1148+
void Quick2ViewCmdExecutor::TouchLongClick(const ElementId& element, Error **error)
1149+
{
1150+
QQuickView* view = getView(view_id_, error);
1151+
if (NULL == view)
1152+
return;
1153+
1154+
Point location(0,0);
1155+
1156+
// calculate the half of the element size and translate by it.
1157+
Size size;
1158+
GetElementSize(element, &size, error);
1159+
if (*error)
1160+
return;
1161+
1162+
location.Offset(size.width() / 2, size.height() / 2);
1163+
1164+
QPointF point = ConvertPointToQPoint(location);
1165+
1166+
QEventLoop loop;
1167+
QTimer::singleShot(1000, &loop, SLOT(quit()));
1168+
1169+
QQuickItem* pItem = getElement(element, error);
1170+
if (*error)
1171+
return;
1172+
1173+
point = pItem->mapToScene(point);
1174+
1175+
QTouchEvent *touchBeginEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, point);
1176+
QGuiApplication::postEvent(view, touchBeginEvent);
1177+
1178+
loop.exec();
1179+
1180+
QTouchEvent *touchEndEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, point);
1181+
QGuiApplication::postEvent(view, touchEndEvent);
1182+
1183+
QGuiApplication::processEvents();
1184+
1185+
}
1186+
1187+
void Quick2ViewCmdExecutor::TouchScroll(const ElementId &element, const int &xoffset, const int &yoffset, Error **error)
1188+
{
1189+
QQuickView* view = getView(view_id_, error);
1190+
if (NULL == view)
1191+
return;
1192+
1193+
Point location(0,0);
1194+
1195+
// calculate the half of the element size and translate by it.
1196+
Size sizel;
1197+
GetElementSize(element, &sizel, error);
1198+
if (*error)
1199+
return;
1200+
1201+
location.Offset(sizel.width() / 2, sizel.height() / 2);
1202+
1203+
QPointF startPoint = ConvertPointToQPoint(location);
1204+
1205+
QQuickItem* pItem = getElement(element, error);
1206+
if (*error)
1207+
return;
1208+
1209+
startPoint = pItem->mapToScene(startPoint);
1210+
1211+
Point offset(xoffset, yoffset);
1212+
QPointF offsetPoint = ConvertPointToQPoint(offset);
1213+
int stepCount = 20;
1214+
int timeBetweenEvent = 30;
1215+
QEventLoop loop;
1216+
1217+
for (int i = 0; i <= stepCount; ++i)
1218+
{
1219+
QPointF touchPoint(startPoint.x()+offsetPoint.x()*i/stepCount, startPoint.y()+offsetPoint.y()*i/stepCount);
1220+
1221+
QTouchEvent *touchEvent;
1222+
if (i == 0)
1223+
touchEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, touchPoint);
1224+
else if (i == stepCount)
1225+
touchEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, touchPoint);
1226+
else
1227+
touchEvent = createSimpleTouchEvent(QEvent::TouchUpdate, Qt::TouchPointMoved, touchPoint);
1228+
1229+
1230+
QGuiApplication::postEvent(view, touchEvent);
1231+
QTimer::singleShot(timeBetweenEvent, &loop, SLOT(quit()));
1232+
loop.exec();
1233+
}
1234+
QGuiApplication::processEvents();
1235+
}
1236+
1237+
void Quick2ViewCmdExecutor::TouchFlick(const ElementId &element, const int &xoffset, const int &yoffset, const int &speed, Error **error)
1238+
{
1239+
QQuickView* view = getView(view_id_, error);
1240+
if (NULL == view)
1241+
return;
1242+
1243+
Point location(0,0);
1244+
1245+
// calculate the half of the element size and translate by it.
1246+
Size size;
1247+
GetElementSize(element, &size, error);
1248+
if (*error)
1249+
return;
1250+
1251+
location.Offset(size.width() / 2, size.height() / 2);
1252+
QPointF startPoint = ConvertPointToQPoint(location);
1253+
1254+
QQuickItem* pItem = getElement(element, error);
1255+
if (*error)
1256+
return;
1257+
1258+
startPoint = pItem->mapToScene(startPoint);
1259+
1260+
QPointF offsetPoint = ConvertPointToQPoint(Point(xoffset, yoffset));
1261+
1262+
QEventLoop loop;
1263+
1264+
//some magic numbers
1265+
int stepCount = 20;
1266+
int timeBetweenEvent = 30/(speed+1);
1267+
1268+
QVector2D velocity(xoffset*1000/(stepCount*timeBetweenEvent), yoffset*1000/(stepCount*timeBetweenEvent));
1269+
1270+
for (int i = 0; i <= stepCount; ++i)
1271+
{
1272+
QPointF touchPoint(startPoint.x()+offsetPoint.x()*i/stepCount, startPoint.y()+offsetPoint.y()*i/stepCount);
1273+
1274+
QTouchEvent *touchEvent;
1275+
if (i == 0)
1276+
touchEvent = createSimpleTouchEvent(QEvent::TouchBegin, Qt::TouchPointPressed, touchPoint, velocity);
1277+
else if (i == stepCount)
1278+
touchEvent = createSimpleTouchEvent(QEvent::TouchEnd, Qt::TouchPointReleased, touchPoint, velocity);
1279+
else
1280+
touchEvent = createSimpleTouchEvent(QEvent::TouchUpdate, Qt::TouchPointMoved, touchPoint, velocity);
1281+
1282+
QGuiApplication::postEvent(view, touchEvent);
1283+
QTimer::singleShot(timeBetweenEvent, &loop, SLOT(quit()));
1284+
loop.exec();
1285+
if (i == stepCount)
1286+
{
1287+
QPointF touchPoint(startPoint);
1288+
touchEvent = createSimpleTouchEvent(QEvent::TouchCancel, Qt::TouchPointPressed, touchPoint);
1289+
QGuiApplication::postEvent(view, touchEvent);
1290+
}
1291+
}
1292+
QGuiApplication::processEvents();
1293+
}
1294+
10301295
QQuickItem* Quick2ViewCmdExecutor::getFocusItem(QQuickView* view) {
10311296
QQuickItem* pFocusItem = view->activeFocusItem();
10321297
if (NULL != pFocusItem) return pFocusItem;

src/webdriver/extension_qt/qwindow_view_executor.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <QtCore/QDebug>
1111
#include <QtGui/QGuiApplication>
12+
#include <QtCore/QDateTime>
1213
#ifdef OS_ANDROID
1314
#include <qpa/qplatformnativeinterface.h>
1415
#include <jni.h>
@@ -18,6 +19,7 @@ namespace webdriver {
1819

1920
QWindowViewCmdExecutor::QWindowViewCmdExecutor(Session* session, ViewId viewId)
2021
: ViewCmdExecutor(session, viewId) {
22+
touchDevice.setCapabilities(QTouchDevice::Velocity);
2123
}
2224

2325
QWindowViewCmdExecutor::~QWindowViewCmdExecutor() {
@@ -283,4 +285,40 @@ Qt::MouseButton QWindowViewCmdExecutor::ConvertMouseButtonToQtMouseButton(MouseB
283285
return result;
284286
}
285287

288+
QTouchEvent::TouchPoint QWindowViewCmdExecutor::createTouchPoint(Qt::TouchPointState state, QPointF &point, QVector2D velocity)
289+
{
290+
QTouchEvent::TouchPoint touchPoint(1);
291+
touchPoint.setPos(point);
292+
touchPoint.setState(state);
293+
touchPoint.setPressure(1);
294+
295+
touchPoint.setVelocity(velocity);
296+
return touchPoint;
297+
}
298+
299+
QTouchEvent* QWindowViewCmdExecutor::createSimpleTouchEvent(QEvent::Type eventType, Qt::TouchPointStates touchPointStates, QPointF &point, QVector2D velocity)
300+
{
301+
QList<QTouchEvent::TouchPoint> points;
302+
Qt::TouchPointState touchPointState;
303+
if (touchPointStates & Qt::TouchPointPressed)
304+
touchPointState = Qt::TouchPointPressed;
305+
else if (touchPointStates & Qt::TouchPointReleased)
306+
touchPointState = Qt::TouchPointReleased;
307+
else {
308+
touchPointState = Qt::TouchPointMoved;
309+
}
310+
QTouchEvent::TouchPoint touchPoint = createTouchPoint(touchPointState, point, velocity);
311+
points.append(touchPoint);
312+
return createTouchEvent(eventType, touchPointStates, points);
313+
}
314+
315+
QTouchEvent* QWindowViewCmdExecutor::createTouchEvent(QEvent::Type eventType, Qt::TouchPointStates touchPointStates, const QList<QTouchEvent::TouchPoint> &touchPoints)
316+
{
317+
QTouchEvent *touchEvent = new QTouchEvent(eventType, &touchDevice, Qt::NoModifier, touchPointStates, touchPoints);
318+
QDateTime current = QDateTime::currentDateTime();
319+
ulong timestame = current.toMSecsSinceEpoch() & (((qint64)1<<(sizeof(ulong)*8))-1);
320+
touchEvent->setTimestamp(timestame);
321+
return touchEvent;
322+
}
323+
286324
} // namespace webdriver

0 commit comments

Comments
 (0)