Lomiri
Loading...
Searching...
No Matches
TouchGate.h
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef LOMIRI_TOUCH_GATE_H
18#define LOMIRI_TOUCH_GATE_H
19
20#include "LomiriGesturesQmlGlobal.h"
21#include "TouchDispatcher.h"
22#include <LomiriGestures/lomirigesturesglobal.h>
23
24#include <QQuickItem>
25#include <QList>
26#include <QMap>
27
28#define TOUCHGATE_DEBUG 0
29
30UG_FORWARD_DECLARE_CLASS(TouchOwnershipEvent)
31
32/*
33 Blocks the passage of events until ownership over the related touch points is granted.
34
35 Blocked touch events won't be discarded. Instead they will be buffered until ownership
36 is granted. If ownership is given to another item, the event buffer is cleared.
37
38 A TouchGate is useful as a mediator for items that do not understand, or gracefully handle,
39 touch canceling. By having a TouchGate in front of them you guarantee that only owned touches (i.e.,
40 touches that won't be canceled later) reaches them.
41 */
42class LOMIRIGESTURESQML_EXPORT TouchGate : public QQuickItem {
43 Q_OBJECT
44
45 // Item that's going to receive the touch events that make it through the gate.
46 Q_PROPERTY(QQuickItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged)
47
48public:
49 TouchGate(QQuickItem *parent = nullptr);
50
51 bool event(QEvent *e) override;
52
53 QQuickItem *targetItem() { return m_dispatcher.targetItem(); }
54 void setTargetItem(QQuickItem *item);
55
56Q_SIGNALS:
57 void targetItemChanged(QQuickItem *item);
58
59protected:
60 void touchEvent(QTouchEvent *event) override;
61 void itemChange(ItemChange change, const ItemChangeData &value) override;
62
63private Q_SLOTS:
64 void onEnabledChanged();
65
66private:
67 void reset();
68
69 class TouchEvent {
70 public:
71 TouchEvent(QTouchDevice *device,
72 Qt::KeyboardModifiers modifiers,
73 const QList<QTouchEvent::TouchPoint> &touchPoints,
74 QWindow *window,
75 ulong timestamp);
76
77 bool removeTouch(int touchId);
78
79 QTouchDevice *device;
80 Qt::KeyboardModifiers modifiers;
81 QList<QTouchEvent::TouchPoint> touchPoints;
82 QWindow *window;
83 ulong timestamp;
84 };
85
86 void touchOwnershipEvent(UG_PREPEND_NAMESPACE(TouchOwnershipEvent) *event);
87 bool isTouchPointOwned(int touchId) const;
88 void storeTouchEvent(QTouchDevice *device,
89 Qt::KeyboardModifiers modifiers,
90 const QList<QTouchEvent::TouchPoint> &touchPoints,
91 QWindow *window,
92 ulong timestamp);
93 void removeTouchFromStoredEvents(int touchId);
94 void dispatchFullyOwnedEvents();
95 bool eventIsFullyOwned(const TouchEvent &event) const;
96
97 void dispatchTouchEventToTarget(const TouchEvent &event);
98
99 void removeTouchInfoForEndedTouches(const QList<QTouchEvent::TouchPoint> &touchPoints);
100
101 #if TOUCHGATE_DEBUG
102 QString oldestPendingTouchIdsString();
103 #endif
104
105 QList<TouchEvent> m_storedEvents;
106
107 enum {
108 OwnershipUndefined,
109 OwnershipRequested,
110 OwnershipGranted,
111 };
112 class TouchInfo {
113 public:
114 TouchInfo() {ownership = OwnershipUndefined; ended = false;}
115 int ownership;
116 bool ended;
117 };
118 QMap<int, TouchInfo> m_touchInfoMap;
119
120 TouchDispatcher m_dispatcher;
121
122 friend class tst_TouchGate;
123};
124
125#endif // LOMIRI_TOUCH_GATE_H