Merge lp:~zsombi/ubuntu-ui-toolkit/bottomedgehint_with_swipearea into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Cris Dywan
Approved revision: 1720
Merged at revision: 1722
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/bottomedgehint_with_swipearea
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/migrate_unity8_gestures
Diff against target: 646 lines (+108/-281)
8 files modified
components.api (+2/-4)
examples/ubuntu-ui-toolkit-gallery/MainPage.qml (+2/-3)
src/Ubuntu/Components/plugin/plugin.pri (+0/-2)
src/Ubuntu/Components/plugin/privates/gesturedetector.cpp (+0/-142)
src/Ubuntu/Components/plugin/privates/gesturedetector.h (+0/-75)
src/Ubuntu/Components/plugin/ucbottomedgehint.cpp (+76/-40)
src/Ubuntu/Components/plugin/ucbottomedgehint.h (+14/-14)
tests/unit_x11/tst_components/tst_bottomedgehint.qml (+14/-1)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/bottomedgehint_with_swipearea
Reviewer Review Type Date Requested Status
Cris Dywan Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+277684@code.launchpad.net

Commit message

Remove GestureDetector in favor of SwipeArea in BottomEdgeHint. Also make possible to assign Action to the component.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1719. By Zsombor Egri

staging sync

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1720. By Zsombor Egri

replace base class calls

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

Like the rebase on ActionItem.
Like the QML-friendly trigger.
Like the use of the SwipeArea.
Like the comments and bug references.
No change in behavior, which is good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2015-11-17 14:44:49 +0000
+++ components.api 2015-11-19 10:02:45 +0000
@@ -175,14 +175,12 @@
175 property var icon175 property var icon
176 property bool iconFrame176 property bool iconFrame
177 property bool progression177 property bool progression
178Ubuntu.Components.BottomEdgeHint 1.3: StyledItem178Ubuntu.Components.BottomEdgeHint 1.3: ActionItem
179 property int deactivateTimeout179 property int deactivateTimeout
180 property Flickable flickable180 property Flickable flickable
181 property string iconName
182 property url iconSource
183 signal clicked()181 signal clicked()
184 property Status status182 property Status status
185 property string text183 readonly property SwipeArea swipeArea
186Ubuntu.Components.BottomEdgeHint.Status: Enum184Ubuntu.Components.BottomEdgeHint.Status: Enum
187 Active185 Active
188 Hidden186 Hidden
189187
=== modified file 'examples/ubuntu-ui-toolkit-gallery/MainPage.qml'
--- examples/ubuntu-ui-toolkit-gallery/MainPage.qml 2015-11-05 13:41:35 +0000
+++ examples/ubuntu-ui-toolkit-gallery/MainPage.qml 2015-11-19 10:02:45 +0000
@@ -50,6 +50,7 @@
50 onTriggered: gallery.theme.name = 'Ubuntu.Components.Themes.Ambiance'50 onTriggered: gallery.theme.name = 'Ubuntu.Components.Themes.Ambiance'
51 },51 },
52 Action {52 Action {
53 id: aboutAction
53 text: i18n.tr('About')54 text: i18n.tr('About')
54 iconName: "info"55 iconName: "info"
55 onTriggered: mainPage.pageStack.addPageToCurrentColumn(mainPage, Qt.resolvedUrl("About.qml"))56 onTriggered: mainPage.pageStack.addPageToCurrentColumn(mainPage, Qt.resolvedUrl("About.qml"))
@@ -135,8 +136,6 @@
135136
136 BottomEdgeHint {137 BottomEdgeHint {
137 flickable: widgetList138 flickable: widgetList
138 text: i18n.tr('About')139 action: aboutAction
139 iconName: "info"
140 onClicked: mainPage.pageStack.addPageToCurrentColumn(mainPage, Qt.resolvedUrl("About.qml"))
141 }140 }
142}141}
143142
=== modified file 'src/Ubuntu/Components/plugin/plugin.pri'
--- src/Ubuntu/Components/plugin/plugin.pri 2015-11-09 16:51:41 +0000
+++ src/Ubuntu/Components/plugin/plugin.pri 2015-11-19 10:02:45 +0000
@@ -94,7 +94,6 @@
94 $$PWD/privates/threelabelsslot_p.h \94 $$PWD/privates/threelabelsslot_p.h \
95 $$PWD/ucimportversionchecker_p.h \95 $$PWD/ucimportversionchecker_p.h \
96 $$PWD/ucbottomedgehint.h \96 $$PWD/ucbottomedgehint.h \
97 $$PWD/privates/gesturedetector.h \
98 $$PWD/gestures/ucswipearea.h \97 $$PWD/gestures/ucswipearea.h \
99 $$PWD/gestures/ucswipearea_p.h \98 $$PWD/gestures/ucswipearea_p.h \
100 $$PWD/gestures/damper.h \99 $$PWD/gestures/damper.h \
@@ -163,7 +162,6 @@
163 $$PWD/privates/threelabelsslot_p.cpp \162 $$PWD/privates/threelabelsslot_p.cpp \
164 $$PWD/ucimportversionchecker_p.cpp \163 $$PWD/ucimportversionchecker_p.cpp \
165 $$PWD/ucbottomedgehint.cpp \164 $$PWD/ucbottomedgehint.cpp \
166 $$PWD/privates/gesturedetector.cpp \
167 $$PWD/gestures/ucswipearea.cpp \165 $$PWD/gestures/ucswipearea.cpp \
168166
169# adapters167# adapters
170168
=== removed file 'src/Ubuntu/Components/plugin/privates/gesturedetector.cpp'
--- src/Ubuntu/Components/plugin/privates/gesturedetector.cpp 2015-11-13 09:02:23 +0000
+++ src/Ubuntu/Components/plugin/privates/gesturedetector.cpp 1970-01-01 00:00:00 +0000
@@ -1,142 +0,0 @@
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
30GestureDetector::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}
38GestureDetector::~GestureDetector()
39{
40 Q_FOREACH(QObject *object, m_filteredItems) {
41 object->removeEventFilter(this);
42 }
43 m_filteredItems.clear();
44}
45
46void GestureDetector::onFilteredItemDeleted(QObject *object)
47{
48 if (object) {
49 object->removeEventFilter(this);
50 m_filteredItems.removeAll(object);
51 }
52}
53
54void GestureDetector::setStatus(Status status)
55{
56 if (status == m_status) {
57 return;
58 }
59 m_status = status;
60 Q_EMIT statusChanged(m_status);
61}
62
63bool GestureDetector::isDetecting()
64{
65 return (m_status > Ready && m_status < Completed);
66}
67
68void GestureDetector::setItemFilter(QObject *item)
69{
70 m_filteredItems.append(item);
71 item->installEventFilter(this);
72 connect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted);
73}
74
75void GestureDetector::removeItemFilter(QObject *item)
76{
77 m_filteredItems.removeAll(item);
78 item->removeEventFilter(this);
79 disconnect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted);
80}
81
82bool GestureDetector::handleTouchEvent(QObject *target, QTouchEvent *event)
83{
84 switch (event->type()) {
85 case QEvent::TouchBegin: {
86 setStatus(Ready);
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;
92 setStatus(Started);
93 if (target == parent()) {
94 event->accept();
95 return true;
96 }
97 }
98 return false;
99 }
100 case QEvent::TouchEnd:
101 {
102 m_startPoint = QPointF();
103 setStatus(Completed);
104 return false;
105 }
106 case QEvent::TouchCancel: {
107 m_startPoint = QPointF();
108 setStatus(Ready);
109 return false;
110 }
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()) {
115 setStatus(Detected);
116 Q_EMIT bottomUpSwipeDetected();
117 }
118 }
119 return false;
120 }
121 default: return false;
122 }
123}
124
125bool GestureDetector::eventFilter(QObject *target, QEvent *event)
126{
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);
135 } else {
136 // pass it on
137 return false;
138 }
139 } else {
140 return QObject::eventFilter(target, event);
141 }
142}
1430
=== removed file 'src/Ubuntu/Components/plugin/privates/gesturedetector.h'
--- src/Ubuntu/Components/plugin/privates/gesturedetector.h 2015-11-13 09:02:23 +0000
+++ src/Ubuntu/Components/plugin/privates/gesturedetector.h 1970-01-01 00:00:00 +0000
@@ -1,75 +0,0 @@
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#ifndef GESTUREDETECTOR_H
20#define GESTUREDETECTOR_H
21
22#include <QtCore/QObject>
23#include <QtCore/QPointF>
24#include <QtCore/QList>
25
26/*
27 * A simple gesture detection filter class that can be used in components to detect
28 * various gestures. Yet swipe from bottom up is the only gesture handled.
29 * It does not grab or consume the event from the environment, acts as a filter.
30 */
31class QTouchEvent;
32class QQuickItem;
33class GestureDetector : public QObject
34{
35 Q_OBJECT
36public:
37 enum Status {
38 Ready,
39 Started,
40 Detected,
41 Completed
42 };
43 explicit GestureDetector(QObject *parent = 0);
44 ~GestureDetector();
45
46 bool isDetecting();
47
48 void setItemFilter(QObject *item);
49 void removeItemFilter(QObject *item);
50
51 bool handleTouchEvent(QObject *target, QTouchEvent *event);
52
53Q_SIGNALS:
54 void statusChanged(Status status);
55
56 void bottomUpSwipeDetected();
57
58public Q_SLOTS:
59
60protected:
61 bool eventFilter(QObject *target, QEvent *event);
62
63 void setStatus(Status status);
64
65private:
66 QList<QObject*> m_filteredItems;
67 QPointF m_startPoint;
68 QQuickItem *m_owner;
69 Status m_status;
70 bool m_bottomUpSwipeDetected:1;
71
72 void onFilteredItemDeleted(QObject *object);
73};
74
75#endif // GESTUREDETECTOR_H
760
=== modified file 'src/Ubuntu/Components/plugin/ucbottomedgehint.cpp'
--- src/Ubuntu/Components/plugin/ucbottomedgehint.cpp 2015-11-05 14:28:58 +0000
+++ src/Ubuntu/Components/plugin/ucbottomedgehint.cpp 2015-11-19 10:02:45 +0000
@@ -20,14 +20,17 @@
20#include "ucstyleditembase_p.h"20#include "ucstyleditembase_p.h"
21#include "quickutils.h"21#include "quickutils.h"
22#include "ucunits.h"22#include "ucunits.h"
23#include "gestures/ucswipearea.h"
23#include <QtQml/private/qqmlproperty_p.h>24#include <QtQml/private/qqmlproperty_p.h>
24#include <QtQuick/private/qquickflickable_p.h>25#include <QtQuick/private/qquickflickable_p.h>
2526
27#define SWIPE_AREA_HEIGHT_GU 3
28
26/*!29/*!
27 \qmltype BottomEdgeHint30 \qmltype BottomEdgeHint
28 \inqmlmodule Ubuntu.Components 1.331 \inqmlmodule Ubuntu.Components 1.3
29 \ingroup ubuntu32 \ingroup ubuntu
30 \inherits StyledItem33 \inherits ActionItem
31 \brief The BottomEdgeHint shows the availability of extra features34 \brief The BottomEdgeHint shows the availability of extra features
32 available from the bottom edge of the application.35 available from the bottom edge of the application.
3336
@@ -50,14 +53,19 @@
50 The component is styled through \b BottomEdgeHintStyle.53 The component is styled through \b BottomEdgeHintStyle.
51*/54*/
52UCBottomEdgeHint::UCBottomEdgeHint(QQuickItem *parent)55UCBottomEdgeHint::UCBottomEdgeHint(QQuickItem *parent)
53 : UCStyledItemBase(parent)56 : UCActionItem(parent)
54 , m_gestureDetector(this)57 , m_swipeArea(new UCSwipeArea)
55 , m_flickable(Q_NULLPTR)58 , m_flickable(Q_NULLPTR)
56 , m_deactivateTimeout(800)59 , m_deactivateTimeout(800)
57 // FIXME: we need QInputDeviceInfo to be complete with the locked!!60 // FIXME: we need QInputDeviceInfo to be complete with the locked!!
61 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808
58 , m_status(QuickUtils::instance().mouseAttached() ? Locked : Inactive)62 , m_status(QuickUtils::instance().mouseAttached() ? Locked : Inactive)
59 , m_pressed(false)63 , m_pressed(false)
60{64{
65 connect(this, &UCBottomEdgeHint::clicked, [=]() {
66 // make sure the overloaded trigger is called!
67 metaObject()->invokeMethod(this, "trigger", Q_ARG(QVariant, QVariant()));
68 });
61 /*69 /*
62 * we cannot use setStyleName as that will trigger style loading70 * we cannot use setStyleName as that will trigger style loading
63 * and the qmlEngine is not known at this phase of the of the initialization71 * and the qmlEngine is not known at this phase of the of the initialization
@@ -69,13 +77,8 @@
69 // connect old stateChanged77 // connect old stateChanged
70 connect(this, &QQuickItem::stateChanged, this, &UCBottomEdgeHint::stateChanged);78 connect(this, &QQuickItem::stateChanged, this, &UCBottomEdgeHint::stateChanged);
7179
72 // connect to gesture detection
73 connect(&m_gestureDetector, &GestureDetector::bottomUpSwipeDetected,
74 this, &UCBottomEdgeHint::onBottomUpSwipeDetected);
75 connect(&m_gestureDetector, &GestureDetector::statusChanged,
76 this, &UCBottomEdgeHint::onGestureStatusChanged);
77
78 // FIXME: use QInputDeviceInfo once available80 // FIXME: use QInputDeviceInfo once available
81 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808
79 connect(&QuickUtils::instance(), &QuickUtils::mouseAttachedChanged, [this]() {82 connect(&QuickUtils::instance(), &QuickUtils::mouseAttachedChanged, [this]() {
80 setStatus(QuickUtils::instance().mouseAttached() ? Locked : Active);83 setStatus(QuickUtils::instance().mouseAttached() ? Locked : Active);
81 if (m_status == Active) {84 if (m_status == Active) {
@@ -87,9 +90,44 @@
87 setAcceptedMouseButtons(Qt::LeftButton);90 setAcceptedMouseButtons(Qt::LeftButton);
88}91}
8992
93void UCBottomEdgeHint::classBegin()
94{
95 UCActionItem::classBegin();
96 init();
97}
98
99void UCBottomEdgeHint::init()
100{
101 QQml_setParent_noEvent(m_swipeArea, this);
102 m_swipeArea->setParentItem(this);
103
104 // set context
105 QQmlEngine::setContextForObject(m_swipeArea, qmlContext(this));
106
107 // initialize swipe area size
108 QQuickAnchors *anchors = QQuickItemPrivate::get(m_swipeArea)->anchors();
109 QQuickItemPrivate *thisPrivate = QQuickItemPrivate::get(this);
110 anchors->setLeft(thisPrivate->left());
111 anchors->setBottom(thisPrivate->bottom());
112 anchors->setRight(thisPrivate->right());
113 m_swipeArea->setImplicitHeight(UCUnits::instance().gu(SWIPE_AREA_HEIGHT_GU));
114
115 // direction
116 m_swipeArea->setDirection(UCSwipeArea::Upwards);
117
118 // grid unit sync
119 connect(&UCUnits::instance(), &UCUnits::gridUnitChanged, [this] {
120 m_swipeArea->setImplicitHeight(UCUnits::instance().gu(SWIPE_AREA_HEIGHT_GU));
121 });
122
123 // connect to gesture detection
124 connect(m_swipeArea, &UCSwipeArea::draggingChanged,
125 this, &UCBottomEdgeHint::onDraggingChanged, Qt::DirectConnection);
126}
127
90void UCBottomEdgeHint::itemChange(ItemChange change, const ItemChangeData &data)128void UCBottomEdgeHint::itemChange(ItemChange change, const ItemChangeData &data)
91{129{
92 UCStyledItemBase::itemChange(change, data);130 UCActionItem::itemChange(change, data);
93 if (change == ItemParentHasChanged) {131 if (change == ItemParentHasChanged) {
94 QQmlProperty bottomAnchors(this, "anchors.bottom", qmlContext(this));132 QQmlProperty bottomAnchors(this, "anchors.bottom", qmlContext(this));
95 if (data.item && !QQmlPropertyPrivate::binding(bottomAnchors)) {133 if (data.item && !QQmlPropertyPrivate::binding(bottomAnchors)) {
@@ -101,7 +139,7 @@
101139
102void UCBottomEdgeHint::timerEvent(QTimerEvent *event)140void UCBottomEdgeHint::timerEvent(QTimerEvent *event)
103{141{
104 UCStyledItemBase::timerEvent(event);142 UCActionItem::timerEvent(event);
105 if (event->timerId() == m_deactivationTimer.timerId()) {143 if (event->timerId() == m_deactivationTimer.timerId()) {
106 setStatus(Inactive);144 setStatus(Inactive);
107 m_deactivationTimer.stop();145 m_deactivationTimer.stop();
@@ -111,49 +149,37 @@
111// handle clicked event when locked and enter or return is pressed149// handle clicked event when locked and enter or return is pressed
112void UCBottomEdgeHint::keyPressEvent(QKeyEvent *event)150void UCBottomEdgeHint::keyPressEvent(QKeyEvent *event)
113{151{
114 UCStyledItemBase::keyPressEvent(event);152 UCActionItem::keyPressEvent(event);
115 if ((status() >= Active) && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) {153 if ((status() >= Active) && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) {
116 Q_EMIT clicked();154 Q_EMIT clicked();
117 }155 }
118}156}
119157
120// handle gesture detection
121void UCBottomEdgeHint::touchEvent(QTouchEvent *event)
122{
123 UCStyledItemBase::touchEvent(event);
124 m_gestureDetector.handleTouchEvent(this, event);
125}
126
127// handle click event158// handle click event
128void UCBottomEdgeHint::mousePressEvent(QMouseEvent *event)159void UCBottomEdgeHint::mousePressEvent(QMouseEvent *event)
129{160{
130 if (contains(event->localPos()) && (m_status >= Active)) {161 if (contains(event->localPos()) && (m_status >= Active)) {
131 m_pressed = true;162 m_pressed = true;
132 } else {163 } else {
133 UCStyledItemBase::mousePressEvent(event);164 UCActionItem::mousePressEvent(event);
134 }165 }
135}166}
136void UCBottomEdgeHint::mouseReleaseEvent(QMouseEvent *event)167void UCBottomEdgeHint::mouseReleaseEvent(QMouseEvent *event)
137{168{
138 UCStyledItemBase::mouseReleaseEvent(event);169 UCActionItem::mouseReleaseEvent(event);
139 if (m_pressed && (m_status >= Active)) {170 if (m_pressed && (m_status >= Active)) {
140 Q_EMIT clicked();171 Q_EMIT clicked();
141 }172 }
142}173}
143174
144// watch gesture detection status changes175// watch gesture detection status changes
145void UCBottomEdgeHint::onBottomUpSwipeDetected()176void UCBottomEdgeHint::onDraggingChanged(bool dragging)
146{177{
147 m_deactivationTimer.stop();178 if (dragging) {
148 setStatus(Active);179 m_deactivationTimer.stop();
149}180 setStatus(Active);
150181 } else if (m_status == Active) {
151void UCBottomEdgeHint::onGestureStatusChanged(GestureDetector::Status status)182 m_deactivationTimer.start(m_deactivateTimeout, this);
152{
153 if (status == GestureDetector::Completed) {
154 if (m_status == Active) {
155 m_deactivationTimer.start(m_deactivateTimeout, this);
156 }
157 }183 }
158}184}
159185
@@ -200,7 +226,6 @@
200 this, &UCBottomEdgeHint::handleFlickableActivation);226 this, &UCBottomEdgeHint::handleFlickableActivation);
201 disconnect(m_flickable, &QQuickFlickable::movingChanged,227 disconnect(m_flickable, &QQuickFlickable::movingChanged,
202 this, &UCBottomEdgeHint::handleFlickableActivation);228 this, &UCBottomEdgeHint::handleFlickableActivation);
203 m_gestureDetector.removeItemFilter(m_flickable);
204 }229 }
205 m_flickable = flickable;230 m_flickable = flickable;
206 if (m_flickable) {231 if (m_flickable) {
@@ -208,7 +233,6 @@
208 this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection);233 this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection);
209 connect(m_flickable, &QQuickFlickable::movingChanged,234 connect(m_flickable, &QQuickFlickable::movingChanged,
210 this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection);235 this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection);
211 m_gestureDetector.setItemFilter(m_flickable);
212 }236 }
213 Q_EMIT flickableChanged();237 Q_EMIT flickableChanged();
214}238}
@@ -216,7 +240,7 @@
216// flickable moves hide the hint only if the current status is not Locked240// flickable moves hide the hint only if the current status is not Locked
217void UCBottomEdgeHint::handleFlickableActivation()241void UCBottomEdgeHint::handleFlickableActivation()
218{242{
219 if (m_status < Locked && !m_gestureDetector.isDetecting() && !m_deactivationTimer.isActive()) {243 if (m_status < Locked && !m_swipeArea->dragging() && !m_deactivationTimer.isActive()) {
220 bool moving = m_flickable->isFlicking() || m_flickable->isMoving();244 bool moving = m_flickable->isFlicking() || m_flickable->isMoving();
221 if (moving) {245 if (moving) {
222 setStatus(Hidden);246 setStatus(Hidden);
@@ -304,6 +328,7 @@
304UCBottomEdgeHint::Status UCBottomEdgeHint::status()328UCBottomEdgeHint::Status UCBottomEdgeHint::status()
305{329{
306 // FIXME: we won't need this once we get the QInputDeviceInfo reporting mouse attach/detach330 // FIXME: we won't need this once we get the QInputDeviceInfo reporting mouse attach/detach
331 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808
307 if (QuickUtils::instance().mouseAttached()) {332 if (QuickUtils::instance().mouseAttached()) {
308 m_status = Locked;333 m_status = Locked;
309 }334 }
@@ -313,15 +338,19 @@
313void UCBottomEdgeHint::setStatus(Status status)338void UCBottomEdgeHint::setStatus(Status status)
314{339{
315 // FIXME: we need QInputDeviceInfo to complete this!340 // FIXME: we need QInputDeviceInfo to complete this!
341 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808
316 // cannot unlock if mouse is attached or we don't have touch screen available342 // cannot unlock if mouse is attached or we don't have touch screen available
317 if (status == m_status || (status != Locked && QuickUtils::instance().mouseAttached())) {343 if (status == m_status || (status != Locked && QuickUtils::instance().mouseAttached())) {
318 return;344 return;
319 }345 }
346 // if the previous state was Locked and the new one is Active, start deactivation timer
347 if (m_status == Locked && status == Active && !m_deactivationTimer.isActive()) {
348 m_deactivationTimer.start(m_deactivateTimeout, this);
349 } else if (status != Active && m_deactivationTimer.isActive()) {
350 // make sure we stop the deactivation timer if Inactive or Locked
351 m_deactivationTimer.stop();
352 }
320 m_status = status;353 m_status = status;
321 // make sure we stop the deactivation timer if Inactive or Locked
322 if (status != Active && m_deactivationTimer.isActive()) {
323 m_deactivationTimer.stop();
324 }
325 Q_EMIT statusChanged();354 Q_EMIT statusChanged();
326}355}
327356
@@ -345,3 +374,10 @@
345 }374 }
346 Q_EMIT deactivateTimeoutChanged();375 Q_EMIT deactivateTimeoutChanged();
347}376}
377
378/*!
379 * \qmlproperty SwipeArea BottomEdgeHint::swipeArea
380 * \readonly
381 * The property specifies the SwipeArea attached to the component driving its
382 * behavior.
383 */
348384
=== modified file 'src/Ubuntu/Components/plugin/ucbottomedgehint.h'
--- src/Ubuntu/Components/plugin/ucbottomedgehint.h 2015-11-05 14:06:36 +0000
+++ src/Ubuntu/Components/plugin/ucbottomedgehint.h 2015-11-19 10:02:45 +0000
@@ -19,20 +19,18 @@
19#ifndef UCBOTTOMEDGEHINT_H19#ifndef UCBOTTOMEDGEHINT_H
20#define UCBOTTOMEDGEHINT_H20#define UCBOTTOMEDGEHINT_H
2121
22#include "ucstyleditembase.h"22#include "ucactionitem.h"
23#include "privates/gesturedetector.h"
2423
25class QQuickFlickable;24class QQuickFlickable;
26class UCBottomEdgeHint : public UCStyledItemBase25class UCSwipeArea;
26class UCBottomEdgeHint : public UCActionItem
27{27{
28 Q_OBJECT28 Q_OBJECT
29 Q_ENUMS(Status)29 Q_ENUMS(Status)
30 Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged FINAL)
31 Q_PROPERTY(QUrl iconSource MEMBER m_iconSource NOTIFY iconSourceChanged FINAL)
32 Q_PROPERTY(QString iconName MEMBER m_iconName NOTIFY iconNameChanged FINAL)
33 Q_PROPERTY(QQuickFlickable *flickable MEMBER m_flickable WRITE setFlickable NOTIFY flickableChanged FINAL)30 Q_PROPERTY(QQuickFlickable *flickable MEMBER m_flickable WRITE setFlickable NOTIFY flickableChanged FINAL)
34 Q_PROPERTY(Status status MEMBER m_status WRITE setStatus NOTIFY statusChanged FINAL)31 Q_PROPERTY(Status status MEMBER m_status WRITE setStatus NOTIFY statusChanged FINAL)
35 Q_PROPERTY(int deactivateTimeout MEMBER m_deactivateTimeout WRITE setDeactivateTimeout NOTIFY deactivateTimeoutChanged FINAL)32 Q_PROPERTY(int deactivateTimeout MEMBER m_deactivateTimeout WRITE setDeactivateTimeout NOTIFY deactivateTimeoutChanged FINAL)
33 Q_PROPERTY(UCSwipeArea* swipeArea READ swipeArea CONSTANT FINAL)
36 // deprecated34 // deprecated
37 Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)35 Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
38public:36public:
@@ -47,11 +45,15 @@
47 void setFlickable(QQuickFlickable *flickable);45 void setFlickable(QQuickFlickable *flickable);
48 Status status();46 Status status();
49 void setStatus(Status status);47 void setStatus(Status status);
48 void setDeactivateTimeout(int timeout);
49 UCSwipeArea *swipeArea() const
50 {
51 return m_swipeArea;
52 }
5053
51 // deprecated54 // deprecated
52 QString state() const;55 QString state() const;
53 void setState(const QString &state);56 void setState(const QString &state);
54 void setDeactivateTimeout(int timeout);
5557
56Q_SIGNALS:58Q_SIGNALS:
57 void textChanged();59 void textChanged();
@@ -66,23 +68,21 @@
66 // deprecated68 // deprecated
67 void stateChanged();69 void stateChanged();
68protected:70protected:
71 void classBegin();
69 void itemChange(ItemChange change, const ItemChangeData &data);72 void itemChange(ItemChange change, const ItemChangeData &data);
70 void timerEvent(QTimerEvent *event);73 void timerEvent(QTimerEvent *event);
71 void keyPressEvent(QKeyEvent *event);74 void keyPressEvent(QKeyEvent *event);
72 void touchEvent(QTouchEvent *event);
73 void mousePressEvent(QMouseEvent *event);75 void mousePressEvent(QMouseEvent *event);
74 void mouseReleaseEvent(QMouseEvent *event);76 void mouseReleaseEvent(QMouseEvent *event);
7577
76 void handleFlickableActivation();78 void handleFlickableActivation();
77 void onBottomUpSwipeDetected();79 void onDraggingChanged(bool dragging);
78 void onGestureStatusChanged(GestureDetector::Status status);80
81 void init();
7982
80private:83private:
81 GestureDetector m_gestureDetector;
82 QBasicTimer m_deactivationTimer;84 QBasicTimer m_deactivationTimer;
83 QString m_text;85 UCSwipeArea *m_swipeArea;
84 QUrl m_iconSource;
85 QString m_iconName;
86 QQuickFlickable *m_flickable;86 QQuickFlickable *m_flickable;
87 int m_deactivateTimeout;87 int m_deactivateTimeout;
88 Status m_status;88 Status m_status;
8989
=== modified file 'tests/unit_x11/tst_components/tst_bottomedgehint.qml'
--- tests/unit_x11/tst_components/tst_bottomedgehint.qml 2015-11-05 14:28:58 +0000
+++ tests/unit_x11/tst_components/tst_bottomedgehint.qml 2015-11-19 10:02:45 +0000
@@ -36,6 +36,11 @@
3636
37 BottomEdgeHint {37 BottomEdgeHint {
38 id: bottomEdgeHint38 id: bottomEdgeHint
39 property int triggerCount: 0
40 function trigger(v)
41 {
42 triggerCount++;
43 }
39 }44 }
40 BottomEdgeHint {45 BottomEdgeHint {
41 id: floatingHint46 id: floatingHint
@@ -199,7 +204,7 @@
199204
200 // FIXME: must be executed before the test_hiding as flick with mouse affects205 // FIXME: must be executed before the test_hiding as flick with mouse affects
201 // the touch drag on ListView for some unknown reason206 // the touch drag on ListView for some unknown reason
202 function test_touch_gesture() {207 function test_0_touch_gesture() {
203 if (hasMouseAttached) {208 if (hasMouseAttached) {
204 skip("", "The test requires touch environment");209 skip("", "The test requires touch environment");
205 }210 }
@@ -210,5 +215,13 @@
210 // then wait till we get back to Idle215 // then wait till we get back to Idle
211 tryCompare(bottomEdgeHint, "status", BottomEdgeHint.Inactive, 1000);216 tryCompare(bottomEdgeHint, "status", BottomEdgeHint.Inactive, 1000);
212 }217 }
218
219 function test_custom_trigger_on_clicked() {
220 bottomEdgeHint.status = BottomEdgeHint.Locked;
221 var prevCount = bottomEdgeHint.triggerCount;
222 mouseClick(bottomEdgeHint, centerOf(bottomEdgeHint).x, centerOf(bottomEdgeHint).y);
223 clickSpy.wait(500);
224 compare(bottomEdgeHint.triggerCount, prevCount + 1, "Overloaded trigger not called");
225 }
213 }226 }
214}227}

Subscribers

People subscribed via source and target branches