Merge lp:~zsombi/ubuntu-ui-toolkit/78-action-property into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 1384
Merged at revision: 1401
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/78-action-property
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/77-pressandhold
Diff against target: 388 lines (+169/-6)
8 files modified
components.api (+1/-0)
modules/Ubuntu/Components/plugin/ucaction.h (+1/-0)
modules/Ubuntu/Components/plugin/uclistitem.cpp (+80/-4)
modules/Ubuntu/Components/plugin/uclistitem.h (+3/-1)
modules/Ubuntu/Components/plugin/uclistitem_p.h (+3/-0)
modules/Ubuntu/Components/plugin/ucstyleditembase.cpp (+1/-0)
tests/resources/listitems/ListItemTest.qml (+20/-1)
tests/unit_x11/tst_components/tst_listitem.qml (+60/-0)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/78-action-property
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Approve
Review via email: mp+244087@code.launchpad.net

Commit message

Introducing action property in ListItem.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

128 + * import QtQiock 2.3

review: Needs Fixing
Revision history for this message
Tim Peeters (tpeeters) wrote :

128 + * import QtQiock 2.3
129 + * import Ubuntu.Components 1.2
130 + *
131 + * ListItem {
132 + * Label {
133 + * text: "This is a label"
134 + * }
135 + * Switch {
136 + * id: toggle
137 + * anchors.right: parent.right
138 + * }
139 + * Component.onCompleted: clicked.connect(toggle.clicked)
140 + * }

please update the example so that it is an actual qml program that can be run (this one doesn't have width and height set, so it won't show anything)

Revision history for this message
Tim Peeters (tpeeters) wrote :

139 + * Component.onCompleted: clicked.connect(toggle.clicked)

The way you set this up seems more complicated than needed. Why not use this:

    onClicked: toggle.checked = !toggle.checked

Revision history for this message
Tim Peeters (tpeeters) wrote :

160 + * The property holds the default action attached to the list item which will be
161 + * triggered when the ListItem is clicked. ListItem will not visualize the action,

why *default* action? You could say "The action that will be triggered when the ListItem is clicked"

Revision history for this message
Tim Peeters (tpeeters) wrote :

please make this also a working example that I can simply copy&paste and then run

175 + * ListItem {
176 + * property bool emitActionTriggered: false
177 + * action: Action {
178 + * onTriggered: console.log("action triggered", value)
179 + * }
180 + * onPresseAndHold: {
181 + * console.log("suppresses clicked() signal, also action triggered");
182 + * emitActionTriggered = true;
183 + * }
184 + * onHighlightedChanged: {
185 + * if (!highlighted && emitActionTriggered) {
186 + * emitActionTriggered = false;
187 + * action.trigger(index);
188 + * }
189 + * }
190 + * }
191 + * \endqml

Revision history for this message
Tim Peeters (tpeeters) wrote :

169 + * \note Handling pressAndHold will suppress the action triggering as the clicked
170 + * signal is also suppressed. If the action triggering is still needed, it must be
171 + * triggered manually on \l highlighted changed.

this is odd. We had something similar in a previous MR.

But it is possible to support both clicked and longpress. From the text it appears as if defining onPressAndHold:..., action handling will be disabled. But I think what it means is that if pressAndHold happens, no clicked event will follow. I think it is already clear that there will be no clicked() event after pressAndHold.

Revision history for this message
Tim Peeters (tpeeters) wrote :

180 + * onPresseAndHold: {

can you run the examples that you add to the documentation to make sure they work and there are no errors in it?

Revision history for this message
Tim Peeters (tpeeters) wrote :

175 + * ListItem {
176 + * property bool emitActionTriggered: false
177 + * action: Action {
178 + * onTriggered: console.log("action triggered", value)
179 + * }
180 + * onPresseAndHold: {
181 + * console.log("suppresses clicked() signal, also action triggered");
182 + * emitActionTriggered = true;
183 + * }
184 + * onHighlightedChanged: {
185 + * if (!highlighted && emitActionTriggered) {
186 + * emitActionTriggered = false;
187 + * action.trigger(index);
188 + * }
189 + * }
190 + * }

This example is I think a bit of a corner case and will only confuse the developers. Normally after a longpress you don't need to handle clicked when you release again. I think we can remove this example.

Revision history for this message
Tim Peeters (tpeeters) wrote :

255 + UCAction *defaultAction;

why call this defaultAction and not action?

Revision history for this message
Tim Peeters (tpeeters) wrote :

298 + ListItem {
299 + Label {
300 + text: "Switch makes this item to highlight"
301 + }
302 + Switch {
303 + id: toggle
304 + anchors.right: parent.right
305 + }
306 + Component.onCompleted: clicked.connect(toggle.clicked)

same comment as for the example above, why not say onClicked: toggle.checked = !toggle.checked?

307 + }
308 + ListItem {
309 + Label {
310 + text: "No action, no trailing/leading actions, no active component"
311 + }
312 + onClicked: print("clicked")
313 + onPressAndHold: print("longPressed")
314 + }

this is fine, but for this MR, maybe you should add a ListItem with an action?

Revision history for this message
Tim Peeters (tpeeters) wrote :

95 + function test_action_triggered_on_clicked() {
396 + testItem.action = stockAction;
397 + actionSpy.target = stockAction;
398 + clickSpy.target = testItem;
399 + mouseClick(testItem, centerOf(testItem).x, centerOf(testItem).y);
400 + clickSpy.wait();
401 + actionSpy.wait();
402 + }

no need to have an actionSpy.count check here?

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 128 + * import QtQiock 2.3
Removed

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 128 + * import QtQiock 2.3
> 129 + * import Ubuntu.Components 1.2
> 130 + *
> 131 + * ListItem {
> 132 + * Label {
> 133 + * text: "This is a label"
> 134 + * }
> 135 + * Switch {
> 136 + * id: toggle
> 137 + * anchors.right: parent.right
> 138 + * }
> 139 + * Component.onCompleted: clicked.connect(toggle.clicked)
> 140 + * }
>
> please update the example so that it is an actual qml program that can be run
> (this one doesn't have width and height set, so it won't show anything)

As said on IRC, this is a snippet, so one can take it and put it in an app. Width is taken from the parent, or if no parent is given, it'll default to 40GU; and height defaults to 7GU, as documented.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 139 + * Component.onCompleted: clicked.connect(toggle.clicked)
>
> The way you set this up seems more complicated than needed. Why not use this:
>
> onClicked: toggle.checked = !toggle.checked

Either ways is good, but this one destroys the binding you may have on the checked property, right? So connecting the signals makes sure the property binding stays.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 160 + * The property holds the default action attached to the list item
> which will be
> 161 + * triggered when the ListItem is clicked. ListItem will not
> visualize the action,
>
> why *default* action? You could say "The action that will be triggered when
> the ListItem is clicked"

The reason for naming like that is to differentiate it from leading/trailing ones.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> please make this also a working example that I can simply copy&paste and then
> run
>
> 175 + * ListItem {
> 176 + * property bool emitActionTriggered: false
> 177 + * action: Action {
> 178 + * onTriggered: console.log("action triggered", value)
> 179 + * }
> 180 + * onPresseAndHold: {
> 181 + * console.log("suppresses clicked() signal, also action
> triggered");
> 182 + * emitActionTriggered = true;
> 183 + * }
> 184 + * onHighlightedChanged: {
> 185 + * if (!highlighted && emitActionTriggered) {
> 186 + * emitActionTriggered = false;
> 187 + * action.trigger(index);
> 188 + * }
> 189 + * }
> 190 + * }
> 191 + * \endqml

Being a code snippet, you can copy/paste in your app any time.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 169 + * \note Handling pressAndHold will suppress the action triggering as
> the clicked
> 170 + * signal is also suppressed. If the action triggering is still
> needed, it must be
> 171 + * triggered manually on \l highlighted changed.
>
> this is odd. We had something similar in a previous MR.
>
> But it is possible to support both clicked and longpress. From the text it
> appears as if defining onPressAndHold:..., action handling will be disabled.
> But I think what it means is that if pressAndHold happens, no clicked event
> will follow. I think it is already clear that there will be no clicked() event
> after pressAndHold.

I think what we did we simply removed from the #77 MR, as this cannot really be formulated to be understandable enough. Let's do the same here.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 175 + * ListItem {
> 176 + * property bool emitActionTriggered: false
> 177 + * action: Action {
> 178 + * onTriggered: console.log("action triggered", value)
> 179 + * }
> 180 + * onPresseAndHold: {
> 181 + * console.log("suppresses clicked() signal, also action
> triggered");
> 182 + * emitActionTriggered = true;
> 183 + * }
> 184 + * onHighlightedChanged: {
> 185 + * if (!highlighted && emitActionTriggered) {
> 186 + * emitActionTriggered = false;
> 187 + * action.trigger(index);
> 188 + * }
> 189 + * }
> 190 + * }
>
> This example is I think a bit of a corner case and will only confuse the
> developers. Normally after a longpress you don't need to handle clicked when
> you release again. I think we can remove this example.

Indeed...

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 255 + UCAction *defaultAction;
>
> why call this defaultAction and not action?

Let's call it mainAction then, action would collide with action() getter.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 298 + ListItem {
> 299 + Label {
> 300 + text: "Switch makes this item to highlight"
> 301 + }
> 302 + Switch {
> 303 + id: toggle
> 304 + anchors.right: parent.right
> 305 + }
> 306 + Component.onCompleted: clicked.connect(toggle.clicked)
>
> same comment as for the example above, why not say onClicked: toggle.checked =
> !toggle.checked?

As said before, that destroys any binding to it. This doesn't.

>
>
> 307 + }
> 308 + ListItem {
> 309 + Label {
> 310 + text: "No action, no trailing/leading actions, no
> active component"
> 311 + }
> 312 + onClicked: print("clicked")
> 313 + onPressAndHold: print("longPressed")
> 314 + }
>
>
> this is fine, but for this MR, maybe you should add a ListItem with an action?

ok, done.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 95 + function test_action_triggered_on_clicked() {
> 396 + testItem.action = stockAction;
> 397 + actionSpy.target = stockAction;
> 398 + clickSpy.target = testItem;
> 399 + mouseClick(testItem, centerOf(testItem).x,
> centerOf(testItem).y);
> 400 + clickSpy.wait();
> 401 + actionSpy.wait();
> 402 + }
>
> no need to have an actionSpy.count check here?

Why would you need that? Actually the clickSpy is the unnecessary thing here. Or would you want to see that the action i triggered once only?

1384. By Zsombor Egri

review comments applied

Revision history for this message
Tim Peeters (tpeeters) wrote :

great, thanks!

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components.api'
2--- components.api 2015-02-03 18:11:32 +0000
3+++ components.api 2015-02-05 14:40:22 +0000
4@@ -869,6 +869,7 @@
5 Property { name: "contentMoving"; type: "bool"; isReadonly: true }
6 Property { name: "color"; type: "QColor" }
7 Property { name: "highlightColor"; type: "QColor" }
8+ Property { name: "action"; type: "UCAction"; isPointer: true }
9 Property { name: "listItemData"; type: "QObject"; isList: true; isReadonly: true }
10 Property { name: "listItemChildren"; type: "QQuickItem"; isList: true; isReadonly: true }
11 Property { name: "style"; type: "QQmlComponent"; isPointer: true }
12
13=== modified file 'modules/Ubuntu/Components/plugin/ucaction.h'
14--- modules/Ubuntu/Components/plugin/ucaction.h 2015-01-06 07:40:49 +0000
15+++ modules/Ubuntu/Components/plugin/ucaction.h 2015-02-05 14:40:22 +0000
16@@ -87,6 +87,7 @@
17 Type m_parameterType;
18
19 friend class UCActionContext;
20+ friend class UCListItemPrivate;
21 friend class UCListItemAttached;
22 friend class UCListItemActionsPrivate;
23
24
25=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.cpp'
26--- modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-01-22 11:34:18 +0000
27+++ modules/Ubuntu/Components/plugin/uclistitem.cpp 2015-02-05 14:40:22 +0000
28@@ -24,6 +24,7 @@
29 #include "propertychange_p.h"
30 #include "i18n.h"
31 #include "quickutils.h"
32+#include "ucaction.h"
33 #include <QtQml/QQmlInfo>
34 #include <QtQuick/private/qquickitem_p.h>
35 #include <QtQuick/private/qquickflickable_p.h>
36@@ -354,6 +355,7 @@
37 , leadingPanel(0)
38 , trailingPanel(0)
39 , animator(0)
40+ , mainAction(0)
41 , styleComponent(0)
42 , implicitStyleComponent(0)
43 , styleItem(0)
44@@ -593,6 +595,7 @@
45 // returns true if the highlight is possible
46 bool UCListItemPrivate::canHighlight(QMouseEvent *event)
47 {
48+ // if automatic, the highlight should not happen if we clicked on an active component;
49 // localPos is a position relative to ListItem which will give us a child from
50 // from the original coordinates; therefore we must map the position to the contentItem
51 Q_Q(UCListItem);
52@@ -604,7 +607,7 @@
53 QQuickMouseArea *ma = q->findChild<QQuickMouseArea*>();
54 bool activeMouseArea = ma && ma->isEnabled();
55 return !activeComponent && (isClickedConnected() || isPressAndHoldConnected() ||
56- leadingActions || trailingActions || activeMouseArea);
57+ mainAction || leadingActions || trailingActions || activeMouseArea);
58 }
59
60 // set highlighted flag and update contentItem
61@@ -929,7 +932,7 @@
62 UCStyledItemBase::itemChange(change, data);
63 if (change == ItemParentHasChanged) {
64 Q_D(UCListItem);
65- // make sure we are not connected to the previous Flickable
66+ // make sure we are not connected to any previous Flickable
67 d->listenToRebind(false);
68 // check if we are in a positioner, and if that positioner is in a Flickable
69 QQuickBasePositioner *positioner = qobject_cast<QQuickBasePositioner*>(data.item);
70@@ -1024,7 +1027,8 @@
71 // while moving, we cannot select any items
72 return;
73 }
74- if (event->button() == Qt::LeftButton && d->canHighlight(event)) {
75+ if (d->canHighlight(event) && !d->suppressClick
76+ && !d->highlighted && event->button() == Qt::LeftButton) {
77 // stop any ongoing animation!
78 if (d->animator) {
79 d->animator->stop();
80@@ -1059,7 +1063,12 @@
81
82 if (!d->suppressClick) {
83 Q_EMIT clicked();
84+ if (d->mainAction) {
85+ Q_EMIT d->mainAction->trigger(d->index());
86+ }
87 d->_q_rebound();
88+ } else {
89+ d->suppressClick = false;
90 }
91 }
92 d->setHighlighted(false);
93@@ -1145,6 +1154,7 @@
94 QMouseEvent *mouse = static_cast<QMouseEvent*>(event);
95 if (child->isEnabled() && (child->acceptedMouseButtons() & mouse->button()) && !qobject_cast<QQuickText*>(child)) {
96 Q_D(UCListItem);
97+ // suppress click
98 d->suppressClick = true;
99 // listen for flickable to be able to rebind if movement started there!
100 d->listenToRebind(true);
101@@ -1299,6 +1309,42 @@
102 * is moved horizontally. When in Flickable (or ListView), the item gets un-highlighted
103 * (false) when the mouse or touch is moved towards the vertical direction causing
104 * the flickable to move.
105+ *
106+ * Configures the color when highlighted. Defaults to the theme palette's background
107+ * color.
108+ *
109+ * An item is highlighted, thus highlight state toggled, when pressed and it has
110+ * one of the following conditions fulfilled:
111+ * \list
112+ * \li * \l leadingActions or \l trailingActions set,
113+ * \li * it has an \l action attached
114+ * \li * if the ListItem has an active child component, such as a \l Button, a
115+ * \l Switch, etc.
116+ * \li * in general, if an active (enabled and visible) \c MouseArea is added
117+ * as a child component
118+ * \li * \l clicked signal handler is implemented or there is a slot or function
119+ * connected to it
120+ * \li * \l pressAndHold signal handler is implemented or there is a slot or
121+ * function connected to it.
122+ * \endlist
123+ *
124+ * \note Adding an active component does not mean the component will be activated
125+ * when the ListItem will be tapped/clicked outside of the component area. If
126+ * such a behavior is needed, that must be done explicitly.
127+ * \qml
128+ * ListItem {
129+ * Label {
130+ * text: "This is a label"
131+ * }
132+ * Switch {
133+ * id: toggle
134+ * anchors.right: parent.right
135+ * }
136+ * Component.onCompleted: clicked.connect(toggle.clicked)
137+ * }
138+ * \endqml
139+ *
140+ * \sa action, leadingActions, trailingActions
141 */
142 bool UCListItem::highlighted() const
143 {
144@@ -1340,7 +1386,6 @@
145 Q_EMIT q->contentMovementEnded();
146 }
147 Q_EMIT q->contentMovingChanged();
148-
149 }
150
151 /*!
152@@ -1395,6 +1440,37 @@
153 }
154
155 /*!
156+ * \qmlproperty Action ListItem::action
157+ * The property holds the action which will be triggered when the ListItem is
158+ * clicked. ListItem will not visualize the action, that is the responsibility
159+ * of the components placed inside the list item. However, when set, the ListItem
160+ * will be highlighted on press.
161+ *
162+ * If the action set has no value type set, ListItem will set its type to \c
163+ * Action.Integer and the \l {Action::triggered}{triggered} signal will be getting
164+ * the ListItem index as \e value parameter.
165+ *
166+ * Defaults no null.
167+ */
168+UCAction *UCListItemPrivate::action() const
169+{
170+ return mainAction;
171+}
172+void UCListItemPrivate::setAction(UCAction *action)
173+{
174+ Q_Q(UCListItem);
175+ if (mainAction == action) {
176+ return;
177+ }
178+ mainAction = action;
179+ if (mainAction && (mainAction->m_parameterType == UCAction::None)) {
180+ // call setProperty to invoke notify signal
181+ mainAction->setProperty("parameterType", UCAction::Integer);
182+ }
183+ Q_EMIT q->actionChanged();
184+}
185+
186+/*!
187 * \qmlproperty real ListItem::swipeOvershoot
188 * The property configures the overshoot value on swiping. Its default value is
189 * configured by the \l {ListItemStyle}{style}. Any positive value overrides the
190
191=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.h'
192--- modules/Ubuntu/Components/plugin/uclistitem.h 2015-01-15 10:37:24 +0000
193+++ modules/Ubuntu/Components/plugin/uclistitem.h 2015-02-05 14:40:22 +0000
194@@ -23,8 +23,8 @@
195 class UCListItemContent;
196 class UCListItemDivider;
197 class UCListItemActions;
198+class UCAction;
199 class UCListItemAttached;
200-class QQuickPropertyAnimation;
201 class UCListItemPrivate;
202 class UCListItem : public UCStyledItemBase
203 {
204@@ -38,6 +38,7 @@
205 Q_PRIVATE_PROPERTY(UCListItem::d_func(), bool contentMoving READ contentMoving NOTIFY contentMovingChanged)
206 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
207 Q_PROPERTY(QColor highlightColor READ highlightColor WRITE setHighlightColor RESET resetHighlightColor NOTIFY highlightColorChanged)
208+ Q_PRIVATE_PROPERTY(UCListItem::d_func(), UCAction *action READ action WRITE setAction NOTIFY actionChanged DESIGNABLE false)
209 Q_PRIVATE_PROPERTY(UCListItem::d_func(), QQmlListProperty<QObject> listItemData READ data DESIGNABLE false)
210 Q_PRIVATE_PROPERTY(UCListItem::d_func(), QQmlListProperty<QQuickItem> listItemChildren READ children NOTIFY listItemChildrenChanged DESIGNABLE false)
211 // FIXME move these to StyledItemBase with subtheming
212@@ -88,6 +89,7 @@
213 void contentMovingChanged();
214 void colorChanged();
215 void highlightColorChanged();
216+ void actionChanged();
217 void listItemChildrenChanged();
218
219 void clicked();
220
221=== modified file 'modules/Ubuntu/Components/plugin/uclistitem_p.h'
222--- modules/Ubuntu/Components/plugin/uclistitem_p.h 2015-01-15 10:37:24 +0000
223+++ modules/Ubuntu/Components/plugin/uclistitem_p.h 2015-02-05 14:40:22 +0000
224@@ -96,6 +96,7 @@
225 UCActionPanel *leadingPanel;
226 UCActionPanel *trailingPanel;
227 UCListItemSnapAnimator *animator;
228+ UCAction *mainAction;
229
230 // FIXME move these to StyledItemBase togehther with subtheming.
231 QQmlComponent *styleComponent;
232@@ -115,6 +116,8 @@
233 void resetStyle();
234 void initStyleItem();
235 QQuickItem *styleInstance() const;
236+ UCAction *action() const;
237+ void setAction(UCAction *action);
238 };
239
240 class UCListItemAttachedPrivate : public QObjectPrivate
241
242=== modified file 'modules/Ubuntu/Components/plugin/ucstyleditembase.cpp'
243--- modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2014-11-25 07:30:40 +0000
244+++ modules/Ubuntu/Components/plugin/ucstyleditembase.cpp 2015-02-05 14:40:22 +0000
245@@ -181,6 +181,7 @@
246 {
247 // only filter pressed events
248 if (event->type() == QEvent::MouseButtonPress) {
249+ // send mouse event
250 QMouseEvent *mouse = static_cast<QMouseEvent*>(event);
251 // the event may occur outside of the parent's boundaries if not clipped
252 // therefore must check containment
253
254=== modified file 'tests/resources/listitems/ListItemTest.qml'
255--- tests/resources/listitems/ListItemTest.qml 2015-01-15 10:44:36 +0000
256+++ tests/resources/listitems/ListItemTest.qml 2015-02-05 14:40:22 +0000
257@@ -21,7 +21,8 @@
258 MainView {
259 id: main
260 width: units.gu(50)
261- height: units.gu(100)
262+ height: units.gu(105)
263+ useDeprecatedToolbar: false
264
265 property bool override: false
266
267@@ -217,5 +218,23 @@
268 }
269 }
270 }
271+ ListItem {
272+ Label {
273+ text: "Switch makes this item to highlight"
274+ }
275+ Switch {
276+ id: toggle
277+ anchors.right: parent.right
278+ }
279+ Component.onCompleted: clicked.connect(toggle.clicked)
280+ }
281+ ListItem {
282+ Label {
283+ text: "With action assigned"
284+ }
285+ onClicked: print("clicked")
286+ onPressAndHold: print("longPressed")
287+ action: stock
288+ }
289 }
290 }
291
292=== modified file 'tests/unit_x11/tst_components/tst_listitem.qml'
293--- tests/unit_x11/tst_components/tst_listitem.qml 2015-01-19 18:21:40 +0000
294+++ tests/unit_x11/tst_components/tst_listitem.qml 2015-02-05 14:40:22 +0000
295@@ -114,6 +114,22 @@
296 trailingActions: trailing
297 }
298 }
299+ Flickable {
300+ id: testFlickable
301+ width: parent.width
302+ height: units.gu(28)
303+ ListView {
304+ id: nestedListView
305+ width: parent.width
306+ height: units.gu(28)
307+ clip: true
308+ model: 10
309+ delegate: ListItem {
310+ objectName: "listItem" + index
311+ leadingActions: leading
312+ }
313+ }
314+ }
315 }
316
317 UbuntuTestCase {
318@@ -171,6 +187,7 @@
319 }
320
321 function cleanup() {
322+ testItem.action = null;
323 movingSpy.clear();
324 highlightedSpy.clear();
325 clickSpy.clear();
326@@ -203,6 +220,7 @@
327 compare(defaults.divider.colorTo, "#ffffff", "colorTo differs.");
328 fuzzyCompare(defaults.divider.colorTo.a, 0.07, 0.01, "colorTo alpha differs");
329 compare(defaults.contentMoving, false, "default is not moving");
330+ compare(defaults.action, null, "No action by default.");
331 compare(defaults.style, null, "Style is loaded upon first use.");
332 compare(defaults.__styleInstance, null, "__styleInstance must be null.");
333
334@@ -357,6 +375,7 @@
335 }
336 function test_listview_not_interactive_while_tugged(data) {
337 listView.positionViewAtBeginning();
338+ interactiveSpy.target = listView;
339 compare(listView.interactive, true, "ListView is not interactive");
340 movingSpy.target = data.item;
341 interactiveSpy.target = listView;
342@@ -672,5 +691,46 @@
343 highlightedSpy.wait();
344 mouseRelease(clickedConnected, centerOf(clickedConnected).x, centerOf(clickedConnected).y);
345 }
346+
347+ function test_listitem_blocks_ascendant_flickables() {
348+ var listItem = findChild(nestedListView, "listItem0");
349+ verify(listItem, "Cannot find test item");
350+ interactiveSpy.target = testFlickable;
351+ movingSpy.target = listItem;
352+ // tug leading
353+ flick(listItem, centerOf(listItem).x, centerOf(listItem).y, listItem.width / 2, 0);
354+ movingSpy.wait();
355+ // check if interactive got changed
356+ interactiveSpy.wait();
357+
358+ // cleanup!!!
359+ rebound(listItem);
360+ }
361+
362+ function test_action_type_set() {
363+ stockAction.parameterType = Action.None;
364+ compare(stockAction.parameterType, Action.None, "No parameter type for stockAction!");
365+ testItem.action = stockAction;
366+ compare(stockAction.parameterType, Action.Integer, "No parameter type for stockAction!");
367+ }
368+
369+ function test_action_triggered_on_clicked() {
370+ testItem.action = stockAction;
371+ actionSpy.target = stockAction;
372+ mouseClick(testItem, centerOf(testItem).x, centerOf(testItem).y);
373+ actionSpy.wait();
374+ }
375+
376+ function test_action_suppressed_on_longpress() {
377+ testItem.action = stockAction;
378+ actionSpy.target = stockAction;
379+ clickSpy.target = testItem;
380+ pressAndHoldSpy.target = testItem;
381+ mouseLongPress(testItem, centerOf(testItem).x, centerOf(testItem).y);
382+ mouseRelease(testItem, centerOf(testItem).x, centerOf(testItem).y);
383+ pressAndHoldSpy.wait();
384+ compare(clickSpy.count, 0, "Click must be suppressed.");
385+ compare(actionSpy.count, 0, "Action triggered must be suppressed");
386+ }
387 }
388 }

Subscribers

People subscribed via source and target branches