1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt for Python. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef PYSIDEQTESTTOUCH_H 41 #define PYSIDEQTESTTOUCH_H 42 43 #include <QtTest/qttestglobal.h> 44 #include <QtTest/qtestassert.h> 45 #include <QtTest/qtestsystem.h> 46 #include <QtTest/qtestspontaneevent.h> 47 #include <QtTest/qtesttouch.h> 48 49 #include <QtCore/qmap.h> 50 #include <QtGui/qevent.h> 51 #include <QtGui/qwindow.h> 52 #ifdef QT_WIDGETS_LIB 53 #include <QtWidgets/qwidget.h> 54 #endif 55 56 QT_BEGIN_NAMESPACE 57 58 namespace QTest 59 { 60 61 class PySideQTouchEventSequence 62 { 63 public: ~PySideQTouchEventSequence()64 ~PySideQTouchEventSequence() 65 { 66 if (commitWhenDestroyed) 67 commit(); 68 } 69 PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWindow *window = nullptr) 70 { 71 QTouchEvent::TouchPoint &p = point(touchId); 72 p.setScreenPos(mapToScreen(window, pt)); 73 p.setState(Qt::TouchPointPressed); 74 return this; 75 } 76 PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWindow *window = nullptr) 77 { 78 QTouchEvent::TouchPoint &p = point(touchId); 79 p.setScreenPos(mapToScreen(window, pt)); 80 p.setState(Qt::TouchPointMoved); 81 return this; 82 } 83 PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWindow *window = nullptr) 84 { 85 QTouchEvent::TouchPoint &p = point(touchId); 86 p.setScreenPos(mapToScreen(window, pt)); 87 p.setState(Qt::TouchPointReleased); 88 return this; 89 } stationary(int touchId)90 PySideQTouchEventSequence *stationary(int touchId) 91 { 92 QTouchEvent::TouchPoint &p = pointOrPreviousPoint(touchId); 93 p.setState(Qt::TouchPointStationary); 94 return this; 95 } 96 97 #ifdef QT_WIDGETS_LIB 98 PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWidget *widget = nullptr) 99 { 100 QTouchEvent::TouchPoint &p = point(touchId); 101 p.setScreenPos(mapToScreen(widget, pt)); 102 p.setState(Qt::TouchPointPressed); 103 return this; 104 } 105 106 PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWidget *widget = nullptr) 107 { 108 QTouchEvent::TouchPoint &p = point(touchId); 109 p.setScreenPos(mapToScreen(widget, pt)); 110 p.setState(Qt::TouchPointMoved); 111 return this; 112 } 113 114 PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWidget *widget = nullptr) 115 { 116 QTouchEvent::TouchPoint &p = point(touchId); 117 p.setScreenPos(mapToScreen(widget, pt)); 118 p.setState(Qt::TouchPointReleased); 119 return this; 120 } 121 #endif 122 123 void commit(bool processEvents = true) 124 { 125 if (!points.isEmpty()) { 126 if (targetWindow) 127 { 128 qt_handleTouchEvent(targetWindow, device, points.values()); 129 } 130 #ifdef QT_WIDGETS_LIB 131 else if (targetWidget) 132 { 133 qt_handleTouchEvent(targetWidget->windowHandle(), device, points.values()); 134 } 135 #endif 136 } 137 if (processEvents) 138 QCoreApplication::processEvents(); 139 previousPoints = points; 140 points.clear(); 141 } 142 143 private: 144 #ifdef QT_WIDGETS_LIB PySideQTouchEventSequence(QWidget * widget,QTouchDevice * aDevice,bool autoCommit)145 PySideQTouchEventSequence(QWidget *widget, QTouchDevice *aDevice, bool autoCommit) 146 : targetWidget(widget), targetWindow(0), device(aDevice), commitWhenDestroyed(autoCommit) 147 { 148 } 149 #endif PySideQTouchEventSequence(QWindow * window,QTouchDevice * aDevice,bool autoCommit)150 PySideQTouchEventSequence(QWindow *window, QTouchDevice *aDevice, bool autoCommit) 151 : 152 #ifdef QT_WIDGETS_LIB 153 targetWidget(0), 154 #endif 155 targetWindow(window), device(aDevice), commitWhenDestroyed(autoCommit) 156 { 157 } 158 point(int touchId)159 QTouchEvent::TouchPoint &point(int touchId) 160 { 161 if (!points.contains(touchId)) 162 points[touchId] = QTouchEvent::TouchPoint(touchId); 163 return points[touchId]; 164 } 165 pointOrPreviousPoint(int touchId)166 QTouchEvent::TouchPoint &pointOrPreviousPoint(int touchId) 167 { 168 if (!points.contains(touchId)) { 169 if (previousPoints.contains(touchId)) 170 points[touchId] = previousPoints.value(touchId); 171 else 172 points[touchId] = QTouchEvent::TouchPoint(touchId); 173 } 174 return points[touchId]; 175 } 176 177 #ifdef QT_WIDGETS_LIB mapToScreen(QWidget * widget,const QPoint & pt)178 QPoint mapToScreen(QWidget *widget, const QPoint &pt) 179 { 180 if (widget) 181 return widget->mapToGlobal(pt); 182 return targetWidget ? targetWidget->mapToGlobal(pt) : pt; 183 } 184 #endif mapToScreen(QWindow * window,const QPoint & pt)185 QPoint mapToScreen(QWindow *window, const QPoint &pt) 186 { 187 if(window) 188 return window->mapToGlobal(pt); 189 return targetWindow ? targetWindow->mapToGlobal(pt) : pt; 190 } 191 192 QMap<int, QTouchEvent::TouchPoint> previousPoints; 193 QMap<int, QTouchEvent::TouchPoint> points; 194 #ifdef QT_WIDGETS_LIB 195 QWidget *targetWidget; 196 #endif 197 QWindow *targetWindow; 198 QTouchDevice *device; 199 bool commitWhenDestroyed; 200 #ifdef QT_WIDGETS_LIB 201 friend PySideQTouchEventSequence *generateTouchEvent(QWidget *, QTouchDevice *, bool); 202 #endif 203 friend PySideQTouchEventSequence *generateTouchEvent(QWindow *, QTouchDevice *, bool); 204 }; 205 206 #ifdef QT_WIDGETS_LIB 207 inline 208 PySideQTouchEventSequence *generateTouchEvent(QWidget *widget, 209 QTouchDevice *device, 210 bool autoCommit = true) 211 { 212 return new PySideQTouchEventSequence(widget, device, autoCommit); 213 } 214 #endif 215 inline 216 PySideQTouchEventSequence *generateTouchEvent(QWindow *window, 217 QTouchDevice *device, 218 bool autoCommit = true) 219 { 220 return new PySideQTouchEventSequence(window, device, autoCommit); 221 } 222 223 } 224 225 QT_END_NAMESPACE 226 227 #endif // PYSIDEQTESTTOUCH_H 228