Merge lp:~zsombi/ubuntu-ui-toolkit/77-pressandhold into lp:ubuntu-ui-toolkit/staging
- 77-pressandhold
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Tim Peeters |
Approved revision: | 1383 |
Merged at revision: | 1387 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/77-pressandhold |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
328 lines (+130/-8) 6 files modified
components.api (+1/-0) modules/Ubuntu/Components/plugin/uclistitem.cpp (+56/-6) modules/Ubuntu/Components/plugin/uclistitem.h (+2/-0) modules/Ubuntu/Components/plugin/uclistitem_p.h (+3/-0) tests/resources/listitems/ListItemTest.qml (+8/-2) tests/unit_x11/tst_components/tst_listitem.qml (+60/-0) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/77-pressandhold |
Related bugs: | |
Related blueprints: |
SDK: Design a new ListItem and layouts
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Tim Peeters | Approve | ||
Review via email: mp+246940@code.launchpad.net |
Commit message
Introducing pressAndHold signal into ListItem.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1381. By Zsombor Egri
-
staging sync
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1381
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1382. By Zsombor Egri
-
staging sync
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1382
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
If you press on a list item without actions, and then start dragging, the long-press still takes effect. This was not totally expected for me, but I tested the MouseArea behavior and that is the same. Nice! :)
When I long-press on a list item with actions it works fine (and it doesn't trigger when dragging the actions).
Tim Peeters (tpeeters) wrote : | # |
82 + * onPressAndHold: console.
"clicked" should be "long-pressed" ;)
Tim Peeters (tpeeters) wrote : | # |
105 + * The signal is emitted when the list item is long pressed. When a slot is connected,
106 + * no \l clicked signal will be emitted, similarly to MouseArea's pressAndHold.
shouldn't that be "When a slot is triggered,"? Connected seems misleading here.
- 1383. By Zsombor Egri
-
review comments applied
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2015-01-22 06:15:59 +0000 |
3 | +++ components.api 2015-01-22 11:34:38 +0000 |
4 | @@ -882,6 +882,7 @@ |
5 | Property { name: "style"; type: "QQmlComponent"; isPointer: true } |
6 | Property { name: "__styleInstance"; type: "QQuickItem"; isReadonly: true; isPointer: true } |
7 | Signal { name: "clicked" } |
8 | + Signal { name: "pressAndHold" } |
9 | Signal { name: "contentMovementStarted" } |
10 | Signal { name: "contentMovementEnded" } |
11 | name: "UCListItemActions" |
12 | |
13 | === modified file 'modules/Ubuntu/Components/plugin/uclistitem.cpp' |
14 | --- modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-01-20 10:24:08 +0000 |
15 | +++ modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-01-22 11:34:38 +0000 |
16 | @@ -28,6 +28,8 @@ |
17 | #include <QtQuick/private/qquickitem_p.h> |
18 | #include <QtQuick/private/qquickflickable_p.h> |
19 | #include <QtQuick/private/qquickpositioners_p.h> |
20 | +#include <QtGui/QGuiApplication> |
21 | +#include <QtGui/QStyleHints> |
22 | #include <QtQuick/private/qquickanimation_p.h> |
23 | #include <QtQuick/private/qquickmousearea_p.h> |
24 | #include "uclistitemstyle.h" |
25 | @@ -395,6 +397,14 @@ |
26 | return QObjectPrivate::get(q)->isSignalConnected(signalIdx); |
27 | } |
28 | |
29 | +bool UCListItemPrivate::isPressAndHoldConnected() |
30 | +{ |
31 | + Q_Q(UCListItem); |
32 | + static QMetaMethod method = QMetaMethod::fromSignal(&UCListItem::pressAndHold); |
33 | + static int signalIdx = QMetaObjectPrivate::signalIndex(method); |
34 | + return QObjectPrivate::get(q)->isSignalConnected(signalIdx); |
35 | +} |
36 | + |
37 | void UCListItemPrivate::_q_updateThemedData() |
38 | { |
39 | Q_Q(UCListItem); |
40 | @@ -593,7 +603,8 @@ |
41 | // action, leading or trailing actions list or at least an active child component declared |
42 | QQuickMouseArea *ma = q->findChild<QQuickMouseArea*>(); |
43 | bool activeMouseArea = ma && ma->isEnabled(); |
44 | - return !activeComponent && (isClickedConnected() || leadingActions || trailingActions || activeMouseArea); |
45 | + return !activeComponent && (isClickedConnected() || isPressAndHoldConnected() || |
46 | + leadingActions || trailingActions || activeMouseArea); |
47 | } |
48 | |
49 | // set highlighted flag and update contentItem |
50 | @@ -604,6 +615,12 @@ |
51 | suppressClick = false; |
52 | Q_Q(UCListItem); |
53 | q->update(); |
54 | + if (highlighted) { |
55 | + // start pressandhold timer |
56 | + pressAndHoldTimer.start(QGuiApplication::styleHints()->mousePressAndHoldInterval(), q); |
57 | + } else { |
58 | + pressAndHoldTimer.stop(); |
59 | + } |
60 | Q_EMIT q->highlightedChanged(); |
61 | } |
62 | } |
63 | @@ -697,9 +714,9 @@ |
64 | * properties. The list item is highlighted if there is an action attached to it. |
65 | * This means that the list item must have an active component declared as child, |
66 | * at least leading- or trailing actions specified, or to have a slot connected to |
67 | - * \l clicked signal. In any other case the component will not be highlighted, and |
68 | - * \l highlighted property will not be toggled either. Also, there will be no highlight |
69 | - * happening if the click happens on the active component. |
70 | + * \l clicked or \l pressAndHold signal. In any other case the component will not |
71 | + * be highlighted, and \l highlighted property will not be toggled either. Also, |
72 | + * there will be no highlight happening if the click happens on the active component. |
73 | * \qml |
74 | * import QtQuick 2.3 |
75 | * import Ubuntu.Components 1.2 |
76 | @@ -744,6 +761,12 @@ |
77 | * } |
78 | * ListItem { |
79 | * Label { |
80 | + * text: "onPressAndHold implemented" |
81 | + * } |
82 | + * onPressAndHold: console.log("long-pressed on ListItem with onPressAndHold implemented") |
83 | + * } |
84 | + * ListItem { |
85 | + * Label { |
86 | * text: "No highlight" |
87 | * } |
88 | * } |
89 | @@ -825,11 +848,22 @@ |
90 | |
91 | /*! |
92 | * \qmlsignal ListItem::clicked() |
93 | - * |
94 | * The signal is emitted when the component gets released while the \l highlighted property |
95 | * is set. The signal is not emitted if the ListItem content is swiped or when used in |
96 | * Flickable (or ListView, GridView) and the Flickable gets moved. |
97 | - */ |
98 | + * |
99 | + * If the ListItem contains a component which contains a MouseArea, the clicked |
100 | + * signal will be supressed. |
101 | + */ |
102 | + |
103 | +/*! |
104 | + * \qmlsignal ListItem::pressAndHold() |
105 | + * The signal is emitted when the list item is long pressed. |
106 | + * |
107 | + * If the ListItem contains a component which contains a MouseArea, the pressAndHold |
108 | + * signal will be supressed. |
109 | + */ |
110 | + |
111 | UCListItem::UCListItem(QQuickItem *parent) |
112 | : UCStyledItemBase(*(new UCListItemPrivate), parent) |
113 | { |
114 | @@ -1073,6 +1107,8 @@ |
115 | d->lastPos = event->localPos(); |
116 | |
117 | if (dx) { |
118 | + // stop pressAndHold timer as we started to drag |
119 | + d->pressAndHoldTimer.stop(); |
120 | d->setContentMoving(true); |
121 | // clamp X into allowed dragging area |
122 | d->clampAndMoveX(x, dx); |
123 | @@ -1146,6 +1182,20 @@ |
124 | return UCStyledItemBase::eventFilter(target, event); |
125 | } |
126 | |
127 | +void UCListItem::timerEvent(QTimerEvent *event) |
128 | +{ |
129 | + Q_D(UCListItem); |
130 | + if (event->timerId() == d->pressAndHoldTimer.timerId() && d->highlighted) { |
131 | + d->pressAndHoldTimer.stop(); |
132 | + if (isEnabled() && d->isPressAndHoldConnected()) { |
133 | + d->suppressClick = true; |
134 | + Q_EMIT pressAndHold(); |
135 | + } |
136 | + } else { |
137 | + QQuickItem::timerEvent(event); |
138 | + } |
139 | +} |
140 | + |
141 | /*! |
142 | * \qmlproperty ListItemActions ListItem::leadingActions |
143 | * |
144 | |
145 | === modified file 'modules/Ubuntu/Components/plugin/uclistitem.h' |
146 | --- modules/Ubuntu/Components/plugin/uclistitem.h 2015-01-12 15:44:59 +0000 |
147 | +++ modules/Ubuntu/Components/plugin/uclistitem.h 2015-01-22 11:34:38 +0000 |
148 | @@ -78,6 +78,7 @@ |
149 | void mouseMoveEvent(QMouseEvent *event); |
150 | bool childMouseEventFilter(QQuickItem *child, QEvent *event); |
151 | bool eventFilter(QObject *, QEvent *); |
152 | + void timerEvent(QTimerEvent *event); |
153 | |
154 | Q_SIGNALS: |
155 | void leadingActionsChanged(); |
156 | @@ -90,6 +91,7 @@ |
157 | void listItemChildrenChanged(); |
158 | |
159 | void clicked(); |
160 | + void pressAndHold(); |
161 | |
162 | void styleChanged(); |
163 | void __styleInstanceChanged(); |
164 | |
165 | === modified file 'modules/Ubuntu/Components/plugin/uclistitem_p.h' |
166 | --- modules/Ubuntu/Components/plugin/uclistitem_p.h 2015-01-12 15:44:59 +0000 |
167 | +++ modules/Ubuntu/Components/plugin/uclistitem_p.h 2015-01-22 11:34:38 +0000 |
168 | @@ -20,6 +20,7 @@ |
169 | #include "uclistitem.h" |
170 | #include "ucstyleditembase_p.h" |
171 | #include <QtCore/QPointer> |
172 | +#include <QtCore/QBasicTimer> |
173 | #include <QtQuick/private/qquickrectangle_p.h> |
174 | |
175 | #define MIN(x, y) ((x < y) ? x : y) |
176 | @@ -54,6 +55,7 @@ |
177 | } |
178 | |
179 | bool isClickedConnected(); |
180 | + bool isPressAndHoldConnected(); |
181 | void _q_updateThemedData(); |
182 | void _q_rebound(); |
183 | void promptRebound(); |
184 | @@ -79,6 +81,7 @@ |
185 | bool flicked:1; |
186 | qreal xAxisMoveThresholdGU; |
187 | qreal overshoot; |
188 | + QBasicTimer pressAndHoldTimer; |
189 | QPointF lastPos; |
190 | QPointF pressedPos; |
191 | QColor color; |
192 | |
193 | === modified file 'tests/resources/listitems/ListItemTest.qml' |
194 | --- tests/resources/listitems/ListItemTest.qml 2015-01-12 07:58:55 +0000 |
195 | +++ tests/resources/listitems/ListItemTest.qml 2015-01-22 11:34:38 +0000 |
196 | @@ -96,16 +96,21 @@ |
197 | print("click") |
198 | main.override = !main.override |
199 | } |
200 | + onPressAndHold: print("pressAndHold", objectName) |
201 | Label { |
202 | anchors.fill: parent |
203 | text: units.gridUnit + "PX/unit" |
204 | } |
205 | + Button { |
206 | + text: "Press me" |
207 | + anchors.centerIn: parent |
208 | + } |
209 | + |
210 | leadingActions: ListItemActions { |
211 | objectName: "InlineLeading" |
212 | actions: [stock] |
213 | delegate: Column { |
214 | width: height + units.gu(2) |
215 | - anchors.verticalCenter: parent.verticalCenter |
216 | Icon { |
217 | width: units.gu(3) |
218 | height: width |
219 | @@ -149,12 +154,13 @@ |
220 | clip: true |
221 | width: parent.width |
222 | height: units.gu(20) |
223 | - model: 10 |
224 | + model: 25 |
225 | pressDelay: 0 |
226 | delegate: ListItem { |
227 | objectName: "ListItem" + index |
228 | id: listItem |
229 | onClicked: print(" clicked") |
230 | + onPressAndHold: print("pressAndHold") |
231 | leadingActions: leading |
232 | trailingActions: leadingActions |
233 | Label { |
234 | |
235 | === modified file 'tests/unit_x11/tst_components/tst_listitem.qml' |
236 | --- tests/unit_x11/tst_components/tst_listitem.qml 2015-01-16 14:08:06 +0000 |
237 | +++ tests/unit_x11/tst_components/tst_listitem.qml 2015-01-22 11:34:38 +0000 |
238 | @@ -78,6 +78,7 @@ |
239 | ListItem { |
240 | id: clickedConnected |
241 | onClicked: {} |
242 | + onPressAndHold: {} |
243 | } |
244 | ListItem { |
245 | id: testItem |
246 | @@ -174,6 +175,8 @@ |
247 | highlightedSpy.clear(); |
248 | clickSpy.clear(); |
249 | actionSpy.clear(); |
250 | + pressAndHoldSpy.clear(); |
251 | + buttonSpy.clear(); |
252 | interactiveSpy.clear(); |
253 | listView.interactive = true; |
254 | // make sure we collapse |
255 | @@ -235,10 +238,12 @@ |
256 | } |
257 | |
258 | function test_clicked_on_mouse() { |
259 | + clickSpy.target = testItem; |
260 | mouseClick(testItem, testItem.width / 2, testItem.height / 2); |
261 | clickSpy.wait(); |
262 | } |
263 | function test_clicked_on_tap() { |
264 | + clickSpy.target = testItem; |
265 | TestExtras.touchClick(0, testItem, centerOf(testItem)); |
266 | clickSpy.wait(); |
267 | } |
268 | @@ -612,5 +617,60 @@ |
269 | compare(highlightedSpy.count, 0, "Should not be highlighted!"); |
270 | } |
271 | } |
272 | + |
273 | + SignalSpy { |
274 | + id: pressAndHoldSpy |
275 | + signalName: "pressAndHold" |
276 | + } |
277 | + SignalSpy { |
278 | + id: buttonSpy |
279 | + signalName: "clicked" |
280 | + target: button |
281 | + } |
282 | + function test_pressandhold_suppress_click() { |
283 | + var center = centerOf(testItem); |
284 | + pressAndHoldSpy.target = testItem; |
285 | + clickSpy.target = testItem; |
286 | + clickSpy.clear(); |
287 | + mouseLongPress(testItem, center.x, center.y); |
288 | + mouseRelease(testItem, center.x, center.y); |
289 | + pressAndHoldSpy.wait(); |
290 | + compare(clickSpy.count, 0, "Click must be suppressed when long pressed"); |
291 | + } |
292 | + |
293 | + function test_pressandhold_not_emitted_when_swiped() { |
294 | + var center = centerOf(testItem); |
295 | + pressAndHoldSpy.target = testItem; |
296 | + // move mouse slowly from left to right, the swipe threshold is 1.5 GU!!!, |
297 | + // so any value less than that will emit pressAndHold |
298 | + mouseMoveSlowly(testItem, center.x, center.y, units.gu(2), 0, 10, 100); |
299 | + mouseRelease(testItem, center.x + units.gu(1), center.y); |
300 | + compare(pressAndHoldSpy.count, 0, "pressAndHold should not be emitted!"); |
301 | + // make sure we have collapsed item |
302 | + rebound(testItem); |
303 | + } |
304 | + |
305 | + function test_pressandhold_not_emitted_when_pressed_over_active_component() { |
306 | + var press = centerOf(button); |
307 | + pressAndHoldSpy.target = controlItem; |
308 | + mouseLongPress(button, press.x, press.y); |
309 | + compare(pressAndHoldSpy.count, 0, "") |
310 | + mouseRelease(button, press.x, press.y); |
311 | + } |
312 | + |
313 | + function test_click_on_button_suppresses_listitem_click() { |
314 | + buttonSpy.target = button; |
315 | + clickSpy.target = controlItem; |
316 | + mouseClick(button, centerOf(button).x, centerOf(button).y); |
317 | + buttonSpy.wait(); |
318 | + compare(clickSpy.count, 0, "ListItem clicked() must be suppressed"); |
319 | + } |
320 | + |
321 | + function test_pressandhold_connected_causes_highlight() { |
322 | + highlightedSpy.target = clickedConnected; |
323 | + mouseLongPress(clickedConnected, centerOf(clickedConnected).x, centerOf(clickedConnected).y); |
324 | + highlightedSpy.wait(); |
325 | + mouseRelease(clickedConnected, centerOf(clickedConnected).x, centerOf(clickedConnected).y); |
326 | + } |
327 | } |
328 | } |
FAILED: Continuous integration, rev:1380 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1373/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 864 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/100 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/103 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/103/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/100 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 756 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 862 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 862/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 17209
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: 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/1373/ rebuild
http://