~faenil/ubuntu-ui-toolkit/flickableBasedScrollView

« back to all changes in this revision

Viewing changes to src/Ubuntu/Components/plugin/privates/gesturedetector.cpp

  • Committer: Andrea Bernabei
  • Date: 2015-11-25 11:50:10 UTC
  • mfrom: (1681.2.44 staging)
  • Revision ID: andrea.bernabei@canonical.com-20151125115010-vpxkm2lze1hav9q9
mergeĀ upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2015 Canonical Ltd.
3
 
 *
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.
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 Lesser General Public License for more details.
12
 
 *
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/>.
15
 
 *
16
 
 * Authors: Zsombor Egri <zsombor.egri@canonical.com>
17
 
 */
18
 
 
19
 
#include "gesturedetector.h"
20
 
#include "ucunits.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>
27
 
 
28
 
#define DETECTION_AREA_THICKNESS_GU 1.2
29
 
 
30
 
GestureDetector::GestureDetector(QObject *parent)
31
 
    : QObject(parent)
32
 
    , m_owner(qobject_cast<QQuickItem*>(parent))
33
 
    , m_status(Ready)
34
 
    , m_bottomUpSwipeDetected(false)
35
 
{
36
 
    Q_ASSERT(m_owner);
37
 
}
38
 
GestureDetector::~GestureDetector()
39
 
{
40
 
    Q_FOREACH(QObject *object, m_filteredItems) {
41
 
        object->removeEventFilter(this);
42
 
    }
43
 
    m_filteredItems.clear();
44
 
}
45
 
 
46
 
void GestureDetector::setStatus(Status status)
47
 
{
48
 
    if (status == m_status) {
49
 
        return;
50
 
    }
51
 
    m_status = status;
52
 
    Q_EMIT statusChanged(m_status);
53
 
}
54
 
 
55
 
bool GestureDetector::isDetecting()
56
 
{
57
 
    return (m_status > Ready && m_status < Completed);
58
 
}
59
 
 
60
 
void GestureDetector::setItemFilter(QObject *item)
61
 
{
62
 
    m_filteredItems.append(item);
63
 
    item->installEventFilter(this);
64
 
}
65
 
 
66
 
void GestureDetector::removeItemFilter(QObject *item)
67
 
{
68
 
    m_filteredItems.removeAll(item);
69
 
    item->removeEventFilter(this);
70
 
}
71
 
 
72
 
bool GestureDetector::handleTouchEvent(QObject *target, QTouchEvent *event)
73
 
{
74
 
    switch (event->type()) {
75
 
    case QEvent::TouchBegin: {
76
 
        setStatus(Ready);
77
 
        QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos());
78
 
        qreal thickness = UCUnits::instance().gu(DETECTION_AREA_THICKNESS_GU);
79
 
        QRectF detectionArea(0.0, m_owner->height() - thickness, m_owner->width(), thickness);
80
 
        if (detectionArea.contains(itemPoint)) {
81
 
            m_startPoint = itemPoint;
82
 
            setStatus(Started);
83
 
            if (target == parent()) {
84
 
                event->accept();
85
 
                return true;
86
 
            }
87
 
        }
88
 
        return false;
89
 
    }
90
 
    case QEvent::TouchEnd:
91
 
    {
92
 
        m_startPoint = QPointF();
93
 
        setStatus(Completed);
94
 
        return false;
95
 
    }
96
 
    case QEvent::TouchCancel: {
97
 
        m_startPoint = QPointF();
98
 
        setStatus(Ready);
99
 
        return false;
100
 
    }
101
 
    case QEvent::TouchUpdate: {
102
 
        if (m_status == Started) {
103
 
            QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos());
104
 
            if (abs(m_startPoint.y() - itemPoint.y()) >= qApp->styleHints()->startDragDistance()) {
105
 
                setStatus(Detected);
106
 
                Q_EMIT bottomUpSwipeDetected();
107
 
            }
108
 
        }
109
 
        return false;
110
 
    }
111
 
    default: return false;
112
 
    }
113
 
}
114
 
 
115
 
bool GestureDetector::eventFilter(QObject *target, QEvent *event)
116
 
{
117
 
    if (m_filteredItems.contains(target)) {
118
 
        QEvent::Type type = event->type();
119
 
        if (type == QEvent::TouchBegin
120
 
                || type == QEvent::TouchUpdate
121
 
                || type == QEvent::TouchEnd
122
 
                || type == QEvent::TouchCancel) {
123
 
            QTouchEvent *touch = static_cast<QTouchEvent*>(event);
124
 
            return handleTouchEvent(target, touch);
125
 
        } else {
126
 
            // pass it on
127
 
            return false;
128
 
        }
129
 
    } else {
130
 
        return QObject::eventFilter(target, event);
131
 
    }
132
 
}