Merge lp:~osomon/webbrowser-app/use-uitk-swipearea into lp:webbrowser-app
- use-uitk-swipearea
- Merge into trunk
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Olivier Tilloy | ||||||||||||
Approved revision: | 1394 | ||||||||||||
Merged at revision: | 1437 | ||||||||||||
Proposed branch: | lp:~osomon/webbrowser-app/use-uitk-swipearea | ||||||||||||
Merge into: | lp:webbrowser-app | ||||||||||||
Diff against target: |
4899 lines (+8/-4580) 46 files modified
CMakeLists.txt (+0/-1) debian/control (+0/-1) src/app/CMakeLists.txt (+1/-3) src/app/browserapplication.cpp (+0/-10) src/app/unity8/CMakeLists.txt (+0/-1) src/app/unity8/README (+0/-8) src/app/unity8/libs/CMakeLists.txt (+0/-1) src/app/unity8/libs/UbuntuGestures/CMakeLists.txt (+0/-36) src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.cpp (+0/-41) src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.h (+0/-49) src/app/unity8/libs/UbuntuGestures/DebugHelpers.cpp (+0/-95) src/app/unity8/libs/UbuntuGestures/DebugHelpers.h (+0/-31) src/app/unity8/libs/UbuntuGestures/Pool.h (+0/-132) src/app/unity8/libs/UbuntuGestures/Timer.cpp (+0/-109) src/app/unity8/libs/UbuntuGestures/Timer.h (+0/-105) src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.cpp (+0/-35) src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.h (+0/-50) src/app/unity8/libs/UbuntuGestures/TouchRegistry.cpp (+0/-500) src/app/unity8/libs/UbuntuGestures/TouchRegistry.h (+0/-182) src/app/unity8/libs/UbuntuGestures/UbuntuGesturesGlobal.h (+0/-23) src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.cpp (+0/-39) src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.h (+0/-45) src/app/unity8/plugins/CMakeLists.txt (+0/-1) src/app/unity8/plugins/Ubuntu/CMakeLists.txt (+0/-1) src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp (+0/-149) src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.h (+0/-146) src/app/unity8/plugins/Ubuntu/Gestures/CMakeLists.txt (+0/-40) src/app/unity8/plugins/Ubuntu/Gestures/Damper.h (+0/-87) src/app/unity8/plugins/Ubuntu/Gestures/Direction.cpp (+0/-36) src/app/unity8/plugins/Ubuntu/Gestures/Direction.h (+0/-45) src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.cpp (+0/-886) src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.h (+0/-308) src/app/unity8/plugins/Ubuntu/Gestures/Gestures.qmltypes (+0/-168) src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp (+0/-119) src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.h (+0/-62) src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.cpp (+0/-49) src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.h (+0/-54) src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.cpp (+0/-367) src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.h (+0/-89) src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.cpp (+0/-253) src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.h (+0/-112) src/app/unity8/plugins/Ubuntu/Gestures/UbuntuGesturesQmlGlobal.h (+0/-23) src/app/unity8/plugins/Ubuntu/Gestures/plugin.cpp (+0/-39) src/app/unity8/plugins/Ubuntu/Gestures/plugin.h (+0/-31) src/app/unity8/plugins/Ubuntu/Gestures/qmldir (+0/-3) src/app/webbrowser/BottomEdgeHandle.qml (+7/-15) |
||||||||||||
To merge this branch: | bzr merge lp:~osomon/webbrowser-app/use-uitk-swipearea | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
system-apps-ci-bot | continuous-integration | Needs Fixing | |
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email:
|
Commit message
Use the UITK’s SwipeArea component for the bottom edge gesture recognition.
This requires oxide 1.14 to work well (because of bug #1459362).
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1393
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 1394. By Olivier Tilloy
-
Merge the latest changes from trunk and resolve conflicts.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1394
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1394
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-09-07 10:37:42 +0000 |
3 | +++ CMakeLists.txt 2016-04-12 20:15:29 +0000 |
4 | @@ -34,7 +34,6 @@ |
5 | ENABLE_COVERAGE_REPORT(EXCLUDES tests/*|.*moc_.*.cpp FILTER tests/* moc_*.cpp) |
6 | endif() |
7 | |
8 | -# for unity8 components |
9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
10 | |
11 | # enable QML debugging |
12 | |
13 | === modified file 'debian/control' |
14 | --- debian/control 2016-04-08 17:06:09 +0000 |
15 | +++ debian/control 2016-04-12 20:15:29 +0000 |
16 | @@ -29,7 +29,6 @@ |
17 | qtbase5-dev-tools, |
18 | qtbase5-private-dev, |
19 | qtdeclarative5-dev, |
20 | - qtdeclarative5-private-dev, |
21 | qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3), |
22 | xvfb, |
23 | Standards-Version: 3.9.6 |
24 | |
25 | === modified file 'src/app/CMakeLists.txt' |
26 | --- src/app/CMakeLists.txt 2016-03-29 11:01:18 +0000 |
27 | +++ src/app/CMakeLists.txt 2016-04-12 20:15:29 +0000 |
28 | @@ -32,8 +32,7 @@ |
29 | |
30 | add_library(${COMMONLIB} STATIC ${COMMONLIB_SRC}) |
31 | |
32 | -include_directories(${unity8_SOURCE_DIR}/libs/UbuntuGestures |
33 | - ${unity8_SOURCE_DIR}/plugins |
34 | +include_directories(${unity8_SOURCE_DIR}/plugins |
35 | ${LIBAPPARMOR_INCLUDE_DIRS} |
36 | ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) |
37 | target_link_libraries(${COMMONLIB} |
38 | @@ -43,7 +42,6 @@ |
39 | Qt5::Qml |
40 | Qt5::Quick |
41 | Qt5::Widgets |
42 | - UbuntuGesturesQml |
43 | InputInfo |
44 | ${LIBAPPARMOR_LDFLAGS} |
45 | ) |
46 | |
47 | === modified file 'src/app/browserapplication.cpp' |
48 | --- src/app/browserapplication.cpp 2016-03-29 11:01:18 +0000 |
49 | +++ src/app/browserapplication.cpp 2016-04-12 20:15:29 +0000 |
50 | @@ -42,9 +42,6 @@ |
51 | #include "session-storage.h" |
52 | #include "webbrowser-window.h" |
53 | |
54 | -#include "TouchRegistry.h" |
55 | -#include "Ubuntu/Gestures/Direction.h" |
56 | -#include "Ubuntu/Gestures/DirectionalDragArea.h" |
57 | #include "Unity/InputInfo/qdeclarativeinputdevicemodel_p.h" |
58 | |
59 | BrowserApplication::BrowserApplication(int& argc, char** argv) |
60 | @@ -117,7 +114,6 @@ |
61 | |
62 | MAKE_SINGLETON_FACTORY(MemInfo) |
63 | MAKE_SINGLETON_FACTORY(MimeDatabase) |
64 | -MAKE_SINGLETON_FACTORY(Direction) |
65 | |
66 | |
67 | bool BrowserApplication::initialize(const QString& qmlFileSubPath) |
68 | @@ -182,10 +178,6 @@ |
69 | qmlRegisterType<SessionStorage>(uri, 0, 1, "SessionStorage"); |
70 | qmlRegisterType<QQuickShortcut>(uri, 0, 1, "Shortcut"); |
71 | |
72 | - const char* gesturesUri = "Ubuntu.Gestures"; |
73 | - qmlRegisterSingletonType<Direction>(gesturesUri, 0, 1, "Direction", Direction_singleton_factory); |
74 | - qmlRegisterType<DirectionalDragArea>(gesturesUri, 0, 1, "DirectionalDragArea"); |
75 | - |
76 | const char* inputInfoUri = "Unity.InputInfo"; |
77 | qmlRegisterType<QDeclarativeInputDeviceModel>(inputInfoUri, 0, 1, "InputDeviceModel"); |
78 | qmlRegisterType<QInputDevice>(inputInfoUri, 0, 1, "InputInfo"); |
79 | @@ -215,8 +207,6 @@ |
80 | m_window = qobject_cast<QQuickWindow*>(browser); |
81 | m_webbrowserWindowProxy->setWindow(m_window); |
82 | |
83 | - m_window->installEventFilter(new TouchRegistry(this)); |
84 | - |
85 | browser->setProperty("developerExtrasEnabled", inspectorEnabled); |
86 | browser->setProperty("forceFullscreen", m_arguments.contains("--fullscreen")); |
87 | |
88 | |
89 | === modified file 'src/app/unity8/CMakeLists.txt' |
90 | --- src/app/unity8/CMakeLists.txt 2015-02-04 10:56:38 +0000 |
91 | +++ src/app/unity8/CMakeLists.txt 2016-04-12 20:15:29 +0000 |
92 | @@ -1,4 +1,3 @@ |
93 | project(unity8) |
94 | |
95 | -add_subdirectory(libs) |
96 | add_subdirectory(plugins) |
97 | |
98 | === modified file 'src/app/unity8/README' |
99 | --- src/app/unity8/README 2016-01-28 13:51:25 +0000 |
100 | +++ src/app/unity8/README 2016-04-12 20:15:29 +0000 |
101 | @@ -1,9 +1,5 @@ |
102 | Code in this directory was copied over from unity8. |
103 | |
104 | -Ubuntu.Gestures: |
105 | - - first import: 2015-02-04, at revision 1583 of lp:unity8 |
106 | - - last sync: 2015-03-17, at revision 1663 of lp:unity8 |
107 | - |
108 | Unity.InputInfo: |
109 | - first import: 2016-01-28, at revision 2143 of lp:unity8 |
110 | |
111 | @@ -11,9 +7,5 @@ |
112 | code in the future. Minor changes were made to the build system to integrate it |
113 | with the existing webbrowser-app code base. |
114 | |
115 | -As of 2015-12-09, the SwipeArea component is available in the UITK, so we should |
116 | -start using it instead of building a local copy of Ubuntu.Gestures. This is |
117 | -currently blocked on https://launchpad.net/bugs/1459362. |
118 | - |
119 | The Unity.InputInfo plugin should be replaced by an upstream Qt API in the near |
120 | future. |
121 | |
122 | === removed directory 'src/app/unity8/libs' |
123 | === removed file 'src/app/unity8/libs/CMakeLists.txt' |
124 | --- src/app/unity8/libs/CMakeLists.txt 2015-02-04 10:56:38 +0000 |
125 | +++ src/app/unity8/libs/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
126 | @@ -1,1 +0,0 @@ |
127 | -add_subdirectory(UbuntuGestures) |
128 | |
129 | === removed directory 'src/app/unity8/libs/UbuntuGestures' |
130 | === removed file 'src/app/unity8/libs/UbuntuGestures/CMakeLists.txt' |
131 | --- src/app/unity8/libs/UbuntuGestures/CMakeLists.txt 2015-02-04 10:56:38 +0000 |
132 | +++ src/app/unity8/libs/UbuntuGestures/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
133 | @@ -1,36 +0,0 @@ |
134 | -# in order to include Qt's private headers |
135 | -remove_definitions(-DQT_NO_KEYWORDS) |
136 | - |
137 | -set(UbuntuGestures_SOURCES |
138 | - CandidateInactivityTimer.cpp |
139 | - DebugHelpers.cpp |
140 | - Timer.cpp |
141 | - TouchOwnershipEvent.cpp |
142 | - TouchRegistry.cpp |
143 | - UnownedTouchEvent.cpp |
144 | -) |
145 | - |
146 | -add_definitions(-DUBUNTUGESTURES_LIBRARY) |
147 | - |
148 | -add_library(UbuntuGestures STATIC ${UbuntuGestures_SOURCES}) |
149 | - |
150 | -qt5_use_modules(UbuntuGestures Core Quick) |
151 | - |
152 | -# So that Foo.cpp can #include "Foo.moc" |
153 | -include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
154 | - |
155 | -# There's no cmake var for v8 include path :-/ so create one |
156 | -LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0) |
157 | -if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0") |
158 | - SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8) |
159 | -else() |
160 | - SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8) |
161 | -endif() |
162 | - |
163 | -# DANGER! DANGER! Using Qt's private API! |
164 | -include_directories( |
165 | - ${Qt5Qml_PRIVATE_INCLUDE_DIRS} |
166 | - ${Qt5Quick_INCLUDE_DIRS} |
167 | - ${Qt5Quick_PRIVATE_INCLUDE_DIRS} |
168 | - ${Qt5V8_PRIVATE_INCLUDE_DIR} |
169 | -) |
170 | |
171 | === removed file 'src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.cpp' |
172 | --- src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.cpp 2015-02-04 10:56:38 +0000 |
173 | +++ src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.cpp 1970-01-01 00:00:00 +0000 |
174 | @@ -1,41 +0,0 @@ |
175 | -/* |
176 | - * Copyright (C) 2014 Canonical, Ltd. |
177 | - * |
178 | - * This program is free software; you can redistribute it and/or modify |
179 | - * it under the terms of the GNU General Public License as published by |
180 | - * the Free Software Foundation; version 3. |
181 | - * |
182 | - * This program is distributed in the hope that it will be useful, |
183 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
184 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
185 | - * GNU General Public License for more details. |
186 | - * |
187 | - * You should have received a copy of the GNU General Public License |
188 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
189 | - */ |
190 | - |
191 | -#include "CandidateInactivityTimer.h" |
192 | - |
193 | -namespace UbuntuGestures { |
194 | - |
195 | -CandidateInactivityTimer::CandidateInactivityTimer(int touchId, QQuickItem *candidate, |
196 | - AbstractTimerFactory &timerFactory, QObject *parent) |
197 | - : QObject(parent) |
198 | - , m_touchId(touchId) |
199 | - , m_candidate(candidate) |
200 | -{ |
201 | - m_timer = timerFactory.createTimer(this); |
202 | - connect(m_timer, &AbstractTimer::timeout, |
203 | - this, &CandidateInactivityTimer::onTimeout); |
204 | - m_timer->setInterval(durationMs); |
205 | - m_timer->setSingleShot(true); |
206 | - m_timer->start(); |
207 | -} |
208 | - |
209 | -void CandidateInactivityTimer::onTimeout() |
210 | -{ |
211 | - qWarning("[TouchRegistry] Candidate for touch %d defaulted!", m_touchId); |
212 | - Q_EMIT candidateDefaulted(m_touchId, m_candidate); |
213 | -} |
214 | - |
215 | -} // namespace UbuntuGestures |
216 | |
217 | === removed file 'src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.h' |
218 | --- src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.h 2015-02-04 10:56:38 +0000 |
219 | +++ src/app/unity8/libs/UbuntuGestures/CandidateInactivityTimer.h 1970-01-01 00:00:00 +0000 |
220 | @@ -1,49 +0,0 @@ |
221 | -/* |
222 | - * Copyright (C) 2014 Canonical, Ltd. |
223 | - * |
224 | - * This program is free software; you can redistribute it and/or modify |
225 | - * it under the terms of the GNU General Public License as published by |
226 | - * the Free Software Foundation; version 3. |
227 | - * |
228 | - * This program is distributed in the hope that it will be useful, |
229 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
230 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
231 | - * GNU General Public License for more details. |
232 | - * |
233 | - * You should have received a copy of the GNU General Public License |
234 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
235 | - */ |
236 | - |
237 | -#ifndef UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H |
238 | -#define UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H |
239 | - |
240 | -#include <QObject> |
241 | - |
242 | -class QQuickItem; |
243 | - |
244 | -#include "Timer.h" |
245 | - |
246 | -namespace UbuntuGestures { |
247 | - |
248 | -class UBUNTUGESTURES_EXPORT CandidateInactivityTimer : public QObject { |
249 | - Q_OBJECT |
250 | -public: |
251 | - CandidateInactivityTimer(int touchId, QQuickItem *candidate, |
252 | - AbstractTimerFactory &timerFactory, |
253 | - QObject *parent = nullptr); |
254 | - |
255 | - const int durationMs = 350; |
256 | - |
257 | -Q_SIGNALS: |
258 | - void candidateDefaulted(int touchId, QQuickItem *candidate); |
259 | -private Q_SLOTS: |
260 | - void onTimeout(); |
261 | -private: |
262 | - AbstractTimer *m_timer; |
263 | - int m_touchId; |
264 | - QQuickItem *m_candidate; |
265 | -}; |
266 | - |
267 | -} // namespace UbuntuGestures |
268 | - |
269 | -#endif // UBUNTUGESTURES_CANDIDATE_INACTIVITY_TIMER_H |
270 | |
271 | === removed file 'src/app/unity8/libs/UbuntuGestures/DebugHelpers.cpp' |
272 | --- src/app/unity8/libs/UbuntuGestures/DebugHelpers.cpp 2015-02-04 10:56:38 +0000 |
273 | +++ src/app/unity8/libs/UbuntuGestures/DebugHelpers.cpp 1970-01-01 00:00:00 +0000 |
274 | @@ -1,95 +0,0 @@ |
275 | -/* |
276 | - * Copyright (C) 2014 Canonical, Ltd. |
277 | - * |
278 | - * This program is free software; you can redistribute it and/or modify |
279 | - * it under the terms of the GNU General Public License as published by |
280 | - * the Free Software Foundation; version 3. |
281 | - * |
282 | - * This program is distributed in the hope that it will be useful, |
283 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
284 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
285 | - * GNU General Public License for more details. |
286 | - * |
287 | - * You should have received a copy of the GNU General Public License |
288 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
289 | - */ |
290 | - |
291 | -#include "DebugHelpers.h" |
292 | -#include <QTouchEvent> |
293 | -#include <QMouseEvent> |
294 | - |
295 | -QString touchPointStateToString(Qt::TouchPointState state) |
296 | -{ |
297 | - switch (state) { |
298 | - case Qt::TouchPointPressed: |
299 | - return QString("pressed"); |
300 | - case Qt::TouchPointMoved: |
301 | - return QString("moved"); |
302 | - case Qt::TouchPointStationary: |
303 | - return QString("stationary"); |
304 | - case Qt::TouchPointReleased: |
305 | - return QString("released"); |
306 | - default: |
307 | - return QString("INVALID_STATE"); |
308 | - } |
309 | -} |
310 | - |
311 | -QString touchEventToString(const QTouchEvent *ev) |
312 | -{ |
313 | - QString message; |
314 | - |
315 | - switch (ev->type()) { |
316 | - case QEvent::TouchBegin: |
317 | - message.append("TouchBegin "); |
318 | - break; |
319 | - case QEvent::TouchUpdate: |
320 | - message.append("TouchUpdate "); |
321 | - break; |
322 | - case QEvent::TouchEnd: |
323 | - message.append("TouchEnd "); |
324 | - break; |
325 | - case QEvent::TouchCancel: |
326 | - message.append("TouchCancel "); |
327 | - break; |
328 | - default: |
329 | - message.append("INVALID_TOUCH_EVENT_TYPE "); |
330 | - } |
331 | - |
332 | - foreach(const QTouchEvent::TouchPoint& touchPoint, ev->touchPoints()) { |
333 | - message.append( |
334 | - QString("(id:%1, state:%2, scenePos:(%3,%4)) ") |
335 | - .arg(touchPoint.id()) |
336 | - .arg(touchPointStateToString(touchPoint.state())) |
337 | - .arg(touchPoint.scenePos().x()) |
338 | - .arg(touchPoint.scenePos().y()) |
339 | - ); |
340 | - } |
341 | - |
342 | - return message; |
343 | -} |
344 | - |
345 | -QString mouseEventToString(const QMouseEvent *ev) |
346 | -{ |
347 | - QString message; |
348 | - |
349 | - switch (ev->type()) { |
350 | - case QEvent::MouseButtonPress: |
351 | - message.append("MouseButtonPress "); |
352 | - break; |
353 | - case QEvent::MouseButtonRelease: |
354 | - message.append("MouseButtonRelease "); |
355 | - break; |
356 | - case QEvent::MouseButtonDblClick: |
357 | - message.append("MouseButtonDblClick "); |
358 | - break; |
359 | - case QEvent::MouseMove: |
360 | - message.append("MouseMove "); |
361 | - break; |
362 | - default: |
363 | - message.append("INVALID_MOUSE_EVENT_TYPE "); |
364 | - } |
365 | - |
366 | - message.append(QString("pos(%1, %2)").arg(ev->x()).arg(ev->y())); |
367 | - |
368 | - return message; |
369 | -} |
370 | |
371 | === removed file 'src/app/unity8/libs/UbuntuGestures/DebugHelpers.h' |
372 | --- src/app/unity8/libs/UbuntuGestures/DebugHelpers.h 2015-02-04 10:56:38 +0000 |
373 | +++ src/app/unity8/libs/UbuntuGestures/DebugHelpers.h 1970-01-01 00:00:00 +0000 |
374 | @@ -1,31 +0,0 @@ |
375 | -/* |
376 | - * Copyright (C) 2014 Canonical, Ltd. |
377 | - * |
378 | - * This program is free software; you can redistribute it and/or modify |
379 | - * it under the terms of the GNU General Public License as published by |
380 | - * the Free Software Foundation; version 3. |
381 | - * |
382 | - * This program is distributed in the hope that it will be useful, |
383 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
384 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
385 | - * GNU General Public License for more details. |
386 | - * |
387 | - * You should have received a copy of the GNU General Public License |
388 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
389 | - */ |
390 | - |
391 | -#ifndef UBUNTUGESTURES_DEBUG_HELPER_H |
392 | -#define UBUNTUGESTURES_DEBUG_HELPER_H |
393 | - |
394 | -#include <QString> |
395 | - |
396 | -#include "UbuntuGesturesGlobal.h" |
397 | - |
398 | -class QMouseEvent; |
399 | -class QTouchEvent; |
400 | - |
401 | -UBUNTUGESTURES_EXPORT QString touchPointStateToString(Qt::TouchPointState state); |
402 | -UBUNTUGESTURES_EXPORT QString touchEventToString(const QTouchEvent *ev); |
403 | -UBUNTUGESTURES_EXPORT QString mouseEventToString(const QMouseEvent *ev); |
404 | - |
405 | -#endif // UBUNTUGESTURES_DEBUG_HELPER_H |
406 | |
407 | === removed file 'src/app/unity8/libs/UbuntuGestures/Pool.h' |
408 | --- src/app/unity8/libs/UbuntuGestures/Pool.h 2015-02-04 10:56:38 +0000 |
409 | +++ src/app/unity8/libs/UbuntuGestures/Pool.h 1970-01-01 00:00:00 +0000 |
410 | @@ -1,132 +0,0 @@ |
411 | -/* |
412 | - * Copyright (C) 2014 Canonical, Ltd. |
413 | - * |
414 | - * This program is free software; you can redistribute it and/or modify |
415 | - * it under the terms of the GNU General Public License as published by |
416 | - * the Free Software Foundation; version 3. |
417 | - * |
418 | - * This program is distributed in the hope that it will be useful, |
419 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
420 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
421 | - * GNU General Public License for more details. |
422 | - * |
423 | - * You should have received a copy of the GNU General Public License |
424 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
425 | - */ |
426 | - |
427 | -#ifndef UBUNTUGESTURES_POOL_H |
428 | -#define UBUNTUGESTURES_POOL_H |
429 | - |
430 | -#include <QVector> |
431 | - |
432 | -#include "UbuntuGesturesGlobal.h" |
433 | - |
434 | -/* |
435 | - An object pool. |
436 | - Avoids unnecessary creations/initializations and deletions/destructions of items. Useful |
437 | - in a scenario where items are created and destroyed very frequently but the total number |
438 | - of items at any given time remains small. They're stored in a unordered fashion. |
439 | - |
440 | - To be used in Pool, ItemType needs to have the following methods: |
441 | - |
442 | - - ItemType(); |
443 | - |
444 | - A constructor that takes no parameters. An object contructed with it must return false if |
445 | - isValid() is called. |
446 | - |
447 | - - bool isValid() const; |
448 | - |
449 | - Returns wheter the object holds a valid , "filled" state or is empty. |
450 | - Used by Pool to check if the slot occupied by this object is actually available. |
451 | - |
452 | - - void reset(); |
453 | - |
454 | - Resets the object to its initial, empty, state. After calling this method, isValid() must |
455 | - return false. |
456 | - */ |
457 | -template <class ItemType> class Pool |
458 | -{ |
459 | -public: |
460 | - Pool() : m_lastUsedIndex(-1) { |
461 | - } |
462 | - |
463 | - class Iterator { |
464 | - public: |
465 | - Iterator() : index(-1), item(nullptr) {} |
466 | - Iterator(int index, ItemType *item) |
467 | - : index(index), item(item) {} |
468 | - |
469 | - ItemType *operator->() const { return item; } |
470 | - ItemType &operator*() const { return *item; } |
471 | - ItemType &value() const { return *item; } |
472 | - |
473 | - Iterator &operator= (const Iterator& other) { |
474 | - index = other.index; |
475 | - item = other.item; |
476 | - |
477 | - // by convention, always return *this |
478 | - return *this; |
479 | - } |
480 | - |
481 | - operator bool() const { return item != nullptr; } |
482 | - |
483 | - int index; |
484 | - ItemType *item; |
485 | - }; |
486 | - |
487 | - ItemType &getEmptySlot() { |
488 | - Q_ASSERT(m_lastUsedIndex < m_slots.size()); |
489 | - |
490 | - // Look for an in-between vacancy first |
491 | - for (int i = 0; i < m_lastUsedIndex; ++i) { |
492 | - ItemType &item = m_slots[i]; |
493 | - if (!item.isValid()) { |
494 | - return item; |
495 | - } |
496 | - } |
497 | - |
498 | - ++m_lastUsedIndex; |
499 | - if (m_lastUsedIndex >= m_slots.size()) { |
500 | - m_slots.resize(m_lastUsedIndex + 1); |
501 | - } |
502 | - |
503 | - return m_slots[m_lastUsedIndex]; |
504 | - } |
505 | - |
506 | - void freeSlot(Iterator &iterator) { |
507 | - m_slots[iterator.index].reset(); |
508 | - if (iterator.index == m_lastUsedIndex) { |
509 | - do { |
510 | - --m_lastUsedIndex; |
511 | - } while (m_lastUsedIndex >= 0 && !m_slots.at(m_lastUsedIndex).isValid()); |
512 | - } |
513 | - } |
514 | - |
515 | - // Iterates through all valid items (i.e. the occupied slots) |
516 | - // calling the given function, with the option of ending the loop early. |
517 | - // |
518 | - // bool Func(Iterator& item) |
519 | - // |
520 | - // Returning true means it wants to continue the "for" loop, false |
521 | - // terminates the loop. |
522 | - template<typename Func> void forEach(Func func) { |
523 | - Iterator it; |
524 | - for (it.index = 0; it.index <= m_lastUsedIndex; ++it.index) { |
525 | - it.item = &m_slots[it.index]; |
526 | - if (!it.item->isValid()) |
527 | - continue; |
528 | - |
529 | - if (!func(it)) |
530 | - break; |
531 | - } |
532 | - } |
533 | - |
534 | - bool isEmpty() const { return m_lastUsedIndex == -1; } |
535 | - |
536 | - |
537 | -private: |
538 | - QVector<ItemType> m_slots; |
539 | - int m_lastUsedIndex; |
540 | -}; |
541 | - |
542 | -#endif // UBUNTUGESTURES_POOL_H |
543 | |
544 | === removed file 'src/app/unity8/libs/UbuntuGestures/Timer.cpp' |
545 | --- src/app/unity8/libs/UbuntuGestures/Timer.cpp 2015-02-04 10:56:38 +0000 |
546 | +++ src/app/unity8/libs/UbuntuGestures/Timer.cpp 1970-01-01 00:00:00 +0000 |
547 | @@ -1,109 +0,0 @@ |
548 | -/* |
549 | - * Copyright (C) 2014 Canonical, Ltd. |
550 | - * |
551 | - * This program is free software; you can redistribute it and/or modify |
552 | - * it under the terms of the GNU General Public License as published by |
553 | - * the Free Software Foundation; version 3. |
554 | - * |
555 | - * This program is distributed in the hope that it will be useful, |
556 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
557 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
558 | - * GNU General Public License for more details. |
559 | - * |
560 | - * You should have received a copy of the GNU General Public License |
561 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
562 | - */ |
563 | - |
564 | -#include "Timer.h" |
565 | - |
566 | -namespace UbuntuGestures { |
567 | - |
568 | -Timer::Timer(QObject *parent) : AbstractTimer(parent) |
569 | -{ |
570 | - m_timer.setSingleShot(false); |
571 | - connect(&m_timer, &QTimer::timeout, this, &AbstractTimer::timeout); |
572 | -} |
573 | - |
574 | -int Timer::interval() const |
575 | -{ |
576 | - return m_timer.interval(); |
577 | -} |
578 | - |
579 | -void Timer::setInterval(int msecs) |
580 | -{ |
581 | - m_timer.setInterval(msecs); |
582 | -} |
583 | - |
584 | -void Timer::start() |
585 | -{ |
586 | - m_timer.start(); |
587 | - AbstractTimer::start(); |
588 | -} |
589 | - |
590 | -void Timer::stop() |
591 | -{ |
592 | - m_timer.stop(); |
593 | - AbstractTimer::stop(); |
594 | -} |
595 | - |
596 | -bool Timer::isSingleShot() const |
597 | -{ |
598 | - return m_timer.isSingleShot(); |
599 | -} |
600 | - |
601 | -void Timer::setSingleShot(bool value) |
602 | -{ |
603 | - m_timer.setSingleShot(value); |
604 | -} |
605 | - |
606 | -/////////////////////////////////// FakeTimer ////////////////////////////////// |
607 | - |
608 | -FakeTimer::FakeTimer(QObject *parent) |
609 | - : UbuntuGestures::AbstractTimer(parent) |
610 | - , m_interval(0) |
611 | - , m_singleShot(false) |
612 | -{ |
613 | -} |
614 | - |
615 | -int FakeTimer::interval() const |
616 | -{ |
617 | - return m_interval; |
618 | -} |
619 | - |
620 | -void FakeTimer::setInterval(int msecs) |
621 | -{ |
622 | - m_interval = msecs; |
623 | -} |
624 | - |
625 | -bool FakeTimer::isSingleShot() const |
626 | -{ |
627 | - return m_singleShot; |
628 | -} |
629 | - |
630 | -void FakeTimer::setSingleShot(bool value) |
631 | -{ |
632 | - m_singleShot = value; |
633 | -} |
634 | - |
635 | -/////////////////////////////////// FakeTimerFactory ////////////////////////////////// |
636 | - |
637 | -AbstractTimer *FakeTimerFactory::createTimer(QObject *parent) |
638 | -{ |
639 | - FakeTimer *fakeTimer = new FakeTimer(parent); |
640 | - |
641 | - timers.append(fakeTimer); |
642 | - |
643 | - return fakeTimer; |
644 | -} |
645 | - |
646 | -void FakeTimerFactory::makeRunningTimersTimeout() |
647 | -{ |
648 | - for (int i = 0; i < timers.count(); ++i) { |
649 | - FakeTimer *timer = timers[i].data(); |
650 | - if (timer && timer->isRunning()) { |
651 | - timer->emitTimeout(); |
652 | - } |
653 | - } |
654 | -} |
655 | - |
656 | -} // namespace UbuntuGestures |
657 | |
658 | === removed file 'src/app/unity8/libs/UbuntuGestures/Timer.h' |
659 | --- src/app/unity8/libs/UbuntuGestures/Timer.h 2015-02-04 10:56:38 +0000 |
660 | +++ src/app/unity8/libs/UbuntuGestures/Timer.h 1970-01-01 00:00:00 +0000 |
661 | @@ -1,105 +0,0 @@ |
662 | -/* |
663 | - * Copyright (C) 2014 Canonical, Ltd. |
664 | - * |
665 | - * This program is free software; you can redistribute it and/or modify |
666 | - * it under the terms of the GNU General Public License as published by |
667 | - * the Free Software Foundation; version 3. |
668 | - * |
669 | - * This program is distributed in the hope that it will be useful, |
670 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
671 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
672 | - * GNU General Public License for more details. |
673 | - * |
674 | - * You should have received a copy of the GNU General Public License |
675 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
676 | - */ |
677 | - |
678 | -#ifndef UBUNTUGESTURES_TIMER_H |
679 | -#define UBUNTUGESTURES_TIMER_H |
680 | - |
681 | -#include "UbuntuGesturesGlobal.h" |
682 | - |
683 | -#include <QObject> |
684 | -#include <QPointer> |
685 | -#include <QTimer> |
686 | - |
687 | -namespace UbuntuGestures { |
688 | - |
689 | -/* Defines an interface for a Timer. Useful for tests. */ |
690 | -class UBUNTUGESTURES_EXPORT AbstractTimer : public QObject |
691 | -{ |
692 | - Q_OBJECT |
693 | -public: |
694 | - AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {} |
695 | - virtual int interval() const = 0; |
696 | - virtual void setInterval(int msecs) = 0; |
697 | - virtual void start() { m_isRunning = true; } |
698 | - virtual void stop() { m_isRunning = false; } |
699 | - bool isRunning() const { return m_isRunning; } |
700 | - virtual bool isSingleShot() const = 0; |
701 | - virtual void setSingleShot(bool value) = 0; |
702 | -Q_SIGNALS: |
703 | - void timeout(); |
704 | -private: |
705 | - bool m_isRunning; |
706 | -}; |
707 | - |
708 | -/* Essentially a QTimer wrapper */ |
709 | -class UBUNTUGESTURES_EXPORT Timer : public AbstractTimer |
710 | -{ |
711 | - Q_OBJECT |
712 | -public: |
713 | - Timer(QObject *parent = nullptr); |
714 | - |
715 | - int interval() const override; |
716 | - void setInterval(int msecs) override; |
717 | - void start() override; |
718 | - void stop() override; |
719 | - bool isSingleShot() const override; |
720 | - void setSingleShot(bool value) override; |
721 | -private: |
722 | - QTimer m_timer; |
723 | -}; |
724 | - |
725 | -/* For tests */ |
726 | -class UBUNTUGESTURES_EXPORT FakeTimer : public AbstractTimer |
727 | -{ |
728 | - Q_OBJECT |
729 | -public: |
730 | - FakeTimer(QObject *parent = nullptr); |
731 | - |
732 | - virtual void emitTimeout() { Q_EMIT timeout(); } |
733 | - |
734 | - int interval() const override; |
735 | - void setInterval(int msecs) override; |
736 | - bool isSingleShot() const override; |
737 | - void setSingleShot(bool value) override; |
738 | -private: |
739 | - int m_interval; |
740 | - bool m_singleShot; |
741 | -}; |
742 | - |
743 | -class UBUNTUGESTURES_EXPORT AbstractTimerFactory |
744 | -{ |
745 | -public: |
746 | - virtual ~AbstractTimerFactory() {} |
747 | - virtual AbstractTimer *createTimer(QObject *parent = nullptr) = 0; |
748 | -}; |
749 | - |
750 | -class UBUNTUGESTURES_EXPORT TimerFactory : public AbstractTimerFactory |
751 | -{ |
752 | -public: |
753 | - AbstractTimer *createTimer(QObject *parent = nullptr) override { return new Timer(parent); } |
754 | -}; |
755 | - |
756 | -class UBUNTUGESTURES_EXPORT FakeTimerFactory : public AbstractTimerFactory |
757 | -{ |
758 | -public: |
759 | - AbstractTimer *createTimer(QObject *parent = nullptr) override; |
760 | - void makeRunningTimersTimeout(); |
761 | - QList<QPointer<FakeTimer>> timers; |
762 | -}; |
763 | - |
764 | -} // namespace UbuntuGestures |
765 | - |
766 | -#endif // UBUNTUGESTURES_TIMER_H |
767 | |
768 | === removed file 'src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.cpp' |
769 | --- src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.cpp 2015-02-04 10:56:38 +0000 |
770 | +++ src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.cpp 1970-01-01 00:00:00 +0000 |
771 | @@ -1,35 +0,0 @@ |
772 | -/* |
773 | - * Copyright (C) 2014 Canonical, Ltd. |
774 | - * |
775 | - * This program is free software; you can redistribute it and/or modify |
776 | - * it under the terms of the GNU General Public License as published by |
777 | - * the Free Software Foundation; version 3. |
778 | - * |
779 | - * This program is distributed in the hope that it will be useful, |
780 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
781 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
782 | - * GNU General Public License for more details. |
783 | - * |
784 | - * You should have received a copy of the GNU General Public License |
785 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
786 | - */ |
787 | - |
788 | -#include "TouchOwnershipEvent.h" |
789 | - |
790 | -QEvent::Type TouchOwnershipEvent::m_touchOwnershipType = (QEvent::Type)-1; |
791 | - |
792 | -TouchOwnershipEvent::TouchOwnershipEvent(int touchId, bool gained) |
793 | - : QEvent(touchOwnershipEventType()) |
794 | - , m_touchId(touchId) |
795 | - , m_gained(gained) |
796 | -{ |
797 | -} |
798 | - |
799 | -QEvent::Type TouchOwnershipEvent::touchOwnershipEventType() |
800 | -{ |
801 | - if (m_touchOwnershipType == (QEvent::Type)-1) { |
802 | - m_touchOwnershipType = (QEvent::Type)registerEventType(); |
803 | - } |
804 | - |
805 | - return m_touchOwnershipType; |
806 | -} |
807 | |
808 | === removed file 'src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.h' |
809 | --- src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.h 2015-02-04 10:56:38 +0000 |
810 | +++ src/app/unity8/libs/UbuntuGestures/TouchOwnershipEvent.h 1970-01-01 00:00:00 +0000 |
811 | @@ -1,50 +0,0 @@ |
812 | -/* |
813 | - * Copyright (C) 2014 Canonical, Ltd. |
814 | - * |
815 | - * This program is free software; you can redistribute it and/or modify |
816 | - * it under the terms of the GNU General Public License as published by |
817 | - * the Free Software Foundation; version 3. |
818 | - * |
819 | - * This program is distributed in the hope that it will be useful, |
820 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
821 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
822 | - * GNU General Public License for more details. |
823 | - * |
824 | - * You should have received a copy of the GNU General Public License |
825 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
826 | - */ |
827 | - |
828 | -#ifndef UBUNTU_TOUCHOWNERSHIPEVENT_H |
829 | -#define UBUNTU_TOUCHOWNERSHIPEVENT_H |
830 | - |
831 | -#include <QEvent> |
832 | -#include "UbuntuGesturesGlobal.h" |
833 | - |
834 | -/* |
835 | - When an item get an ownership event for a touch it can grab/steal that touch |
836 | - with a clean conscience. |
837 | - */ |
838 | -class UBUNTUGESTURES_EXPORT TouchOwnershipEvent : public QEvent |
839 | -{ |
840 | -public: |
841 | - TouchOwnershipEvent(int touchId, bool gained); |
842 | - |
843 | - static Type touchOwnershipEventType(); |
844 | - |
845 | - /* |
846 | - Whether ownership was gained (true) or lost (false) |
847 | - */ |
848 | - bool gained() const { return m_gained; } |
849 | - |
850 | - /* |
851 | - Id of the touch whose ownership was granted. |
852 | - */ |
853 | - int touchId() const { return m_touchId; } |
854 | - |
855 | -private: |
856 | - static Type m_touchOwnershipType; |
857 | - int m_touchId; |
858 | - bool m_gained; |
859 | -}; |
860 | - |
861 | -#endif // UBUNTU_TOUCHOWNERSHIPEVENT_H |
862 | |
863 | === removed file 'src/app/unity8/libs/UbuntuGestures/TouchRegistry.cpp' |
864 | --- src/app/unity8/libs/UbuntuGestures/TouchRegistry.cpp 2015-02-04 10:56:38 +0000 |
865 | +++ src/app/unity8/libs/UbuntuGestures/TouchRegistry.cpp 1970-01-01 00:00:00 +0000 |
866 | @@ -1,500 +0,0 @@ |
867 | -/* |
868 | - * Copyright (C) 2014 Canonical, Ltd. |
869 | - * |
870 | - * This program is free software; you can redistribute it and/or modify |
871 | - * it under the terms of the GNU General Public License as published by |
872 | - * the Free Software Foundation; version 3. |
873 | - * |
874 | - * This program is distributed in the hope that it will be useful, |
875 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
876 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
877 | - * GNU General Public License for more details. |
878 | - * |
879 | - * You should have received a copy of the GNU General Public License |
880 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
881 | - */ |
882 | - |
883 | -#include "TouchRegistry.h" |
884 | - |
885 | -#include <QCoreApplication> |
886 | -#include <QDebug> |
887 | - |
888 | -#pragma GCC diagnostic push |
889 | -#pragma GCC diagnostic ignored "-pedantic" |
890 | -#include <private/qquickitem_p.h> |
891 | -#pragma GCC diagnostic pop |
892 | - |
893 | -#include "CandidateInactivityTimer.h" |
894 | -#include "Timer.h" |
895 | -#include "TouchOwnershipEvent.h" |
896 | -#include "UnownedTouchEvent.h" |
897 | - |
898 | -#define TOUCHREGISTRY_DEBUG 0 |
899 | - |
900 | -#if TOUCHREGISTRY_DEBUG |
901 | - #include "DebugHelpers.h" |
902 | - #define UG_DEBUG qDebug() << "[TouchRegistry]" |
903 | -#endif // TOUCHREGISTRY_DEBUG |
904 | - |
905 | -using namespace UbuntuGestures; |
906 | - |
907 | -TouchRegistry *TouchRegistry::m_instance = nullptr; |
908 | - |
909 | -TouchRegistry::TouchRegistry(QObject *parent) |
910 | - : TouchRegistry(parent, new TimerFactory) |
911 | -{ |
912 | -} |
913 | - |
914 | -TouchRegistry::TouchRegistry(QObject *parent, AbstractTimerFactory *timerFactory) |
915 | - : QObject(parent) |
916 | - , m_inDispatchLoop(false) |
917 | - , m_timerFactory(timerFactory) |
918 | -{ |
919 | - if (m_instance == nullptr) { |
920 | - m_instance = this; |
921 | - } else { |
922 | - qFatal("Cannot have more than one instance of TouchRegistry. It must be a singleton."); |
923 | - } |
924 | -} |
925 | - |
926 | -TouchRegistry::~TouchRegistry() |
927 | -{ |
928 | - Q_ASSERT(m_instance != nullptr); |
929 | - m_instance = nullptr; |
930 | - delete m_timerFactory; |
931 | -} |
932 | - |
933 | -void TouchRegistry::update(const QTouchEvent *event) |
934 | -{ |
935 | - #if TOUCHREGISTRY_DEBUG |
936 | - UG_DEBUG << "got" << qPrintable(touchEventToString(event)); |
937 | - #endif |
938 | - |
939 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
940 | - for (int i = 0; i < touchPoints.count(); ++i) { |
941 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
942 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
943 | - TouchInfo &touchInfo = m_touchInfoPool.getEmptySlot(); |
944 | - touchInfo.init(touchPoint.id()); |
945 | - } else if (touchPoint.state() == Qt::TouchPointReleased) { |
946 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(touchPoint.id()); |
947 | - |
948 | - touchInfo->physicallyEnded = true; |
949 | - } |
950 | - } |
951 | - |
952 | - deliverTouchUpdatesToUndecidedCandidatesAndWatchers(event); |
953 | - |
954 | - freeEndedTouchInfos(); |
955 | -} |
956 | - |
957 | -void TouchRegistry::deliverTouchUpdatesToUndecidedCandidatesAndWatchers(const QTouchEvent *event) |
958 | -{ |
959 | - // TODO: Look into how we could optimize this whole thing. |
960 | - // Although it's not really a problem as we should have at most two candidates |
961 | - // for each point and there should not be many active points at any given moment. |
962 | - // But having three nested for-loops does scare. |
963 | - |
964 | - // TODO: Don't send it to the object that is already receiving the regular event |
965 | - // because QQuickWindow is sending it to him (i.e., he's the touch owner from Qt's point of view) |
966 | - // Problem is, we cannnot easily get this information. |
967 | - |
968 | - const QList<QTouchEvent::TouchPoint> &updatedTouchPoints = event->touchPoints(); |
969 | - |
970 | - // Maps an item to the touches in this event he should be informed about. |
971 | - // E.g.: a QTouchEvent might have three touches but a given item might be interested in only |
972 | - // one of them. So he will get a UnownedTouchEvent from this QTouchEvent containing only that |
973 | - // touch point. |
974 | - QMap<QQuickItem*, QList<int>> touchIdsForItems; |
975 | - |
976 | - // Build touchIdsForItems |
977 | - m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &touchInfo) { |
978 | - if (touchInfo->isOwned() && touchInfo->watchers.isEmpty()) |
979 | - return true; |
980 | - |
981 | - for (int j = 0; j < updatedTouchPoints.count(); ++j) { |
982 | - if (updatedTouchPoints[j].id() == touchInfo->id) { |
983 | - if (!touchInfo->isOwned()) { |
984 | - for (int i = 0; i < touchInfo->candidates.count(); ++i) { |
985 | - CandidateInfo &candidate = touchInfo->candidates[i]; |
986 | - Q_ASSERT(!candidate.item.isNull()); |
987 | - touchIdsForItems[candidate.item.data()].append(touchInfo->id); |
988 | - } |
989 | - } |
990 | - |
991 | - const QList<QPointer<QQuickItem>> &watchers = touchInfo->watchers; |
992 | - for (int i = 0; i < watchers.count(); ++i) { |
993 | - if (!watchers[i].isNull()) { |
994 | - touchIdsForItems[watchers[i].data()].append(touchInfo->id); |
995 | - } |
996 | - } |
997 | - |
998 | - return true; |
999 | - } |
1000 | - } |
1001 | - |
1002 | - return true; |
1003 | - }); |
1004 | - |
1005 | - // TODO: Consider what happens if an item calls any of TouchRegistry's public methods |
1006 | - // from the event handler callback. |
1007 | - m_inDispatchLoop = true; |
1008 | - auto it = touchIdsForItems.constBegin(); |
1009 | - while (it != touchIdsForItems.constEnd()) { |
1010 | - QQuickItem *item = it.key(); |
1011 | - const QList<int> &touchIds = it.value(); |
1012 | - dispatchPointsToItem(event, touchIds, item); |
1013 | - ++it; |
1014 | - }; |
1015 | - m_inDispatchLoop = false; |
1016 | -} |
1017 | - |
1018 | -void TouchRegistry::freeEndedTouchInfos() |
1019 | -{ |
1020 | - m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &touchInfo) { |
1021 | - if (touchInfo->ended()) { |
1022 | - m_touchInfoPool.freeSlot(touchInfo); |
1023 | - } |
1024 | - return true; |
1025 | - }); |
1026 | -} |
1027 | - |
1028 | -/* |
1029 | - Extracts the touches with the given touchIds from event and send them in a |
1030 | - UnownedTouchEvent to the given item |
1031 | - */ |
1032 | -void TouchRegistry::dispatchPointsToItem(const QTouchEvent *event, const QList<int> &touchIds, |
1033 | - QQuickItem *item) |
1034 | -{ |
1035 | - Qt::TouchPointStates touchPointStates = 0; |
1036 | - QList<QTouchEvent::TouchPoint> touchPoints; |
1037 | - |
1038 | - const QList<QTouchEvent::TouchPoint> &allTouchPoints = event->touchPoints(); |
1039 | - |
1040 | - QTransform windowToCandidateTransform = QQuickItemPrivate::get(item)->windowToItemTransform(); |
1041 | - QMatrix4x4 windowToCandidateMatrix(windowToCandidateTransform); |
1042 | - |
1043 | - for (int i = 0; i < allTouchPoints.count(); ++i) { |
1044 | - const QTouchEvent::TouchPoint &originalTouchPoint = allTouchPoints[i]; |
1045 | - if (touchIds.contains(originalTouchPoint.id())) { |
1046 | - QTouchEvent::TouchPoint touchPoint = originalTouchPoint; |
1047 | - |
1048 | - translateTouchPointFromScreenToWindowCoords(touchPoint); |
1049 | - |
1050 | - // Set the point's local coordinates to that of the item |
1051 | - touchPoint.setRect(windowToCandidateTransform.mapRect(touchPoint.sceneRect())); |
1052 | - touchPoint.setStartPos(windowToCandidateTransform.map(touchPoint.startScenePos())); |
1053 | - touchPoint.setLastPos(windowToCandidateTransform.map(touchPoint.lastScenePos())); |
1054 | - touchPoint.setVelocity(windowToCandidateMatrix.mapVector(touchPoint.velocity()).toVector2D()); |
1055 | - |
1056 | - touchPoints.append(touchPoint); |
1057 | - touchPointStates |= touchPoint.state(); |
1058 | - } |
1059 | - } |
1060 | - |
1061 | - QTouchEvent *eventForItem = new QTouchEvent(event->type(), |
1062 | - event->device(), |
1063 | - event->modifiers(), |
1064 | - touchPointStates, |
1065 | - touchPoints); |
1066 | - eventForItem->setWindow(event->window()); |
1067 | - eventForItem->setTimestamp(event->timestamp()); |
1068 | - eventForItem->setTarget(event->target()); |
1069 | - |
1070 | - UnownedTouchEvent unownedTouchEvent(eventForItem); |
1071 | - |
1072 | - #if TOUCHREGISTRY_DEBUG |
1073 | - UG_DEBUG << "Sending unowned" << qPrintable(touchEventToString(eventForItem)) |
1074 | - << "to" << item; |
1075 | - #endif |
1076 | - |
1077 | - QCoreApplication::sendEvent(item, &unownedTouchEvent); |
1078 | -} |
1079 | - |
1080 | -void TouchRegistry::translateTouchPointFromScreenToWindowCoords(QTouchEvent::TouchPoint &touchPoint) |
1081 | -{ |
1082 | - touchPoint.setScreenRect(touchPoint.sceneRect()); |
1083 | - touchPoint.setStartScreenPos(touchPoint.startScenePos()); |
1084 | - touchPoint.setLastScreenPos(touchPoint.lastScenePos()); |
1085 | - |
1086 | - touchPoint.setSceneRect(touchPoint.rect()); |
1087 | - touchPoint.setStartScenePos(touchPoint.startPos()); |
1088 | - touchPoint.setLastScenePos(touchPoint.lastPos()); |
1089 | -} |
1090 | - |
1091 | -bool TouchRegistry::eventFilter(QObject *watched, QEvent *event) |
1092 | -{ |
1093 | - Q_UNUSED(watched); |
1094 | - |
1095 | - switch (event->type()) { |
1096 | - case QEvent::TouchBegin: |
1097 | - case QEvent::TouchUpdate: |
1098 | - case QEvent::TouchEnd: |
1099 | - case QEvent::TouchCancel: |
1100 | - update(static_cast<QTouchEvent*>(event)); |
1101 | - break; |
1102 | - default: |
1103 | - // do nothing |
1104 | - break; |
1105 | - } |
1106 | - |
1107 | - // Do not filter out the event. i.e., let it be handled further as |
1108 | - // we're just monitoring events |
1109 | - return false; |
1110 | -} |
1111 | - |
1112 | -void TouchRegistry::addCandidateOwnerForTouch(int id, QQuickItem *candidate) |
1113 | -{ |
1114 | - #if TOUCHREGISTRY_DEBUG |
1115 | - UG_DEBUG << "addCandidateOwnerForTouch id" << id << "candidate" << candidate; |
1116 | - #endif |
1117 | - |
1118 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id); |
1119 | - if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); } |
1120 | - |
1121 | - if (touchInfo->isOwned()) { |
1122 | - qWarning("TouchRegistry: trying to add candidate owner for a touch that's already owned"); |
1123 | - return; |
1124 | - } |
1125 | - |
1126 | - // TODO: Check if candidate already exists |
1127 | - |
1128 | - CandidateInfo candidateInfo; |
1129 | - candidateInfo.undecided = true; |
1130 | - candidateInfo.item = candidate; |
1131 | - candidateInfo.inactivityTimer = new CandidateInactivityTimer(id, candidate, |
1132 | - *m_timerFactory, |
1133 | - this); |
1134 | - connect(candidateInfo.inactivityTimer, &CandidateInactivityTimer::candidateDefaulted, |
1135 | - this, &TouchRegistry::rejectCandidateOwnerForTouch); |
1136 | - |
1137 | - touchInfo->candidates.append(candidateInfo); |
1138 | -} |
1139 | - |
1140 | -void TouchRegistry::addTouchWatcher(int touchId, QQuickItem *watcher) |
1141 | -{ |
1142 | - #if TOUCHREGISTRY_DEBUG |
1143 | - UG_DEBUG << "addTouchWatcher id" << touchId << "watcher" << watcher; |
1144 | - #endif |
1145 | - |
1146 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(touchId); |
1147 | - if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); } |
1148 | - |
1149 | - // TODO: Check if watcher already exists |
1150 | - |
1151 | - touchInfo->watchers.append(watcher); |
1152 | -} |
1153 | - |
1154 | -void TouchRegistry::removeCandidateOwnerForTouch(int id, QQuickItem *candidate) |
1155 | -{ |
1156 | - #if TOUCHREGISTRY_DEBUG |
1157 | - UG_DEBUG << "removeCandidateOwnerForTouch id" << id << "candidate" << candidate; |
1158 | - #endif |
1159 | - |
1160 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id); |
1161 | - if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); } |
1162 | - |
1163 | - int indexRemoved = -1; |
1164 | - |
1165 | - // TODO: check if the candidate is in fact the owner of the touch |
1166 | - |
1167 | - for (int i = 0; i < touchInfo->candidates.count() && indexRemoved == -1; ++i) { |
1168 | - CandidateInfo &candidateInfo = touchInfo->candidates[i]; |
1169 | - if (candidateInfo.item == candidate) { |
1170 | - Q_ASSERT(i > 0 || candidateInfo.undecided); |
1171 | - if (i == 0 && !candidateInfo.undecided) { |
1172 | - qCritical("TouchRegistry: touch owner is being removed."); |
1173 | - } |
1174 | - delete candidateInfo.inactivityTimer; |
1175 | - candidateInfo.inactivityTimer = nullptr; |
1176 | - touchInfo->candidates.removeAt(i); |
1177 | - indexRemoved = i; |
1178 | - } |
1179 | - } |
1180 | - |
1181 | - if (indexRemoved == 0) { |
1182 | - // the top candidate has been removed. if the new top candidate |
1183 | - // wants the touch let him know he's now the owner. |
1184 | - if (touchInfo->isOwned()) { |
1185 | - touchInfo->notifyCandidatesOfOwnershipResolution(); |
1186 | - } |
1187 | - } |
1188 | - |
1189 | - if (!m_inDispatchLoop && touchInfo->ended()) { |
1190 | - m_touchInfoPool.freeSlot(touchInfo); |
1191 | - } |
1192 | -} |
1193 | - |
1194 | -void TouchRegistry::requestTouchOwnership(int id, QQuickItem *candidate) |
1195 | -{ |
1196 | - #if TOUCHREGISTRY_DEBUG |
1197 | - UG_DEBUG << "requestTouchOwnership id " << id << "candidate" << candidate; |
1198 | - #endif |
1199 | - |
1200 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id); |
1201 | - if (!touchInfo) { qFatal("TouchRegistry: Failed to find TouchInfo"); } |
1202 | - |
1203 | - Q_ASSERT(!touchInfo->isOwned()); |
1204 | - |
1205 | - int candidateIndex = -1; |
1206 | - for (int i = 0; i < touchInfo->candidates.count(); ++i) { |
1207 | - CandidateInfo &candidateInfo = touchInfo->candidates[i]; |
1208 | - if (candidateInfo.item == candidate) { |
1209 | - candidateInfo.undecided = false; |
1210 | - delete candidateInfo.inactivityTimer; |
1211 | - candidateInfo.inactivityTimer = nullptr; |
1212 | - candidateIndex = i; |
1213 | - break; |
1214 | - } |
1215 | - } |
1216 | - |
1217 | - // add it as a candidate if not present yet |
1218 | - if (candidateIndex < 0) { |
1219 | - CandidateInfo candidateInfo; |
1220 | - candidateInfo.undecided = false; |
1221 | - candidateInfo.item = candidate; |
1222 | - candidateInfo.inactivityTimer = nullptr; |
1223 | - touchInfo->candidates.append(candidateInfo); |
1224 | - // it's the last one |
1225 | - candidateIndex = touchInfo->candidates.count() - 1; |
1226 | - } |
1227 | - |
1228 | - // If it's the top candidate it means it's now the owner. Let |
1229 | - // it know about it. |
1230 | - if (candidateIndex == 0) { |
1231 | - touchInfo->notifyCandidatesOfOwnershipResolution(); |
1232 | - } |
1233 | -} |
1234 | - |
1235 | -Pool<TouchRegistry::TouchInfo>::Iterator TouchRegistry::findTouchInfo(int id) |
1236 | -{ |
1237 | - Pool<TouchInfo>::Iterator touchInfo; |
1238 | - |
1239 | - m_touchInfoPool.forEach([&](Pool<TouchInfo>::Iterator &someTouchInfo) -> bool { |
1240 | - if (someTouchInfo->id == id) { |
1241 | - touchInfo = someTouchInfo; |
1242 | - return false; |
1243 | - } else { |
1244 | - return true; |
1245 | - } |
1246 | - }); |
1247 | - |
1248 | - return touchInfo; |
1249 | -} |
1250 | - |
1251 | - |
1252 | -void TouchRegistry::rejectCandidateOwnerForTouch(int id, QQuickItem *candidate) |
1253 | -{ |
1254 | - // NB: It's technically possible that candidate is a dangling pointer at this point. |
1255 | - // Although that would most likely be due to a bug in our code. |
1256 | - // In any case, only dereference it after it's confirmed that it indeed exists. |
1257 | - |
1258 | - #if TOUCHREGISTRY_DEBUG |
1259 | - UG_DEBUG << "rejectCandidateOwnerForTouch id" << id << "candidate" << (void*)candidate; |
1260 | - #endif |
1261 | - |
1262 | - Pool<TouchInfo>::Iterator touchInfo = findTouchInfo(id); |
1263 | - if (!touchInfo) { |
1264 | - #if TOUCHREGISTRY_DEBUG |
1265 | - UG_DEBUG << "Failed to find TouchInfo for id" << id; |
1266 | - #endif |
1267 | - return; |
1268 | - } |
1269 | - |
1270 | - int rejectedCandidateIndex = -1; |
1271 | - |
1272 | - // Check if the given candidate is valid and still undecided |
1273 | - for (int i = 0; i < touchInfo->candidates.count() && rejectedCandidateIndex == -1; ++i) { |
1274 | - CandidateInfo &candidateInfo = touchInfo->candidates[i]; |
1275 | - if (candidateInfo.item == candidate) { |
1276 | - Q_ASSERT(i > 0 || candidateInfo.undecided); |
1277 | - if (i == 0 && !candidateInfo.undecided) { |
1278 | - qCritical() << "TouchRegistry: Can't reject item (" << (void*)candidate |
1279 | - << ") as it already owns touch" << id; |
1280 | - return; |
1281 | - } else { |
1282 | - // we found the guy and it's all fine. |
1283 | - rejectedCandidateIndex = i; |
1284 | - } |
1285 | - } |
1286 | - } |
1287 | - |
1288 | - // If we reached this point it's because the given candidate exists and is indeed undecided. |
1289 | - |
1290 | - Q_ASSERT(rejectedCandidateIndex >= 0 && rejectedCandidateIndex < touchInfo->candidates.size()); |
1291 | - |
1292 | - { |
1293 | - TouchOwnershipEvent lostOwnershipEvent(id, false /*gained*/); |
1294 | - QCoreApplication::sendEvent(candidate, &lostOwnershipEvent); |
1295 | - } |
1296 | - |
1297 | - touchInfo->candidates.removeAt(rejectedCandidateIndex); |
1298 | - |
1299 | - if (rejectedCandidateIndex == 0) { |
1300 | - // the top candidate has been removed. if the new top candidate |
1301 | - // wants the touch let him know he's now the owner. |
1302 | - if (touchInfo->isOwned()) { |
1303 | - touchInfo->notifyCandidatesOfOwnershipResolution(); |
1304 | - } |
1305 | - } |
1306 | -} |
1307 | - |
1308 | -////////////////////////////////////// TouchRegistry::TouchInfo //////////////////////////////////// |
1309 | - |
1310 | -TouchRegistry::TouchInfo::TouchInfo(int id) |
1311 | -{ |
1312 | - init(id); |
1313 | -} |
1314 | - |
1315 | -void TouchRegistry::TouchInfo::reset() |
1316 | -{ |
1317 | - id = -1; |
1318 | - |
1319 | - for (int i = 0; i < candidates.count(); ++i) { |
1320 | - CandidateInfo &candidate = candidates[i]; |
1321 | - delete candidate.inactivityTimer; |
1322 | - candidate.inactivityTimer.clear(); // shoundn't be needed but anyway... |
1323 | - } |
1324 | -} |
1325 | - |
1326 | -void TouchRegistry::TouchInfo::init(int id) |
1327 | -{ |
1328 | - this->id = id; |
1329 | - physicallyEnded = false; |
1330 | - candidates.clear(); |
1331 | - watchers.clear(); |
1332 | -} |
1333 | - |
1334 | -bool TouchRegistry::TouchInfo::isOwned() const |
1335 | -{ |
1336 | - return !candidates.isEmpty() && !candidates.first().undecided; |
1337 | -} |
1338 | - |
1339 | -bool TouchRegistry::TouchInfo::ended() const |
1340 | -{ |
1341 | - Q_ASSERT(isValid()); |
1342 | - return physicallyEnded && (isOwned() || candidates.isEmpty()); |
1343 | -} |
1344 | - |
1345 | -void TouchRegistry::TouchInfo::notifyCandidatesOfOwnershipResolution() |
1346 | -{ |
1347 | - Q_ASSERT(isOwned()); |
1348 | - |
1349 | - #if TOUCHREGISTRY_DEBUG |
1350 | - UG_DEBUG << "sending TouchOwnershipEvent(id =" << id |
1351 | - << " gained) to candidate" << candidates[0].item; |
1352 | - #endif |
1353 | - |
1354 | - TouchOwnershipEvent gainedOwnershipEvent(id, true /*gained*/); |
1355 | - QCoreApplication::sendEvent(candidates[0].item, &gainedOwnershipEvent); |
1356 | - |
1357 | - |
1358 | - TouchOwnershipEvent lostOwnershipEvent(id, false /*gained*/); |
1359 | - for (int i = 1; i < candidates.count(); ++i) { |
1360 | - #if TOUCHREGISTRY_DEBUG |
1361 | - UG_DEBUG << "sending TouchWonershipEvent(id =" << id << " lost) to candidate" |
1362 | - << candidates[i].item; |
1363 | - #endif |
1364 | - QCoreApplication::sendEvent(candidates[i].item, &lostOwnershipEvent); |
1365 | - } |
1366 | -} |
1367 | |
1368 | === removed file 'src/app/unity8/libs/UbuntuGestures/TouchRegistry.h' |
1369 | --- src/app/unity8/libs/UbuntuGestures/TouchRegistry.h 2015-02-04 10:56:38 +0000 |
1370 | +++ src/app/unity8/libs/UbuntuGestures/TouchRegistry.h 1970-01-01 00:00:00 +0000 |
1371 | @@ -1,182 +0,0 @@ |
1372 | -/* |
1373 | - * Copyright (C) 2014 Canonical, Ltd. |
1374 | - * |
1375 | - * This program is free software; you can redistribute it and/or modify |
1376 | - * it under the terms of the GNU General Public License as published by |
1377 | - * the Free Software Foundation; version 3. |
1378 | - * |
1379 | - * This program is distributed in the hope that it will be useful, |
1380 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1381 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1382 | - * GNU General Public License for more details. |
1383 | - * |
1384 | - * You should have received a copy of the GNU General Public License |
1385 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1386 | - */ |
1387 | - |
1388 | -#ifndef UNITY_TOUCHREGISTRY_H |
1389 | -#define UNITY_TOUCHREGISTRY_H |
1390 | - |
1391 | -#include <QQuickItem> |
1392 | -#include <QObject> |
1393 | -#include <QPointer> |
1394 | -#include <QTouchEvent> |
1395 | -#include <QVector> |
1396 | - |
1397 | -#include "UbuntuGesturesGlobal.h" |
1398 | -#include "CandidateInactivityTimer.h" |
1399 | -#include "Pool.h" |
1400 | - |
1401 | -namespace UbuntuGestures { |
1402 | - class AbstractTimerFactory; |
1403 | -} |
1404 | - |
1405 | -/* |
1406 | - Where the ownership of touches is registered. |
1407 | - |
1408 | - Singleton used for adding a touch point ownership model analogous to the one |
1409 | - described in the XInput 2.2 protocol[1] on top of the existing input dispatch logic in QQuickWindow. |
1410 | - |
1411 | - It provides a much more flexible and powerful way of dealing with pointer ownership than the existing |
1412 | - mechanisms in Qt. Namely QQuickItem::grabTouchPoints, QuickItem::keepTouchGrab, |
1413 | - QQuickItem::setFiltersChildMouseEvents, QQuickItem::ungrabTouchPoints and QQuickItem::touchUngrabEvent. |
1414 | - |
1415 | - Usage: |
1416 | - |
1417 | - 1- An item receives a a new touch point. If he's not sure whether he wants it yet, he calls: |
1418 | - TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, this); |
1419 | - touchEvent->ignore(); |
1420 | - Ignoring the event is crucial so that it can be seen by other interested parties, which will |
1421 | - behave similarly. |
1422 | - |
1423 | - 2- That item will then start receiving UnownedTouchEvents for that touch from step 1. Once he's |
1424 | - made a decision he calls either: |
1425 | - TouchRegistry::instance()->requestTouchOwnership(touchId, this); |
1426 | - If he wants the touch point or: |
1427 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(touchId, this); |
1428 | - if he does not want it. |
1429 | - |
1430 | - Candidates are put in a priority queue. The first one to call addCandidateOwnerForTouch() will |
1431 | - take precedence over the others for receiving ownership over the touch point (from now on called |
1432 | - simply top-candidate). |
1433 | - |
1434 | - If the top-candidate calls requestTouchOwnership() he will immediately receive a |
1435 | - TouchOwnershipEvent(gained=true) for that touch point. He can then safely call |
1436 | - QQuickItem::grabTouchPoints to actually get the owned touch points. The other candidates |
1437 | - will receive TouchOwnershipEvent(gained=false) and will no longer receive UnownedTouchEvents |
1438 | - for that touch point. They will have to undo whatever action they were performing with that |
1439 | - touch point. |
1440 | - |
1441 | - But if the top-candidate calls removeCandidateOwnerForTouch() instead, he's popped from the |
1442 | - candidacy queue and ownership is given to the new top-most candidate if he has already |
1443 | - made his decision, that is. |
1444 | - |
1445 | - The TouchRegistry cannot enforce the results of this pointer ownership negotiation (i.e., |
1446 | - who gets to grab the touch points) as that would clash with QQuickWindow's input event |
1447 | - dispatching logic. The candidates have to respect the decision and grab the touch points |
1448 | - themselves. |
1449 | - |
1450 | - If an item wants ownership over touches as soon as he receives the TouchBegin for them, his step 1 |
1451 | - would be instead: |
1452 | - TouchRegistry::instance()->requestTouchOwnership(touchId, this); |
1453 | - return true; |
1454 | - He would then be notified once ownership has been granted to him, from which point onwards he could |
1455 | - safely assume other TouchRegistry users wouldn't snatch this touch away from him. |
1456 | - |
1457 | - Items oblivious to TouchRegistry will lose their touch points without warning, just like in plain Qt. |
1458 | - |
1459 | - [1] - http://www.x.org/releases/X11R7.7/doc/inputproto/XI2proto.txt (see multitouch-ownership) |
1460 | - */ |
1461 | -class UBUNTUGESTURES_EXPORT TouchRegistry : public QObject |
1462 | -{ |
1463 | - Q_OBJECT |
1464 | -public: |
1465 | - TouchRegistry(QObject *parent = nullptr); |
1466 | - // Useful for tests, where you should feed a fake timer |
1467 | - TouchRegistry(QObject *parent, UbuntuGestures::AbstractTimerFactory *timerFactory); |
1468 | - |
1469 | - virtual ~TouchRegistry(); |
1470 | - |
1471 | - // Returns a pointer to the application's TouchRegistry instance. |
1472 | - // If no instance has been allocated, null is returned. |
1473 | - static TouchRegistry *instance() { return m_instance; } |
1474 | - |
1475 | - void update(const QTouchEvent *event); |
1476 | - |
1477 | - // Calls update() if the given event is a QTouchEvent |
1478 | - bool eventFilter(QObject *watched, QEvent *event) override; |
1479 | - |
1480 | - // An item that might later request ownership over the given touch point. |
1481 | - // He will be kept informed about that touch point through UnownedTouchEvents |
1482 | - // All candidates must eventually decide whether they want to own the touch point |
1483 | - // or not. That decision is informed through requestTouchOwnership() or |
1484 | - // removeCandidateOwnerForTouch() |
1485 | - void addCandidateOwnerForTouch(int id, QQuickItem *candidate); |
1486 | - |
1487 | - // The same as rejecting ownership of a touch |
1488 | - void removeCandidateOwnerForTouch(int id, QQuickItem *candidate); |
1489 | - |
1490 | - // The candidate object wants to be the owner of the touch with the given id. |
1491 | - // If he's currently the oldest/top-most candidate, he will get an ownership |
1492 | - // event immediately. If not, he will get ownership if (or once) he becomes the |
1493 | - // top-most candidate. |
1494 | - void requestTouchOwnership(int id, QQuickItem *candidate); |
1495 | - |
1496 | - // An item that has no interest (effective or potential) in owning a touch point |
1497 | - // but would nonetheless like to be kept up-to-date on its state. |
1498 | - void addTouchWatcher(int touchId, QQuickItem *watcherItem); |
1499 | - |
1500 | -private Q_SLOTS: |
1501 | - void rejectCandidateOwnerForTouch(int id, QQuickItem *candidate); |
1502 | - |
1503 | -private: |
1504 | - class CandidateInfo { |
1505 | - public: |
1506 | - bool undecided; |
1507 | - // TODO: Prune candidates that become null and resolve ownership accordingly. |
1508 | - QPointer<QQuickItem> item; |
1509 | - QPointer<UbuntuGestures::CandidateInactivityTimer> inactivityTimer; |
1510 | - }; |
1511 | - |
1512 | - class TouchInfo { |
1513 | - public: |
1514 | - TouchInfo() : id(-1) {} |
1515 | - TouchInfo(int id); |
1516 | - bool isValid() const { return id >= 0; } |
1517 | - void reset(); |
1518 | - void init(int id); |
1519 | - int id; |
1520 | - bool physicallyEnded; |
1521 | - bool isOwned() const; |
1522 | - bool ended() const; |
1523 | - void notifyCandidatesOfOwnershipResolution(); |
1524 | - |
1525 | - // TODO optimize storage (s/QList/Pool) |
1526 | - QList<CandidateInfo> candidates; |
1527 | - QList<QPointer<QQuickItem>> watchers; |
1528 | - }; |
1529 | - |
1530 | - Pool<TouchInfo>::Iterator findTouchInfo(int id); |
1531 | - |
1532 | - void deliverTouchUpdatesToUndecidedCandidatesAndWatchers(const QTouchEvent *event); |
1533 | - |
1534 | - static void translateTouchPointFromScreenToWindowCoords(QTouchEvent::TouchPoint &touchPoint); |
1535 | - |
1536 | - static void dispatchPointsToItem(const QTouchEvent *event, const QList<int> &touchIds, |
1537 | - QQuickItem *item); |
1538 | - void freeEndedTouchInfos(); |
1539 | - |
1540 | - Pool<TouchInfo> m_touchInfoPool; |
1541 | - |
1542 | - // the singleton instance |
1543 | - static TouchRegistry *m_instance; |
1544 | - |
1545 | - bool m_inDispatchLoop; |
1546 | - |
1547 | - UbuntuGestures::AbstractTimerFactory *m_timerFactory; |
1548 | - |
1549 | - friend class tst_TouchRegistry; |
1550 | - friend class tst_DirectionalDragArea; |
1551 | -}; |
1552 | - |
1553 | -#endif // UNITY_TOUCHREGISTRY_H |
1554 | |
1555 | === removed file 'src/app/unity8/libs/UbuntuGestures/UbuntuGesturesGlobal.h' |
1556 | --- src/app/unity8/libs/UbuntuGestures/UbuntuGesturesGlobal.h 2015-02-04 10:56:38 +0000 |
1557 | +++ src/app/unity8/libs/UbuntuGestures/UbuntuGesturesGlobal.h 1970-01-01 00:00:00 +0000 |
1558 | @@ -1,23 +0,0 @@ |
1559 | -/* |
1560 | - * Copyright (C) 2014 Canonical, Ltd. |
1561 | - * |
1562 | - * This program is free software; you can redistribute it and/or modify |
1563 | - * it under the terms of the GNU General Public License as published by |
1564 | - * the Free Software Foundation; version 3. |
1565 | - * |
1566 | - * This program is distributed in the hope that it will be useful, |
1567 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1568 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1569 | - * GNU General Public License for more details. |
1570 | - * |
1571 | - * You should have received a copy of the GNU General Public License |
1572 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1573 | - */ |
1574 | - |
1575 | -#include <QtCore/QtGlobal> |
1576 | - |
1577 | -#if defined(UBUNTUGESTURES_LIBRARY) |
1578 | -# define UBUNTUGESTURES_EXPORT Q_DECL_EXPORT |
1579 | -#else |
1580 | -# define UBUNTUGESTURES_EXPORT Q_DECL_IMPORT |
1581 | -#endif |
1582 | |
1583 | === removed file 'src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.cpp' |
1584 | --- src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.cpp 2015-02-04 10:56:38 +0000 |
1585 | +++ src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.cpp 1970-01-01 00:00:00 +0000 |
1586 | @@ -1,39 +0,0 @@ |
1587 | -/* |
1588 | - * Copyright (C) 2014 Canonical, Ltd. |
1589 | - * |
1590 | - * This program is free software; you can redistribute it and/or modify |
1591 | - * it under the terms of the GNU General Public License as published by |
1592 | - * the Free Software Foundation; version 3. |
1593 | - * |
1594 | - * This program is distributed in the hope that it will be useful, |
1595 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1596 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1597 | - * GNU General Public License for more details. |
1598 | - * |
1599 | - * You should have received a copy of the GNU General Public License |
1600 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1601 | - */ |
1602 | - |
1603 | -#include "UnownedTouchEvent.h" |
1604 | - |
1605 | -QEvent::Type UnownedTouchEvent::m_unownedTouchEventType = (QEvent::Type)-1; |
1606 | - |
1607 | -UnownedTouchEvent::UnownedTouchEvent(QTouchEvent *touchEvent) |
1608 | - : QEvent(unownedTouchEventType()) |
1609 | - , m_touchEvent(touchEvent) |
1610 | -{ |
1611 | -} |
1612 | - |
1613 | -QEvent::Type UnownedTouchEvent::unownedTouchEventType() |
1614 | -{ |
1615 | - if (m_unownedTouchEventType == (QEvent::Type)-1) { |
1616 | - m_unownedTouchEventType = (QEvent::Type)registerEventType(); |
1617 | - } |
1618 | - |
1619 | - return m_unownedTouchEventType; |
1620 | -} |
1621 | - |
1622 | -QTouchEvent *UnownedTouchEvent::touchEvent() |
1623 | -{ |
1624 | - return m_touchEvent.data(); |
1625 | -} |
1626 | |
1627 | === removed file 'src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.h' |
1628 | --- src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.h 2015-02-04 10:56:38 +0000 |
1629 | +++ src/app/unity8/libs/UbuntuGestures/UnownedTouchEvent.h 1970-01-01 00:00:00 +0000 |
1630 | @@ -1,45 +0,0 @@ |
1631 | -/* |
1632 | - * Copyright (C) 2014 Canonical, Ltd. |
1633 | - * |
1634 | - * This program is free software; you can redistribute it and/or modify |
1635 | - * it under the terms of the GNU General Public License as published by |
1636 | - * the Free Software Foundation; version 3. |
1637 | - * |
1638 | - * This program is distributed in the hope that it will be useful, |
1639 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1640 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1641 | - * GNU General Public License for more details. |
1642 | - * |
1643 | - * You should have received a copy of the GNU General Public License |
1644 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1645 | - */ |
1646 | - |
1647 | -#ifndef UBUNTU_UNOWNEDTOUCHEVENT_H |
1648 | -#define UBUNTU_UNOWNEDTOUCHEVENT_H |
1649 | - |
1650 | -#include <QTouchEvent> |
1651 | -#include <QScopedPointer> |
1652 | -#include "UbuntuGesturesGlobal.h" |
1653 | - |
1654 | -/* |
1655 | - A touch event with touch points that do not belong the item receiving it. |
1656 | - |
1657 | - See TouchRegistry::addCandidateOwnerForTouch and TouchRegistry::addTouchWatcher |
1658 | - */ |
1659 | -class UBUNTUGESTURES_EXPORT UnownedTouchEvent : public QEvent |
1660 | -{ |
1661 | -public: |
1662 | - UnownedTouchEvent(QTouchEvent *touchEvent); |
1663 | - static Type unownedTouchEventType(); |
1664 | - |
1665 | - // TODO: It might be cleaner to store the information directly in UnownedTouchEvent |
1666 | - // instead of carrying around a synthesized QTouchEvent. But the latter option |
1667 | - // is very convenient. |
1668 | - QTouchEvent *touchEvent(); |
1669 | - |
1670 | -private: |
1671 | - static Type m_unownedTouchEventType; |
1672 | - QScopedPointer<QTouchEvent> m_touchEvent; |
1673 | -}; |
1674 | - |
1675 | -#endif // UBUNTU_UNOWNEDTOUCHEVENT_H |
1676 | |
1677 | === modified file 'src/app/unity8/plugins/CMakeLists.txt' |
1678 | --- src/app/unity8/plugins/CMakeLists.txt 2016-01-28 13:51:25 +0000 |
1679 | +++ src/app/unity8/plugins/CMakeLists.txt 2016-04-12 20:15:29 +0000 |
1680 | @@ -1,2 +1,1 @@ |
1681 | -add_subdirectory(Ubuntu) |
1682 | add_subdirectory(Unity) |
1683 | |
1684 | === removed directory 'src/app/unity8/plugins/Ubuntu' |
1685 | === removed file 'src/app/unity8/plugins/Ubuntu/CMakeLists.txt' |
1686 | --- src/app/unity8/plugins/Ubuntu/CMakeLists.txt 2015-02-04 10:56:38 +0000 |
1687 | +++ src/app/unity8/plugins/Ubuntu/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1688 | @@ -1,1 +0,0 @@ |
1689 | -add_subdirectory(Gestures) |
1690 | |
1691 | === removed directory 'src/app/unity8/plugins/Ubuntu/Gestures' |
1692 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp' |
1693 | --- src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp 2015-02-04 10:56:38 +0000 |
1694 | +++ src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp 1970-01-01 00:00:00 +0000 |
1695 | @@ -1,149 +0,0 @@ |
1696 | -/* |
1697 | - * Copyright (C) 2013 - Canonical Ltd. |
1698 | - * |
1699 | - * This program is free software: you can redistribute it and/or modify it |
1700 | - * under the terms of the GNU Lesser General Public License, as |
1701 | - * published by the Free Software Foundation; either version 2.1 or 3.0 |
1702 | - * of the License. |
1703 | - * |
1704 | - * This program is distributed in the hope that it will be useful, but |
1705 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1706 | - * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
1707 | - * PURPOSE. See the applicable version of the GNU Lesser General Public |
1708 | - * License for more details. |
1709 | - * |
1710 | - * You should have received a copy of both the GNU Lesser General Public |
1711 | - * License along with this program. If not, see <http://www.gnu.org/licenses/> |
1712 | - * |
1713 | - * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
1714 | - */ |
1715 | - |
1716 | -#include "AxisVelocityCalculator.h" |
1717 | -#include <QtCore/QElapsedTimer> |
1718 | - |
1719 | -using namespace UbuntuGestures; |
1720 | - |
1721 | -AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent) |
1722 | - : AxisVelocityCalculator(SharedTimeSource(new RealTimeSource), parent) |
1723 | -{ |
1724 | -} |
1725 | - |
1726 | -AxisVelocityCalculator::AxisVelocityCalculator(const SharedTimeSource &timeSource, |
1727 | - QObject *parent) |
1728 | - : QObject(parent) |
1729 | - , m_timeSource(timeSource) |
1730 | - , m_trackedPosition(0.0) |
1731 | -{ |
1732 | - reset(); |
1733 | -} |
1734 | - |
1735 | -AxisVelocityCalculator::~AxisVelocityCalculator() |
1736 | -{ |
1737 | -} |
1738 | - |
1739 | -qreal AxisVelocityCalculator::trackedPosition() const |
1740 | -{ |
1741 | - return m_trackedPosition; |
1742 | -} |
1743 | - |
1744 | -void AxisVelocityCalculator::setTrackedPosition(qreal newPosition) |
1745 | -{ |
1746 | - processMovement(newPosition - m_trackedPosition); |
1747 | - |
1748 | - if (newPosition != m_trackedPosition) { |
1749 | - m_trackedPosition = newPosition; |
1750 | - Q_EMIT trackedPositionChanged(newPosition); |
1751 | - } |
1752 | -} |
1753 | - |
1754 | -void AxisVelocityCalculator::updateIdleTime() |
1755 | -{ |
1756 | - processMovement(0); |
1757 | -} |
1758 | - |
1759 | -void AxisVelocityCalculator::processMovement(qreal movement) |
1760 | -{ |
1761 | - if (m_samplesRead == -1) { |
1762 | - m_samplesRead = m_samplesWrite; |
1763 | - } else if (m_samplesRead == m_samplesWrite) { |
1764 | - /* the oldest value is going to be overwritten. |
1765 | - so now the oldest will be the next one. */ |
1766 | - m_samplesRead = (m_samplesRead + 1) % MAX_SAMPLES; |
1767 | - } |
1768 | - |
1769 | - m_samples[m_samplesWrite].mov = movement; |
1770 | - m_samples[m_samplesWrite].time = m_timeSource->msecsSinceReference(); |
1771 | - m_samplesWrite = (m_samplesWrite + 1) % MAX_SAMPLES; |
1772 | -} |
1773 | - |
1774 | -qreal AxisVelocityCalculator::calculate() |
1775 | -{ |
1776 | - if (numSamples() < MIN_SAMPLES_NEEDED) { |
1777 | - return 0.0; |
1778 | - } |
1779 | - updateIdleTime(); // consider the time elapsed since the last update and now |
1780 | - |
1781 | - int lastIndex; |
1782 | - if (m_samplesWrite == 0) { |
1783 | - lastIndex = MAX_SAMPLES - 1; |
1784 | - } else { |
1785 | - lastIndex = m_samplesWrite - 1; |
1786 | - } |
1787 | - |
1788 | - qint64 currTime = m_samples[lastIndex].time; |
1789 | - |
1790 | - qreal totalTime = 0; |
1791 | - qreal totalDistance = 0; |
1792 | - |
1793 | - int sampleIndex = (m_samplesRead + 1) % MAX_SAMPLES; |
1794 | - qint64 previousTime = m_samples[m_samplesRead].time; |
1795 | - while (sampleIndex != m_samplesWrite) { |
1796 | - // Skip this sample if it's too old |
1797 | - if (currTime - m_samples[sampleIndex].time <= AGE_OLDEST_SAMPLE) { |
1798 | - int deltaTime = m_samples[sampleIndex].time - previousTime; |
1799 | - totalDistance += m_samples[sampleIndex].mov; |
1800 | - totalTime += deltaTime; |
1801 | - } |
1802 | - |
1803 | - previousTime = m_samples[sampleIndex].time; |
1804 | - sampleIndex = (sampleIndex + 1) % MAX_SAMPLES; |
1805 | - } |
1806 | - |
1807 | - return totalDistance / totalTime; |
1808 | -} |
1809 | - |
1810 | -void AxisVelocityCalculator::reset() |
1811 | -{ |
1812 | - m_samplesRead = -1; |
1813 | - m_samplesWrite = 0; |
1814 | -} |
1815 | - |
1816 | -int AxisVelocityCalculator::numSamples() const |
1817 | -{ |
1818 | - if (m_samplesRead == -1) { |
1819 | - return 0; |
1820 | - } else { |
1821 | - if (m_samplesWrite == 0) { |
1822 | - /* consider only what's to the right of m_samplesRead (including himself) */ |
1823 | - return MAX_SAMPLES - m_samplesRead; |
1824 | - } else if (m_samplesWrite == m_samplesRead) { |
1825 | - return MAX_SAMPLES; /* buffer is full */ |
1826 | - } else if (m_samplesWrite < m_samplesRead) { |
1827 | - return (MAX_SAMPLES - m_samplesRead) + m_samplesWrite; |
1828 | - } else { |
1829 | - return m_samplesWrite - m_samplesRead; |
1830 | - } |
1831 | - } |
1832 | -} |
1833 | - |
1834 | -void AxisVelocityCalculator::setTimeSource(const SharedTimeSource &timeSource) |
1835 | -{ |
1836 | - m_timeSource = timeSource; |
1837 | - |
1838 | - if (numSamples() > 0) { |
1839 | - qWarning("AxisVelocityCalculator: changing time source while there are samples present."); |
1840 | - // Any existent samples are based on the old time source and are, therefore, incompatible |
1841 | - // with this new one. |
1842 | - reset(); |
1843 | - } |
1844 | -} |
1845 | |
1846 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.h' |
1847 | --- src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.h 2015-02-04 10:56:38 +0000 |
1848 | +++ src/app/unity8/plugins/Ubuntu/Gestures/AxisVelocityCalculator.h 1970-01-01 00:00:00 +0000 |
1849 | @@ -1,146 +0,0 @@ |
1850 | -/* |
1851 | - * Copyright (C) 2013 - Canonical Ltd. |
1852 | - * |
1853 | - * This program is free software: you can redistribute it and/or modify it |
1854 | - * under the terms of the GNU Lesser General Public License, as |
1855 | - * published by the Free Software Foundation; either version 2.1 or 3.0 |
1856 | - * of the License. |
1857 | - * |
1858 | - * This program is distributed in the hope that it will be useful, but |
1859 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1860 | - * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
1861 | - * PURPOSE. See the applicable version of the GNU Lesser General Public |
1862 | - * License for more details. |
1863 | - * |
1864 | - * You should have received a copy of both the GNU Lesser General Public |
1865 | - * License along with this program. If not, see <http://www.gnu.org/licenses/> |
1866 | - * |
1867 | - * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
1868 | - */ |
1869 | - |
1870 | -#ifndef VELOCITY_CALCULATOR_H |
1871 | -#define VELOCITY_CALCULATOR_H |
1872 | - |
1873 | -#include "UbuntuGesturesQmlGlobal.h" |
1874 | -#include <stdint.h> |
1875 | -#include <QtCore/QObject> |
1876 | -#include "TimeSource.h" |
1877 | - |
1878 | -/* |
1879 | - Estimates the current velocity of a finger based on recent movement along an axis |
1880 | - |
1881 | - Taking an estimate from a reasonable number of samples, instead of only |
1882 | - from its last movement, removes wild variations in velocity caused |
1883 | - by the jitter normally present in input from a touchscreen. |
1884 | - |
1885 | - Usage example: |
1886 | - |
1887 | - AxisVelocityCalculator { |
1888 | - id: velocityCalculator |
1889 | - trackedPosition: myMouseArea.mouseX |
1890 | - } |
1891 | - |
1892 | - MouseArea { |
1893 | - id: myMouseArea |
1894 | - |
1895 | - onReleased: { |
1896 | - console.log("Drag velocity along the X axis before release was: " |
1897 | - + velocityCalculator.calculate()) |
1898 | - } |
1899 | - } |
1900 | - */ |
1901 | -class UBUNTUGESTURESQML_EXPORT AxisVelocityCalculator : public QObject |
1902 | -{ |
1903 | - Q_OBJECT |
1904 | - |
1905 | - /* |
1906 | - Position whose movement will be tracked to calculate its velocity |
1907 | - */ |
1908 | - Q_PROPERTY(qreal trackedPosition READ trackedPosition WRITE setTrackedPosition |
1909 | - NOTIFY trackedPositionChanged) |
1910 | -public: |
1911 | - |
1912 | - /* |
1913 | - Regular, simple, constructor |
1914 | - */ |
1915 | - AxisVelocityCalculator(QObject *parent = 0); |
1916 | - |
1917 | - /* |
1918 | - Constructor that takes a TimeSource |
1919 | - */ |
1920 | - AxisVelocityCalculator(const UbuntuGestures::SharedTimeSource &timeSource, QObject *parent = 0); |
1921 | - |
1922 | - virtual ~AxisVelocityCalculator(); |
1923 | - |
1924 | - qreal trackedPosition() const; |
1925 | - void setTrackedPosition(qreal value); |
1926 | - |
1927 | - /* |
1928 | - Calculates the finger velocity, in axis units/millisecond |
1929 | - */ |
1930 | - Q_INVOKABLE qreal calculate(); |
1931 | - |
1932 | - /* |
1933 | - Removes all stored movements from previous calls to setTrackedPosition() |
1934 | - */ |
1935 | - Q_INVOKABLE void reset(); |
1936 | - |
1937 | - int numSamples() const; |
1938 | - |
1939 | - /* |
1940 | - Replaces the TimeSource with the given one. Useful for testing purposes. |
1941 | - */ |
1942 | - void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource); |
1943 | - |
1944 | - /* |
1945 | - The minimum amount of samples needed for a velocity calculation. |
1946 | - */ |
1947 | - static const int MIN_SAMPLES_NEEDED = 2; |
1948 | - |
1949 | - /* |
1950 | - Maximum number of movement samples stored |
1951 | - */ |
1952 | - static const int MAX_SAMPLES = 50; |
1953 | - |
1954 | - /* |
1955 | - Age of the oldest sample considered in the velocity calculations, in |
1956 | - milliseconds, compared to the most recent one. |
1957 | - */ |
1958 | - static const int AGE_OLDEST_SAMPLE = 100; |
1959 | - |
1960 | -Q_SIGNALS: |
1961 | - void trackedPositionChanged(qreal value); |
1962 | - |
1963 | -private: |
1964 | - |
1965 | - /* |
1966 | - Inform that trackedPosition remained motionless since the time it was |
1967 | - last changed. |
1968 | - |
1969 | - It's the same as calling setTrackedPosition(trackedPosition()) |
1970 | - */ |
1971 | - void updateIdleTime(); |
1972 | - |
1973 | - /* |
1974 | - How much the finger has moved since processMovement() was last called. |
1975 | - */ |
1976 | - void processMovement(qreal movement); |
1977 | - |
1978 | - class Sample |
1979 | - { |
1980 | - public: |
1981 | - qreal mov; /* movement distance since last sample */ |
1982 | - qint64 time; /* time, in milliseconds */ |
1983 | - }; |
1984 | - |
1985 | - /* a circular buffer of samples */ |
1986 | - Sample m_samples[MAX_SAMPLES]; |
1987 | - int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */ |
1988 | - int m_samplesWrite; /* index where the next sample will be written */ |
1989 | - |
1990 | - UbuntuGestures::SharedTimeSource m_timeSource; |
1991 | - |
1992 | - qreal m_trackedPosition; |
1993 | -}; |
1994 | - |
1995 | -#endif // VELOCITY_CALCULATOR_H |
1996 | |
1997 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/CMakeLists.txt' |
1998 | --- src/app/unity8/plugins/Ubuntu/Gestures/CMakeLists.txt 2015-02-04 10:56:38 +0000 |
1999 | +++ src/app/unity8/plugins/Ubuntu/Gestures/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2000 | @@ -1,40 +0,0 @@ |
2001 | -# in order to include Qt's private headers |
2002 | -remove_definitions(-DQT_NO_KEYWORDS) |
2003 | - |
2004 | -set(UbuntuGesturesQml_SOURCES |
2005 | -# plugin.cpp |
2006 | - AxisVelocityCalculator.cpp |
2007 | - Direction.cpp |
2008 | - DirectionalDragArea.cpp |
2009 | - PressedOutsideNotifier.cpp |
2010 | - TimeSource.cpp |
2011 | - TouchDispatcher.cpp |
2012 | - TouchGate.cpp |
2013 | -) |
2014 | - |
2015 | -add_definitions(-DUBUNTUGESTURESQML_LIBRARY) |
2016 | - |
2017 | -add_library(UbuntuGesturesQml STATIC ${UbuntuGesturesQml_SOURCES}) |
2018 | -target_link_libraries(UbuntuGesturesQml UbuntuGestures) |
2019 | - |
2020 | -qt5_use_modules(UbuntuGesturesQml Core Quick) |
2021 | - |
2022 | -# So that Foo.cpp can #include "Foo.moc" |
2023 | -include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
2024 | - |
2025 | -include_directories(${unity8_SOURCE_DIR}/libs/UbuntuGestures) |
2026 | - |
2027 | -# There's no cmake var for v8 include path :-/ so create one |
2028 | -LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0) |
2029 | -SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8) |
2030 | - |
2031 | -# DANGER! DANGER! Using Qt's private API! |
2032 | -include_directories( |
2033 | - ${Qt5Qml_PRIVATE_INCLUDE_DIRS} |
2034 | - ${Qt5Quick_INCLUDE_DIRS} |
2035 | - ${Qt5Quick_PRIVATE_INCLUDE_DIRS} |
2036 | - ${Qt5V8_PRIVATE_INCLUDE_DIR} |
2037 | -) |
2038 | - |
2039 | -#add_unity8_plugin(Ubuntu.Gestures 0.1 Ubuntu/Gestures TARGETS UbuntuGesturesQml) |
2040 | -# TODO |
2041 | |
2042 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/Damper.h' |
2043 | --- src/app/unity8/plugins/Ubuntu/Gestures/Damper.h 2015-02-04 10:56:38 +0000 |
2044 | +++ src/app/unity8/plugins/Ubuntu/Gestures/Damper.h 1970-01-01 00:00:00 +0000 |
2045 | @@ -1,87 +0,0 @@ |
2046 | -/* |
2047 | - * Copyright (C) 2013 Canonical, Ltd. |
2048 | - * |
2049 | - * This program is free software; you can redistribute it and/or modify |
2050 | - * it under the terms of the GNU General Public License as published by |
2051 | - * the Free Software Foundation; version 3. |
2052 | - * |
2053 | - * This program is distributed in the hope that it will be useful, |
2054 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2055 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2056 | - * GNU General Public License for more details. |
2057 | - * |
2058 | - * You should have received a copy of the GNU General Public License |
2059 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2060 | - */ |
2061 | - |
2062 | -#ifndef UBUNTU_GESTURES_DAMPER_H |
2063 | -#define UBUNTU_GESTURES_DAMPER_H |
2064 | - |
2065 | -#include <QtCore/QPointF> |
2066 | - |
2067 | -/* |
2068 | - Decreases the oscillations of a value along an axis. |
2069 | - */ |
2070 | -template <class Type> class Damper { |
2071 | -public: |
2072 | - Damper() : m_value(0), m_maxDelta(0) { } |
2073 | - |
2074 | - // Maximum delta between the raw value and its dampened counterpart. |
2075 | - void setMaxDelta(Type maxDelta) { |
2076 | - if (maxDelta < 0) qFatal("Damper::maxDelta must be a positive number."); |
2077 | - m_maxDelta = maxDelta; |
2078 | - } |
2079 | - Type maxDelta() const { return m_maxDelta; } |
2080 | - |
2081 | - void reset(Type value) { |
2082 | - m_value = value; |
2083 | - } |
2084 | - |
2085 | - Type update(Type value) { |
2086 | - Type delta = value - m_value; |
2087 | - if (delta > 0 && delta > m_maxDelta) { |
2088 | - m_value += delta - m_maxDelta; |
2089 | - } else if (delta < 0 && delta < -m_maxDelta) { |
2090 | - m_value += delta + m_maxDelta; |
2091 | - } |
2092 | - |
2093 | - return m_value; |
2094 | - } |
2095 | - |
2096 | - Type value() const { return m_value; } |
2097 | - |
2098 | -private: |
2099 | - Type m_value; |
2100 | - Type m_maxDelta; |
2101 | -}; |
2102 | - |
2103 | -/* |
2104 | - A point that has its movement dampened. |
2105 | - */ |
2106 | -class DampedPointF { |
2107 | -public: |
2108 | - void setMaxDelta(qreal maxDelta) { |
2109 | - m_x.setMaxDelta(maxDelta); |
2110 | - m_y.setMaxDelta(maxDelta); |
2111 | - } |
2112 | - |
2113 | - qreal maxDelta() const { return m_x.maxDelta(); } |
2114 | - |
2115 | - void reset(const QPointF &point) { |
2116 | - m_x.reset(point.x()); |
2117 | - m_y.reset(point.y()); |
2118 | - } |
2119 | - |
2120 | - void update(const QPointF &point) { |
2121 | - m_x.update(point.x()); |
2122 | - m_y.update(point.y()); |
2123 | - } |
2124 | - |
2125 | - qreal x() const { return m_x.value(); } |
2126 | - qreal y() const { return m_y.value(); } |
2127 | -private: |
2128 | - Damper<qreal> m_x; |
2129 | - Damper<qreal> m_y; |
2130 | -}; |
2131 | - |
2132 | -#endif // UBUNTU_GESTURES_DAMPER_H |
2133 | |
2134 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/Direction.cpp' |
2135 | --- src/app/unity8/plugins/Ubuntu/Gestures/Direction.cpp 2015-02-04 10:56:38 +0000 |
2136 | +++ src/app/unity8/plugins/Ubuntu/Gestures/Direction.cpp 1970-01-01 00:00:00 +0000 |
2137 | @@ -1,36 +0,0 @@ |
2138 | -/* |
2139 | - * Copyright (C) 2013 Canonical, Ltd. |
2140 | - * |
2141 | - * This program is free software; you can redistribute it and/or modify |
2142 | - * it under the terms of the GNU General Public License as published by |
2143 | - * the Free Software Foundation; version 3. |
2144 | - * |
2145 | - * This program is distributed in the hope that it will be useful, |
2146 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2147 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2148 | - * GNU General Public License for more details. |
2149 | - * |
2150 | - * You should have received a copy of the GNU General Public License |
2151 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2152 | - */ |
2153 | - |
2154 | -#include "Direction.h" |
2155 | - |
2156 | -bool Direction::isHorizontal(Direction::Type type) |
2157 | -{ |
2158 | - return type == Direction::Leftwards |
2159 | - || type == Direction::Rightwards |
2160 | - || type == Direction::Horizontal; |
2161 | -} |
2162 | - |
2163 | -bool Direction::isVertical(Direction::Type type) |
2164 | -{ |
2165 | - return type == Direction::Upwards || type == Direction::Downwards; |
2166 | -} |
2167 | - |
2168 | -bool Direction::isPositive(Direction::Type type) |
2169 | -{ |
2170 | - return type == Rightwards |
2171 | - || type == Downwards |
2172 | - || type == Horizontal; |
2173 | -} |
2174 | |
2175 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/Direction.h' |
2176 | --- src/app/unity8/plugins/Ubuntu/Gestures/Direction.h 2015-02-04 10:56:38 +0000 |
2177 | +++ src/app/unity8/plugins/Ubuntu/Gestures/Direction.h 1970-01-01 00:00:00 +0000 |
2178 | @@ -1,45 +0,0 @@ |
2179 | -/* |
2180 | - * Copyright (C) 2013 Canonical, Ltd. |
2181 | - * |
2182 | - * This program is free software; you can redistribute it and/or modify |
2183 | - * it under the terms of the GNU General Public License as published by |
2184 | - * the Free Software Foundation; version 3. |
2185 | - * |
2186 | - * This program is distributed in the hope that it will be useful, |
2187 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2188 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2189 | - * GNU General Public License for more details. |
2190 | - * |
2191 | - * You should have received a copy of the GNU General Public License |
2192 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2193 | - */ |
2194 | - |
2195 | -#ifndef DIRECTION_H |
2196 | -#define DIRECTION_H |
2197 | - |
2198 | -#include "UbuntuGesturesQmlGlobal.h" |
2199 | -#include <QObject> |
2200 | - |
2201 | -/* |
2202 | - A Direction enum wrapper so that we can do things like "direction: Direction.Righwards" |
2203 | - from QML. |
2204 | - */ |
2205 | -class UBUNTUGESTURESQML_EXPORT Direction : public QObject { |
2206 | - Q_OBJECT |
2207 | - Q_ENUMS(Type) |
2208 | - |
2209 | -public: |
2210 | - enum Type { |
2211 | - Rightwards, // Along the positive direction of the X axis |
2212 | - Leftwards, // Along the negative direction of the X axis |
2213 | - Downwards, // Along the positive direction of the Y axis |
2214 | - Upwards, // Along the negative direction of the Y axis |
2215 | - Horizontal // Along the X axis, in any direction |
2216 | - }; |
2217 | - |
2218 | - Q_INVOKABLE static bool isHorizontal(Direction::Type type); |
2219 | - Q_INVOKABLE static bool isVertical(Direction::Type type); |
2220 | - Q_INVOKABLE static bool isPositive(Direction::Type type); |
2221 | -}; |
2222 | - |
2223 | -#endif // DIRECTION_H |
2224 | |
2225 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.cpp' |
2226 | --- src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2015-02-04 10:56:38 +0000 |
2227 | +++ src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 1970-01-01 00:00:00 +0000 |
2228 | @@ -1,886 +0,0 @@ |
2229 | -/* |
2230 | - * Copyright (C) 2013-2014 Canonical, Ltd. |
2231 | - * |
2232 | - * This program is free software; you can redistribute it and/or modify |
2233 | - * it under the terms of the GNU General Public License as published by |
2234 | - * the Free Software Foundation; version 3. |
2235 | - * |
2236 | - * This program is distributed in the hope that it will be useful, |
2237 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2238 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2239 | - * GNU General Public License for more details. |
2240 | - * |
2241 | - * You should have received a copy of the GNU General Public License |
2242 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2243 | - */ |
2244 | - |
2245 | -#define ACTIVETOUCHESINFO_DEBUG 0 |
2246 | -#define DIRECTIONALDRAGAREA_DEBUG 0 |
2247 | - |
2248 | -#include "DirectionalDragArea.h" |
2249 | - |
2250 | -#include <QQuickWindow> |
2251 | -#include <QtCore/qmath.h> |
2252 | -#include <QDebug> |
2253 | - |
2254 | -#pragma GCC diagnostic push |
2255 | -#pragma GCC diagnostic ignored "-pedantic" |
2256 | -#include <private/qquickwindow_p.h> |
2257 | -#pragma GCC diagnostic pop |
2258 | - |
2259 | -// local |
2260 | -#include "TouchOwnershipEvent.h" |
2261 | -#include "TouchRegistry.h" |
2262 | -#include "UnownedTouchEvent.h" |
2263 | - |
2264 | -using namespace UbuntuGestures; |
2265 | - |
2266 | -#if DIRECTIONALDRAGAREA_DEBUG |
2267 | -#define ddaDebug(params) qDebug().nospace() << "[DDA(" << qPrintable(objectName()) << ")] " << params |
2268 | -#include "DebugHelpers.h" |
2269 | - |
2270 | -namespace { |
2271 | -const char *statusToString(DirectionalDragArea::Status status) |
2272 | -{ |
2273 | - if (status == DirectionalDragArea::WaitingForTouch) { |
2274 | - return "WaitingForTouch"; |
2275 | - } else if (status == DirectionalDragArea::Undecided) { |
2276 | - return "Undecided"; |
2277 | - } else { |
2278 | - return "Recognized"; |
2279 | - } |
2280 | -} |
2281 | - |
2282 | -} // namespace { |
2283 | -#else // DIRECTIONALDRAGAREA_DEBUG |
2284 | -#define ddaDebug(params) ((void)0) |
2285 | -#endif // DIRECTIONALDRAGAREA_DEBUG |
2286 | - |
2287 | - |
2288 | -DirectionalDragArea::DirectionalDragArea(QQuickItem *parent) |
2289 | - : QQuickItem(parent) |
2290 | - , m_status(WaitingForTouch) |
2291 | - , m_sceneDistance(0) |
2292 | - , m_touchId(-1) |
2293 | - , m_direction(Direction::Rightwards) |
2294 | - , m_wideningAngle(0) |
2295 | - , m_wideningFactor(0) |
2296 | - , m_distanceThreshold(0) |
2297 | - , m_distanceThresholdSquared(0.) |
2298 | - , m_minSpeed(0) |
2299 | - , m_maxSilenceTime(200) |
2300 | - , m_silenceTime(0) |
2301 | - , m_compositionTime(60) |
2302 | - , m_numSamplesOnLastSpeedCheck(0) |
2303 | - , m_recognitionTimer(0) |
2304 | - , m_velocityCalculator(0) |
2305 | - , m_timeSource(new RealTimeSource) |
2306 | - , m_activeTouches(m_timeSource) |
2307 | -{ |
2308 | - setRecognitionTimer(new Timer(this)); |
2309 | - m_recognitionTimer->setInterval(60); |
2310 | - m_recognitionTimer->setSingleShot(false); |
2311 | - |
2312 | - m_velocityCalculator = new AxisVelocityCalculator(this); |
2313 | - |
2314 | - connect(this, &QQuickItem::enabledChanged, this, &DirectionalDragArea::giveUpIfDisabledOrInvisible); |
2315 | - connect(this, &QQuickItem::visibleChanged, this, &DirectionalDragArea::giveUpIfDisabledOrInvisible); |
2316 | -} |
2317 | - |
2318 | -Direction::Type DirectionalDragArea::direction() const |
2319 | -{ |
2320 | - return m_direction; |
2321 | -} |
2322 | - |
2323 | -void DirectionalDragArea::setDirection(Direction::Type direction) |
2324 | -{ |
2325 | - if (direction != m_direction) { |
2326 | - m_direction = direction; |
2327 | - Q_EMIT directionChanged(m_direction); |
2328 | - } |
2329 | -} |
2330 | - |
2331 | -void DirectionalDragArea::setMaxDeviation(qreal value) |
2332 | -{ |
2333 | - if (m_dampedScenePos.maxDelta() != value) { |
2334 | - m_dampedScenePos.setMaxDelta(value); |
2335 | - Q_EMIT maxDeviationChanged(value); |
2336 | - } |
2337 | -} |
2338 | - |
2339 | -qreal DirectionalDragArea::wideningAngle() const |
2340 | -{ |
2341 | - return m_wideningAngle; |
2342 | -} |
2343 | - |
2344 | -void DirectionalDragArea::setWideningAngle(qreal angle) |
2345 | -{ |
2346 | - if (angle == m_wideningAngle) |
2347 | - return; |
2348 | - |
2349 | - m_wideningAngle = angle; |
2350 | - |
2351 | - // wideningFactor = pow(cosine(angle), 2) |
2352 | - { |
2353 | - qreal angleRadians = angle * M_PI / 180.0; |
2354 | - m_wideningFactor = qCos(angleRadians); |
2355 | - m_wideningFactor = m_wideningFactor * m_wideningFactor; |
2356 | - } |
2357 | - |
2358 | - Q_EMIT wideningAngleChanged(angle); |
2359 | -} |
2360 | - |
2361 | -void DirectionalDragArea::setDistanceThreshold(qreal value) |
2362 | -{ |
2363 | - if (m_distanceThreshold != value) { |
2364 | - m_distanceThreshold = value; |
2365 | - m_distanceThresholdSquared = m_distanceThreshold * m_distanceThreshold; |
2366 | - Q_EMIT distanceThresholdChanged(value); |
2367 | - } |
2368 | -} |
2369 | - |
2370 | -void DirectionalDragArea::setMinSpeed(qreal value) |
2371 | -{ |
2372 | - if (m_minSpeed != value) { |
2373 | - m_minSpeed = value; |
2374 | - Q_EMIT minSpeedChanged(value); |
2375 | - } |
2376 | -} |
2377 | - |
2378 | -void DirectionalDragArea::setMaxSilenceTime(int value) |
2379 | -{ |
2380 | - if (m_maxSilenceTime != value) { |
2381 | - m_maxSilenceTime = value; |
2382 | - Q_EMIT maxSilenceTimeChanged(value); |
2383 | - } |
2384 | -} |
2385 | - |
2386 | -void DirectionalDragArea::setCompositionTime(int value) |
2387 | -{ |
2388 | - if (m_compositionTime != value) { |
2389 | - m_compositionTime = value; |
2390 | - Q_EMIT compositionTimeChanged(value); |
2391 | - } |
2392 | -} |
2393 | - |
2394 | -void DirectionalDragArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer) |
2395 | -{ |
2396 | - int interval = 0; |
2397 | - bool timerWasRunning = false; |
2398 | - bool wasSingleShot = false; |
2399 | - |
2400 | - // can be null when called from the constructor |
2401 | - if (m_recognitionTimer) { |
2402 | - interval = m_recognitionTimer->interval(); |
2403 | - timerWasRunning = m_recognitionTimer->isRunning(); |
2404 | - if (m_recognitionTimer->parent() == this) { |
2405 | - delete m_recognitionTimer; |
2406 | - } |
2407 | - } |
2408 | - |
2409 | - m_recognitionTimer = timer; |
2410 | - timer->setInterval(interval); |
2411 | - timer->setSingleShot(wasSingleShot); |
2412 | - connect(timer, &UbuntuGestures::AbstractTimer::timeout, |
2413 | - this, &DirectionalDragArea::checkSpeed); |
2414 | - if (timerWasRunning) { |
2415 | - m_recognitionTimer->start(); |
2416 | - } |
2417 | -} |
2418 | - |
2419 | -void DirectionalDragArea::setTimeSource(const SharedTimeSource &timeSource) |
2420 | -{ |
2421 | - m_timeSource = timeSource; |
2422 | - m_velocityCalculator->setTimeSource(timeSource); |
2423 | - m_activeTouches.m_timeSource = timeSource; |
2424 | -} |
2425 | - |
2426 | -qreal DirectionalDragArea::distance() const |
2427 | -{ |
2428 | - if (Direction::isHorizontal(m_direction)) { |
2429 | - return m_previousPos.x() - m_startPos.x(); |
2430 | - } else { |
2431 | - return m_previousPos.y() - m_startPos.y(); |
2432 | - } |
2433 | -} |
2434 | - |
2435 | -void DirectionalDragArea::updateSceneDistance() |
2436 | -{ |
2437 | - QPointF totalMovement = m_previousScenePos - m_startScenePos; |
2438 | - m_sceneDistance = projectOntoDirectionVector(totalMovement); |
2439 | -} |
2440 | - |
2441 | -qreal DirectionalDragArea::sceneDistance() const |
2442 | -{ |
2443 | - return m_sceneDistance; |
2444 | -} |
2445 | - |
2446 | -qreal DirectionalDragArea::touchX() const |
2447 | -{ |
2448 | - return m_previousPos.x(); |
2449 | -} |
2450 | - |
2451 | -qreal DirectionalDragArea::touchY() const |
2452 | -{ |
2453 | - return m_previousPos.y(); |
2454 | -} |
2455 | - |
2456 | -qreal DirectionalDragArea::touchSceneX() const |
2457 | -{ |
2458 | - return m_previousScenePos.x(); |
2459 | -} |
2460 | - |
2461 | -qreal DirectionalDragArea::touchSceneY() const |
2462 | -{ |
2463 | - return m_previousScenePos.y(); |
2464 | -} |
2465 | - |
2466 | -bool DirectionalDragArea::event(QEvent *event) |
2467 | -{ |
2468 | - if (event->type() == TouchOwnershipEvent::touchOwnershipEventType()) { |
2469 | - touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(event)); |
2470 | - return true; |
2471 | - } else if (event->type() == UnownedTouchEvent::unownedTouchEventType()) { |
2472 | - unownedTouchEvent(static_cast<UnownedTouchEvent *>(event)); |
2473 | - return true; |
2474 | - } else { |
2475 | - return QQuickItem::event(event); |
2476 | - } |
2477 | -} |
2478 | - |
2479 | -void DirectionalDragArea::touchOwnershipEvent(TouchOwnershipEvent *event) |
2480 | -{ |
2481 | - if (event->gained()) { |
2482 | - QVector<int> ids; |
2483 | - ids.append(event->touchId()); |
2484 | - ddaDebug("grabbing touch"); |
2485 | - grabTouchPoints(ids); |
2486 | - |
2487 | - // Work around for Qt bug. If we grab a touch that is being used for mouse pointer |
2488 | - // emulation it will cause the emulation logic to go nuts. |
2489 | - // Thus we have to also grab the mouse in this case. |
2490 | - // |
2491 | - // The fix for this bug has landed in Qt 5.4 (https://codereview.qt-project.org/96887) |
2492 | - // TODO: Remove this workaround once we start using Qt 5.4 |
2493 | - if (window()) { |
2494 | - QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(window()); |
2495 | - if (windowPrivate->touchMouseId == event->touchId() && window()->mouseGrabberItem()) { |
2496 | - ddaDebug("removing mouse grabber"); |
2497 | - window()->mouseGrabberItem()->ungrabMouse(); |
2498 | - } |
2499 | - } |
2500 | - } else { |
2501 | - // We still wanna know when it ends for keeping the composition time window up-to-date |
2502 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2503 | - |
2504 | - setStatus(WaitingForTouch); |
2505 | - } |
2506 | -} |
2507 | - |
2508 | -void DirectionalDragArea::unownedTouchEvent(UnownedTouchEvent *unownedTouchEvent) |
2509 | -{ |
2510 | - QTouchEvent *event = unownedTouchEvent->touchEvent(); |
2511 | - |
2512 | - Q_ASSERT(!event->touchPointStates().testFlag(Qt::TouchPointPressed)); |
2513 | - |
2514 | - ddaDebug("Unowned " << m_timeSource->msecsSinceReference() << " " << qPrintable(touchEventToString(event))); |
2515 | - |
2516 | - switch (m_status) { |
2517 | - case WaitingForTouch: |
2518 | - // do nothing |
2519 | - break; |
2520 | - case Undecided: |
2521 | - Q_ASSERT(isEnabled() && isVisible()); |
2522 | - unownedTouchEvent_undecided(unownedTouchEvent); |
2523 | - break; |
2524 | - default: // Recognized: |
2525 | - // do nothing |
2526 | - break; |
2527 | - } |
2528 | - |
2529 | - m_activeTouches.update(event); |
2530 | -} |
2531 | - |
2532 | -void DirectionalDragArea::unownedTouchEvent_undecided(UnownedTouchEvent *unownedTouchEvent) |
2533 | -{ |
2534 | - const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(unownedTouchEvent->touchEvent()); |
2535 | - if (!touchPoint) { |
2536 | - qCritical() << "DirectionalDragArea[status=Undecided]: touch " << m_touchId |
2537 | - << "missing from UnownedTouchEvent without first reaching state Qt::TouchPointReleased. " |
2538 | - "Considering it as released."; |
2539 | - |
2540 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2541 | - setStatus(WaitingForTouch); |
2542 | - return; |
2543 | - } |
2544 | - |
2545 | - const QPointF &touchScenePos = touchPoint->scenePos(); |
2546 | - |
2547 | - if (touchPoint->state() == Qt::TouchPointReleased) { |
2548 | - // touch has ended before recognition concluded |
2549 | - ddaDebug("Touch has ended before recognition concluded"); |
2550 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2551 | - emitSignalIfTapped(); |
2552 | - setStatus(WaitingForTouch); |
2553 | - return; |
2554 | - } |
2555 | - |
2556 | - m_previousDampedScenePos.setX(m_dampedScenePos.x()); |
2557 | - m_previousDampedScenePos.setY(m_dampedScenePos.y()); |
2558 | - m_dampedScenePos.update(touchScenePos); |
2559 | - updateVelocityCalculator(touchScenePos); |
2560 | - |
2561 | - if (!pointInsideAllowedArea()) { |
2562 | - ddaDebug("Rejecting gesture because touch point is outside allowed area."); |
2563 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2564 | - // We still wanna know when it ends for keeping the composition time window up-to-date |
2565 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2566 | - setStatus(WaitingForTouch); |
2567 | - return; |
2568 | - } |
2569 | - |
2570 | - if (!movingInRightDirection()) { |
2571 | - ddaDebug("Rejecting gesture because touch point is moving in the wrong direction."); |
2572 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2573 | - // We still wanna know when it ends for keeping the composition time window up-to-date |
2574 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2575 | - setStatus(WaitingForTouch); |
2576 | - return; |
2577 | - } |
2578 | - |
2579 | - setPreviousPos(touchPoint->pos()); |
2580 | - setPreviousScenePos(touchScenePos); |
2581 | - |
2582 | - if (isWithinTouchCompositionWindow()) { |
2583 | - // There's still time for some new touch to appear and ruin our party as it would be combined |
2584 | - // with our m_touchId one and therefore deny the possibility of a single-finger gesture. |
2585 | - ddaDebug("Sill within composition window. Let's wait more."); |
2586 | - return; |
2587 | - } |
2588 | - |
2589 | - if (movedFarEnough(touchScenePos)) { |
2590 | - TouchRegistry::instance()->requestTouchOwnership(m_touchId, this); |
2591 | - setStatus(Recognized); |
2592 | - } else { |
2593 | - ddaDebug("Didn't move far enough yet. Let's wait more."); |
2594 | - } |
2595 | -} |
2596 | - |
2597 | -void DirectionalDragArea::touchEvent(QTouchEvent *event) |
2598 | -{ |
2599 | - // TODO: Consider when more than one touch starts in the same event (although it's not possible |
2600 | - // with Mir's android-input). Have to track them all. Consider it a plus/bonus. |
2601 | - |
2602 | - ddaDebug(m_timeSource->msecsSinceReference() << " " << qPrintable(touchEventToString(event))); |
2603 | - |
2604 | - if (!isEnabled() || !isVisible()) { |
2605 | - QQuickItem::touchEvent(event); |
2606 | - return; |
2607 | - } |
2608 | - |
2609 | - switch (m_status) { |
2610 | - case WaitingForTouch: |
2611 | - touchEvent_absent(event); |
2612 | - break; |
2613 | - case Undecided: |
2614 | - touchEvent_undecided(event); |
2615 | - break; |
2616 | - default: // Recognized: |
2617 | - touchEvent_recognized(event); |
2618 | - break; |
2619 | - } |
2620 | - |
2621 | - m_activeTouches.update(event); |
2622 | -} |
2623 | - |
2624 | -void DirectionalDragArea::touchEvent_absent(QTouchEvent *event) |
2625 | -{ |
2626 | - // TODO: accept/reject is for the whole event, not per touch id. See how that affects us. |
2627 | - |
2628 | - if (!event->touchPointStates().testFlag(Qt::TouchPointPressed)) { |
2629 | - // Nothing to see here. No touch starting in this event. |
2630 | - return; |
2631 | - } |
2632 | - |
2633 | - // to be proven wrong, if that's the case |
2634 | - bool allGood = true; |
2635 | - |
2636 | - if (isWithinTouchCompositionWindow()) { |
2637 | - // too close to the last touch start. So we consider them as starting roughly at the same time. |
2638 | - // Can't be a single-touch gesture. |
2639 | - ddaDebug("A new touch point came in but we're still within time composition window. Ignoring it."); |
2640 | - allGood = false; |
2641 | - } |
2642 | - |
2643 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
2644 | - |
2645 | - const QTouchEvent::TouchPoint *newTouchPoint = nullptr; |
2646 | - for (int i = 0; i < touchPoints.count() && allGood; ++i) { |
2647 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
2648 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
2649 | - if (newTouchPoint) { |
2650 | - // more than one touch starting in this QTouchEvent. Can't be a single-touch gesture |
2651 | - allGood = false; |
2652 | - } else { |
2653 | - // that's our candidate |
2654 | - m_touchId = touchPoint.id(); |
2655 | - newTouchPoint = &touchPoint; |
2656 | - } |
2657 | - } |
2658 | - } |
2659 | - |
2660 | - if (allGood) { |
2661 | - Q_ASSERT(newTouchPoint); |
2662 | - |
2663 | - m_startPos = newTouchPoint->pos(); |
2664 | - m_startScenePos = newTouchPoint->scenePos(); |
2665 | - m_touchId = newTouchPoint->id(); |
2666 | - m_dampedScenePos.reset(m_startScenePos); |
2667 | - m_velocityCalculator->setTrackedPosition(0.); |
2668 | - m_velocityCalculator->reset(); |
2669 | - m_numSamplesOnLastSpeedCheck = 0; |
2670 | - m_silenceTime = 0; |
2671 | - setPreviousPos(m_startPos); |
2672 | - setPreviousScenePos(m_startScenePos); |
2673 | - updateSceneDirectionVector(); |
2674 | - |
2675 | - if (recognitionIsDisabled()) { |
2676 | - // Behave like a dumb TouchArea |
2677 | - ddaDebug("Gesture recognition is disabled. Requesting touch ownership immediately."); |
2678 | - TouchRegistry::instance()->requestTouchOwnership(m_touchId, this); |
2679 | - setStatus(Recognized); |
2680 | - event->accept(); |
2681 | - } else { |
2682 | - // just monitor the touch points for now. |
2683 | - TouchRegistry::instance()->addCandidateOwnerForTouch(m_touchId, this); |
2684 | - |
2685 | - setStatus(Undecided); |
2686 | - // Let the item below have it. We will monitor it and grab it later if a gesture |
2687 | - // gets recognized. |
2688 | - event->ignore(); |
2689 | - } |
2690 | - } else { |
2691 | - watchPressedTouchPoints(touchPoints); |
2692 | - event->ignore(); |
2693 | - } |
2694 | -} |
2695 | - |
2696 | -void DirectionalDragArea::touchEvent_undecided(QTouchEvent *event) |
2697 | -{ |
2698 | - Q_ASSERT(event->type() == QEvent::TouchBegin); |
2699 | - Q_ASSERT(fetchTargetTouchPoint(event) == nullptr); |
2700 | - |
2701 | - // We're not interested in new touch points. We already have our candidate (m_touchId). |
2702 | - // But we do want to know when those new touches end for keeping the composition time |
2703 | - // window up-to-date |
2704 | - event->ignore(); |
2705 | - watchPressedTouchPoints(event->touchPoints()); |
2706 | - |
2707 | - if (event->touchPointStates().testFlag(Qt::TouchPointPressed) && isWithinTouchCompositionWindow()) { |
2708 | - // multi-finger drags are not accepted |
2709 | - ddaDebug("Multi-finger drags are not accepted"); |
2710 | - |
2711 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2712 | - // We still wanna know when it ends for keeping the composition time window up-to-date |
2713 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2714 | - |
2715 | - setStatus(WaitingForTouch); |
2716 | - } |
2717 | -} |
2718 | - |
2719 | -void DirectionalDragArea::touchEvent_recognized(QTouchEvent *event) |
2720 | -{ |
2721 | - const QTouchEvent::TouchPoint *touchPoint = fetchTargetTouchPoint(event); |
2722 | - |
2723 | - if (!touchPoint) { |
2724 | - qCritical() << "DirectionalDragArea[status=Recognized]: touch " << m_touchId |
2725 | - << "missing from QTouchEvent without first reaching state Qt::TouchPointReleased. " |
2726 | - "Considering it as released."; |
2727 | - setStatus(WaitingForTouch); |
2728 | - } else { |
2729 | - setPreviousPos(touchPoint->pos()); |
2730 | - setPreviousScenePos(touchPoint->scenePos()); |
2731 | - |
2732 | - if (touchPoint->state() == Qt::TouchPointReleased) { |
2733 | - emitSignalIfTapped(); |
2734 | - setStatus(WaitingForTouch); |
2735 | - } |
2736 | - } |
2737 | -} |
2738 | - |
2739 | -void DirectionalDragArea::watchPressedTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints) |
2740 | -{ |
2741 | - for (int i = 0; i < touchPoints.count(); ++i) { |
2742 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
2743 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
2744 | - TouchRegistry::instance()->addTouchWatcher(touchPoint.id(), this); |
2745 | - } |
2746 | - } |
2747 | -} |
2748 | - |
2749 | -bool DirectionalDragArea::recognitionIsDisabled() const |
2750 | -{ |
2751 | - return distanceThreshold() <= 0 && compositionTime() <= 0; |
2752 | -} |
2753 | - |
2754 | -void DirectionalDragArea::emitSignalIfTapped() |
2755 | -{ |
2756 | - qint64 touchDuration = m_timeSource->msecsSinceReference() - m_activeTouches.touchStartTime(m_touchId); |
2757 | - if (touchDuration <= maxTapDuration()) { |
2758 | - Q_EMIT tapped(); |
2759 | - } |
2760 | -} |
2761 | - |
2762 | -const QTouchEvent::TouchPoint *DirectionalDragArea::fetchTargetTouchPoint(QTouchEvent *event) |
2763 | -{ |
2764 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
2765 | - const QTouchEvent::TouchPoint *touchPoint = 0; |
2766 | - for (int i = 0; i < touchPoints.size(); ++i) { |
2767 | - if (touchPoints.at(i).id() == m_touchId) { |
2768 | - touchPoint = &touchPoints.at(i); |
2769 | - break; |
2770 | - } |
2771 | - } |
2772 | - return touchPoint; |
2773 | -} |
2774 | - |
2775 | -bool DirectionalDragArea::pointInsideAllowedArea() const |
2776 | -{ |
2777 | - // NB: Using squared values to avoid computing the square root to find |
2778 | - // the length totalMovement |
2779 | - |
2780 | - QPointF totalMovement(m_dampedScenePos.x() - m_startScenePos.x(), |
2781 | - m_dampedScenePos.y() - m_startScenePos.y()); |
2782 | - |
2783 | - qreal squaredTotalMovSize = totalMovement.x() * totalMovement.x() + |
2784 | - totalMovement.y() * totalMovement.y(); |
2785 | - |
2786 | - if (squaredTotalMovSize == 0.) { |
2787 | - // didn't move |
2788 | - return true; |
2789 | - } |
2790 | - |
2791 | - qreal projectedMovement = projectOntoDirectionVector(totalMovement); |
2792 | - |
2793 | - |
2794 | - qreal cosineAngleSquared = (projectedMovement * projectedMovement) / squaredTotalMovSize; |
2795 | - |
2796 | - // Same as: |
2797 | - // angle_between_movement_vector_and_gesture_direction_vector <= widening_angle |
2798 | - return cosineAngleSquared >= m_wideningFactor; |
2799 | -} |
2800 | - |
2801 | -bool DirectionalDragArea::movingInRightDirection() const |
2802 | -{ |
2803 | - if (m_direction == Direction::Horizontal) { |
2804 | - return true; |
2805 | - } else { |
2806 | - QPointF movementVector(m_dampedScenePos.x() - m_previousDampedScenePos.x(), |
2807 | - m_dampedScenePos.y() - m_previousDampedScenePos.y()); |
2808 | - |
2809 | - qreal scalarProjection = projectOntoDirectionVector(movementVector); |
2810 | - |
2811 | - return scalarProjection >= 0.; |
2812 | - } |
2813 | -} |
2814 | - |
2815 | -bool DirectionalDragArea::movedFarEnough(const QPointF &point) const |
2816 | -{ |
2817 | - if (m_distanceThreshold <= 0.) { |
2818 | - // distance threshold check is disabled |
2819 | - return true; |
2820 | - } else { |
2821 | - QPointF totalMovement(point.x() - m_startScenePos.x(), |
2822 | - point.y() - m_startScenePos.y()); |
2823 | - |
2824 | - qreal squaredTotalMovSize = totalMovement.x() * totalMovement.x() + |
2825 | - totalMovement.y() * totalMovement.y(); |
2826 | - |
2827 | - return squaredTotalMovSize > m_distanceThresholdSquared; |
2828 | - } |
2829 | -} |
2830 | - |
2831 | -void DirectionalDragArea::checkSpeed() |
2832 | -{ |
2833 | - Q_ASSERT(m_status == Undecided); |
2834 | - |
2835 | - if (m_velocityCalculator->numSamples() >= AxisVelocityCalculator::MIN_SAMPLES_NEEDED) { |
2836 | - qreal speed = qFabs(m_velocityCalculator->calculate()); |
2837 | - qreal minSpeedMsecs = m_minSpeed / 1000.0; |
2838 | - |
2839 | - if (speed < minSpeedMsecs) { |
2840 | - ddaDebug("Rejecting gesture because it's below minimum speed."); |
2841 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2842 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2843 | - setStatus(WaitingForTouch); |
2844 | - } |
2845 | - } |
2846 | - |
2847 | - if (m_velocityCalculator->numSamples() == m_numSamplesOnLastSpeedCheck) { |
2848 | - m_silenceTime += m_recognitionTimer->interval(); |
2849 | - |
2850 | - if (m_silenceTime > m_maxSilenceTime) { |
2851 | - ddaDebug("Rejecting gesture because its silence time has been exceeded."); |
2852 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2853 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2854 | - setStatus(WaitingForTouch); |
2855 | - } |
2856 | - } else { |
2857 | - m_silenceTime = 0; |
2858 | - } |
2859 | - m_numSamplesOnLastSpeedCheck = m_velocityCalculator->numSamples(); |
2860 | -} |
2861 | - |
2862 | -void DirectionalDragArea::giveUpIfDisabledOrInvisible() |
2863 | -{ |
2864 | - if (!isEnabled() || !isVisible()) { |
2865 | - if (m_status == Undecided) { |
2866 | - TouchRegistry::instance()->removeCandidateOwnerForTouch(m_touchId, this); |
2867 | - // We still wanna know when it ends for keeping the composition time window up-to-date |
2868 | - TouchRegistry::instance()->addTouchWatcher(m_touchId, this); |
2869 | - } |
2870 | - |
2871 | - if (m_status != WaitingForTouch) { |
2872 | - ddaDebug("Resetting status because got disabled or made invisible"); |
2873 | - setStatus(WaitingForTouch); |
2874 | - } |
2875 | - } |
2876 | -} |
2877 | - |
2878 | -void DirectionalDragArea::setStatus(DirectionalDragArea::Status newStatus) |
2879 | -{ |
2880 | - if (newStatus == m_status) |
2881 | - return; |
2882 | - |
2883 | - DirectionalDragArea::Status oldStatus = m_status; |
2884 | - |
2885 | - if (oldStatus == Undecided) { |
2886 | - m_recognitionTimer->stop(); |
2887 | - } |
2888 | - |
2889 | - m_status = newStatus; |
2890 | - Q_EMIT statusChanged(m_status); |
2891 | - |
2892 | - ddaDebug(statusToString(oldStatus) << " -> " << statusToString(newStatus)); |
2893 | - |
2894 | - switch (newStatus) { |
2895 | - case WaitingForTouch: |
2896 | - Q_EMIT draggingChanged(false); |
2897 | - break; |
2898 | - case Undecided: |
2899 | - m_recognitionTimer->start(); |
2900 | - Q_EMIT draggingChanged(true); |
2901 | - break; |
2902 | - case Recognized: |
2903 | - if (oldStatus == WaitingForTouch) |
2904 | - Q_EMIT draggingChanged(true); |
2905 | - break; |
2906 | - default: |
2907 | - // no-op |
2908 | - break; |
2909 | - } |
2910 | -} |
2911 | - |
2912 | -void DirectionalDragArea::setPreviousPos(const QPointF &point) |
2913 | -{ |
2914 | - bool xChanged = m_previousPos.x() != point.x(); |
2915 | - bool yChanged = m_previousPos.y() != point.y(); |
2916 | - |
2917 | - m_previousPos = point; |
2918 | - |
2919 | - if (xChanged) { |
2920 | - Q_EMIT touchXChanged(point.x()); |
2921 | - if (Direction::isHorizontal(m_direction)) |
2922 | - Q_EMIT distanceChanged(distance()); |
2923 | - } |
2924 | - |
2925 | - if (yChanged) { |
2926 | - Q_EMIT touchYChanged(point.y()); |
2927 | - if (Direction::isVertical(m_direction)) |
2928 | - Q_EMIT distanceChanged(distance()); |
2929 | - } |
2930 | -} |
2931 | - |
2932 | -void DirectionalDragArea::setPreviousScenePos(const QPointF &point) |
2933 | -{ |
2934 | - bool xChanged = m_previousScenePos.x() != point.x(); |
2935 | - bool yChanged = m_previousScenePos.y() != point.y(); |
2936 | - |
2937 | - if (!xChanged && !yChanged) |
2938 | - return; |
2939 | - |
2940 | - qreal oldSceneDistance = sceneDistance(); |
2941 | - m_previousScenePos = point; |
2942 | - updateSceneDistance(); |
2943 | - |
2944 | - if (oldSceneDistance != sceneDistance()) { |
2945 | - Q_EMIT sceneDistanceChanged(sceneDistance()); |
2946 | - } |
2947 | - |
2948 | - if (xChanged) { |
2949 | - Q_EMIT touchSceneXChanged(point.x()); |
2950 | - } |
2951 | - |
2952 | - if (yChanged) { |
2953 | - Q_EMIT touchSceneYChanged(point.y()); |
2954 | - } |
2955 | -} |
2956 | - |
2957 | -void DirectionalDragArea::updateVelocityCalculator(const QPointF &scenePos) |
2958 | -{ |
2959 | - QPointF totalSceneMovement = scenePos - m_startScenePos; |
2960 | - |
2961 | - qreal scalarProjection = projectOntoDirectionVector(totalSceneMovement); |
2962 | - |
2963 | - m_velocityCalculator->setTrackedPosition(scalarProjection); |
2964 | -} |
2965 | - |
2966 | -bool DirectionalDragArea::isWithinTouchCompositionWindow() |
2967 | -{ |
2968 | - return |
2969 | - compositionTime() > 0 && |
2970 | - !m_activeTouches.isEmpty() && |
2971 | - m_timeSource->msecsSinceReference() <= |
2972 | - m_activeTouches.mostRecentStartTime() + (qint64)compositionTime(); |
2973 | -} |
2974 | - |
2975 | -//************************** ActiveTouchesInfo ************************** |
2976 | - |
2977 | -DirectionalDragArea::ActiveTouchesInfo::ActiveTouchesInfo(const SharedTimeSource &timeSource) |
2978 | - : m_timeSource(timeSource) |
2979 | -{ |
2980 | -} |
2981 | - |
2982 | -void DirectionalDragArea::ActiveTouchesInfo::update(QTouchEvent *event) |
2983 | -{ |
2984 | - if (!(event->touchPointStates() & (Qt::TouchPointPressed | Qt::TouchPointReleased))) { |
2985 | - // nothing to update |
2986 | - #if ACTIVETOUCHESINFO_DEBUG |
2987 | - qDebug("[DDA::ActiveTouchesInfo] Nothing to Update"); |
2988 | - #endif |
2989 | - return; |
2990 | - } |
2991 | - |
2992 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
2993 | - for (int i = 0; i < touchPoints.count(); ++i) { |
2994 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
2995 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
2996 | - addTouchPoint(touchPoint.id()); |
2997 | - } else if (touchPoint.state() == Qt::TouchPointReleased) { |
2998 | - removeTouchPoint(touchPoint.id()); |
2999 | - } |
3000 | - } |
3001 | -} |
3002 | - |
3003 | -#if ACTIVETOUCHESINFO_DEBUG |
3004 | -QString DirectionalDragArea::ActiveTouchesInfo::toString() |
3005 | -{ |
3006 | - QString string = "("; |
3007 | - |
3008 | - { |
3009 | - QTextStream stream(&string); |
3010 | - m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) { |
3011 | - stream << "(id=" << touchInfo->id << ",startTime=" << touchInfo->startTime << ")"; |
3012 | - return true; |
3013 | - }); |
3014 | - } |
3015 | - |
3016 | - string.append(")"); |
3017 | - |
3018 | - return string; |
3019 | -} |
3020 | -#endif // ACTIVETOUCHESINFO_DEBUG |
3021 | - |
3022 | -void DirectionalDragArea::ActiveTouchesInfo::addTouchPoint(int touchId) |
3023 | -{ |
3024 | - ActiveTouchInfo &activeTouchInfo = m_touchInfoPool.getEmptySlot(); |
3025 | - activeTouchInfo.id = touchId; |
3026 | - activeTouchInfo.startTime = m_timeSource->msecsSinceReference(); |
3027 | - |
3028 | - #if ACTIVETOUCHESINFO_DEBUG |
3029 | - qDebug() << "[DDA::ActiveTouchesInfo]" << qPrintable(toString()); |
3030 | - #endif |
3031 | -} |
3032 | - |
3033 | -qint64 DirectionalDragArea::ActiveTouchesInfo::touchStartTime(int touchId) |
3034 | -{ |
3035 | - qint64 result = -1; |
3036 | - |
3037 | - m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) { |
3038 | - if (touchId == touchInfo->id) { |
3039 | - result = touchInfo->startTime; |
3040 | - return false; |
3041 | - } else { |
3042 | - return true; |
3043 | - } |
3044 | - }); |
3045 | - |
3046 | - Q_ASSERT(result != -1); |
3047 | - return result; |
3048 | -} |
3049 | - |
3050 | -void DirectionalDragArea::ActiveTouchesInfo::removeTouchPoint(int touchId) |
3051 | -{ |
3052 | - m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &touchInfo) { |
3053 | - if (touchId == touchInfo->id) { |
3054 | - m_touchInfoPool.freeSlot(touchInfo); |
3055 | - return false; |
3056 | - } else { |
3057 | - return true; |
3058 | - } |
3059 | - }); |
3060 | - |
3061 | - #if ACTIVETOUCHESINFO_DEBUG |
3062 | - qDebug() << "[DDA::ActiveTouchesInfo]" << qPrintable(toString()); |
3063 | - #endif |
3064 | -} |
3065 | - |
3066 | -qint64 DirectionalDragArea::ActiveTouchesInfo::mostRecentStartTime() |
3067 | -{ |
3068 | - Q_ASSERT(!m_touchInfoPool.isEmpty()); |
3069 | - |
3070 | - qint64 highestStartTime = -1; |
3071 | - |
3072 | - m_touchInfoPool.forEach([&](Pool<ActiveTouchInfo>::Iterator &activeTouchInfo) { |
3073 | - if (activeTouchInfo->startTime > highestStartTime) { |
3074 | - highestStartTime = activeTouchInfo->startTime; |
3075 | - } |
3076 | - return true; |
3077 | - }); |
3078 | - |
3079 | - return highestStartTime; |
3080 | -} |
3081 | - |
3082 | -void DirectionalDragArea::updateSceneDirectionVector() |
3083 | -{ |
3084 | - QPointF localOrigin(0., 0.); |
3085 | - QPointF localDirection; |
3086 | - switch (m_direction) { |
3087 | - case Direction::Upwards: |
3088 | - localDirection.rx() = 0.; |
3089 | - localDirection.ry() = -1.; |
3090 | - break; |
3091 | - case Direction::Downwards: |
3092 | - localDirection.rx() = 0.; |
3093 | - localDirection.ry() = 1; |
3094 | - break; |
3095 | - case Direction::Leftwards: |
3096 | - localDirection.rx() = -1.; |
3097 | - localDirection.ry() = 0.; |
3098 | - break; |
3099 | - default: // Direction::Rightwards || Direction.Horizontal |
3100 | - localDirection.rx() = 1.; |
3101 | - localDirection.ry() = 0.; |
3102 | - break; |
3103 | - } |
3104 | - QPointF sceneOrigin = mapToScene(localOrigin); |
3105 | - QPointF sceneDirection = mapToScene(localDirection); |
3106 | - m_sceneDirectionVector = sceneDirection - sceneOrigin; |
3107 | -} |
3108 | - |
3109 | -qreal DirectionalDragArea::projectOntoDirectionVector(const QPointF &sceneVector) const |
3110 | -{ |
3111 | - // same as dot product as m_sceneDirectionVector is a unit vector |
3112 | - return sceneVector.x() * m_sceneDirectionVector.x() + |
3113 | - sceneVector.y() * m_sceneDirectionVector.y(); |
3114 | -} |
3115 | |
3116 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.h' |
3117 | --- src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.h 2015-02-04 10:56:38 +0000 |
3118 | +++ src/app/unity8/plugins/Ubuntu/Gestures/DirectionalDragArea.h 1970-01-01 00:00:00 +0000 |
3119 | @@ -1,308 +0,0 @@ |
3120 | -/* |
3121 | - * Copyright (C) 2013,2014 Canonical, Ltd. |
3122 | - * |
3123 | - * This program is free software; you can redistribute it and/or modify |
3124 | - * it under the terms of the GNU General Public License as published by |
3125 | - * the Free Software Foundation; version 3. |
3126 | - * |
3127 | - * This program is distributed in the hope that it will be useful, |
3128 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3129 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3130 | - * GNU General Public License for more details. |
3131 | - * |
3132 | - * You should have received a copy of the GNU General Public License |
3133 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3134 | - */ |
3135 | - |
3136 | -#ifndef DIRECTIONAL_DRAG_AREA_H |
3137 | -#define DIRECTIONAL_DRAG_AREA_H |
3138 | - |
3139 | -#include <QtQuick/QQuickItem> |
3140 | -#include "AxisVelocityCalculator.h" |
3141 | -#include "UbuntuGesturesQmlGlobal.h" |
3142 | -#include "Damper.h" |
3143 | -#include "Direction.h" |
3144 | - |
3145 | -// lib UbuntuGestures |
3146 | -#include <Pool.h> |
3147 | -#include <Timer.h> |
3148 | - |
3149 | -class TouchOwnershipEvent; |
3150 | -class UnownedTouchEvent; |
3151 | - |
3152 | -/* |
3153 | - An area that detects axis-aligned single-finger drag gestures |
3154 | - |
3155 | - If a drag deviates too much from the components' direction recognition will |
3156 | - fail. It will also fail if the drag or flick is too short. E.g. a noisy or |
3157 | - fidgety click |
3158 | - |
3159 | - See doc/DirectionalDragArea.svg |
3160 | - */ |
3161 | -class UBUNTUGESTURESQML_EXPORT DirectionalDragArea : public QQuickItem { |
3162 | - Q_OBJECT |
3163 | - |
3164 | - // The direction in which the gesture should move in order to be recognized. |
3165 | - Q_PROPERTY(Direction::Type direction READ direction WRITE setDirection NOTIFY directionChanged) |
3166 | - |
3167 | - // The distance travelled by the finger along the axis specified by |
3168 | - // DirectionalDragArea's direction. |
3169 | - Q_PROPERTY(qreal distance READ distance NOTIFY distanceChanged) |
3170 | - |
3171 | - // The distance travelled by the finger along the axis specified by |
3172 | - // DirectionalDragArea's direction in scene coordinates |
3173 | - Q_PROPERTY(qreal sceneDistance READ sceneDistance NOTIFY sceneDistanceChanged) |
3174 | - |
3175 | - // Position of the touch point performing the drag relative to this item. |
3176 | - Q_PROPERTY(qreal touchX READ touchX NOTIFY touchXChanged) |
3177 | - Q_PROPERTY(qreal touchY READ touchY NOTIFY touchYChanged) |
3178 | - |
3179 | - // Position of the touch point performing the drag, in scene's coordinate system |
3180 | - Q_PROPERTY(qreal touchSceneX READ touchSceneX NOTIFY touchSceneXChanged) |
3181 | - Q_PROPERTY(qreal touchSceneY READ touchSceneY NOTIFY touchSceneYChanged) |
3182 | - |
3183 | - // The current status of the directional drag gesture area. |
3184 | - Q_PROPERTY(Status status READ status NOTIFY statusChanged) |
3185 | - |
3186 | - // Whether a drag gesture is taking place |
3187 | - // This will be true as long as status is Undecided or Recognized |
3188 | - // When a gesture gets rejected, dragging turns to false. |
3189 | - Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged) |
3190 | - |
3191 | - ///// |
3192 | - // stuff that will be set in stone at some point |
3193 | - |
3194 | - // How far the touch point can move away from its expected position before |
3195 | - // it causes a rejection in the gesture recognition. This is to compensate |
3196 | - // for both noise in the touch input signal and for the natural irregularities |
3197 | - // in the finger movement. |
3198 | - // Proper value is likely device-specific. |
3199 | - Q_PROPERTY(qreal maxDeviation READ maxDeviation WRITE setMaxDeviation NOTIFY maxDeviationChanged) |
3200 | - |
3201 | - // Widening angle, in degrees |
3202 | - // It's roughly the maximum angle a touch point can make relative to the |
3203 | - // axis defined by the compoment's direction for it to be recognized as a |
3204 | - // directional drag. |
3205 | - Q_PROPERTY(qreal wideningAngle READ wideningAngle WRITE setWideningAngle |
3206 | - NOTIFY wideningAngleChanged) |
3207 | - |
3208 | - // How far a touch point has to move from its initial position in order for |
3209 | - // it to be recognized as a directional drag. |
3210 | - Q_PROPERTY(qreal distanceThreshold READ distanceThreshold WRITE setDistanceThreshold |
3211 | - NOTIFY distanceThresholdChanged) |
3212 | - |
3213 | - // Minimum speed a gesture needs to have in order to be recognized as a |
3214 | - // directional drag. |
3215 | - // In pixels per second |
3216 | - Q_PROPERTY(qreal minSpeed READ minSpeed WRITE setMinSpeed NOTIFY minSpeedChanged) |
3217 | - |
3218 | - // A gesture will be rejected if more than maxSilenceTime milliseconds has |
3219 | - // passed since we last got an input event from it (during Undecided state). |
3220 | - // |
3221 | - // Silence (i.e., lack of new input events) doesn't necessarily mean that the user's |
3222 | - // finger is still (zero drag speed). In some cases the finger might be moving but |
3223 | - // the driver's high noise filtering might cause those silence periods, specially |
3224 | - // in the moments succeeding a press (talking about Galaxy Nexus here). |
3225 | - Q_PROPERTY(int maxSilenceTime READ maxSilenceTime |
3226 | - WRITE setMaxSilenceTime |
3227 | - NOTIFY maxSilenceTimeChanged) |
3228 | - |
3229 | - // |
3230 | - ///// |
3231 | - |
3232 | - // Maximum time (in milliseconds) after the start of a given touch point where |
3233 | - // subsequent touch starts are grouped with the first one into an N-touches gesture |
3234 | - // (e.g. a two-fingers tap or drag). |
3235 | - Q_PROPERTY(int compositionTime READ compositionTime |
3236 | - WRITE setCompositionTime |
3237 | - NOTIFY compositionTimeChanged) |
3238 | - |
3239 | - Q_ENUMS(Direction) |
3240 | - Q_ENUMS(Status) |
3241 | -public: |
3242 | - DirectionalDragArea(QQuickItem *parent = 0); |
3243 | - |
3244 | - Direction::Type direction() const; |
3245 | - void setDirection(Direction::Type); |
3246 | - |
3247 | - // Describes the state of the directional drag gesture. |
3248 | - enum Status { |
3249 | - // Waiting for a new touch point to land on this area. No gesture is being processed |
3250 | - // or tracked. |
3251 | - WaitingForTouch, |
3252 | - |
3253 | - // A touch point has landed on this area but it's not know yet whether it is |
3254 | - // performing a drag in the correct direction. |
3255 | - // If it's decided that the touch point is not performing a directional drag gesture, |
3256 | - // it will be rejected/ignored and status will return to WaitingForTouch. |
3257 | - Undecided, //Recognizing, |
3258 | - |
3259 | - // There's a touch point in this area and it performed a drag in the correct |
3260 | - // direction. |
3261 | - // |
3262 | - // Once recognized, the gesture state will move back to WaitingForTouch only once |
3263 | - // that touch point ends. The gesture will remain in the Recognized state even if |
3264 | - // the touch point starts moving in other directions or halts. |
3265 | - Recognized, |
3266 | - }; |
3267 | - Status status() const { return m_status; } |
3268 | - |
3269 | - qreal distance() const; |
3270 | - qreal sceneDistance() const; |
3271 | - void updateSceneDistance(); |
3272 | - |
3273 | - qreal touchX() const; |
3274 | - qreal touchY() const; |
3275 | - |
3276 | - qreal touchSceneX() const; |
3277 | - qreal touchSceneY() const; |
3278 | - |
3279 | - bool dragging() const { return (m_status == Undecided) || (m_status == Recognized); } |
3280 | - |
3281 | - qreal maxDeviation() const { return m_dampedScenePos.maxDelta(); } |
3282 | - void setMaxDeviation(qreal value); |
3283 | - |
3284 | - qreal wideningAngle() const; |
3285 | - void setWideningAngle(qreal value); |
3286 | - |
3287 | - qreal distanceThreshold() const { return m_distanceThreshold; } |
3288 | - void setDistanceThreshold(qreal value); |
3289 | - |
3290 | - qreal minSpeed() const { return m_minSpeed; } |
3291 | - void setMinSpeed(qreal value); |
3292 | - |
3293 | - int maxSilenceTime() const { return m_maxSilenceTime; } |
3294 | - void setMaxSilenceTime(int value); |
3295 | - |
3296 | - int compositionTime() const { return m_compositionTime; } |
3297 | - void setCompositionTime(int value); |
3298 | - |
3299 | - // Replaces the existing Timer with the given one. |
3300 | - // |
3301 | - // Useful for providing a fake timer when testing. |
3302 | - void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer); |
3303 | - |
3304 | - // Useful for testing, where a fake time source can be supplied |
3305 | - void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource); |
3306 | - |
3307 | - bool event(QEvent *e) override; |
3308 | - |
3309 | - // Maximum time, in milliseconds, between a press and a release, for a touch |
3310 | - // sequence to be considered a tap. |
3311 | - int maxTapDuration() const { return 300; } |
3312 | - |
3313 | -Q_SIGNALS: |
3314 | - void directionChanged(Direction::Type direction); |
3315 | - void statusChanged(Status value); |
3316 | - void draggingChanged(bool value); |
3317 | - void distanceChanged(qreal value); |
3318 | - void sceneDistanceChanged(qreal value); |
3319 | - void maxDeviationChanged(qreal value); |
3320 | - void wideningAngleChanged(qreal value); |
3321 | - void distanceThresholdChanged(qreal value); |
3322 | - void minSpeedChanged(qreal value); |
3323 | - void maxSilenceTimeChanged(int value); |
3324 | - void compositionTimeChanged(int value); |
3325 | - void touchXChanged(qreal value); |
3326 | - void touchYChanged(qreal value); |
3327 | - void touchSceneXChanged(qreal value); |
3328 | - void touchSceneYChanged(qreal value); |
3329 | - |
3330 | - // TODO: I would rather not have such signal as it has nothing to do with drag gestures. |
3331 | - // Remove when no longer used or move its implementation to the QML code that uses it |
3332 | - // See maxTapDuration() |
3333 | - void tapped(); |
3334 | - |
3335 | -protected: |
3336 | - virtual void touchEvent(QTouchEvent *event); |
3337 | - |
3338 | -private Q_SLOTS: |
3339 | - void checkSpeed(); |
3340 | - void giveUpIfDisabledOrInvisible(); |
3341 | - |
3342 | -private: |
3343 | - void touchEvent_absent(QTouchEvent *event); |
3344 | - void touchEvent_undecided(QTouchEvent *event); |
3345 | - void touchEvent_recognized(QTouchEvent *event); |
3346 | - bool pointInsideAllowedArea() const; |
3347 | - bool movingInRightDirection() const; |
3348 | - bool movedFarEnough(const QPointF &point) const; |
3349 | - const QTouchEvent::TouchPoint *fetchTargetTouchPoint(QTouchEvent *event); |
3350 | - void setStatus(Status newStatus); |
3351 | - void setPreviousPos(const QPointF &point); |
3352 | - void setPreviousScenePos(const QPointF &point); |
3353 | - void updateVelocityCalculator(const QPointF &point); |
3354 | - bool isWithinTouchCompositionWindow(); |
3355 | - void updateSceneDirectionVector(); |
3356 | - // returns the scalar projection between the given vector (in scene coordinates) |
3357 | - // and m_sceneDirectionVector |
3358 | - qreal projectOntoDirectionVector(const QPointF &sceneVector) const; |
3359 | - void touchOwnershipEvent(TouchOwnershipEvent *event); |
3360 | - void unownedTouchEvent(UnownedTouchEvent *event); |
3361 | - void unownedTouchEvent_undecided(UnownedTouchEvent *unownedTouchEvent); |
3362 | - void watchPressedTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints); |
3363 | - bool recognitionIsDisabled() const; |
3364 | - void emitSignalIfTapped(); |
3365 | - |
3366 | - Status m_status; |
3367 | - |
3368 | - QPointF m_startPos; |
3369 | - QPointF m_startScenePos; |
3370 | - QPointF m_previousPos; |
3371 | - QPointF m_previousScenePos; |
3372 | - qreal m_sceneDistance; |
3373 | - int m_touchId; |
3374 | - |
3375 | - // A movement damper is used in some of the gesture recognition calculations |
3376 | - // to get rid of noise or small oscillations in the touch position. |
3377 | - DampedPointF m_dampedScenePos; |
3378 | - QPointF m_previousDampedScenePos; |
3379 | - |
3380 | - // Unit vector in scene coordinates describing the direction of the gesture recognition |
3381 | - QPointF m_sceneDirectionVector; |
3382 | - |
3383 | - Direction::Type m_direction; |
3384 | - qreal m_wideningAngle; // in degrees |
3385 | - qreal m_wideningFactor; // it's pow(cosine(m_wideningAngle), 2) |
3386 | - qreal m_distanceThreshold; |
3387 | - qreal m_distanceThresholdSquared; // it's pow(m_distanceThreshold, 2) |
3388 | - qreal m_minSpeed; |
3389 | - int m_maxSilenceTime; // in milliseconds |
3390 | - int m_silenceTime; // in milliseconds |
3391 | - int m_compositionTime; // in milliseconds |
3392 | - int m_numSamplesOnLastSpeedCheck; |
3393 | - UbuntuGestures::AbstractTimer *m_recognitionTimer; |
3394 | - AxisVelocityCalculator *m_velocityCalculator; |
3395 | - |
3396 | - UbuntuGestures::SharedTimeSource m_timeSource; |
3397 | - |
3398 | - // Information about an active touch point |
3399 | - struct ActiveTouchInfo { |
3400 | - ActiveTouchInfo() : id(-1), startTime(-1) {} |
3401 | - bool isValid() const { return id != -1; } |
3402 | - void reset() { id = -1; } |
3403 | - int id; |
3404 | - qint64 startTime; |
3405 | - }; |
3406 | - class ActiveTouchesInfo { |
3407 | - public: |
3408 | - ActiveTouchesInfo(const UbuntuGestures::SharedTimeSource &timeSource); |
3409 | - void update(QTouchEvent *event); |
3410 | - qint64 touchStartTime(int id); |
3411 | - bool isEmpty() const { return m_touchInfoPool.isEmpty(); } |
3412 | - qint64 mostRecentStartTime(); |
3413 | - UbuntuGestures::SharedTimeSource m_timeSource; |
3414 | - private: |
3415 | - void addTouchPoint(int touchId); |
3416 | - void removeTouchPoint(int touchId); |
3417 | - #if ACTIVETOUCHESINFO_DEBUG |
3418 | - QString toString(); |
3419 | - #endif |
3420 | - |
3421 | - Pool<ActiveTouchInfo> m_touchInfoPool; |
3422 | - } m_activeTouches; |
3423 | - |
3424 | - friend class tst_DirectionalDragArea; |
3425 | -}; |
3426 | - |
3427 | -#endif // DIRECTIONAL_DRAG_AREA_H |
3428 | |
3429 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/Gestures.qmltypes' |
3430 | --- src/app/unity8/plugins/Ubuntu/Gestures/Gestures.qmltypes 2015-03-17 15:14:11 +0000 |
3431 | +++ src/app/unity8/plugins/Ubuntu/Gestures/Gestures.qmltypes 1970-01-01 00:00:00 +0000 |
3432 | @@ -1,168 +0,0 @@ |
3433 | -import QtQuick.tooling 1.1 |
3434 | - |
3435 | -// This file describes the plugin-supplied types contained in the library. |
3436 | -// It is used for QML tooling purposes only. |
3437 | -// |
3438 | -// This file was auto-generated by: |
3439 | -// 'qmlplugindump -notrelocatable Ubuntu.Gestures 0.1 plugins' |
3440 | - |
3441 | -Module { |
3442 | - Component { |
3443 | - name: "AxisVelocityCalculator" |
3444 | - prototype: "QObject" |
3445 | - exports: ["Ubuntu.Gestures/AxisVelocityCalculator 0.1"] |
3446 | - exportMetaObjectRevisions: [0] |
3447 | - Property { name: "trackedPosition"; type: "double" } |
3448 | - Signal { |
3449 | - name: "trackedPositionChanged" |
3450 | - Parameter { name: "value"; type: "double" } |
3451 | - } |
3452 | - Method { name: "calculate"; type: "double" } |
3453 | - Method { name: "reset" } |
3454 | - } |
3455 | - Component { |
3456 | - name: "Direction" |
3457 | - prototype: "QObject" |
3458 | - exports: ["Ubuntu.Gestures/Direction 0.1"] |
3459 | - isCreatable: false |
3460 | - isSingleton: true |
3461 | - exportMetaObjectRevisions: [0] |
3462 | - Enum { |
3463 | - name: "Type" |
3464 | - values: { |
3465 | - "Rightwards": 0, |
3466 | - "Leftwards": 1, |
3467 | - "Downwards": 2, |
3468 | - "Upwards": 3, |
3469 | - "Horizontal": 4 |
3470 | - } |
3471 | - } |
3472 | - Method { |
3473 | - name: "isHorizontal" |
3474 | - type: "bool" |
3475 | - Parameter { name: "type"; type: "Direction::Type" } |
3476 | - } |
3477 | - Method { |
3478 | - name: "isVertical" |
3479 | - type: "bool" |
3480 | - Parameter { name: "type"; type: "Direction::Type" } |
3481 | - } |
3482 | - Method { |
3483 | - name: "isPositive" |
3484 | - type: "bool" |
3485 | - Parameter { name: "type"; type: "Direction::Type" } |
3486 | - } |
3487 | - } |
3488 | - Component { |
3489 | - name: "DirectionalDragArea" |
3490 | - defaultProperty: "data" |
3491 | - prototype: "QQuickItem" |
3492 | - exports: ["Ubuntu.Gestures/DirectionalDragArea 0.1"] |
3493 | - exportMetaObjectRevisions: [0] |
3494 | - Enum { |
3495 | - name: "Status" |
3496 | - values: { |
3497 | - "WaitingForTouch": 0, |
3498 | - "Undecided": 1, |
3499 | - "Recognized": 2 |
3500 | - } |
3501 | - } |
3502 | - Property { name: "direction"; type: "Direction::Type" } |
3503 | - Property { name: "distance"; type: "double"; isReadonly: true } |
3504 | - Property { name: "sceneDistance"; type: "double"; isReadonly: true } |
3505 | - Property { name: "touchX"; type: "double"; isReadonly: true } |
3506 | - Property { name: "touchY"; type: "double"; isReadonly: true } |
3507 | - Property { name: "touchSceneX"; type: "double"; isReadonly: true } |
3508 | - Property { name: "touchSceneY"; type: "double"; isReadonly: true } |
3509 | - Property { name: "status"; type: "Status"; isReadonly: true } |
3510 | - Property { name: "dragging"; type: "bool"; isReadonly: true } |
3511 | - Property { name: "maxDeviation"; type: "double" } |
3512 | - Property { name: "wideningAngle"; type: "double" } |
3513 | - Property { name: "distanceThreshold"; type: "double" } |
3514 | - Property { name: "minSpeed"; type: "double" } |
3515 | - Property { name: "maxSilenceTime"; type: "int" } |
3516 | - Property { name: "compositionTime"; type: "int" } |
3517 | - Signal { |
3518 | - name: "directionChanged" |
3519 | - Parameter { name: "direction"; type: "Direction::Type" } |
3520 | - } |
3521 | - Signal { |
3522 | - name: "statusChanged" |
3523 | - Parameter { name: "value"; type: "Status" } |
3524 | - } |
3525 | - Signal { |
3526 | - name: "draggingChanged" |
3527 | - Parameter { name: "value"; type: "bool" } |
3528 | - } |
3529 | - Signal { |
3530 | - name: "distanceChanged" |
3531 | - Parameter { name: "value"; type: "double" } |
3532 | - } |
3533 | - Signal { |
3534 | - name: "sceneDistanceChanged" |
3535 | - Parameter { name: "value"; type: "double" } |
3536 | - } |
3537 | - Signal { |
3538 | - name: "maxDeviationChanged" |
3539 | - Parameter { name: "value"; type: "double" } |
3540 | - } |
3541 | - Signal { |
3542 | - name: "wideningAngleChanged" |
3543 | - Parameter { name: "value"; type: "double" } |
3544 | - } |
3545 | - Signal { |
3546 | - name: "distanceThresholdChanged" |
3547 | - Parameter { name: "value"; type: "double" } |
3548 | - } |
3549 | - Signal { |
3550 | - name: "minSpeedChanged" |
3551 | - Parameter { name: "value"; type: "double" } |
3552 | - } |
3553 | - Signal { |
3554 | - name: "maxSilenceTimeChanged" |
3555 | - Parameter { name: "value"; type: "int" } |
3556 | - } |
3557 | - Signal { |
3558 | - name: "compositionTimeChanged" |
3559 | - Parameter { name: "value"; type: "int" } |
3560 | - } |
3561 | - Signal { |
3562 | - name: "touchXChanged" |
3563 | - Parameter { name: "value"; type: "double" } |
3564 | - } |
3565 | - Signal { |
3566 | - name: "touchYChanged" |
3567 | - Parameter { name: "value"; type: "double" } |
3568 | - } |
3569 | - Signal { |
3570 | - name: "touchSceneXChanged" |
3571 | - Parameter { name: "value"; type: "double" } |
3572 | - } |
3573 | - Signal { |
3574 | - name: "touchSceneYChanged" |
3575 | - Parameter { name: "value"; type: "double" } |
3576 | - } |
3577 | - Signal { name: "tapped" } |
3578 | - } |
3579 | - Component { |
3580 | - name: "PressedOutsideNotifier" |
3581 | - defaultProperty: "data" |
3582 | - prototype: "QQuickItem" |
3583 | - exports: ["Ubuntu.Gestures/PressedOutsideNotifier 0.1"] |
3584 | - exportMetaObjectRevisions: [0] |
3585 | - Signal { name: "pressedOutside" } |
3586 | - } |
3587 | - Component { |
3588 | - name: "TouchGate" |
3589 | - defaultProperty: "data" |
3590 | - prototype: "QQuickItem" |
3591 | - exports: ["Ubuntu.Gestures/TouchGate 0.1"] |
3592 | - exportMetaObjectRevisions: [0] |
3593 | - Property { name: "targetItem"; type: "QQuickItem"; isPointer: true } |
3594 | - Signal { |
3595 | - name: "targetItemChanged" |
3596 | - Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
3597 | - } |
3598 | - Signal { name: "pressed" } |
3599 | - } |
3600 | -} |
3601 | |
3602 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp' |
3603 | --- src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp 2015-02-04 10:56:38 +0000 |
3604 | +++ src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp 1970-01-01 00:00:00 +0000 |
3605 | @@ -1,119 +0,0 @@ |
3606 | -/* |
3607 | - * Copyright (C) 2013 Canonical, Ltd. |
3608 | - * |
3609 | - * This program is free software; you can redistribute it and/or modify |
3610 | - * it under the terms of the GNU General Public License as published by |
3611 | - * the Free Software Foundation; version 3. |
3612 | - * |
3613 | - * This program is distributed in the hope that it will be useful, |
3614 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3615 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3616 | - * GNU General Public License for more details. |
3617 | - * |
3618 | - * You should have received a copy of the GNU General Public License |
3619 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3620 | - */ |
3621 | - |
3622 | -#include "PressedOutsideNotifier.h" |
3623 | - |
3624 | -#include <QMouseEvent> |
3625 | - |
3626 | -PressedOutsideNotifier::PressedOutsideNotifier(QQuickItem *parent) |
3627 | - : QQuickItem(parent) |
3628 | -{ |
3629 | - connect(this, &QQuickItem::enabledChanged, |
3630 | - this, &PressedOutsideNotifier::setupOrTearDownEventFiltering); |
3631 | - |
3632 | - m_signalEmissionTimer.setSingleShot(true); |
3633 | - m_signalEmissionTimer.setInterval(0); // times out on the next iteration of the event loop |
3634 | - connect(&m_signalEmissionTimer, &QTimer::timeout, |
3635 | - this, &PressedOutsideNotifier::pressedOutside); |
3636 | -} |
3637 | - |
3638 | -bool PressedOutsideNotifier::eventFilter(QObject *watched, QEvent *event) |
3639 | -{ |
3640 | - Q_UNUSED(watched); |
3641 | - Q_ASSERT(watched == m_filteredWindow); |
3642 | - |
3643 | - // We are already going to emit pressedOutside() anyway, thus no need |
3644 | - // for new checks. |
3645 | - // This case takes place when a QTouchEvent comes in and isn't handled by any item, |
3646 | - // causing QQuickWindow to synthesize a QMouseEvent out of it, which would |
3647 | - // be filtered by us as well and count as a second press, which is wrong. |
3648 | - if (m_signalEmissionTimer.isActive()) { |
3649 | - return false; |
3650 | - } |
3651 | - |
3652 | - switch (event->type()) { |
3653 | - case QEvent::MouseButtonPress: { |
3654 | - QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); |
3655 | - QPointF p = mapFromScene(mouseEvent->windowPos()); |
3656 | - if (!contains(p)) { |
3657 | - m_signalEmissionTimer.start(); |
3658 | - } |
3659 | - break; |
3660 | - } |
3661 | - case QEvent::TouchBegin: |
3662 | - processFilteredTouchBegin(static_cast<QTouchEvent*>(event)); |
3663 | - default: |
3664 | - break; |
3665 | - } |
3666 | - |
3667 | - // let the event be handled further |
3668 | - return false; |
3669 | -} |
3670 | - |
3671 | -void PressedOutsideNotifier::itemChange(ItemChange change, const ItemChangeData &value) |
3672 | -{ |
3673 | - if (change == QQuickItem::ItemSceneChange) { |
3674 | - setupOrTearDownEventFiltering(); |
3675 | - } |
3676 | - |
3677 | - QQuickItem::itemChange(change, value); |
3678 | -} |
3679 | - |
3680 | -void PressedOutsideNotifier::setupOrTearDownEventFiltering() |
3681 | -{ |
3682 | - if (isEnabled() && window()) { |
3683 | - setupEventFiltering(); |
3684 | - } else if (m_filteredWindow) { |
3685 | - tearDownEventFiltering(); |
3686 | - } |
3687 | -} |
3688 | - |
3689 | -void PressedOutsideNotifier::setupEventFiltering() |
3690 | -{ |
3691 | - QQuickWindow *currentWindow = window(); |
3692 | - Q_ASSERT(currentWindow != nullptr); |
3693 | - |
3694 | - if (currentWindow == m_filteredWindow) |
3695 | - return; |
3696 | - |
3697 | - if (m_filteredWindow) { |
3698 | - m_filteredWindow->removeEventFilter(this); |
3699 | - } |
3700 | - |
3701 | - currentWindow->installEventFilter(this); |
3702 | - m_filteredWindow = currentWindow; |
3703 | -} |
3704 | - |
3705 | -void PressedOutsideNotifier::tearDownEventFiltering() |
3706 | -{ |
3707 | - m_filteredWindow->removeEventFilter(this); |
3708 | - m_filteredWindow.clear(); |
3709 | -} |
3710 | - |
3711 | -void PressedOutsideNotifier::processFilteredTouchBegin(QTouchEvent *event) |
3712 | -{ |
3713 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
3714 | - for (int i = 0; i < touchPoints.count(); ++i) { |
3715 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
3716 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
3717 | - QPointF p = mapFromScene(touchPoint.pos()); |
3718 | - if (!contains(p)) { |
3719 | - m_signalEmissionTimer.start(); |
3720 | - return; |
3721 | - } |
3722 | - } |
3723 | - } |
3724 | -} |
3725 | |
3726 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.h' |
3727 | --- src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 2015-02-04 10:56:38 +0000 |
3728 | +++ src/app/unity8/plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 1970-01-01 00:00:00 +0000 |
3729 | @@ -1,62 +0,0 @@ |
3730 | -/* |
3731 | - * Copyright (C) 2013 Canonical, Ltd. |
3732 | - * |
3733 | - * This program is free software; you can redistribute it and/or modify |
3734 | - * it under the terms of the GNU General Public License as published by |
3735 | - * the Free Software Foundation; version 3. |
3736 | - * |
3737 | - * This program is distributed in the hope that it will be useful, |
3738 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3739 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3740 | - * GNU General Public License for more details. |
3741 | - * |
3742 | - * You should have received a copy of the GNU General Public License |
3743 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3744 | - */ |
3745 | - |
3746 | -#ifndef PRESSED_OUTSIDE_NOTIFIER_H |
3747 | -#define PRESSED_OUTSIDE_NOTIFIER_H |
3748 | - |
3749 | -#include <QQuickItem> |
3750 | - |
3751 | -#include <QQuickWindow> |
3752 | -#include <QPointer> |
3753 | -#include <QTimer> |
3754 | - |
3755 | -#include "UbuntuGesturesGlobal.h" |
3756 | - |
3757 | -/* |
3758 | - Notifies when a point, mouse or touch, is pressed outside its area. |
3759 | - |
3760 | - Only enable it while needed. |
3761 | - */ |
3762 | -class UBUNTUGESTURES_EXPORT PressedOutsideNotifier : public QQuickItem { |
3763 | - Q_OBJECT |
3764 | - |
3765 | -public: |
3766 | - PressedOutsideNotifier(QQuickItem * parent = nullptr); |
3767 | - |
3768 | - // From QObject |
3769 | - bool eventFilter(QObject *watched, QEvent *event) override; |
3770 | - |
3771 | -Q_SIGNALS: |
3772 | - void pressedOutside(); |
3773 | - |
3774 | -protected: |
3775 | - void itemChange(ItemChange change, const ItemChangeData &value) override; |
3776 | - |
3777 | -private Q_SLOTS: |
3778 | - void setupOrTearDownEventFiltering(); |
3779 | - |
3780 | -private: |
3781 | - void setupEventFiltering(); |
3782 | - void tearDownEventFiltering(); |
3783 | - void processFilteredTouchBegin(QTouchEvent *event); |
3784 | - |
3785 | - QPointer<QQuickWindow> m_filteredWindow; |
3786 | - |
3787 | - // Emits pressedOutside() signal on timeout |
3788 | - QTimer m_signalEmissionTimer; |
3789 | -}; |
3790 | - |
3791 | -#endif // PRESSED_OUTSIDE_NOTIFIER_H |
3792 | |
3793 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.cpp' |
3794 | --- src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.cpp 2015-02-04 10:56:38 +0000 |
3795 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.cpp 1970-01-01 00:00:00 +0000 |
3796 | @@ -1,49 +0,0 @@ |
3797 | -/* |
3798 | - * Copyright (C) 2013 - Canonical Ltd. |
3799 | - * |
3800 | - * This program is free software: you can redistribute it and/or modify it |
3801 | - * under the terms of the GNU Lesser General Public License, as |
3802 | - * published by the Free Software Foundation; either version 2.1 or 3.0 |
3803 | - * of the License. |
3804 | - * |
3805 | - * This program is distributed in the hope that it will be useful, but |
3806 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
3807 | - * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
3808 | - * PURPOSE. See the applicable version of the GNU Lesser General Public |
3809 | - * License for more details. |
3810 | - * |
3811 | - * You should have received a copy of both the GNU Lesser General Public |
3812 | - * License along with this program. If not, see <http://www.gnu.org/licenses/> |
3813 | - * |
3814 | - * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
3815 | - */ |
3816 | - |
3817 | -#include "TimeSource.h" |
3818 | - |
3819 | -#include <QElapsedTimer> |
3820 | - |
3821 | -namespace UbuntuGestures { |
3822 | -class RealTimeSourcePrivate { |
3823 | -public: |
3824 | - QElapsedTimer timer; |
3825 | -}; |
3826 | -} |
3827 | - |
3828 | -using namespace UbuntuGestures; |
3829 | - |
3830 | -RealTimeSource::RealTimeSource() |
3831 | - : UbuntuGestures::TimeSource() |
3832 | - , d(new RealTimeSourcePrivate) |
3833 | -{ |
3834 | - d->timer.start(); |
3835 | -} |
3836 | - |
3837 | -RealTimeSource::~RealTimeSource() |
3838 | -{ |
3839 | - delete d; |
3840 | -} |
3841 | - |
3842 | -qint64 RealTimeSource::msecsSinceReference() |
3843 | -{ |
3844 | - return d->timer.elapsed(); |
3845 | -} |
3846 | |
3847 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.h' |
3848 | --- src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.h 2015-02-04 10:56:38 +0000 |
3849 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TimeSource.h 1970-01-01 00:00:00 +0000 |
3850 | @@ -1,54 +0,0 @@ |
3851 | -/* |
3852 | - * Copyright (C) 2013 - Canonical Ltd. |
3853 | - * |
3854 | - * This program is free software: you can redistribute it and/or modify it |
3855 | - * under the terms of the GNU Lesser General Public License, as |
3856 | - * published by the Free Software Foundation; either version 2.1 or 3.0 |
3857 | - * of the License. |
3858 | - * |
3859 | - * This program is distributed in the hope that it will be useful, but |
3860 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
3861 | - * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
3862 | - * PURPOSE. See the applicable version of the GNU Lesser General Public |
3863 | - * License for more details. |
3864 | - * |
3865 | - * You should have received a copy of both the GNU Lesser General Public |
3866 | - * License along with this program. If not, see <http://www.gnu.org/licenses/> |
3867 | - * |
3868 | - * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
3869 | - */ |
3870 | - |
3871 | -#ifndef UBUNTUGESTURES_TIMESOURCE_H |
3872 | -#define UBUNTUGESTURES_TIMESOURCE_H |
3873 | - |
3874 | -#include "UbuntuGesturesQmlGlobal.h" |
3875 | -#include <QSharedPointer> |
3876 | - |
3877 | -namespace UbuntuGestures { |
3878 | -/* |
3879 | - Interface for a time source. |
3880 | - */ |
3881 | -class UBUNTUGESTURESQML_EXPORT TimeSource { |
3882 | -public: |
3883 | - virtual ~TimeSource() {} |
3884 | - /* Returns the current time in milliseconds since some reference time in the past. */ |
3885 | - virtual qint64 msecsSinceReference() = 0; |
3886 | -}; |
3887 | -typedef QSharedPointer<TimeSource> SharedTimeSource; |
3888 | - |
3889 | -/* |
3890 | - Implementation of a time source |
3891 | - */ |
3892 | -class RealTimeSourcePrivate; |
3893 | -class RealTimeSource : public TimeSource { |
3894 | -public: |
3895 | - RealTimeSource(); |
3896 | - virtual ~RealTimeSource(); |
3897 | - qint64 msecsSinceReference() override; |
3898 | -private: |
3899 | - RealTimeSourcePrivate *d; |
3900 | -}; |
3901 | - |
3902 | -} // namespace UbuntuGestures |
3903 | - |
3904 | -#endif // UBUNTUGESTURES_TIMESOURCE_H |
3905 | |
3906 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.cpp' |
3907 | --- src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.cpp 2015-02-04 10:56:38 +0000 |
3908 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.cpp 1970-01-01 00:00:00 +0000 |
3909 | @@ -1,367 +0,0 @@ |
3910 | -/* |
3911 | - * Copyright (C) 2014 Canonical, Ltd. |
3912 | - * |
3913 | - * This program is free software; you can redistribute it and/or modify |
3914 | - * it under the terms of the GNU General Public License as published by |
3915 | - * the Free Software Foundation; version 3. |
3916 | - * |
3917 | - * This program is distributed in the hope that it will be useful, |
3918 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3919 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3920 | - * GNU General Public License for more details. |
3921 | - * |
3922 | - * You should have received a copy of the GNU General Public License |
3923 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3924 | - */ |
3925 | - |
3926 | -#include "TouchDispatcher.h" |
3927 | - |
3928 | -#include <QGuiApplication> |
3929 | -#include <QScopedPointer> |
3930 | -#include <QStyleHints> |
3931 | - |
3932 | -#pragma GCC diagnostic push |
3933 | -#pragma GCC diagnostic ignored "-pedantic" |
3934 | -#include <private/qquickitem_p.h> |
3935 | -#pragma GCC diagnostic pop |
3936 | - |
3937 | -#define TOUCHDISPATCHER_DEBUG 0 |
3938 | - |
3939 | -#if TOUCHDISPATCHER_DEBUG |
3940 | -#include <DebugHelpers.h> |
3941 | -#endif |
3942 | - |
3943 | -TouchDispatcher::TouchDispatcher() |
3944 | - : m_status(NoActiveTouch) |
3945 | - , m_touchMouseId(-1) |
3946 | - , m_touchMousePressTimestamp(0) |
3947 | -{ |
3948 | -} |
3949 | - |
3950 | -void TouchDispatcher::setTargetItem(QQuickItem *target) |
3951 | -{ |
3952 | - if (target != m_targetItem) { |
3953 | - m_targetItem = target; |
3954 | - if (m_status != NoActiveTouch) { |
3955 | - qWarning("[TouchDispatcher] Changing target item in the middle of a touch stream"); |
3956 | - m_status = TargetRejectedTouches; |
3957 | - } |
3958 | - } |
3959 | -} |
3960 | - |
3961 | -void TouchDispatcher::dispatch(QEvent::Type eventType, |
3962 | - QTouchDevice *device, |
3963 | - Qt::KeyboardModifiers modifiers, |
3964 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
3965 | - QWindow *window, |
3966 | - ulong timestamp) |
3967 | -{ |
3968 | - if (m_targetItem.isNull()) { |
3969 | - qWarning("[TouchDispatcher] Cannot dispatch touch event because target item is null"); |
3970 | - return; |
3971 | - } |
3972 | - |
3973 | - if (eventType == QEvent::TouchBegin) { |
3974 | - dispatchTouchBegin(device, modifiers, touchPoints, window, timestamp); |
3975 | - |
3976 | - } else if (eventType == QEvent::TouchUpdate || eventType == QEvent::TouchEnd) { |
3977 | - |
3978 | - if (m_status == DeliveringTouchEvents) { |
3979 | - dispatchAsTouch(eventType, device, modifiers, touchPoints, window, timestamp); |
3980 | - } else if (m_status == DeliveringMouseEvents) { |
3981 | - dispatchAsMouse(device, modifiers, touchPoints, timestamp); |
3982 | - } else { |
3983 | - Q_ASSERT(m_status == TargetRejectedTouches); |
3984 | - #if TOUCHDISPATCHER_DEBUG |
3985 | - qDebug() << "[TouchDispatcher] Not dispatching touch event to" << m_targetItem.data() |
3986 | - << "because it already rejected the touch stream."; |
3987 | - #endif |
3988 | - // Do nothing |
3989 | - } |
3990 | - |
3991 | - if (eventType == QEvent::TouchEnd) { |
3992 | - m_status = NoActiveTouch; |
3993 | - m_touchMouseId = -1; |
3994 | - } |
3995 | - |
3996 | - } else { |
3997 | - // Should never happen |
3998 | - qCritical() << "[TouchDispatcher] Unexpected event type" << eventType; |
3999 | - Q_ASSERT(false); |
4000 | - return; |
4001 | - } |
4002 | -} |
4003 | - |
4004 | -void TouchDispatcher::dispatchTouchBegin( |
4005 | - QTouchDevice *device, |
4006 | - Qt::KeyboardModifiers modifiers, |
4007 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4008 | - QWindow *window, |
4009 | - ulong timestamp) |
4010 | -{ |
4011 | - Q_ASSERT(m_status == NoActiveTouch); |
4012 | - QQuickItem *targetItem = m_targetItem.data(); |
4013 | - |
4014 | - if (!targetItem->isEnabled() || !targetItem->isVisible()) { |
4015 | - #if TOUCHDISPATCHER_DEBUG |
4016 | - qDebug() << "[TouchDispatcher] Cannot dispatch touch event to" << targetItem |
4017 | - << "because it's disabled or invisible."; |
4018 | - #endif |
4019 | - return; |
4020 | - } |
4021 | - |
4022 | - // Map touch points to targetItem coordinates |
4023 | - QList<QTouchEvent::TouchPoint> targetTouchPoints = touchPoints; |
4024 | - transformTouchPoints(targetTouchPoints, QQuickItemPrivate::get(targetItem)->windowToItemTransform()); |
4025 | - |
4026 | - QScopedPointer<QTouchEvent> touchEvent( |
4027 | - createQTouchEvent(QEvent::TouchBegin, device, modifiers, targetTouchPoints, window, timestamp)); |
4028 | - |
4029 | - |
4030 | - #if TOUCHDISPATCHER_DEBUG |
4031 | - qDebug() << "[TouchDispatcher] dispatching" << qPrintable(touchEventToString(touchEvent.data())) |
4032 | - << "to" << targetItem; |
4033 | - #endif |
4034 | - QCoreApplication::sendEvent(targetItem, touchEvent.data()); |
4035 | - |
4036 | - |
4037 | - if (touchEvent->isAccepted()) { |
4038 | - #if TOUCHDISPATCHER_DEBUG |
4039 | - qDebug() << "[TouchDispatcher] Item accepted the touch event."; |
4040 | - #endif |
4041 | - m_status = DeliveringTouchEvents; |
4042 | - } else if (targetItem->acceptedMouseButtons() & Qt::LeftButton) { |
4043 | - #if TOUCHDISPATCHER_DEBUG |
4044 | - qDebug() << "[TouchDispatcher] Item rejected the touch event. Trying a QMouseEvent"; |
4045 | - #endif |
4046 | - // NB: Arbitrarily chose the first touch point to emulate the mouse pointer |
4047 | - QScopedPointer<QMouseEvent> mouseEvent( |
4048 | - touchToMouseEvent(QEvent::MouseButtonPress, targetTouchPoints.at(0), timestamp, |
4049 | - modifiers, false /* transformNeeded */)); |
4050 | - Q_ASSERT(targetTouchPoints.at(0).state() == Qt::TouchPointPressed); |
4051 | - |
4052 | - #if TOUCHDISPATCHER_DEBUG |
4053 | - qDebug() << "[TouchDispatcher] dispatching" << qPrintable(mouseEventToString(mouseEvent.data())) |
4054 | - << "to" << m_targetItem.data(); |
4055 | - #endif |
4056 | - QCoreApplication::sendEvent(targetItem, mouseEvent.data()); |
4057 | - if (mouseEvent->isAccepted()) { |
4058 | - #if TOUCHDISPATCHER_DEBUG |
4059 | - qDebug() << "[TouchDispatcher] Item accepted the QMouseEvent."; |
4060 | - #endif |
4061 | - m_status = DeliveringMouseEvents; |
4062 | - m_touchMouseId = targetTouchPoints.at(0).id(); |
4063 | - |
4064 | - if (checkIfDoubleClicked(timestamp)) { |
4065 | - QScopedPointer<QMouseEvent> doubleClickEvent( |
4066 | - touchToMouseEvent(QEvent::MouseButtonDblClick, targetTouchPoints.at(0), timestamp, |
4067 | - modifiers, false /* transformNeeded */)); |
4068 | - #if TOUCHDISPATCHER_DEBUG |
4069 | - qDebug() << "[TouchDispatcher] dispatching" << qPrintable(mouseEventToString(doubleClickEvent.data())) |
4070 | - << "to" << m_targetItem.data(); |
4071 | - #endif |
4072 | - QCoreApplication::sendEvent(targetItem, doubleClickEvent.data()); |
4073 | - } |
4074 | - |
4075 | - } else { |
4076 | - #if TOUCHDISPATCHER_DEBUG |
4077 | - qDebug() << "[TouchDispatcher] Item rejected the QMouseEvent."; |
4078 | - #endif |
4079 | - m_status = TargetRejectedTouches; |
4080 | - } |
4081 | - } else { |
4082 | - #if TOUCHDISPATCHER_DEBUG |
4083 | - qDebug() << "[TouchDispatcher] Item rejected the touch event and does not accept mouse buttons."; |
4084 | - #endif |
4085 | - m_status = TargetRejectedTouches; |
4086 | - } |
4087 | -} |
4088 | - |
4089 | -void TouchDispatcher::dispatchAsTouch(QEvent::Type eventType, |
4090 | - QTouchDevice *device, |
4091 | - Qt::KeyboardModifiers modifiers, |
4092 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4093 | - QWindow *window, |
4094 | - ulong timestamp) |
4095 | -{ |
4096 | - QQuickItem *targetItem = m_targetItem.data(); |
4097 | - |
4098 | - // Map touch points to targetItem coordinates |
4099 | - QList<QTouchEvent::TouchPoint> targetTouchPoints = touchPoints; |
4100 | - transformTouchPoints(targetTouchPoints, QQuickItemPrivate::get(targetItem)->windowToItemTransform()); |
4101 | - |
4102 | - QScopedPointer<QTouchEvent> eventForTargetItem( |
4103 | - createQTouchEvent(eventType, device, modifiers, targetTouchPoints, window, timestamp)); |
4104 | - |
4105 | - |
4106 | - #if TOUCHDISPATCHER_DEBUG |
4107 | - qDebug() << "[TouchDispatcher] dispatching" << qPrintable(touchEventToString(eventForTargetItem.data())) |
4108 | - << "to" << targetItem; |
4109 | - #endif |
4110 | - QCoreApplication::sendEvent(targetItem, eventForTargetItem.data()); |
4111 | -} |
4112 | - |
4113 | -void TouchDispatcher::dispatchAsMouse( |
4114 | - QTouchDevice * /*device*/, |
4115 | - Qt::KeyboardModifiers modifiers, |
4116 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4117 | - ulong timestamp) |
4118 | -{ |
4119 | - // TODO: Detect double clicks in order to synthesize QEvent::MouseButtonDblClick events accordingly |
4120 | - |
4121 | - Q_ASSERT(!touchPoints.isEmpty()); |
4122 | - |
4123 | - const QTouchEvent::TouchPoint *touchMouse = nullptr; |
4124 | - |
4125 | - if (m_touchMouseId != -1) { |
4126 | - for (int i = 0; i < touchPoints.count() && !touchMouse; ++i) { |
4127 | - const auto &touchPoint = touchPoints.at(i); |
4128 | - if (touchPoint.id() == m_touchMouseId) { |
4129 | - touchMouse = &touchPoint; |
4130 | - } |
4131 | - } |
4132 | - |
4133 | - Q_ASSERT(touchMouse); |
4134 | - if (!touchMouse) { |
4135 | - // should not happen, but deal with it just in case. |
4136 | - qWarning("[TouchDispatcher] Didn't find touch with id %d, used for mouse pointer emulation.", |
4137 | - m_touchMouseId); |
4138 | - m_touchMouseId = touchPoints.at(0).id(); |
4139 | - touchMouse = &touchPoints.at(0); |
4140 | - } |
4141 | - } else { |
4142 | - // Try to find a new touch for mouse emulation |
4143 | - for (int i = 0; i < touchPoints.count() && !touchMouse; ++i) { |
4144 | - const auto &touchPoint = touchPoints.at(i); |
4145 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
4146 | - touchMouse = &touchPoint; |
4147 | - m_touchMouseId = touchMouse->id(); |
4148 | - } |
4149 | - } |
4150 | - } |
4151 | - |
4152 | - if (touchMouse) { |
4153 | - QEvent::Type eventType; |
4154 | - if (touchMouse->state() == Qt::TouchPointPressed) { |
4155 | - eventType = QEvent::MouseButtonPress; |
4156 | - } if (touchMouse->state() == Qt::TouchPointReleased) { |
4157 | - eventType = QEvent::MouseButtonRelease; |
4158 | - m_touchMouseId = -1; |
4159 | - } else { |
4160 | - eventType = QEvent::MouseMove; |
4161 | - } |
4162 | - |
4163 | - QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(eventType, *touchMouse, timestamp, modifiers, |
4164 | - true /* transformNeeded */)); |
4165 | - |
4166 | - #if TOUCHDISPATCHER_DEBUG |
4167 | - qDebug() << "[TouchDispatcher] dispatching" << qPrintable(mouseEventToString(mouseEvent.data())) |
4168 | - << "to" << m_targetItem.data(); |
4169 | - #endif |
4170 | - QCoreApplication::sendEvent(m_targetItem.data(), mouseEvent.data()); |
4171 | - } |
4172 | -} |
4173 | - |
4174 | -QTouchEvent *TouchDispatcher::createQTouchEvent(QEvent::Type eventType, |
4175 | - QTouchDevice *device, |
4176 | - Qt::KeyboardModifiers modifiers, |
4177 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4178 | - QWindow *window, |
4179 | - ulong timestamp) |
4180 | -{ |
4181 | - Qt::TouchPointStates eventStates = 0; |
4182 | - for (int i = 0; i < touchPoints.count(); i++) |
4183 | - eventStates |= touchPoints[i].state(); |
4184 | - // if all points have the same state, set the event type accordingly |
4185 | - switch (eventStates) { |
4186 | - case Qt::TouchPointPressed: |
4187 | - eventType = QEvent::TouchBegin; |
4188 | - break; |
4189 | - case Qt::TouchPointReleased: |
4190 | - eventType = QEvent::TouchEnd; |
4191 | - break; |
4192 | - default: |
4193 | - eventType = QEvent::TouchUpdate; |
4194 | - break; |
4195 | - } |
4196 | - |
4197 | - QTouchEvent *touchEvent = new QTouchEvent(eventType); |
4198 | - touchEvent->setWindow(window); |
4199 | - touchEvent->setTarget(m_targetItem.data()); |
4200 | - touchEvent->setDevice(device); |
4201 | - touchEvent->setModifiers(modifiers); |
4202 | - touchEvent->setTouchPoints(touchPoints); |
4203 | - touchEvent->setTouchPointStates(eventStates); |
4204 | - touchEvent->setTimestamp(timestamp); |
4205 | - touchEvent->accept(); |
4206 | - return touchEvent; |
4207 | -} |
4208 | - |
4209 | -// NB: From QQuickWindow |
4210 | -void TouchDispatcher::transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform) |
4211 | -{ |
4212 | - QMatrix4x4 transformMatrix(transform); |
4213 | - for (int i=0; i<touchPoints.count(); i++) { |
4214 | - QTouchEvent::TouchPoint &touchPoint = touchPoints[i]; |
4215 | - touchPoint.setRect(transform.mapRect(touchPoint.sceneRect())); |
4216 | - touchPoint.setStartPos(transform.map(touchPoint.startScenePos())); |
4217 | - touchPoint.setLastPos(transform.map(touchPoint.lastScenePos())); |
4218 | - touchPoint.setVelocity(transformMatrix.mapVector(touchPoint.velocity()).toVector2D()); |
4219 | - } |
4220 | -} |
4221 | - |
4222 | -// Copied with minor modifications from qtdeclarative/src/quick/items/qquickwindow.cpp |
4223 | -QMouseEvent *TouchDispatcher::touchToMouseEvent( |
4224 | - QEvent::Type type, const QTouchEvent::TouchPoint &p, |
4225 | - ulong timestamp, Qt::KeyboardModifiers modifiers, |
4226 | - bool transformNeeded) |
4227 | -{ |
4228 | - QQuickItem *item = m_targetItem.data(); |
4229 | - |
4230 | - // The touch point local position and velocity are not yet transformed. |
4231 | - QMouseEvent *me = new QMouseEvent(type, transformNeeded ? item->mapFromScene(p.scenePos()) : p.pos(), |
4232 | - p.scenePos(), p.screenPos(), Qt::LeftButton, |
4233 | - (type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton), |
4234 | - modifiers); |
4235 | - me->setAccepted(true); |
4236 | - me->setTimestamp(timestamp); |
4237 | - QVector2D transformedVelocity = p.velocity(); |
4238 | - if (transformNeeded) { |
4239 | - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); |
4240 | - QMatrix4x4 transformMatrix(itemPrivate->windowToItemTransform()); |
4241 | - transformedVelocity = transformMatrix.mapVector(p.velocity()).toVector2D(); |
4242 | - } |
4243 | - |
4244 | - // Add these later if needed: |
4245 | - //QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, event->device()->capabilities(), transformedVelocity); |
4246 | - //QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt); |
4247 | - return me; |
4248 | -} |
4249 | - |
4250 | -/* |
4251 | - Copied from qquickwindow.cpp which has: |
4252 | - Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) |
4253 | - Under GPL 3.0 license. |
4254 | -*/ |
4255 | -bool TouchDispatcher::checkIfDoubleClicked(ulong newPressEventTimestamp) |
4256 | -{ |
4257 | - bool doubleClicked; |
4258 | - |
4259 | - if (m_touchMousePressTimestamp == 0) { |
4260 | - // just initialize the variable |
4261 | - m_touchMousePressTimestamp = newPressEventTimestamp; |
4262 | - doubleClicked = false; |
4263 | - } else { |
4264 | - ulong timeBetweenPresses = newPressEventTimestamp - m_touchMousePressTimestamp; |
4265 | - ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()-> |
4266 | - mouseDoubleClickInterval()); |
4267 | - doubleClicked = timeBetweenPresses < doubleClickInterval; |
4268 | - if (doubleClicked) { |
4269 | - m_touchMousePressTimestamp = 0; |
4270 | - } else { |
4271 | - m_touchMousePressTimestamp = newPressEventTimestamp; |
4272 | - } |
4273 | - } |
4274 | - |
4275 | - return doubleClicked; |
4276 | -} |
4277 | |
4278 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.h' |
4279 | --- src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.h 2015-02-04 10:56:38 +0000 |
4280 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TouchDispatcher.h 1970-01-01 00:00:00 +0000 |
4281 | @@ -1,89 +0,0 @@ |
4282 | -/* |
4283 | - * Copyright (C) 2014 Canonical, Ltd. |
4284 | - * |
4285 | - * This program is free software; you can redistribute it and/or modify |
4286 | - * it under the terms of the GNU General Public License as published by |
4287 | - * the Free Software Foundation; version 3. |
4288 | - * |
4289 | - * This program is distributed in the hope that it will be useful, |
4290 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4291 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4292 | - * GNU General Public License for more details. |
4293 | - * |
4294 | - * You should have received a copy of the GNU General Public License |
4295 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4296 | - */ |
4297 | - |
4298 | -#ifndef UBUNTU_TOUCH_DISPATCHER_H |
4299 | -#define UBUNTU_TOUCH_DISPATCHER_H |
4300 | - |
4301 | -#include "UbuntuGesturesQmlGlobal.h" |
4302 | - |
4303 | -#include <QPointer> |
4304 | -#include <QQuickItem> |
4305 | - |
4306 | -/* |
4307 | - Dispatches touches to the given target, converting the touch point |
4308 | - coordinates accordingly. |
4309 | - |
4310 | - Also takes care of synthesizing mouse events in case the target |
4311 | - doesn't work with touch events. |
4312 | - */ |
4313 | -class UBUNTUGESTURESQML_EXPORT TouchDispatcher { |
4314 | -public: |
4315 | - TouchDispatcher(); |
4316 | - |
4317 | - void setTargetItem(QQuickItem *target); |
4318 | - QQuickItem *targetItem() { return m_targetItem; } |
4319 | - |
4320 | - void dispatch(QEvent::Type eventType, |
4321 | - QTouchDevice *device, |
4322 | - Qt::KeyboardModifiers modifiers, |
4323 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4324 | - QWindow *window, |
4325 | - ulong timestamp); |
4326 | -private: |
4327 | - void dispatchTouchBegin( |
4328 | - QTouchDevice *device, |
4329 | - Qt::KeyboardModifiers modifiers, |
4330 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4331 | - QWindow *window, |
4332 | - ulong timestamp); |
4333 | - void dispatchAsTouch(QEvent::Type eventType, |
4334 | - QTouchDevice *device, |
4335 | - Qt::KeyboardModifiers modifiers, |
4336 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4337 | - QWindow *window, |
4338 | - ulong timestamp); |
4339 | - void dispatchAsMouse( |
4340 | - QTouchDevice *device, |
4341 | - Qt::KeyboardModifiers modifiers, |
4342 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4343 | - ulong timestamp); |
4344 | - |
4345 | - static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform); |
4346 | - QTouchEvent *createQTouchEvent(QEvent::Type eventType, |
4347 | - QTouchDevice *device, |
4348 | - Qt::KeyboardModifiers modifiers, |
4349 | - const QList<QTouchEvent::TouchPoint> &touchPoints, |
4350 | - QWindow *window, |
4351 | - ulong timestamp); |
4352 | - QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, |
4353 | - ulong timestamp, Qt::KeyboardModifiers modifiers, bool transformNeeded = true); |
4354 | - |
4355 | - bool checkIfDoubleClicked(ulong newPressEventTimestamp); |
4356 | - |
4357 | - QPointer<QQuickItem> m_targetItem; |
4358 | - |
4359 | - enum { |
4360 | - NoActiveTouch, |
4361 | - DeliveringTouchEvents, |
4362 | - DeliveringMouseEvents, |
4363 | - TargetRejectedTouches |
4364 | - } m_status; |
4365 | - |
4366 | - int m_touchMouseId; |
4367 | - ulong m_touchMousePressTimestamp; |
4368 | -}; |
4369 | - |
4370 | -#endif // UBUNTU_TOUCH_DISPATCHER_H |
4371 | |
4372 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.cpp' |
4373 | --- src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.cpp 2015-03-17 15:14:11 +0000 |
4374 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.cpp 1970-01-01 00:00:00 +0000 |
4375 | @@ -1,253 +0,0 @@ |
4376 | -/* |
4377 | - * Copyright (C) 2014 Canonical, Ltd. |
4378 | - * |
4379 | - * This program is free software; you can redistribute it and/or modify |
4380 | - * it under the terms of the GNU General Public License as published by |
4381 | - * the Free Software Foundation; version 3. |
4382 | - * |
4383 | - * This program is distributed in the hope that it will be useful, |
4384 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4385 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4386 | - * GNU General Public License for more details. |
4387 | - * |
4388 | - * You should have received a copy of the GNU General Public License |
4389 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4390 | - */ |
4391 | - |
4392 | -#include "TouchGate.h" |
4393 | - |
4394 | -#include <QCoreApplication> |
4395 | -#include <QDebug> |
4396 | - |
4397 | -#include <TouchOwnershipEvent.h> |
4398 | -#include <TouchRegistry.h> |
4399 | - |
4400 | -#if TOUCHGATE_DEBUG |
4401 | -#include <DebugHelpers.h> |
4402 | -#endif |
4403 | - |
4404 | -bool TouchGate::event(QEvent *e) |
4405 | -{ |
4406 | - if (e->type() == TouchOwnershipEvent::touchOwnershipEventType()) { |
4407 | - touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(e)); |
4408 | - return true; |
4409 | - } else { |
4410 | - return QQuickItem::event(e); |
4411 | - } |
4412 | -} |
4413 | - |
4414 | -void TouchGate::touchEvent(QTouchEvent *event) |
4415 | -{ |
4416 | - #if TOUCHGATE_DEBUG |
4417 | - qDebug() << "[TouchGate] got touch event" << qPrintable(touchEventToString(event)); |
4418 | - #endif |
4419 | - event->accept(); |
4420 | - |
4421 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
4422 | - bool goodToGo = true; |
4423 | - for (int i = 0; i < touchPoints.count(); ++i) { |
4424 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints[i]; |
4425 | - |
4426 | - if (touchPoint.state() == Qt::TouchPointPressed) { |
4427 | - Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id())); |
4428 | - m_touchInfoMap[touchPoint.id()].ownership = OwnershipRequested; |
4429 | - m_touchInfoMap[touchPoint.id()].ended = false; |
4430 | - TouchRegistry::instance()->requestTouchOwnership(touchPoint.id(), this); |
4431 | - |
4432 | - Q_EMIT pressed(); |
4433 | - } |
4434 | - |
4435 | - goodToGo &= m_touchInfoMap.contains(touchPoint.id()) |
4436 | - && m_touchInfoMap[touchPoint.id()].ownership == OwnershipGranted; |
4437 | - |
4438 | - if (touchPoint.state() == Qt::TouchPointReleased && m_touchInfoMap.contains(touchPoint.id())) { |
4439 | - m_touchInfoMap[touchPoint.id()].ended = true; |
4440 | - } |
4441 | - |
4442 | - } |
4443 | - |
4444 | - if (goodToGo) { |
4445 | - if (m_storedEvents.isEmpty()) { |
4446 | - // let it pass through |
4447 | - dispatchTouchEventToTarget(event); |
4448 | - } else { |
4449 | - // Retain the event to ensure TouchGate dispatches them in order. |
4450 | - // Otherwise the current event would come before the stored ones, which are older. |
4451 | - #if TOUCHGATE_DEBUG |
4452 | - qDebug("[TouchGate] Storing event because thouches %s are still pending ownership.", |
4453 | - qPrintable(oldestPendingTouchIdsString())); |
4454 | - #endif |
4455 | - storeTouchEvent(event); |
4456 | - } |
4457 | - } else { |
4458 | - // Retain events that have unowned touches |
4459 | - storeTouchEvent(event); |
4460 | - } |
4461 | -} |
4462 | - |
4463 | -void TouchGate::touchOwnershipEvent(TouchOwnershipEvent *event) |
4464 | -{ |
4465 | - // TODO: Optimization: batch those actions as TouchOwnershipEvents |
4466 | - // might come one right after the other. |
4467 | - |
4468 | - Q_ASSERT(m_touchInfoMap.contains(event->touchId())); |
4469 | - |
4470 | - TouchInfo &touchInfo = m_touchInfoMap[event->touchId()]; |
4471 | - |
4472 | - if (event->gained()) { |
4473 | - #if TOUCHGATE_DEBUG |
4474 | - qDebug() << "[TouchGate] Got ownership of touch " << event->touchId(); |
4475 | - #endif |
4476 | - touchInfo.ownership = OwnershipGranted; |
4477 | - } else { |
4478 | - #if TOUCHGATE_DEBUG |
4479 | - qDebug() << "[TouchGate] Lost ownership of touch " << event->touchId(); |
4480 | - #endif |
4481 | - m_touchInfoMap.remove(event->touchId()); |
4482 | - removeTouchFromStoredEvents(event->touchId()); |
4483 | - } |
4484 | - |
4485 | - dispatchFullyOwnedEvents(); |
4486 | -} |
4487 | - |
4488 | -bool TouchGate::isTouchPointOwned(int touchId) const |
4489 | -{ |
4490 | - return m_touchInfoMap[touchId].ownership == OwnershipGranted; |
4491 | -} |
4492 | - |
4493 | -void TouchGate::storeTouchEvent(const QTouchEvent *event) |
4494 | -{ |
4495 | - #if TOUCHGATE_DEBUG |
4496 | - qDebug() << "[TouchGate] Storing" << qPrintable(touchEventToString(event)); |
4497 | - #endif |
4498 | - |
4499 | - TouchEvent clonedEvent(event); |
4500 | - m_storedEvents.append(std::move(clonedEvent)); |
4501 | -} |
4502 | - |
4503 | -void TouchGate::removeTouchFromStoredEvents(int touchId) |
4504 | -{ |
4505 | - int i = 0; |
4506 | - while (i < m_storedEvents.count()) { |
4507 | - TouchEvent &event = m_storedEvents[i]; |
4508 | - bool removed = event.removeTouch(touchId); |
4509 | - |
4510 | - if (removed && event.touchPoints.isEmpty()) { |
4511 | - m_storedEvents.removeAt(i); |
4512 | - } else { |
4513 | - ++i; |
4514 | - } |
4515 | - } |
4516 | -} |
4517 | - |
4518 | -void TouchGate::dispatchFullyOwnedEvents() |
4519 | -{ |
4520 | - while (!m_storedEvents.isEmpty() && eventIsFullyOwned(m_storedEvents.first())) { |
4521 | - TouchEvent event = m_storedEvents.takeFirst(); |
4522 | - dispatchTouchEventToTarget(event); |
4523 | - } |
4524 | -} |
4525 | - |
4526 | -#if TOUCHGATE_DEBUG |
4527 | -QString TouchGate::oldestPendingTouchIdsString() |
4528 | -{ |
4529 | - Q_ASSERT(!m_storedEvents.isEmpty()); |
4530 | - |
4531 | - QString str; |
4532 | - |
4533 | - const auto &touchPoints = m_storedEvents.first().touchPoints; |
4534 | - for (int i = 0; i < touchPoints.count(); ++i) { |
4535 | - if (!isTouchPointOwned(touchPoints[i].id())) { |
4536 | - if (!str.isEmpty()) { |
4537 | - str.append(", "); |
4538 | - } |
4539 | - str.append(QString::number(touchPoints[i].id())); |
4540 | - } |
4541 | - } |
4542 | - |
4543 | - return str; |
4544 | -} |
4545 | -#endif |
4546 | - |
4547 | -bool TouchGate::eventIsFullyOwned(const TouchGate::TouchEvent &event) const |
4548 | -{ |
4549 | - for (int i = 0; i < event.touchPoints.count(); ++i) { |
4550 | - if (!isTouchPointOwned(event.touchPoints[i].id())) { |
4551 | - return false; |
4552 | - } |
4553 | - } |
4554 | - |
4555 | - return true; |
4556 | -} |
4557 | - |
4558 | -void TouchGate::setTargetItem(QQuickItem *item) |
4559 | -{ |
4560 | - // TODO: changing the target item while dispatch of touch events is taking place will |
4561 | - // create a mess |
4562 | - |
4563 | - if (item == m_dispatcher.targetItem()) |
4564 | - return; |
4565 | - |
4566 | - m_dispatcher.setTargetItem(item); |
4567 | - Q_EMIT targetItemChanged(item); |
4568 | -} |
4569 | - |
4570 | -void TouchGate::dispatchTouchEventToTarget(const TouchEvent &event) |
4571 | -{ |
4572 | - removeTouchInfoForEndedTouches(event.touchPoints); |
4573 | - m_dispatcher.dispatch(event.eventType, |
4574 | - event.device, |
4575 | - event.modifiers, |
4576 | - event.touchPoints, |
4577 | - event.window, |
4578 | - event.timestamp); |
4579 | -} |
4580 | - |
4581 | -void TouchGate::dispatchTouchEventToTarget(QTouchEvent* event) |
4582 | -{ |
4583 | - removeTouchInfoForEndedTouches(event->touchPoints()); |
4584 | - m_dispatcher.dispatch(event->type(), |
4585 | - event->device(), |
4586 | - event->modifiers(), |
4587 | - event->touchPoints(), |
4588 | - event->window(), |
4589 | - event->timestamp()); |
4590 | -} |
4591 | - |
4592 | -void TouchGate::removeTouchInfoForEndedTouches(const QList<QTouchEvent::TouchPoint> &touchPoints) |
4593 | -{ |
4594 | - for (int i = 0; i < touchPoints.size(); ++i) {\ |
4595 | - const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
4596 | - |
4597 | - if (touchPoint.state() == Qt::TouchPointReleased) { |
4598 | - Q_ASSERT(m_touchInfoMap.contains(touchPoint.id())); |
4599 | - Q_ASSERT(m_touchInfoMap[touchPoint.id()].ended); |
4600 | - Q_ASSERT(m_touchInfoMap[touchPoint.id()].ownership == OwnershipGranted); |
4601 | - m_touchInfoMap.remove(touchPoint.id()); |
4602 | - } |
4603 | - } |
4604 | -} |
4605 | - |
4606 | -TouchGate::TouchEvent::TouchEvent(const QTouchEvent *event) |
4607 | - : eventType(event->type()) |
4608 | - , device(event->device()) |
4609 | - , modifiers(event->modifiers()) |
4610 | - , touchPoints(event->touchPoints()) |
4611 | - , target(qobject_cast<QQuickItem*>(event->target())) |
4612 | - , window(event->window()) |
4613 | - , timestamp(event->timestamp()) |
4614 | -{ |
4615 | -} |
4616 | - |
4617 | -bool TouchGate::TouchEvent::removeTouch(int touchId) |
4618 | -{ |
4619 | - bool removed = false; |
4620 | - for (int i = 0; i < touchPoints.count() && !removed; ++i) { |
4621 | - if (touchPoints[i].id() == touchId) { |
4622 | - touchPoints.removeAt(i); |
4623 | - removed = true; |
4624 | - } |
4625 | - } |
4626 | - |
4627 | - return removed; |
4628 | -} |
4629 | |
4630 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.h' |
4631 | --- src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.h 2015-03-17 15:14:11 +0000 |
4632 | +++ src/app/unity8/plugins/Ubuntu/Gestures/TouchGate.h 1970-01-01 00:00:00 +0000 |
4633 | @@ -1,112 +0,0 @@ |
4634 | -/* |
4635 | - * Copyright (C) 2014 Canonical, Ltd. |
4636 | - * |
4637 | - * This program is free software; you can redistribute it and/or modify |
4638 | - * it under the terms of the GNU General Public License as published by |
4639 | - * the Free Software Foundation; version 3. |
4640 | - * |
4641 | - * This program is distributed in the hope that it will be useful, |
4642 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4643 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4644 | - * GNU General Public License for more details. |
4645 | - * |
4646 | - * You should have received a copy of the GNU General Public License |
4647 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4648 | - */ |
4649 | - |
4650 | -#ifndef UBUNTU_TOUCH_GATE_H |
4651 | -#define UBUNTU_TOUCH_GATE_H |
4652 | - |
4653 | -#include "UbuntuGesturesQmlGlobal.h" |
4654 | -#include "TouchDispatcher.h" |
4655 | - |
4656 | -#include <QQuickItem> |
4657 | -#include <QList> |
4658 | -#include <QMap> |
4659 | - |
4660 | -#define TOUCHGATE_DEBUG 0 |
4661 | - |
4662 | -class TouchOwnershipEvent; |
4663 | - |
4664 | -/* |
4665 | - Blocks the passage of events until ownership over the related touch points is granted. |
4666 | - |
4667 | - Blocked touch events won't be discarded. Instead they will be buffered until ownership |
4668 | - is granted. If ownership is given to another item, the event buffer is cleared. |
4669 | - |
4670 | - A TouchGate is useful as a mediator for items that do not understand, or gracefully handle, |
4671 | - touch canceling. By having a TouchGate in front of them you guarantee that only owned touches (i.e., |
4672 | - touches that won't be canceled later) reaches them. |
4673 | - */ |
4674 | -class UBUNTUGESTURESQML_EXPORT TouchGate : public QQuickItem { |
4675 | - Q_OBJECT |
4676 | - |
4677 | - // Item that's going to receive the touch events that make it through the gate. |
4678 | - Q_PROPERTY(QQuickItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged) |
4679 | - |
4680 | -public: |
4681 | - bool event(QEvent *e) override; |
4682 | - |
4683 | - QQuickItem *targetItem() { return m_dispatcher.targetItem(); } |
4684 | - void setTargetItem(QQuickItem *item); |
4685 | - |
4686 | -Q_SIGNALS: |
4687 | - void targetItemChanged(QQuickItem *item); |
4688 | - |
4689 | - void pressed(); |
4690 | - |
4691 | -protected: |
4692 | - void touchEvent(QTouchEvent *event) override; |
4693 | -private: |
4694 | - class TouchEvent { |
4695 | - public: |
4696 | - TouchEvent(const QTouchEvent *event); |
4697 | - |
4698 | - bool removeTouch(int touchId); |
4699 | - |
4700 | - QEvent::Type eventType; |
4701 | - QTouchDevice *device; |
4702 | - Qt::KeyboardModifiers modifiers; |
4703 | - QList<QTouchEvent::TouchPoint> touchPoints; |
4704 | - QQuickItem *target; |
4705 | - QWindow *window; |
4706 | - ulong timestamp; |
4707 | - }; |
4708 | - |
4709 | - void touchOwnershipEvent(TouchOwnershipEvent *event); |
4710 | - bool isTouchPointOwned(int touchId) const; |
4711 | - void storeTouchEvent(const QTouchEvent *event); |
4712 | - void removeTouchFromStoredEvents(int touchId); |
4713 | - void dispatchFullyOwnedEvents(); |
4714 | - bool eventIsFullyOwned(const TouchEvent &event) const; |
4715 | - |
4716 | - void dispatchTouchEventToTarget(const TouchEvent &event); |
4717 | - void dispatchTouchEventToTarget(QTouchEvent* event); |
4718 | - |
4719 | - void removeTouchInfoForEndedTouches(const QList<QTouchEvent::TouchPoint> &touchPoints); |
4720 | - |
4721 | - #if TOUCHGATE_DEBUG |
4722 | - QString oldestPendingTouchIdsString(); |
4723 | - #endif |
4724 | - |
4725 | - QList<TouchEvent> m_storedEvents; |
4726 | - |
4727 | - enum { |
4728 | - OwnershipUndefined, |
4729 | - OwnershipRequested, |
4730 | - OwnershipGranted, |
4731 | - }; |
4732 | - class TouchInfo { |
4733 | - public: |
4734 | - TouchInfo() {ownership = OwnershipUndefined; ended = false;} |
4735 | - int ownership; |
4736 | - bool ended; |
4737 | - }; |
4738 | - QMap<int, TouchInfo> m_touchInfoMap; |
4739 | - |
4740 | - TouchDispatcher m_dispatcher; |
4741 | - |
4742 | - friend class tst_TouchGate; |
4743 | -}; |
4744 | - |
4745 | -#endif // UBUNTU_TOUCH_GATE_H |
4746 | |
4747 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/UbuntuGesturesQmlGlobal.h' |
4748 | --- src/app/unity8/plugins/Ubuntu/Gestures/UbuntuGesturesQmlGlobal.h 2015-02-04 10:56:38 +0000 |
4749 | +++ src/app/unity8/plugins/Ubuntu/Gestures/UbuntuGesturesQmlGlobal.h 1970-01-01 00:00:00 +0000 |
4750 | @@ -1,23 +0,0 @@ |
4751 | -/* |
4752 | - * Copyright (C) 2013 Canonical, Ltd. |
4753 | - * |
4754 | - * This program is free software; you can redistribute it and/or modify |
4755 | - * it under the terms of the GNU General Public License as published by |
4756 | - * the Free Software Foundation; version 3. |
4757 | - * |
4758 | - * This program is distributed in the hope that it will be useful, |
4759 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4760 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4761 | - * GNU General Public License for more details. |
4762 | - * |
4763 | - * You should have received a copy of the GNU General Public License |
4764 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4765 | - */ |
4766 | - |
4767 | -#include <QtCore/QtGlobal> |
4768 | - |
4769 | -#if defined(UBUNTUGESTURESQML_LIBRARY) |
4770 | -# define UBUNTUGESTURESQML_EXPORT Q_DECL_EXPORT |
4771 | -#else |
4772 | -# define UBUNTUGESTURESQML_EXPORT Q_DECL_IMPORT |
4773 | -#endif |
4774 | |
4775 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/plugin.cpp' |
4776 | --- src/app/unity8/plugins/Ubuntu/Gestures/plugin.cpp 2015-02-04 10:56:38 +0000 |
4777 | +++ src/app/unity8/plugins/Ubuntu/Gestures/plugin.cpp 1970-01-01 00:00:00 +0000 |
4778 | @@ -1,39 +0,0 @@ |
4779 | -/* |
4780 | - * Copyright (C) 2013 Canonical, Ltd. |
4781 | - * |
4782 | - * This program is free software; you can redistribute it and/or modify |
4783 | - * it under the terms of the GNU General Public License as published by |
4784 | - * the Free Software Foundation; version 3. |
4785 | - * |
4786 | - * This program is distributed in the hope that it will be useful, |
4787 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4788 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4789 | - * GNU General Public License for more details. |
4790 | - * |
4791 | - * You should have received a copy of the GNU General Public License |
4792 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4793 | - */ |
4794 | - |
4795 | -#include "plugin.h" |
4796 | -#include "AxisVelocityCalculator.h" |
4797 | -#include "Direction.h" |
4798 | -#include "DirectionalDragArea.h" |
4799 | -#include "PressedOutsideNotifier.h" |
4800 | -#include "TouchGate.h" |
4801 | - |
4802 | -#include <qqml.h> |
4803 | - |
4804 | -static QObject* directionSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) { |
4805 | - Q_UNUSED(engine); |
4806 | - Q_UNUSED(scriptEngine); |
4807 | - return new Direction; |
4808 | -} |
4809 | - |
4810 | -void UbuntuGesturesQmlPlugin::registerTypes(const char *uri) |
4811 | -{ |
4812 | - qmlRegisterSingletonType<Direction>(uri, 0, 1, "Direction", directionSingleton); |
4813 | - qmlRegisterType<DirectionalDragArea>(uri, 0, 1, "DirectionalDragArea"); |
4814 | - qmlRegisterType<AxisVelocityCalculator>(uri, 0, 1, "AxisVelocityCalculator"); |
4815 | - qmlRegisterType<PressedOutsideNotifier>(uri, 0, 1, "PressedOutsideNotifier"); |
4816 | - qmlRegisterType<TouchGate>(uri, 0, 1, "TouchGate"); |
4817 | -} |
4818 | |
4819 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/plugin.h' |
4820 | --- src/app/unity8/plugins/Ubuntu/Gestures/plugin.h 2015-02-04 10:56:38 +0000 |
4821 | +++ src/app/unity8/plugins/Ubuntu/Gestures/plugin.h 1970-01-01 00:00:00 +0000 |
4822 | @@ -1,31 +0,0 @@ |
4823 | -/* |
4824 | - * Copyright (C) 2013 Canonical, Ltd. |
4825 | - * |
4826 | - * This program is free software; you can redistribute it and/or modify |
4827 | - * it under the terms of the GNU General Public License as published by |
4828 | - * the Free Software Foundation; version 3. |
4829 | - * |
4830 | - * This program is distributed in the hope that it will be useful, |
4831 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4832 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4833 | - * GNU General Public License for more details. |
4834 | - * |
4835 | - * You should have received a copy of the GNU General Public License |
4836 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4837 | - */ |
4838 | - |
4839 | -#ifndef PLUGIN_H |
4840 | -#define PLUGIN_H |
4841 | - |
4842 | -#include <QtQml/QQmlExtensionPlugin> |
4843 | - |
4844 | -class UbuntuGesturesQmlPlugin : public QQmlExtensionPlugin |
4845 | -{ |
4846 | - Q_OBJECT |
4847 | - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
4848 | -public: |
4849 | - void registerTypes(const char *uri); |
4850 | -}; |
4851 | - |
4852 | - |
4853 | -#endif |
4854 | |
4855 | === removed file 'src/app/unity8/plugins/Ubuntu/Gestures/qmldir' |
4856 | --- src/app/unity8/plugins/Ubuntu/Gestures/qmldir 2015-02-04 10:56:38 +0000 |
4857 | +++ src/app/unity8/plugins/Ubuntu/Gestures/qmldir 1970-01-01 00:00:00 +0000 |
4858 | @@ -1,3 +0,0 @@ |
4859 | -module Ubuntu.Gestures |
4860 | -plugin UbuntuGesturesQml |
4861 | -typeinfo Gestures.qmltypes |
4862 | |
4863 | === modified file 'src/app/webbrowser/BottomEdgeHandle.qml' |
4864 | --- src/app/webbrowser/BottomEdgeHandle.qml 2015-08-10 15:22:00 +0000 |
4865 | +++ src/app/webbrowser/BottomEdgeHandle.qml 2016-04-12 20:15:29 +0000 |
4866 | @@ -1,5 +1,5 @@ |
4867 | /* |
4868 | - * Copyright 2014-2015 Canonical Ltd. |
4869 | + * Copyright 2014-2016 Canonical Ltd. |
4870 | * |
4871 | * This file is part of webbrowser-app. |
4872 | * |
4873 | @@ -17,20 +17,12 @@ |
4874 | */ |
4875 | |
4876 | import QtQuick 2.4 |
4877 | -import Ubuntu.Gestures 0.1 |
4878 | - |
4879 | -DirectionalDragArea { |
4880 | - direction: Direction.Upwards |
4881 | - |
4882 | - // default values taken from unity8’s EdgeDragArea component |
4883 | - maxDeviation: units.gu(3) |
4884 | - wideningAngle: 50 |
4885 | - distanceThreshold: units.gu(1.5) |
4886 | - minSpeed: 0 |
4887 | - maxSilenceTime: 200 |
4888 | - compositionTime: 60 |
4889 | - |
4890 | - readonly property real dragFraction: dragging ? Math.min(1.0, Math.max(0.0, sceneDistance / parent.height)) : 0.0 |
4891 | +import Ubuntu.Components 1.3 |
4892 | + |
4893 | +SwipeArea { |
4894 | + direction: SwipeArea.Upwards |
4895 | + |
4896 | + readonly property real dragFraction: dragging ? Math.min(1.0, Math.max(0.0, distance / parent.height)) : 0.0 |
4897 | readonly property var thresholds: [0.05, 0.18, 0.36, 0.54, 1.0] |
4898 | readonly property int stage: thresholds.map(function(t) { return dragFraction <= t }).indexOf(true) |
4899 | } |
FAILED: Continuous integration, rev:1393 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 2678/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 6790 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 1431 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 1431 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 1431/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 1431 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-touch/ 5145 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6801 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6801/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 28052
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 2678/rebuild
http://