2
* Copyright 2015 Canonical Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Lesser General Public License as published by
6
* the Free Software Foundation; version 3.
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 Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authors: Zsombor Egri <zsombor.egri@canonical.com>
19
#include "gesturedetector.h"
21
#include <QtCore/QEvent>
22
#include <QtCore/QRectF>
23
#include <QtGui/QTouchEvent>
24
#include <QtQuick/QQuickItem>
25
#include <QtGui/QGuiApplication>
26
#include <QtGui/QStyleHints>
28
#define DETECTION_AREA_THICKNESS_GU 1.2
30
GestureDetector::GestureDetector(QObject *parent)
32
, m_owner(qobject_cast<QQuickItem*>(parent))
34
, m_bottomUpSwipeDetected(false)
38
GestureDetector::~GestureDetector()
40
Q_FOREACH(QObject *object, m_filteredItems) {
41
object->removeEventFilter(this);
43
m_filteredItems.clear();
46
void GestureDetector::onFilteredItemDeleted(QObject *object)
49
object->removeEventFilter(this);
50
m_filteredItems.removeAll(object);
54
void GestureDetector::setStatus(Status status)
56
if (status == m_status) {
60
Q_EMIT statusChanged(m_status);
63
bool GestureDetector::isDetecting()
65
return (m_status > Ready && m_status < Completed);
68
void GestureDetector::setItemFilter(QObject *item)
70
m_filteredItems.append(item);
71
item->installEventFilter(this);
72
connect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted);
75
void GestureDetector::removeItemFilter(QObject *item)
77
m_filteredItems.removeAll(item);
78
item->removeEventFilter(this);
79
disconnect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted);
82
bool GestureDetector::handleTouchEvent(QObject *target, QTouchEvent *event)
84
switch (event->type()) {
85
case QEvent::TouchBegin: {
87
QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos());
88
qreal thickness = UCUnits::instance().gu(DETECTION_AREA_THICKNESS_GU);
89
QRectF detectionArea(0.0, m_owner->height() - thickness, m_owner->width(), thickness);
90
if (detectionArea.contains(itemPoint)) {
91
m_startPoint = itemPoint;
93
if (target == parent()) {
100
case QEvent::TouchEnd:
102
m_startPoint = QPointF();
103
setStatus(Completed);
106
case QEvent::TouchCancel: {
107
m_startPoint = QPointF();
111
case QEvent::TouchUpdate: {
112
if (m_status == Started) {
113
QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos());
114
if (abs(m_startPoint.y() - itemPoint.y()) >= qApp->styleHints()->startDragDistance()) {
116
Q_EMIT bottomUpSwipeDetected();
121
default: return false;
125
bool GestureDetector::eventFilter(QObject *target, QEvent *event)
127
if (m_filteredItems.contains(target)) {
128
QEvent::Type type = event->type();
129
if (type == QEvent::TouchBegin
130
|| type == QEvent::TouchUpdate
131
|| type == QEvent::TouchEnd
132
|| type == QEvent::TouchCancel) {
133
QTouchEvent *touch = static_cast<QTouchEvent*>(event);
134
return handleTouchEvent(target, touch);
140
return QObject::eventFilter(target, event);