Merge lp:~zsombi/ubuntu-ui-toolkit/bottomedgehint_with_swipearea into lp:ubuntu-ui-toolkit/staging
- bottomedgehint_with_swipearea
- Merge into staging
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 |
Related bugs: |
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.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1719. By Zsombor Egri
-
staging sync
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1719
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1720. By Zsombor Egri
-
replace base class calls
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1720
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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.
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2015-11-17 14:44:49 +0000 |
3 | +++ components.api 2015-11-19 10:02:45 +0000 |
4 | @@ -175,14 +175,12 @@ |
5 | property var icon |
6 | property bool iconFrame |
7 | property bool progression |
8 | -Ubuntu.Components.BottomEdgeHint 1.3: StyledItem |
9 | +Ubuntu.Components.BottomEdgeHint 1.3: ActionItem |
10 | property int deactivateTimeout |
11 | property Flickable flickable |
12 | - property string iconName |
13 | - property url iconSource |
14 | signal clicked() |
15 | property Status status |
16 | - property string text |
17 | + readonly property SwipeArea swipeArea |
18 | Ubuntu.Components.BottomEdgeHint.Status: Enum |
19 | Active |
20 | Hidden |
21 | |
22 | === modified file 'examples/ubuntu-ui-toolkit-gallery/MainPage.qml' |
23 | --- examples/ubuntu-ui-toolkit-gallery/MainPage.qml 2015-11-05 13:41:35 +0000 |
24 | +++ examples/ubuntu-ui-toolkit-gallery/MainPage.qml 2015-11-19 10:02:45 +0000 |
25 | @@ -50,6 +50,7 @@ |
26 | onTriggered: gallery.theme.name = 'Ubuntu.Components.Themes.Ambiance' |
27 | }, |
28 | Action { |
29 | + id: aboutAction |
30 | text: i18n.tr('About') |
31 | iconName: "info" |
32 | onTriggered: mainPage.pageStack.addPageToCurrentColumn(mainPage, Qt.resolvedUrl("About.qml")) |
33 | @@ -135,8 +136,6 @@ |
34 | |
35 | BottomEdgeHint { |
36 | flickable: widgetList |
37 | - text: i18n.tr('About') |
38 | - iconName: "info" |
39 | - onClicked: mainPage.pageStack.addPageToCurrentColumn(mainPage, Qt.resolvedUrl("About.qml")) |
40 | + action: aboutAction |
41 | } |
42 | } |
43 | |
44 | === modified file 'src/Ubuntu/Components/plugin/plugin.pri' |
45 | --- src/Ubuntu/Components/plugin/plugin.pri 2015-11-09 16:51:41 +0000 |
46 | +++ src/Ubuntu/Components/plugin/plugin.pri 2015-11-19 10:02:45 +0000 |
47 | @@ -94,7 +94,6 @@ |
48 | $$PWD/privates/threelabelsslot_p.h \ |
49 | $$PWD/ucimportversionchecker_p.h \ |
50 | $$PWD/ucbottomedgehint.h \ |
51 | - $$PWD/privates/gesturedetector.h \ |
52 | $$PWD/gestures/ucswipearea.h \ |
53 | $$PWD/gestures/ucswipearea_p.h \ |
54 | $$PWD/gestures/damper.h \ |
55 | @@ -163,7 +162,6 @@ |
56 | $$PWD/privates/threelabelsslot_p.cpp \ |
57 | $$PWD/ucimportversionchecker_p.cpp \ |
58 | $$PWD/ucbottomedgehint.cpp \ |
59 | - $$PWD/privates/gesturedetector.cpp \ |
60 | $$PWD/gestures/ucswipearea.cpp \ |
61 | |
62 | # adapters |
63 | |
64 | === removed file 'src/Ubuntu/Components/plugin/privates/gesturedetector.cpp' |
65 | --- src/Ubuntu/Components/plugin/privates/gesturedetector.cpp 2015-11-13 09:02:23 +0000 |
66 | +++ src/Ubuntu/Components/plugin/privates/gesturedetector.cpp 1970-01-01 00:00:00 +0000 |
67 | @@ -1,142 +0,0 @@ |
68 | -/* |
69 | - * Copyright 2015 Canonical Ltd. |
70 | - * |
71 | - * This program is free software; you can redistribute it and/or modify |
72 | - * it under the terms of the GNU Lesser General Public License as published by |
73 | - * the Free Software Foundation; version 3. |
74 | - * |
75 | - * This program is distributed in the hope that it will be useful, |
76 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
77 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
78 | - * GNU Lesser General Public License for more details. |
79 | - * |
80 | - * You should have received a copy of the GNU Lesser General Public License |
81 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
82 | - * |
83 | - * Authors: Zsombor Egri <zsombor.egri@canonical.com> |
84 | - */ |
85 | - |
86 | -#include "gesturedetector.h" |
87 | -#include "ucunits.h" |
88 | -#include <QtCore/QEvent> |
89 | -#include <QtCore/QRectF> |
90 | -#include <QtGui/QTouchEvent> |
91 | -#include <QtQuick/QQuickItem> |
92 | -#include <QtGui/QGuiApplication> |
93 | -#include <QtGui/QStyleHints> |
94 | - |
95 | -#define DETECTION_AREA_THICKNESS_GU 1.2 |
96 | - |
97 | -GestureDetector::GestureDetector(QObject *parent) |
98 | - : QObject(parent) |
99 | - , m_owner(qobject_cast<QQuickItem*>(parent)) |
100 | - , m_status(Ready) |
101 | - , m_bottomUpSwipeDetected(false) |
102 | -{ |
103 | - Q_ASSERT(m_owner); |
104 | -} |
105 | -GestureDetector::~GestureDetector() |
106 | -{ |
107 | - Q_FOREACH(QObject *object, m_filteredItems) { |
108 | - object->removeEventFilter(this); |
109 | - } |
110 | - m_filteredItems.clear(); |
111 | -} |
112 | - |
113 | -void GestureDetector::onFilteredItemDeleted(QObject *object) |
114 | -{ |
115 | - if (object) { |
116 | - object->removeEventFilter(this); |
117 | - m_filteredItems.removeAll(object); |
118 | - } |
119 | -} |
120 | - |
121 | -void GestureDetector::setStatus(Status status) |
122 | -{ |
123 | - if (status == m_status) { |
124 | - return; |
125 | - } |
126 | - m_status = status; |
127 | - Q_EMIT statusChanged(m_status); |
128 | -} |
129 | - |
130 | -bool GestureDetector::isDetecting() |
131 | -{ |
132 | - return (m_status > Ready && m_status < Completed); |
133 | -} |
134 | - |
135 | -void GestureDetector::setItemFilter(QObject *item) |
136 | -{ |
137 | - m_filteredItems.append(item); |
138 | - item->installEventFilter(this); |
139 | - connect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted); |
140 | -} |
141 | - |
142 | -void GestureDetector::removeItemFilter(QObject *item) |
143 | -{ |
144 | - m_filteredItems.removeAll(item); |
145 | - item->removeEventFilter(this); |
146 | - disconnect(item, &QObject::destroyed, this, &GestureDetector::onFilteredItemDeleted); |
147 | -} |
148 | - |
149 | -bool GestureDetector::handleTouchEvent(QObject *target, QTouchEvent *event) |
150 | -{ |
151 | - switch (event->type()) { |
152 | - case QEvent::TouchBegin: { |
153 | - setStatus(Ready); |
154 | - QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos()); |
155 | - qreal thickness = UCUnits::instance().gu(DETECTION_AREA_THICKNESS_GU); |
156 | - QRectF detectionArea(0.0, m_owner->height() - thickness, m_owner->width(), thickness); |
157 | - if (detectionArea.contains(itemPoint)) { |
158 | - m_startPoint = itemPoint; |
159 | - setStatus(Started); |
160 | - if (target == parent()) { |
161 | - event->accept(); |
162 | - return true; |
163 | - } |
164 | - } |
165 | - return false; |
166 | - } |
167 | - case QEvent::TouchEnd: |
168 | - { |
169 | - m_startPoint = QPointF(); |
170 | - setStatus(Completed); |
171 | - return false; |
172 | - } |
173 | - case QEvent::TouchCancel: { |
174 | - m_startPoint = QPointF(); |
175 | - setStatus(Ready); |
176 | - return false; |
177 | - } |
178 | - case QEvent::TouchUpdate: { |
179 | - if (m_status == Started) { |
180 | - QPointF itemPoint = m_owner->mapFromScene(event->touchPoints()[0].scenePos()); |
181 | - if (abs(m_startPoint.y() - itemPoint.y()) >= qApp->styleHints()->startDragDistance()) { |
182 | - setStatus(Detected); |
183 | - Q_EMIT bottomUpSwipeDetected(); |
184 | - } |
185 | - } |
186 | - return false; |
187 | - } |
188 | - default: return false; |
189 | - } |
190 | -} |
191 | - |
192 | -bool GestureDetector::eventFilter(QObject *target, QEvent *event) |
193 | -{ |
194 | - if (m_filteredItems.contains(target)) { |
195 | - QEvent::Type type = event->type(); |
196 | - if (type == QEvent::TouchBegin |
197 | - || type == QEvent::TouchUpdate |
198 | - || type == QEvent::TouchEnd |
199 | - || type == QEvent::TouchCancel) { |
200 | - QTouchEvent *touch = static_cast<QTouchEvent*>(event); |
201 | - return handleTouchEvent(target, touch); |
202 | - } else { |
203 | - // pass it on |
204 | - return false; |
205 | - } |
206 | - } else { |
207 | - return QObject::eventFilter(target, event); |
208 | - } |
209 | -} |
210 | |
211 | === removed file 'src/Ubuntu/Components/plugin/privates/gesturedetector.h' |
212 | --- src/Ubuntu/Components/plugin/privates/gesturedetector.h 2015-11-13 09:02:23 +0000 |
213 | +++ src/Ubuntu/Components/plugin/privates/gesturedetector.h 1970-01-01 00:00:00 +0000 |
214 | @@ -1,75 +0,0 @@ |
215 | -/* |
216 | - * Copyright 2015 Canonical Ltd. |
217 | - * |
218 | - * This program is free software; you can redistribute it and/or modify |
219 | - * it under the terms of the GNU Lesser General Public License as published by |
220 | - * the Free Software Foundation; version 3. |
221 | - * |
222 | - * This program is distributed in the hope that it will be useful, |
223 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
224 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
225 | - * GNU Lesser General Public License for more details. |
226 | - * |
227 | - * You should have received a copy of the GNU Lesser General Public License |
228 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
229 | - * |
230 | - * Authors: Zsombor Egri <zsombor.egri@canonical.com> |
231 | - */ |
232 | - |
233 | -#ifndef GESTUREDETECTOR_H |
234 | -#define GESTUREDETECTOR_H |
235 | - |
236 | -#include <QtCore/QObject> |
237 | -#include <QtCore/QPointF> |
238 | -#include <QtCore/QList> |
239 | - |
240 | -/* |
241 | - * A simple gesture detection filter class that can be used in components to detect |
242 | - * various gestures. Yet swipe from bottom up is the only gesture handled. |
243 | - * It does not grab or consume the event from the environment, acts as a filter. |
244 | - */ |
245 | -class QTouchEvent; |
246 | -class QQuickItem; |
247 | -class GestureDetector : public QObject |
248 | -{ |
249 | - Q_OBJECT |
250 | -public: |
251 | - enum Status { |
252 | - Ready, |
253 | - Started, |
254 | - Detected, |
255 | - Completed |
256 | - }; |
257 | - explicit GestureDetector(QObject *parent = 0); |
258 | - ~GestureDetector(); |
259 | - |
260 | - bool isDetecting(); |
261 | - |
262 | - void setItemFilter(QObject *item); |
263 | - void removeItemFilter(QObject *item); |
264 | - |
265 | - bool handleTouchEvent(QObject *target, QTouchEvent *event); |
266 | - |
267 | -Q_SIGNALS: |
268 | - void statusChanged(Status status); |
269 | - |
270 | - void bottomUpSwipeDetected(); |
271 | - |
272 | -public Q_SLOTS: |
273 | - |
274 | -protected: |
275 | - bool eventFilter(QObject *target, QEvent *event); |
276 | - |
277 | - void setStatus(Status status); |
278 | - |
279 | -private: |
280 | - QList<QObject*> m_filteredItems; |
281 | - QPointF m_startPoint; |
282 | - QQuickItem *m_owner; |
283 | - Status m_status; |
284 | - bool m_bottomUpSwipeDetected:1; |
285 | - |
286 | - void onFilteredItemDeleted(QObject *object); |
287 | -}; |
288 | - |
289 | -#endif // GESTUREDETECTOR_H |
290 | |
291 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedgehint.cpp' |
292 | --- src/Ubuntu/Components/plugin/ucbottomedgehint.cpp 2015-11-05 14:28:58 +0000 |
293 | +++ src/Ubuntu/Components/plugin/ucbottomedgehint.cpp 2015-11-19 10:02:45 +0000 |
294 | @@ -20,14 +20,17 @@ |
295 | #include "ucstyleditembase_p.h" |
296 | #include "quickutils.h" |
297 | #include "ucunits.h" |
298 | +#include "gestures/ucswipearea.h" |
299 | #include <QtQml/private/qqmlproperty_p.h> |
300 | #include <QtQuick/private/qquickflickable_p.h> |
301 | |
302 | +#define SWIPE_AREA_HEIGHT_GU 3 |
303 | + |
304 | /*! |
305 | \qmltype BottomEdgeHint |
306 | \inqmlmodule Ubuntu.Components 1.3 |
307 | \ingroup ubuntu |
308 | - \inherits StyledItem |
309 | + \inherits ActionItem |
310 | \brief The BottomEdgeHint shows the availability of extra features |
311 | available from the bottom edge of the application. |
312 | |
313 | @@ -50,14 +53,19 @@ |
314 | The component is styled through \b BottomEdgeHintStyle. |
315 | */ |
316 | UCBottomEdgeHint::UCBottomEdgeHint(QQuickItem *parent) |
317 | - : UCStyledItemBase(parent) |
318 | - , m_gestureDetector(this) |
319 | + : UCActionItem(parent) |
320 | + , m_swipeArea(new UCSwipeArea) |
321 | , m_flickable(Q_NULLPTR) |
322 | , m_deactivateTimeout(800) |
323 | // FIXME: we need QInputDeviceInfo to be complete with the locked!! |
324 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808 |
325 | , m_status(QuickUtils::instance().mouseAttached() ? Locked : Inactive) |
326 | , m_pressed(false) |
327 | { |
328 | + connect(this, &UCBottomEdgeHint::clicked, [=]() { |
329 | + // make sure the overloaded trigger is called! |
330 | + metaObject()->invokeMethod(this, "trigger", Q_ARG(QVariant, QVariant())); |
331 | + }); |
332 | /* |
333 | * we cannot use setStyleName as that will trigger style loading |
334 | * and the qmlEngine is not known at this phase of the of the initialization |
335 | @@ -69,13 +77,8 @@ |
336 | // connect old stateChanged |
337 | connect(this, &QQuickItem::stateChanged, this, &UCBottomEdgeHint::stateChanged); |
338 | |
339 | - // connect to gesture detection |
340 | - connect(&m_gestureDetector, &GestureDetector::bottomUpSwipeDetected, |
341 | - this, &UCBottomEdgeHint::onBottomUpSwipeDetected); |
342 | - connect(&m_gestureDetector, &GestureDetector::statusChanged, |
343 | - this, &UCBottomEdgeHint::onGestureStatusChanged); |
344 | - |
345 | // FIXME: use QInputDeviceInfo once available |
346 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808 |
347 | connect(&QuickUtils::instance(), &QuickUtils::mouseAttachedChanged, [this]() { |
348 | setStatus(QuickUtils::instance().mouseAttached() ? Locked : Active); |
349 | if (m_status == Active) { |
350 | @@ -87,9 +90,44 @@ |
351 | setAcceptedMouseButtons(Qt::LeftButton); |
352 | } |
353 | |
354 | +void UCBottomEdgeHint::classBegin() |
355 | +{ |
356 | + UCActionItem::classBegin(); |
357 | + init(); |
358 | +} |
359 | + |
360 | +void UCBottomEdgeHint::init() |
361 | +{ |
362 | + QQml_setParent_noEvent(m_swipeArea, this); |
363 | + m_swipeArea->setParentItem(this); |
364 | + |
365 | + // set context |
366 | + QQmlEngine::setContextForObject(m_swipeArea, qmlContext(this)); |
367 | + |
368 | + // initialize swipe area size |
369 | + QQuickAnchors *anchors = QQuickItemPrivate::get(m_swipeArea)->anchors(); |
370 | + QQuickItemPrivate *thisPrivate = QQuickItemPrivate::get(this); |
371 | + anchors->setLeft(thisPrivate->left()); |
372 | + anchors->setBottom(thisPrivate->bottom()); |
373 | + anchors->setRight(thisPrivate->right()); |
374 | + m_swipeArea->setImplicitHeight(UCUnits::instance().gu(SWIPE_AREA_HEIGHT_GU)); |
375 | + |
376 | + // direction |
377 | + m_swipeArea->setDirection(UCSwipeArea::Upwards); |
378 | + |
379 | + // grid unit sync |
380 | + connect(&UCUnits::instance(), &UCUnits::gridUnitChanged, [this] { |
381 | + m_swipeArea->setImplicitHeight(UCUnits::instance().gu(SWIPE_AREA_HEIGHT_GU)); |
382 | + }); |
383 | + |
384 | + // connect to gesture detection |
385 | + connect(m_swipeArea, &UCSwipeArea::draggingChanged, |
386 | + this, &UCBottomEdgeHint::onDraggingChanged, Qt::DirectConnection); |
387 | +} |
388 | + |
389 | void UCBottomEdgeHint::itemChange(ItemChange change, const ItemChangeData &data) |
390 | { |
391 | - UCStyledItemBase::itemChange(change, data); |
392 | + UCActionItem::itemChange(change, data); |
393 | if (change == ItemParentHasChanged) { |
394 | QQmlProperty bottomAnchors(this, "anchors.bottom", qmlContext(this)); |
395 | if (data.item && !QQmlPropertyPrivate::binding(bottomAnchors)) { |
396 | @@ -101,7 +139,7 @@ |
397 | |
398 | void UCBottomEdgeHint::timerEvent(QTimerEvent *event) |
399 | { |
400 | - UCStyledItemBase::timerEvent(event); |
401 | + UCActionItem::timerEvent(event); |
402 | if (event->timerId() == m_deactivationTimer.timerId()) { |
403 | setStatus(Inactive); |
404 | m_deactivationTimer.stop(); |
405 | @@ -111,49 +149,37 @@ |
406 | // handle clicked event when locked and enter or return is pressed |
407 | void UCBottomEdgeHint::keyPressEvent(QKeyEvent *event) |
408 | { |
409 | - UCStyledItemBase::keyPressEvent(event); |
410 | + UCActionItem::keyPressEvent(event); |
411 | if ((status() >= Active) && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) { |
412 | Q_EMIT clicked(); |
413 | } |
414 | } |
415 | |
416 | -// handle gesture detection |
417 | -void UCBottomEdgeHint::touchEvent(QTouchEvent *event) |
418 | -{ |
419 | - UCStyledItemBase::touchEvent(event); |
420 | - m_gestureDetector.handleTouchEvent(this, event); |
421 | -} |
422 | - |
423 | // handle click event |
424 | void UCBottomEdgeHint::mousePressEvent(QMouseEvent *event) |
425 | { |
426 | if (contains(event->localPos()) && (m_status >= Active)) { |
427 | m_pressed = true; |
428 | } else { |
429 | - UCStyledItemBase::mousePressEvent(event); |
430 | + UCActionItem::mousePressEvent(event); |
431 | } |
432 | } |
433 | void UCBottomEdgeHint::mouseReleaseEvent(QMouseEvent *event) |
434 | { |
435 | - UCStyledItemBase::mouseReleaseEvent(event); |
436 | + UCActionItem::mouseReleaseEvent(event); |
437 | if (m_pressed && (m_status >= Active)) { |
438 | Q_EMIT clicked(); |
439 | } |
440 | } |
441 | |
442 | // watch gesture detection status changes |
443 | -void UCBottomEdgeHint::onBottomUpSwipeDetected() |
444 | -{ |
445 | - m_deactivationTimer.stop(); |
446 | - setStatus(Active); |
447 | -} |
448 | - |
449 | -void UCBottomEdgeHint::onGestureStatusChanged(GestureDetector::Status status) |
450 | -{ |
451 | - if (status == GestureDetector::Completed) { |
452 | - if (m_status == Active) { |
453 | - m_deactivationTimer.start(m_deactivateTimeout, this); |
454 | - } |
455 | +void UCBottomEdgeHint::onDraggingChanged(bool dragging) |
456 | +{ |
457 | + if (dragging) { |
458 | + m_deactivationTimer.stop(); |
459 | + setStatus(Active); |
460 | + } else if (m_status == Active) { |
461 | + m_deactivationTimer.start(m_deactivateTimeout, this); |
462 | } |
463 | } |
464 | |
465 | @@ -200,7 +226,6 @@ |
466 | this, &UCBottomEdgeHint::handleFlickableActivation); |
467 | disconnect(m_flickable, &QQuickFlickable::movingChanged, |
468 | this, &UCBottomEdgeHint::handleFlickableActivation); |
469 | - m_gestureDetector.removeItemFilter(m_flickable); |
470 | } |
471 | m_flickable = flickable; |
472 | if (m_flickable) { |
473 | @@ -208,7 +233,6 @@ |
474 | this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection); |
475 | connect(m_flickable, &QQuickFlickable::movingChanged, |
476 | this, &UCBottomEdgeHint::handleFlickableActivation, Qt::DirectConnection); |
477 | - m_gestureDetector.setItemFilter(m_flickable); |
478 | } |
479 | Q_EMIT flickableChanged(); |
480 | } |
481 | @@ -216,7 +240,7 @@ |
482 | // flickable moves hide the hint only if the current status is not Locked |
483 | void UCBottomEdgeHint::handleFlickableActivation() |
484 | { |
485 | - if (m_status < Locked && !m_gestureDetector.isDetecting() && !m_deactivationTimer.isActive()) { |
486 | + if (m_status < Locked && !m_swipeArea->dragging() && !m_deactivationTimer.isActive()) { |
487 | bool moving = m_flickable->isFlicking() || m_flickable->isMoving(); |
488 | if (moving) { |
489 | setStatus(Hidden); |
490 | @@ -304,6 +328,7 @@ |
491 | UCBottomEdgeHint::Status UCBottomEdgeHint::status() |
492 | { |
493 | // FIXME: we won't need this once we get the QInputDeviceInfo reporting mouse attach/detach |
494 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808 |
495 | if (QuickUtils::instance().mouseAttached()) { |
496 | m_status = Locked; |
497 | } |
498 | @@ -313,15 +338,19 @@ |
499 | void UCBottomEdgeHint::setStatus(Status status) |
500 | { |
501 | // FIXME: we need QInputDeviceInfo to complete this! |
502 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808 |
503 | // cannot unlock if mouse is attached or we don't have touch screen available |
504 | if (status == m_status || (status != Locked && QuickUtils::instance().mouseAttached())) { |
505 | return; |
506 | } |
507 | + // if the previous state was Locked and the new one is Active, start deactivation timer |
508 | + if (m_status == Locked && status == Active && !m_deactivationTimer.isActive()) { |
509 | + m_deactivationTimer.start(m_deactivateTimeout, this); |
510 | + } else if (status != Active && m_deactivationTimer.isActive()) { |
511 | + // make sure we stop the deactivation timer if Inactive or Locked |
512 | + m_deactivationTimer.stop(); |
513 | + } |
514 | m_status = status; |
515 | - // make sure we stop the deactivation timer if Inactive or Locked |
516 | - if (status != Active && m_deactivationTimer.isActive()) { |
517 | - m_deactivationTimer.stop(); |
518 | - } |
519 | Q_EMIT statusChanged(); |
520 | } |
521 | |
522 | @@ -345,3 +374,10 @@ |
523 | } |
524 | Q_EMIT deactivateTimeoutChanged(); |
525 | } |
526 | + |
527 | +/*! |
528 | + * \qmlproperty SwipeArea BottomEdgeHint::swipeArea |
529 | + * \readonly |
530 | + * The property specifies the SwipeArea attached to the component driving its |
531 | + * behavior. |
532 | + */ |
533 | |
534 | === modified file 'src/Ubuntu/Components/plugin/ucbottomedgehint.h' |
535 | --- src/Ubuntu/Components/plugin/ucbottomedgehint.h 2015-11-05 14:06:36 +0000 |
536 | +++ src/Ubuntu/Components/plugin/ucbottomedgehint.h 2015-11-19 10:02:45 +0000 |
537 | @@ -19,20 +19,18 @@ |
538 | #ifndef UCBOTTOMEDGEHINT_H |
539 | #define UCBOTTOMEDGEHINT_H |
540 | |
541 | -#include "ucstyleditembase.h" |
542 | -#include "privates/gesturedetector.h" |
543 | +#include "ucactionitem.h" |
544 | |
545 | class QQuickFlickable; |
546 | -class UCBottomEdgeHint : public UCStyledItemBase |
547 | +class UCSwipeArea; |
548 | +class UCBottomEdgeHint : public UCActionItem |
549 | { |
550 | Q_OBJECT |
551 | Q_ENUMS(Status) |
552 | - Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged FINAL) |
553 | - Q_PROPERTY(QUrl iconSource MEMBER m_iconSource NOTIFY iconSourceChanged FINAL) |
554 | - Q_PROPERTY(QString iconName MEMBER m_iconName NOTIFY iconNameChanged FINAL) |
555 | Q_PROPERTY(QQuickFlickable *flickable MEMBER m_flickable WRITE setFlickable NOTIFY flickableChanged FINAL) |
556 | Q_PROPERTY(Status status MEMBER m_status WRITE setStatus NOTIFY statusChanged FINAL) |
557 | Q_PROPERTY(int deactivateTimeout MEMBER m_deactivateTimeout WRITE setDeactivateTimeout NOTIFY deactivateTimeoutChanged FINAL) |
558 | + Q_PROPERTY(UCSwipeArea* swipeArea READ swipeArea CONSTANT FINAL) |
559 | // deprecated |
560 | Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged) |
561 | public: |
562 | @@ -47,11 +45,15 @@ |
563 | void setFlickable(QQuickFlickable *flickable); |
564 | Status status(); |
565 | void setStatus(Status status); |
566 | + void setDeactivateTimeout(int timeout); |
567 | + UCSwipeArea *swipeArea() const |
568 | + { |
569 | + return m_swipeArea; |
570 | + } |
571 | |
572 | // deprecated |
573 | QString state() const; |
574 | void setState(const QString &state); |
575 | - void setDeactivateTimeout(int timeout); |
576 | |
577 | Q_SIGNALS: |
578 | void textChanged(); |
579 | @@ -66,23 +68,21 @@ |
580 | // deprecated |
581 | void stateChanged(); |
582 | protected: |
583 | + void classBegin(); |
584 | void itemChange(ItemChange change, const ItemChangeData &data); |
585 | void timerEvent(QTimerEvent *event); |
586 | void keyPressEvent(QKeyEvent *event); |
587 | - void touchEvent(QTouchEvent *event); |
588 | void mousePressEvent(QMouseEvent *event); |
589 | void mouseReleaseEvent(QMouseEvent *event); |
590 | |
591 | void handleFlickableActivation(); |
592 | - void onBottomUpSwipeDetected(); |
593 | - void onGestureStatusChanged(GestureDetector::Status status); |
594 | + void onDraggingChanged(bool dragging); |
595 | + |
596 | + void init(); |
597 | |
598 | private: |
599 | - GestureDetector m_gestureDetector; |
600 | QBasicTimer m_deactivationTimer; |
601 | - QString m_text; |
602 | - QUrl m_iconSource; |
603 | - QString m_iconName; |
604 | + UCSwipeArea *m_swipeArea; |
605 | QQuickFlickable *m_flickable; |
606 | int m_deactivateTimeout; |
607 | Status m_status; |
608 | |
609 | === modified file 'tests/unit_x11/tst_components/tst_bottomedgehint.qml' |
610 | --- tests/unit_x11/tst_components/tst_bottomedgehint.qml 2015-11-05 14:28:58 +0000 |
611 | +++ tests/unit_x11/tst_components/tst_bottomedgehint.qml 2015-11-19 10:02:45 +0000 |
612 | @@ -36,6 +36,11 @@ |
613 | |
614 | BottomEdgeHint { |
615 | id: bottomEdgeHint |
616 | + property int triggerCount: 0 |
617 | + function trigger(v) |
618 | + { |
619 | + triggerCount++; |
620 | + } |
621 | } |
622 | BottomEdgeHint { |
623 | id: floatingHint |
624 | @@ -199,7 +204,7 @@ |
625 | |
626 | // FIXME: must be executed before the test_hiding as flick with mouse affects |
627 | // the touch drag on ListView for some unknown reason |
628 | - function test_touch_gesture() { |
629 | + function test_0_touch_gesture() { |
630 | if (hasMouseAttached) { |
631 | skip("", "The test requires touch environment"); |
632 | } |
633 | @@ -210,5 +215,13 @@ |
634 | // then wait till we get back to Idle |
635 | tryCompare(bottomEdgeHint, "status", BottomEdgeHint.Inactive, 1000); |
636 | } |
637 | + |
638 | + function test_custom_trigger_on_clicked() { |
639 | + bottomEdgeHint.status = BottomEdgeHint.Locked; |
640 | + var prevCount = bottomEdgeHint.triggerCount; |
641 | + mouseClick(bottomEdgeHint, centerOf(bottomEdgeHint).x, centerOf(bottomEdgeHint).y); |
642 | + clickSpy.wait(500); |
643 | + compare(bottomEdgeHint.triggerCount, prevCount + 1, "Overloaded trigger not called"); |
644 | + } |
645 | } |
646 | } |
PASSED: Continuous integration, rev:1718 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2493/ jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/1221 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/1223 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/1223/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/1220
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2493/ rebuild
http://