Merge lp:~osomon/webbrowser-app/use-uitk-swipearea into lp:webbrowser-app

Proposed by Olivier Tilloy
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
Reviewer Review Type Date Requested Status
system-apps-ci-bot continuous-integration Needs Fixing
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+290700@code.launchpad.net

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).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
1394. By Olivier Tilloy

Merge the latest changes from trunk and resolve conflicts.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 }

Subscribers

People subscribed via source and target branches

to status/vote changes: