Merge lp:~zsombi/ubuntu-ui-toolkit/78-action-property into lp:ubuntu-ui-toolkit/staging
- 78-action-property
- Merge into staging
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 | ||||||||
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+244087@code.launchpad.net |
Commit message
Introducing action property in ListItem.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1383
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://
Tim Peeters (tpeeters) wrote : | # |
128 + * import QtQiock 2.3
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.
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)
Tim Peeters (tpeeters) wrote : | # |
139 + * Component.
The way you set this up seems more complicated than needed. Why not use this:
onClicked: toggle.checked = !toggle.checked
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"
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 emitActionTrigg
177 + * action: Action {
178 + * onTriggered: console.log("action triggered", value)
179 + * }
180 + * onPresseAndHold: {
181 + * console.
182 + * emitActionTriggered = true;
183 + * }
184 + * onHighlightedCh
185 + * if (!highlighted && emitActionTrigg
186 + * emitActionTriggered = false;
187 + * action.
188 + * }
189 + * }
190 + * }
191 + * \endqml
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.
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?
Tim Peeters (tpeeters) wrote : | # |
175 + * ListItem {
176 + * property bool emitActionTrigg
177 + * action: Action {
178 + * onTriggered: console.log("action triggered", value)
179 + * }
180 + * onPresseAndHold: {
181 + * console.
182 + * emitActionTriggered = true;
183 + * }
184 + * onHighlightedCh
185 + * if (!highlighted && emitActionTrigg
186 + * emitActionTriggered = false;
187 + * action.
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.
Tim Peeters (tpeeters) wrote : | # |
255 + UCAction *defaultAction;
why call this defaultAction and not action?
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.
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("
314 + }
this is fine, but for this MR, maybe you should add a ListItem with an action?
Tim Peeters (tpeeters) wrote : | # |
95 + function test_action_
396 + testItem.action = stockAction;
397 + actionSpy.target = stockAction;
398 + clickSpy.target = testItem;
399 + mouseClick(
400 + clickSpy.wait();
401 + actionSpy.wait();
402 + }
no need to have an actionSpy.count check here?
Zsombor Egri (zsombi) wrote : | # |
> 128 + * import QtQiock 2.3
Removed
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.
> 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.
Zsombor Egri (zsombi) wrote : | # |
> 139 + * Component.
>
> 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.
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.
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 emitActionTrigg
> 177 + * action: Action {
> 178 + * onTriggered: console.log("action triggered", value)
> 179 + * }
> 180 + * onPresseAndHold: {
> 181 + * console.
> triggered");
> 182 + * emitActionTriggered = true;
> 183 + * }
> 184 + * onHighlightedCh
> 185 + * if (!highlighted && emitActionTrigg
> 186 + * emitActionTriggered = false;
> 187 + * action.
> 188 + * }
> 189 + * }
> 190 + * }
> 191 + * \endqml
Being a code snippet, you can copy/paste in your app any time.
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.
Zsombor Egri (zsombi) wrote : | # |
> 175 + * ListItem {
> 176 + * property bool emitActionTrigg
> 177 + * action: Action {
> 178 + * onTriggered: console.log("action triggered", value)
> 179 + * }
> 180 + * onPresseAndHold: {
> 181 + * console.
> triggered");
> 182 + * emitActionTriggered = true;
> 183 + * }
> 184 + * onHighlightedCh
> 185 + * if (!highlighted && emitActionTrigg
> 186 + * emitActionTriggered = false;
> 187 + * action.
> 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...
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.
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.
>
> 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("
> 314 + }
>
>
> this is fine, but for this MR, maybe you should add a ListItem with an action?
ok, done.
Zsombor Egri (zsombi) wrote : | # |
> 95 + function test_action_
> 396 + testItem.action = stockAction;
> 397 + actionSpy.target = stockAction;
> 398 + clickSpy.target = testItem;
> 399 + mouseClick(
> centerOf(
> 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
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
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 | } |
FAILED: Continuous integration, rev:1379 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1372/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 853 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/99 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/102 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/102/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/99 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 745 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 851 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 851/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 17187
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/1372/ rebuild
http://