17 #include "TouchGate.h"
19 #include <QCoreApplication>
22 #include <TouchOwnershipEvent.h>
23 #include <TouchRegistry.h>
26 #include <DebugHelpers.h>
29 bool TouchGate::event(QEvent *e)
31 if (e->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
32 touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(e));
35 return QQuickItem::event(e);
39 void TouchGate::touchEvent(QTouchEvent *event)
42 qDebug() <<
"[TouchGate] got touch event" << qPrintable(touchEventToString(event));
46 const QList<QTouchEvent::TouchPoint> &touchPoints =
event->touchPoints();
48 for (
int i = 0; i < touchPoints.count(); ++i) {
49 const QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
51 if (touchPoint.state() == Qt::TouchPointPressed) {
52 Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id()));
53 m_touchInfoMap[touchPoint.id()].ownership = OwnershipRequested;
54 m_touchInfoMap[touchPoint.id()].ended =
false;
55 TouchRegistry::instance()->requestTouchOwnership(touchPoint.id(),
this);
58 goodToGo &= m_touchInfoMap.contains(touchPoint.id())
59 && m_touchInfoMap[touchPoint.id()].ownership == OwnershipGranted;
61 if (touchPoint.state() == Qt::TouchPointReleased && m_touchInfoMap.contains(touchPoint.id())) {
62 m_touchInfoMap[touchPoint.id()].ended =
true;
68 if (m_storedEvents.isEmpty()) {
70 dispatchTouchEventToTarget(event);
75 qDebug(
"[TouchGate] Storing event because thouches %s are still pending ownership.",
76 qPrintable(oldestPendingTouchIdsString()));
78 storeTouchEvent(event);
82 storeTouchEvent(event);
86 void TouchGate::touchOwnershipEvent(TouchOwnershipEvent *event)
91 Q_ASSERT(m_touchInfoMap.contains(event->touchId()));
93 TouchInfo &touchInfo = m_touchInfoMap[
event->touchId()];
95 if (event->gained()) {
97 qDebug() <<
"[TouchGate] Got ownership of touch " <<
event->touchId();
99 touchInfo.ownership = OwnershipGranted;
102 qDebug() <<
"[TouchGate] Lost ownership of touch " <<
event->touchId();
104 m_touchInfoMap.remove(event->touchId());
105 removeTouchFromStoredEvents(event->touchId());
108 dispatchFullyOwnedEvents();
111 bool TouchGate::isTouchPointOwned(
int touchId)
const
113 return m_touchInfoMap[touchId].ownership == OwnershipGranted;
116 void TouchGate::storeTouchEvent(
const QTouchEvent *event)
119 qDebug() <<
"[TouchGate] Storing" << qPrintable(touchEventToString(event));
122 TouchEvent clonedEvent(event);
123 m_storedEvents.append(std::move(clonedEvent));
126 void TouchGate::removeTouchFromStoredEvents(
int touchId)
129 while (i < m_storedEvents.count()) {
130 TouchEvent &
event = m_storedEvents[i];
131 bool removed =
event.removeTouch(touchId);
133 if (removed && event.touchPoints.isEmpty()) {
134 m_storedEvents.removeAt(i);
141 void TouchGate::dispatchFullyOwnedEvents()
143 while (!m_storedEvents.isEmpty() && eventIsFullyOwned(m_storedEvents.first())) {
144 TouchEvent
event = m_storedEvents.takeFirst();
145 dispatchTouchEventToTarget(event);
150 QString TouchGate::oldestPendingTouchIdsString()
152 Q_ASSERT(!m_storedEvents.isEmpty());
156 const auto &touchPoints = m_storedEvents.first().touchPoints;
157 for (
int i = 0; i < touchPoints.count(); ++i) {
158 if (!isTouchPointOwned(touchPoints[i].
id())) {
159 if (!str.isEmpty()) {
162 str.append(QString::number(touchPoints[i].
id()));
170 bool TouchGate::eventIsFullyOwned(
const TouchGate::TouchEvent &event)
const
172 for (
int i = 0; i <
event.touchPoints.count(); ++i) {
173 if (!isTouchPointOwned(event.touchPoints[i].id())) {
181 void TouchGate::setTargetItem(QQuickItem *item)
186 if (item == m_dispatcher.targetItem())
189 m_dispatcher.setTargetItem(item);
190 Q_EMIT targetItemChanged(item);
193 void TouchGate::dispatchTouchEventToTarget(
const TouchEvent &event)
195 removeTouchInfoForEndedTouches(event.touchPoints);
196 m_dispatcher.dispatch(event.eventType,
204 void TouchGate::dispatchTouchEventToTarget(QTouchEvent* event)
206 removeTouchInfoForEndedTouches(event->touchPoints());
207 m_dispatcher.dispatch(event->type(),
210 event->touchPoints(),
215 void TouchGate::removeTouchInfoForEndedTouches(
const QList<QTouchEvent::TouchPoint> &touchPoints)
217 for (
int i = 0; i < touchPoints.size(); ++i) {\
218 const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
220 if (touchPoint.state() == Qt::TouchPointReleased) {
221 Q_ASSERT(m_touchInfoMap.contains(touchPoint.id()));
222 Q_ASSERT(m_touchInfoMap[touchPoint.id()].ended);
223 Q_ASSERT(m_touchInfoMap[touchPoint.id()].ownership == OwnershipGranted);
224 m_touchInfoMap.remove(touchPoint.id());
229 TouchGate::TouchEvent::TouchEvent(
const QTouchEvent *event)
230 : eventType(event->type())
231 , device(event->device())
232 , modifiers(event->modifiers())
233 , touchPoints(event->touchPoints())
234 , target(qobject_cast<QQuickItem*>(event->target()))
235 , window(event->window())
236 , timestamp(event->timestamp())
240 bool TouchGate::TouchEvent::removeTouch(
int touchId)
242 bool removed =
false;
243 for (
int i = 0; i < touchPoints.count() && !removed; ++i) {
244 if (touchPoints[i].
id() == touchId) {
245 touchPoints.removeAt(i);