Merge lp:~mzanetti/ubuntu-ui-toolkit/expanding-listitem into lp:ubuntu-ui-toolkit
- expanding-listitem
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Zsombor Egri |
Proposed branch: | lp:~mzanetti/ubuntu-ui-toolkit/expanding-listitem |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
1200 lines (+1077/-12) 13 files modified
components.api (+17/-0) examples/ubuntu-ui-toolkit-gallery/ListItems.qml (+135/-0) modules/Ubuntu/Components/ListItems/Base.qml (+1/-1) modules/Ubuntu/Components/ListItems/Expandable.qml (+196/-0) modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml (+136/-0) modules/Ubuntu/Components/ListItems/ExpandablesListView.qml (+126/-0) modules/Ubuntu/Components/ListItems/qmldir (+3/-0) modules/Ubuntu/Test/UbuntuTestCase.qml (+14/-9) tests/unit_x11/tst_components/tst_Expandable.qml (+119/-0) tests/unit_x11/tst_components/tst_ExpandablesColumn.qml (+157/-0) tests/unit_x11/tst_components/tst_ExpandablesListView.qml (+170/-0) tests/unit_x11/tst_components/tst_pickerpanel.qml (+1/-0) tests/unit_x11/tst_test/tst_ubuntutestcase.qml (+2/-2) |
To merge this branch: | bzr merge lp:~mzanetti/ubuntu-ui-toolkit/expanding-listitem |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Zanetti (community) | Disapprove | ||
PS Jenkins bot | continuous-integration | Needs Fixing | |
Zsombor Egri | Needs Fixing | ||
Michał Sawicz | Needs Fixing | ||
Florian Boucault | Pending | ||
Review via email: mp+195602@code.launchpad.net |
Commit message
Add ExpandablesList
Description of the change
This adds an ExpandablesList
- 846. By Michael Zanetti
-
fix typo in docs
- 847. By Michael Zanetti
-
fix one more typo
- 848. By Michael Zanetti
-
more fixes to the doc
- 849. By Michael Zanetti
-
change dimmed opacity to 0.5 as requested by design
PS Jenkins bot (ps-jenkins) wrote : | # |
- 850. By Michael Zanetti
-
update components.api
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:849
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:850
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:850
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 851. By Michael Zanetti
-
fix issues in docs as found by jenkins
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:851
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 852. By Michael Zanetti
-
added tests that check for not expanded items to dim when there is an expanded item
- 853. By Michael Zanetti
-
fix another link issue in docs
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:853
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
Hey, some functional issues:
- There seem to be two thin dividers visible, and they get out of sync when dragging the view slowly (http://
- Did you confirm the dragging behaviours with UX design? Are you supposed to be able to drag when an item is expanded at all? Shouldn't it collapse as soon as you touch outside?
- Scrollable expanded items overlay the divider (http://
Wonder if it'd make sense to have a more real-life example in the gallery, where you'd have one ExpandablesColumn or ExpandablesListView covering the whole view - would be easier to see the behaviours.
Also, One thing that happened for me repeatedly - when tapping on one of the faded-out items, I expected it to expand straight away, not only collapse the current item - something worth exploring with UX design.
- 854. By Michael Zanetti
-
fix content overlapping with bottom divider
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:854
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Florian Boucault (fboucault) wrote : | # |
Corresponding bug report: https:/
Michał Sawicz (saviq) wrote : | # |
Hey guys, can we get a review of this?
- 855. By Michael Zanetti
-
merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:855
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 856. By Michael Zanetti
-
get rid of the workaround to set ListView.view in case of a column. Use a more elegant workaround.
- 857. By Michael Zanetti
-
fix copyright header year
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:857
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
Your change to modules/
- 858. By Michael Zanetti
-
take divider.height into account when calculating if we should be flickable or not
- 859. By Michael Zanetti
-
change findChild to do a breadth first instad of a depth first search to avoid running out of memory
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:858
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 860. By Michael Zanetti
-
change the test_findChild to check for null instead of undefined as that's more correct
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:859
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 861. By Michael Zanetti
-
fix error message on test_findChild
- 862. By Michael Zanetti
-
wait for it to be fully set up and rendered before running the test
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:861
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:862
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 863. By Michael Zanetti
-
waitForRendering on the PickerPanel too
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:863
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Zsombor Egri (zsombi) wrote : | # |
So to summarize what we discussed in hangout (+ some additional things to check with design):
For ListItems.
- provide property which configures the possibility to collapse the Expandable while clicked on its "header"
- make sure design does not want a down/up pointing chevron to be shown which would indicate there is something more to be shown (as in OptionSelector's case)
ExpandablesColumn name can stay... Not the nicest name however...
ExpandablesListView to be renamed onto UbuntuListView giving room for other enhancements on ListView, and should be moved under Ubuntu.Components.
Additional comments:
=======
36 +
please remove this empty line.
Expandable:
287 + /*!
288 + \internal
289 + Reparent any content to inside the Flickable
290 + */
291 + property alias children: flickableConten
Shouldn't this be a default property? It should also be a public one.
ExpandablesList
593 + readonly property alias expandedItem: priv.expandedItem
We should have expandedIndex property as well to keep the API in sync with ListView API.
599 + function expandItem(item) {
As ListView creates the items dynamically, we cannot really rely on instance parameters. This function assumes the instance to be expanded is in visible area). What if the instance is re-created due to flicking? The function should take index instead of instance, and should have an option to set the currentIndex as well.
function expandAtIndex(
Also there is no example in documentation on how the function should be used.
624 + function collapse() {
A better name for this would be collapseExpanded()
tst_Expandables
Please add a test case where the column has other list items included.
Beside these, I'd recommend to split the MR in 3: Expandable, ExpandablesColumn and for UbuntuListView. Also, thanks for fixing the UbuntuTestCase, but that fix should also come in a separate MR, maybe the base one for all 3 others. This one could also contain the PickerPanel test fix :)
- 864. By Michael Zanetti
-
added property collapseOnClick (defaulting to false) to easily add a collapse mechanism
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:864
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
This has been split into 3 other merges
Unmerged revisions
- 864. By Michael Zanetti
-
added property collapseOnClick (defaulting to false) to easily add a collapse mechanism
- 863. By Michael Zanetti
-
waitForRendering on the PickerPanel too
- 862. By Michael Zanetti
-
wait for it to be fully set up and rendered before running the test
- 861. By Michael Zanetti
-
fix error message on test_findChild
- 860. By Michael Zanetti
-
change the test_findChild to check for null instead of undefined as that's more correct
- 859. By Michael Zanetti
-
change findChild to do a breadth first instad of a depth first search to avoid running out of memory
- 858. By Michael Zanetti
-
take divider.height into account when calculating if we should be flickable or not
- 857. By Michael Zanetti
-
fix copyright header year
- 856. By Michael Zanetti
-
get rid of the workaround to set ListView.view in case of a column. Use a more elegant workaround.
- 855. By Michael Zanetti
-
merge trunk
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2014-02-11 17:51:15 +0000 |
3 | +++ components.api 2014-02-13 10:10:25 +0000 |
4 | @@ -106,6 +106,23 @@ |
5 | property ThinDivider divider |
6 | property real __contentsMargins |
7 | function cancelItemRemoval() |
8 | +modules/Ubuntu/Components/ListItems/Expandable.qml |
9 | +Empty |
10 | + property bool expanded |
11 | + property real collapsedHeight |
12 | + property real expandedHeight |
13 | + property internal children |
14 | +modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml |
15 | +Flickable |
16 | + readonly property Item expandedItem |
17 | + function expandItem(item) |
18 | + function collapse() |
19 | + default property internal children |
20 | +modules/Ubuntu/Components/ListItems/ExpandablesListView.qml |
21 | +ListView |
22 | + readonly property Item expandedItem |
23 | + function expandItem(item) |
24 | + function collapse() |
25 | modules/Ubuntu/Components/ListItems/Header.qml |
26 | Item |
27 | property string text |
28 | |
29 | === modified file 'examples/ubuntu-ui-toolkit-gallery/ListItems.qml' |
30 | --- examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2013-11-22 14:49:12 +0000 |
31 | +++ examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2014-02-13 10:10:25 +0000 |
32 | @@ -19,6 +19,7 @@ |
33 | import Ubuntu.Components.ListItems 0.1 as ListItem |
34 | |
35 | Template { |
36 | + |
37 | ListItemsSection { |
38 | title: i18n.tr("Standard") |
39 | className: "Standard" |
40 | @@ -222,4 +223,138 @@ |
41 | } |
42 | } |
43 | } |
44 | + |
45 | + TemplateSection { |
46 | + title: i18n.tr("ExpandablesListView") |
47 | + className: "Header" |
48 | + |
49 | + ListModel { |
50 | + id: fruitModel |
51 | + ListElement { name: "Orange"; details: "The orange (specifically, the sweet orange) is the fruit of the citrus species Citrus × sinensis in the family Rutaceae. The fruit of the Citrus sinensis is called sweet orange to distinguish it from that of the Citrus aurantium, the bitter orange. The orange is a hybrid, possibly between pomelo (Citrus maxima) and mandarin (Citrus reticulata), cultivated since ancient times.\n-\nWikipedia"} |
52 | + ListElement { name: "Apple"; details: "Fruit" } |
53 | + ListElement { name: "Tomato"; details: "The tomato is the edible, often red fruit of the plant Solanum lycopersicum, commonly known as a tomato plant. Both the species and its use as a food originated in Mexico, and spread throughout the world following the Spanish colonization of the Americas. Its many varieties are now widely grown, sometimes in greenhouses in cooler climates. The tomato is consumed in diverse ways, including raw, as an ingredient in many dishes, sauces, salads, and drinks. While it is botanically a fruit, it is considered a vegetable for culinary purposes (as well as under U.S. customs regulations, see Nix v. Hedden), which has caused some confusion. The fruit is rich in lycopene, which may have beneficial health effects. The tomato belongs to the nightshade family (Solanaceae). The plants typically grow to 1–3 meters (3–10 ft) in height and have a weak stem that often sprawls over the ground and vines over other plants. It is a perennial in its native habitat, although often grown outdoors in temperate climates as an annual. An average common tomato weighs approximately 100 grams (4 oz).\n-\nWikipedia" } |
54 | + ListElement { name: "Carrot"; details: "Vegetable" } |
55 | + ListElement { name: "Potato"; details: "Vegetable" } |
56 | + } |
57 | + |
58 | + ListItem.ExpandablesListView { |
59 | + anchors { left: parent.left; right: parent.right } |
60 | + height: units.gu(24) |
61 | + model: fruitModel |
62 | + clip: true |
63 | + |
64 | + delegate: ListItem.Expandable { |
65 | + id: expandingItem |
66 | + |
67 | + expandedHeight: contentColumn.height + units.gu(1) |
68 | + |
69 | + onClicked: { |
70 | + expanded = true; |
71 | + } |
72 | + |
73 | + Column { |
74 | + id: contentColumn |
75 | + anchors { left: parent.left; right: parent.right } |
76 | + Item { |
77 | + anchors { left: parent.left; right: parent.right} |
78 | + height: expandingItem.collapsedHeight |
79 | + Toolkit.Label { |
80 | + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} |
81 | + text: model.name |
82 | + } |
83 | + } |
84 | + |
85 | + Toolkit.Label { |
86 | + anchors { left: parent.left; right: parent.right } |
87 | + text: model.details |
88 | + wrapMode: Text.WordWrap |
89 | + } |
90 | + } |
91 | + } |
92 | + } |
93 | + } |
94 | + |
95 | + TemplateSection { |
96 | + title: i18n.tr("ExpandablesColumn") |
97 | + className: "Header" |
98 | + |
99 | + ListItem.ExpandablesColumn { |
100 | + anchors { left: parent.left; right: parent.right } |
101 | + clip: true |
102 | + height: units.gu(24) |
103 | + |
104 | + Repeater { |
105 | + model: 8 |
106 | + ListItem.Expandable { |
107 | + id: expandingColumnItem |
108 | + expandedHeight: contentColumn1.height + units.gu(1) |
109 | + collapseOnClick: index % 2 == 0 |
110 | + |
111 | + onClicked: { |
112 | + expanded = true; |
113 | + } |
114 | + |
115 | + Column { |
116 | + id: contentColumn1 |
117 | + anchors { left: parent.left; right: parent.right } |
118 | + Item { |
119 | + anchors { left: parent.left; right: parent.right} |
120 | + height: expandingColumnItem.collapsedHeight |
121 | + Toolkit.Label { |
122 | + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} |
123 | + text: "Item " + index + (expandingColumnItem.collapseOnClick ? " (with collapseOnClick)" : "") |
124 | + } |
125 | + } |
126 | + |
127 | + Toolkit.UbuntuShape { |
128 | + anchors { left: parent.left; right: parent.right } |
129 | + height: index % 2 == 0 ? units.gu(6) : units.gu(18) |
130 | + color: "khaki" |
131 | + } |
132 | + } |
133 | + } |
134 | + } |
135 | + } |
136 | + } |
137 | + |
138 | + TemplateSection { |
139 | + title: i18n.tr("Expandable") |
140 | + className: "Header" |
141 | + |
142 | + Column { |
143 | + anchors { left: parent.left; right: parent.right } |
144 | + clip: true |
145 | + |
146 | + Repeater { |
147 | + model: 2 |
148 | + ListItem.Expandable { |
149 | + id: expandingItem1 |
150 | + expandedHeight: contentCol1.height + units.gu(1) |
151 | + |
152 | + onClicked: { |
153 | + expanded = !expanded; |
154 | + } |
155 | + |
156 | + Column { |
157 | + id: contentCol1 |
158 | + anchors { left: parent.left; right: parent.right } |
159 | + Item { |
160 | + anchors { left: parent.left; right: parent.right} |
161 | + height: expandingItem1.collapsedHeight |
162 | + Toolkit.Label { |
163 | + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter} |
164 | + text: "Item " + index |
165 | + } |
166 | + } |
167 | + |
168 | + Toolkit.UbuntuShape { |
169 | + anchors { left: parent.left; right: parent.right } |
170 | + height: index % 2 == 0 ? units.gu(6) : units.gu(18) |
171 | + color: "khaki" |
172 | + } |
173 | + } |
174 | + } |
175 | + } |
176 | + } |
177 | + } |
178 | } |
179 | |
180 | === modified file 'modules/Ubuntu/Components/ListItems/Base.qml' |
181 | --- modules/Ubuntu/Components/ListItems/Base.qml 2013-11-07 19:45:58 +0000 |
182 | +++ modules/Ubuntu/Components/ListItems/Base.qml 2014-02-13 10:10:25 +0000 |
183 | @@ -185,7 +185,7 @@ |
184 | /*! |
185 | \internal |
186 | */ |
187 | - property alias children: middle.children |
188 | + property alias children: middle.data |
189 | Item { |
190 | id: middle |
191 | property bool anchorToIconHelper: !__iconIsItem && iconHelper.source != "" |
192 | |
193 | === added file 'modules/Ubuntu/Components/ListItems/Expandable.qml' |
194 | --- modules/Ubuntu/Components/ListItems/Expandable.qml 1970-01-01 00:00:00 +0000 |
195 | +++ modules/Ubuntu/Components/ListItems/Expandable.qml 2014-02-13 10:10:25 +0000 |
196 | @@ -0,0 +1,196 @@ |
197 | +/* |
198 | + * Copyright 2014 Canonical Ltd. |
199 | + * |
200 | + * This program is free software; you can redistribute it and/or modify |
201 | + * it under the terms of the GNU Lesser General Public License as published by |
202 | + * the Free Software Foundation; version 3. |
203 | + * |
204 | + * This program is distributed in the hope that it will be useful, |
205 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
206 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
207 | + * GNU Lesser General Public License for more details. |
208 | + * |
209 | + * You should have received a copy of the GNU Lesser General Public License |
210 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
211 | + */ |
212 | +import QtQuick 2.0 |
213 | +import Ubuntu.Components 0.1 |
214 | + |
215 | +/*! |
216 | + \qmltype Expandable |
217 | + \inqmlmodule Ubuntu.Components.ListItems 0.1 |
218 | + \ingroup ubuntu-listitems |
219 | + \brief An expandable list item with no contents. |
220 | + The Expandable class can be used for generic list items containing other |
221 | + components such as buttons. It subclasses \l Empty and thus brings all that |
222 | + functionality, but additionally provides means to expand and collapse the item. |
223 | + |
224 | + When used together with an \l ExpandablesListView or \l ExpandablesColumn it |
225 | + can coordinate with other items in the list to make sure it is scrolled while |
226 | + expanding to be fully visible in the view. Additionally it is made sure that |
227 | + only one Expandable item is expanded at a time and it is collapsed when the |
228 | + user clicks outside the item. |
229 | + |
230 | + You can set \l expanded to true/false to expand/collapse the item. |
231 | + |
232 | + Examples: |
233 | + \qml |
234 | + import Ubuntu.Components 0.1 |
235 | + import Ubuntu.Components.ListItems 0.1 as ListItem |
236 | + |
237 | + Item { |
238 | + ListModel { |
239 | + id: listModel |
240 | + } |
241 | + |
242 | + ListItem.ExpandablesListView { |
243 | + anchors { left: parent.left; right: parent.right } |
244 | + height: units.gu(24) |
245 | + model: listModel |
246 | + |
247 | + delegate: ListItem.Expandable { |
248 | + id: expandingItem |
249 | + |
250 | + expandedHeight: units.gu(30) |
251 | + |
252 | + onClicked: { |
253 | + expanded = true; |
254 | + } |
255 | + } |
256 | + } |
257 | + } |
258 | + \endqml |
259 | + |
260 | + \b{This component is under heavy development.} |
261 | +*/ |
262 | + |
263 | +Empty { |
264 | + id: root |
265 | + implicitHeight: expanded ? priv.maxExpandedHeight : collapsedHeight |
266 | + |
267 | + /*! |
268 | + \preliminary |
269 | + Reflects the expanded state. Set this to true/false to expand/collapse the item. |
270 | + */ |
271 | + property bool expanded: false |
272 | + |
273 | + /*! |
274 | + \preliminary |
275 | + The collapsed (normal) height of the item. Defaults to the standard height for list items. |
276 | + */ |
277 | + property real collapsedHeight: __height |
278 | + |
279 | + /*! |
280 | + \preliminary |
281 | + The expanded height of the item's content. Defaults to the same as collapsedHeight which |
282 | + disables the expanding feature. In order for the item to be expandable, set this to the |
283 | + expanded size. Note that the actual expanded size can be smaller if there is not enough |
284 | + space in the containing list. In that case the item becomes flickable automatically. |
285 | + */ |
286 | + property real expandedHeight: collapsedHeight |
287 | + |
288 | + /*! |
289 | + If set to true, the item will collapse again when the user clicks somewhere in the always |
290 | + visible (when collapsed) area. |
291 | + */ |
292 | + property bool collapseOnClick: false |
293 | + |
294 | + /*! |
295 | + \internal |
296 | + Reparent any content to inside the Flickable |
297 | + */ |
298 | + property alias children: flickableContent.data |
299 | + |
300 | + /*! \internal */ |
301 | + QtObject { |
302 | + id: priv |
303 | + |
304 | + /*! |
305 | + \internal |
306 | + Points to the containing ExpandablesListView or ExpandablesColumn |
307 | + */ |
308 | + property Item view: root.ListView.view ? root.ListView.view : (root.parent.parent.parent.hasOwnProperty("expandItem") ? root.parent.parent.parent : null) |
309 | + |
310 | + /*! \internal |
311 | + Gives information whether this item is inside a ExpandablesListView or ExpandablesColumn |
312 | + */ |
313 | + readonly property bool isInExpandableList: view && view !== undefined && view.hasOwnProperty("expandItem") && view.hasOwnProperty("collapse") |
314 | + |
315 | + /*! \internal |
316 | + Gives information if there is another item expanded in the containing ExpandablesListView or ExpandablesColumn |
317 | + */ |
318 | + readonly property bool otherExpanded: isInExpandableList && view.expandedItem !== null && view.expandedItem !== undefined && view.expandedItem !== root |
319 | + |
320 | + /*! \internal |
321 | + Gives information about the maximum expanded height, in case that is limited by the containing ExpandablesListView or ExpandablesColumn |
322 | + */ |
323 | + readonly property real maxExpandedHeight: isInExpandableList ? Math.min(view.height - collapsedHeight, expandedHeight) : expandedHeight |
324 | + } |
325 | + |
326 | + states: [ |
327 | + State { |
328 | + name: "" |
329 | + PropertyChanges { target: root; opacity: 1 } |
330 | + }, |
331 | + State { |
332 | + name: "otherExpanded"; when: priv.otherExpanded |
333 | + PropertyChanges { target: root; opacity: .5 } |
334 | + }, |
335 | + State { |
336 | + name: "expanded"; when: expanded |
337 | + PropertyChanges { target: root; z: 3 } |
338 | + } |
339 | + ] |
340 | + |
341 | + /*! \internal */ |
342 | + onExpandedChanged: { |
343 | + if (!expanded) { |
344 | + contentFlickable.contentY = 0; |
345 | + } |
346 | + |
347 | + if (priv.isInExpandableList) { |
348 | + if (expanded) { |
349 | + priv.view.expandItem(root); |
350 | + } else { |
351 | + priv.view.collapse(); |
352 | + } |
353 | + } |
354 | + } |
355 | + |
356 | + Behavior on height { |
357 | + UbuntuNumberAnimation {} |
358 | + } |
359 | + Behavior on opacity { |
360 | + UbuntuNumberAnimation {} |
361 | + } |
362 | + |
363 | + Flickable { |
364 | + id: contentFlickable |
365 | + objectName: "__expandableContentFlickable" |
366 | + anchors { fill: parent; leftMargin: root.__contentsMargins; rightMargin: __contentsMargins; bottomMargin: divider.height } |
367 | + interactive: root.expanded && contentHeight > height + root.divider.height |
368 | + contentHeight: root.expandedHeight |
369 | + flickableDirection: Flickable.VerticalFlick |
370 | + clip: true |
371 | + |
372 | + Behavior on contentY { |
373 | + UbuntuNumberAnimation {} |
374 | + } |
375 | + |
376 | + Item { |
377 | + id: flickableContent |
378 | + anchors { |
379 | + left: parent.left |
380 | + right: parent.right |
381 | + } |
382 | + height: childrenRect.height |
383 | + } |
384 | + } |
385 | + |
386 | + MouseArea { |
387 | + anchors { left: parent.left; top: parent.top; right: parent.right } |
388 | + enabled: root.collapseOnClick && root.expanded |
389 | + height: root.collapsedHeight |
390 | + onClicked: root.expanded = false; |
391 | + } |
392 | +} |
393 | |
394 | === added file 'modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml' |
395 | --- modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml 1970-01-01 00:00:00 +0000 |
396 | +++ modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml 2014-02-13 10:10:25 +0000 |
397 | @@ -0,0 +1,136 @@ |
398 | +/* |
399 | + * Copyright 2014 Canonical Ltd. |
400 | + * |
401 | + * This program is free software; you can redistribute it and/or modify |
402 | + * it under the terms of the GNU Lesser General Public License as published by |
403 | + * the Free Software Foundation; version 3. |
404 | + * |
405 | + * This program is distributed in the hope that it will be useful, |
406 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
407 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
408 | + * GNU Lesser General Public License for more details. |
409 | + * |
410 | + * You should have received a copy of the GNU Lesser General Public License |
411 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
412 | + */ |
413 | + |
414 | +import QtQuick 2.0 |
415 | +import Ubuntu.Components 0.1 |
416 | + |
417 | +/*! |
418 | + \qmltype ExpandablesColumn |
419 | + \inqmlmodule Ubuntu.Components.ListItems 0.1 |
420 | + \ingroup ubuntu-listitems |
421 | + \brief A column to be used together with the \l Expandable item. |
422 | + This lays out its content just like a regular Column inside a Flickable but |
423 | + when used together with items of type \l Expandable it provides additional features |
424 | + like automatically positioning the expanding item when it expands and collapsing |
425 | + it again when the user taps outside of it. |
426 | + |
427 | + Examples: |
428 | + \qml |
429 | + import Ubuntu.Components 0.1 |
430 | + import Ubuntu.Components.ListItems 0.1 as ListItem |
431 | + |
432 | + ListItem.ExpandablesColumn { |
433 | + anchors { left: parent.left; right: parent.right } |
434 | + height: units.gu(24) |
435 | + |
436 | + Repeater { |
437 | + model: 8 |
438 | + ListItem.Expandable { |
439 | + expandedHeight: units.gu(30) |
440 | + |
441 | + onClicked: { |
442 | + expanded = true; |
443 | + } |
444 | + } |
445 | + } |
446 | + } |
447 | + \endqml |
448 | + |
449 | + \b{This component is under heavy development.} |
450 | +*/ |
451 | + |
452 | +Flickable { |
453 | + id: root |
454 | + contentHeight: column.height |
455 | + |
456 | + /*! |
457 | + \preliminary |
458 | + Points to the currently expanded item. Null if no item is expanded. |
459 | + \qmlproperty Item expandedItem |
460 | + */ |
461 | + readonly property alias expandedItem: priv.expandedItem |
462 | + |
463 | + /*! |
464 | + \preliminary |
465 | + Expand the given item. The item must be a child of this ListView. |
466 | + */ |
467 | + function expandItem(item) { |
468 | + if (!item.hasOwnProperty("expandedHeight") || !item.hasOwnProperty("collapsedHeight")) { |
469 | + return; |
470 | + } |
471 | + |
472 | + if (priv.expandedItem != null) { |
473 | + priv.expandedItem.expanded = false; |
474 | + } |
475 | + priv.expandedItem = item; |
476 | + |
477 | + var maxExpandedHeight = root.height - item.collapsedHeight; |
478 | + var expandedItemHeight = Math.min(item.expandedHeight, maxExpandedHeight); |
479 | + var bottomIntersect = root.mapFromItem(item).y + expandedItemHeight - maxExpandedHeight; |
480 | + if (bottomIntersect > 0) { |
481 | + contentY += bottomIntersect; |
482 | + } |
483 | + } |
484 | + |
485 | + /*! |
486 | + \preliminary |
487 | + Collapse the currently expanded item. If there isn't any item expanded, this function does nothing. |
488 | + */ |
489 | + function collapse() { |
490 | + priv.expandedItem.expanded = false; |
491 | + priv.expandedItem = null; |
492 | + } |
493 | + |
494 | + /*! |
495 | + \internal |
496 | + Reparent any content to inside the Column. |
497 | + */ |
498 | + default property alias children: column.data |
499 | + |
500 | + /*! \internal */ |
501 | + QtObject { |
502 | + id: priv |
503 | + |
504 | + /*! \internal |
505 | + Points to the currently expanded item. Null if no item is expanded. |
506 | + */ |
507 | + property var expandedItem: null |
508 | + } |
509 | + |
510 | + Behavior on contentY { |
511 | + UbuntuNumberAnimation { } |
512 | + } |
513 | + |
514 | + Column { |
515 | + id: column |
516 | + anchors { left: parent.left; right: parent.right } |
517 | + |
518 | + } |
519 | + |
520 | + MouseArea { |
521 | + anchors {left: parent.left; right: parent.right; top: parent.top } |
522 | + height: root.mapFromItem(priv.expandedItem).y + root.contentY |
523 | + enabled: priv.expandedItem != null |
524 | + onClicked: root.collapse(); |
525 | + } |
526 | + |
527 | + MouseArea { |
528 | + anchors {left: parent.left; right: parent.right; bottom: parent.bottom } |
529 | + height: priv.expandedItem != null ? root.contentHeight - (root.mapFromItem(priv.expandedItem).y + root.contentY + priv.expandedItem.height) : 0 |
530 | + enabled: priv.expandedItem != null |
531 | + onClicked: root.collapse(); |
532 | + } |
533 | +} |
534 | |
535 | === added file 'modules/Ubuntu/Components/ListItems/ExpandablesListView.qml' |
536 | --- modules/Ubuntu/Components/ListItems/ExpandablesListView.qml 1970-01-01 00:00:00 +0000 |
537 | +++ modules/Ubuntu/Components/ListItems/ExpandablesListView.qml 2014-02-13 10:10:25 +0000 |
538 | @@ -0,0 +1,126 @@ |
539 | +/* |
540 | + * Copyright 2014 Canonical Ltd. |
541 | + * |
542 | + * This program is free software; you can redistribute it and/or modify |
543 | + * it under the terms of the GNU Lesser General Public License as published by |
544 | + * the Free Software Foundation; version 3. |
545 | + * |
546 | + * This program is distributed in the hope that it will be useful, |
547 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
548 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
549 | + * GNU Lesser General Public License for more details. |
550 | + * |
551 | + * You should have received a copy of the GNU Lesser General Public License |
552 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
553 | + */ |
554 | + |
555 | +import QtQuick 2.0 |
556 | +import Ubuntu.Components 0.1 |
557 | + |
558 | +/*! |
559 | + \qmltype ExpandablesListView |
560 | + \inqmlmodule Ubuntu.Components.ListItems 0.1 |
561 | + \ingroup ubuntu-listitems |
562 | + \brief A ListView to be used together with the \l Expandable item. |
563 | + The ExpandablesListView works just like a regular ListView, but is intended |
564 | + to be used with together with \l Expandable items as delegates. |
565 | + It provides additional features like automatically positioning the expanding |
566 | + item when it expands and collapsing it again when the user taps outside of it. |
567 | + |
568 | + Examples: |
569 | + \qml |
570 | + import Ubuntu.Components 0.1 |
571 | + import Ubuntu.Components.ListItems 0.1 as ListItem |
572 | + |
573 | + Item { |
574 | + ListModel { |
575 | + id: listModel |
576 | + } |
577 | + |
578 | + ListItem.ExpandablesListView { |
579 | + anchors { left: parent.left; right: parent.right } |
580 | + height: units.gu(24) |
581 | + model: listModel |
582 | + |
583 | + delegate: ListItem.Expandable { |
584 | + id: expandingItem |
585 | + |
586 | + expandedHeight: units.gu(30) |
587 | + |
588 | + onClicked: { |
589 | + expanded = true; |
590 | + } |
591 | + } |
592 | + } |
593 | + } |
594 | + \endqml |
595 | + |
596 | + \b{This component is under heavy development.} |
597 | +*/ |
598 | + |
599 | +ListView { |
600 | + id: root |
601 | + |
602 | + /*! |
603 | + \preliminary |
604 | + Points to the currently expanded item. Null if no item is expanded. |
605 | + \qmlproperty Item expandedItem |
606 | + */ |
607 | + readonly property alias expandedItem: priv.expandedItem |
608 | + |
609 | + /*! |
610 | + \preliminary |
611 | + Expand the given item. The item must be a child of this ListView. |
612 | + */ |
613 | + function expandItem(item) { |
614 | + if (!item.hasOwnProperty("expandedHeight") || !item.hasOwnProperty("collapsedHeight")) { |
615 | + return; |
616 | + } |
617 | + |
618 | + if (priv.expandedItem != null) { |
619 | + priv.expandedItem.expanded = false; |
620 | + } |
621 | + item.expanded = true; |
622 | + priv.expandedItem = item; |
623 | + |
624 | + var itemY = contentItem.mapFromItem(item).y; |
625 | + var itemHeight = item.expandedHeight; |
626 | + var itemIndex = indexAt(item.x, item.y); |
627 | + |
628 | + var bottomSpacing = itemIndex == model.count - 1 ? 0 : item.collapsedHeight; |
629 | + if (itemY + itemHeight > height + contentY - bottomSpacing) { |
630 | + contentY = Math.min(itemY, itemY + itemHeight - height + bottomSpacing); |
631 | + } |
632 | + } |
633 | + |
634 | + /*! |
635 | + \preliminary |
636 | + Collapse the currently expanded item. If there isn't any item expanded, this function does nothing. |
637 | + */ |
638 | + function collapse() { |
639 | + priv.expandedItem.expanded = false; |
640 | + priv.expandedItem = null; |
641 | + } |
642 | + |
643 | + /*! \internal */ |
644 | + QtObject { |
645 | + id: priv |
646 | + |
647 | + /*! \internal |
648 | + Points to the currently expanded item. Null if no item is expanded. |
649 | + */ |
650 | + property Item expandedItem: null |
651 | + } |
652 | + |
653 | + Behavior on contentY { |
654 | + UbuntuNumberAnimation {} |
655 | + } |
656 | + |
657 | + MouseArea { |
658 | + parent: contentItem |
659 | + anchors.fill: parent |
660 | + z: 2 |
661 | + enabled: priv.expandedItem != null |
662 | + onClicked: root.collapse(); |
663 | + } |
664 | +} |
665 | |
666 | === modified file 'modules/Ubuntu/Components/ListItems/qmldir' |
667 | --- modules/Ubuntu/Components/ListItems/qmldir 2013-11-29 14:15:51 +0000 |
668 | +++ modules/Ubuntu/Components/ListItems/qmldir 2014-02-13 10:10:25 +0000 |
669 | @@ -14,3 +14,6 @@ |
670 | Subtitled 0.1 Subtitled.qml |
671 | SingleControl 0.1 SingleControl.qml |
672 | ThinDivider 0.1 ThinDivider.qml |
673 | +ExpandablesListView 0.1 ExpandablesListView.qml |
674 | +ExpandablesColumn 0.1 ExpandablesColumn.qml |
675 | +Expandable 0.1 Expandable.qml |
676 | |
677 | === modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml' |
678 | --- modules/Ubuntu/Test/UbuntuTestCase.qml 2013-12-02 17:36:20 +0000 |
679 | +++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-02-13 10:10:25 +0000 |
680 | @@ -33,15 +33,20 @@ |
681 | /*! |
682 | Find a child from the item based on the objectName. |
683 | */ |
684 | - function findChild(obj,objectName) { |
685 | - for (var i in obj.children) { |
686 | - var child = obj.children[i]; |
687 | - if (child.objectName === objectName) return child; |
688 | - var subChild = findChild(child,objectName); |
689 | - if (subChild !== undefined) return subChild; |
690 | - } |
691 | - return undefined; |
692 | - } |
693 | + function findChild(obj,objectName) { |
694 | + var childs = new Array(0); |
695 | + childs.push(obj) |
696 | + while (childs.length > 0) { |
697 | + if (childs[0].objectName == objectName) { |
698 | + return childs[0] |
699 | + } |
700 | + for (var i in childs[0].data) { |
701 | + childs.push(childs[0].data[i]) |
702 | + } |
703 | + childs.splice(0, 1); |
704 | + } |
705 | + return null; |
706 | + } |
707 | |
708 | /*! |
709 | Move Mouse from x,y to distance of dx, dy divided to steps with a stepdelay (ms). |
710 | |
711 | === added file 'tests/unit_x11/tst_components/tst_Expandable.qml' |
712 | --- tests/unit_x11/tst_components/tst_Expandable.qml 1970-01-01 00:00:00 +0000 |
713 | +++ tests/unit_x11/tst_components/tst_Expandable.qml 2014-02-13 10:10:25 +0000 |
714 | @@ -0,0 +1,119 @@ |
715 | +/* |
716 | + * Copyright 2012 Canonical Ltd. |
717 | + * |
718 | + * This program is free software; you can redistribute it and/or modify |
719 | + * it under the terms of the GNU Lesser General Public License as published by |
720 | + * the Free Software Foundation; version 3. |
721 | + * |
722 | + * This program is distributed in the hope that it will be useful, |
723 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
724 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
725 | + * GNU Lesser General Public License for more details. |
726 | + * |
727 | + * You should have received a copy of the GNU Lesser General Public License |
728 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
729 | + */ |
730 | + |
731 | +import QtQuick 2.0 |
732 | +import QtTest 1.0 |
733 | +import Ubuntu.Test 0.1 |
734 | +import Ubuntu.Components 0.1 |
735 | +import Ubuntu.Components.ListItems 0.1 |
736 | + |
737 | +Item { |
738 | + width: units.gu(40) |
739 | + height: units.gu(60) |
740 | + |
741 | + ExpandablesColumn { |
742 | + id: expandablesColumn |
743 | + anchors { left: parent.left; top: parent.top; right: parent.right } |
744 | + height: units.gu(60) |
745 | + |
746 | + Expandable { |
747 | + id: expandable |
748 | + expandedHeight: contentColumn.height |
749 | + |
750 | + onClicked: expanded = !expanded |
751 | + |
752 | + Column { |
753 | + id: contentColumn |
754 | + anchors { left: parent.left; right: parent.right; top: parent.top } |
755 | + Rectangle { |
756 | + anchors { left: parent.left; right: parent.right} |
757 | + id: collapsedRect |
758 | + color: "khaki" |
759 | + height: expandable.collapsedHeight |
760 | + } |
761 | + Rectangle { |
762 | + anchors { left: parent.left; right: parent.right } |
763 | + height: units.gu(40) |
764 | + color: "orange" |
765 | + } |
766 | + } |
767 | + } |
768 | + } |
769 | + |
770 | + UbuntuTestCase { |
771 | + name: "Expandable" |
772 | + when: windowShown |
773 | + |
774 | + function test_expanding_collapsing() { |
775 | + waitForRendering(expandable); |
776 | + // expand it and make sure it eventually reaches the expandedHeight |
777 | + expandable.expanded = true; |
778 | + tryCompare(expandable, "height", contentColumn.height); |
779 | + |
780 | + // Item's flickable must not be interactive when the full expandedHeight fits |
781 | + var flickable = findChild(expandable, "__expandableContentFlickable"); |
782 | + compare(flickable.interactive, false); |
783 | + |
784 | + // collapse it and make sure it eventually reaches the collapsedHeight |
785 | + expandable.expanded = false; |
786 | + tryCompare(expandable, "height", expandable.collapsedHeight); |
787 | + } |
788 | + |
789 | + function test_maxExpandingHeight() { |
790 | + // resize the column to something smaller |
791 | + expandablesColumn.height = units.gu(30); |
792 | + |
793 | + // Item's flickable must not be interactive when collapsed |
794 | + var flickable = findChild(expandable, "__expandableContentFlickable"); |
795 | + compare(flickable.interactive, false); |
796 | + |
797 | + expandable.expanded = true; |
798 | + tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight); |
799 | + |
800 | + // Now that we're expanded and don't fit into the parent, flicking must be enabled |
801 | + compare(flickable.interactive, true); |
802 | + } |
803 | + |
804 | + function test_restoreCollapsingFlickable() { |
805 | + // resize the column to something smaller |
806 | + expandablesColumn.height = units.gu(30); |
807 | + |
808 | + expandable.expanded = true; |
809 | + tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight); |
810 | + |
811 | + var flickable = findChild(expandable, "__expandableContentFlickable"); |
812 | + flickable.flick(0, -units.gu(500)) |
813 | + tryCompare(flickable, "flicking", false); |
814 | + |
815 | + // contentY should be off the grid now |
816 | + verify(flickable.contentY != 0); |
817 | + |
818 | + // Now collapse and make sure that the contentY ends up again at 0 |
819 | + expandable.expanded = false; |
820 | + tryCompare(expandable, "height", expandable.collapsedHeight); |
821 | + compare(flickable.contentY, 0); |
822 | + } |
823 | + |
824 | + function cleanup() { |
825 | + // Restore listview height |
826 | + expandablesColumn.height = units.gu(60); |
827 | + |
828 | + // restore collapsed state |
829 | + expandable.expanded = false; |
830 | + tryCompare(expandable, "height", expandable.collapsedHeight); |
831 | + } |
832 | + } |
833 | +} |
834 | |
835 | === added file 'tests/unit_x11/tst_components/tst_ExpandablesColumn.qml' |
836 | --- tests/unit_x11/tst_components/tst_ExpandablesColumn.qml 1970-01-01 00:00:00 +0000 |
837 | +++ tests/unit_x11/tst_components/tst_ExpandablesColumn.qml 2014-02-13 10:10:25 +0000 |
838 | @@ -0,0 +1,157 @@ |
839 | +/* |
840 | + * Copyright 2012 Canonical Ltd. |
841 | + * |
842 | + * This program is free software; you can redistribute it and/or modify |
843 | + * it under the terms of the GNU Lesser General Public License as published by |
844 | + * the Free Software Foundation; version 3. |
845 | + * |
846 | + * This program is distributed in the hope that it will be useful, |
847 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
848 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
849 | + * GNU Lesser General Public License for more details. |
850 | + * |
851 | + * You should have received a copy of the GNU Lesser General Public License |
852 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
853 | + */ |
854 | + |
855 | +import QtQuick 2.0 |
856 | +import QtTest 1.0 |
857 | +import Ubuntu.Test 0.1 |
858 | +import Ubuntu.Components 0.1 |
859 | +import Ubuntu.Components.ListItems 0.1 |
860 | + |
861 | +Item { |
862 | + width: units.gu(40) |
863 | + height: units.gu(60) |
864 | + |
865 | + ExpandablesColumn { |
866 | + id: expandablesColumn |
867 | + anchors { left: parent.left; top: parent.top; right: parent.right } |
868 | + height: units.gu(60) |
869 | + clip: true |
870 | + |
871 | + Repeater { |
872 | + id: repeater |
873 | + model: 20 |
874 | + delegate: Expandable { |
875 | + id: expandable |
876 | + objectName: "expandable" + index |
877 | + expandedHeight: contentColumn.height |
878 | + |
879 | + onClicked: expanded = !expanded |
880 | + |
881 | + Column { |
882 | + id: contentColumn |
883 | + anchors { left: parent.left; right: parent.right; top: parent.top } |
884 | + Rectangle { |
885 | + anchors { left: parent.left; right: parent.right} |
886 | + id: collapsedRect |
887 | + color: index % 2 == 0 ? "khaki" : "blue" |
888 | + height: expandable.collapsedHeight |
889 | + } |
890 | + Rectangle { |
891 | + anchors { left: parent.left; right: parent.right } |
892 | + height: units.gu(40) |
893 | + color: "orange" |
894 | + } |
895 | + } |
896 | + } |
897 | + } |
898 | + } |
899 | + |
900 | + UbuntuTestCase { |
901 | + name: "ExpandablesColumn" |
902 | + when: windowShown |
903 | + |
904 | + function init() { |
905 | + waitForRendering(expandablesColumn); |
906 | + } |
907 | + |
908 | + function expandItem(item) { |
909 | + item.expanded = true; |
910 | + var targetHeight = Math.min(item.expandedHeight, expandablesColumn.height - item.collapsedHeight); |
911 | + tryCompare(item, "height", targetHeight); |
912 | + } |
913 | + |
914 | + function collapse() { |
915 | + var expandedItem = expandablesColumn.expandedItem; |
916 | + if (expandedItem != undefined) { |
917 | + expandedItem.expanded = false; |
918 | + tryCompare(expandedItem, "height", expandedItem.collapsedHeight); |
919 | + } |
920 | + } |
921 | + |
922 | + function test_expandedItem() { |
923 | + var item = findChild(expandablesColumn, "expandable1"); |
924 | + expandItem(item); |
925 | + |
926 | + // expandedItem needs to point to the expanded item |
927 | + compare(expandablesColumn.expandedItem, item); |
928 | + |
929 | + collapse(); |
930 | + |
931 | + // expandedItem must be unset after collapsing |
932 | + compare(expandablesColumn.expandedItem, undefined); |
933 | + } |
934 | + |
935 | + function test_noScrollingNeeded() { |
936 | + var item = findChild(expandablesColumn, "expandable1"); |
937 | + compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); |
938 | + |
939 | + expandItem(item); |
940 | + |
941 | + compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); |
942 | + } |
943 | + |
944 | + function test_scrollToTop() { |
945 | + expandablesColumn.height = units.gu(30); |
946 | + |
947 | + var item = findChild(expandablesColumn, "expandable1"); |
948 | + compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight); |
949 | + |
950 | + expandItem(item); |
951 | + |
952 | + compare(expandablesColumn.mapFromItem(item).y, 0); |
953 | + } |
954 | + |
955 | + function test_scrollIntoView() { |
956 | + var item = findChild(expandablesColumn, "expandable9"); |
957 | + expandItem(item); |
958 | + |
959 | + // The item must be scrolled upwards, leaving space for one other item at the bottom |
960 | + compare(expandablesColumn.mapFromItem(item).y, expandablesColumn.height - item.collapsedHeight - item.expandedHeight); |
961 | + } |
962 | + |
963 | + function test_collapseByClickingOutside() { |
964 | + // expand item 0 |
965 | + var item = findChild(expandablesColumn, "expandable0"); |
966 | + expandItem(item); |
967 | + |
968 | + // click on item 1 |
969 | + var item1 = findChild(expandablesColumn, "expandable1"); |
970 | + mouseClick(item1, item1.width / 2, item1.height / 2); |
971 | + |
972 | + // make sure item1 is collapsed |
973 | + tryCompare(item, "expanded", false); |
974 | + } |
975 | + |
976 | + function test_dimOthers() { |
977 | + var item = findChild(expandablesColumn, "expandable1"); |
978 | + expandItem(item); |
979 | + |
980 | + for (var i = 0; i < repeater.count; ++i) { |
981 | + var isCurrent = (repeater.itemAt(i) === expandablesColumn.expandedItem) |
982 | + compare(repeater.itemAt(i).opacity, isCurrent ? 1 : .5) |
983 | + } |
984 | + } |
985 | + |
986 | + function cleanup() { |
987 | + // Restore listview height |
988 | + expandablesColumn.height = units.gu(60); |
989 | + collapse(); |
990 | + // scroll the column back to top |
991 | + expandablesColumn.flick(0, units.gu(500)); |
992 | + tryCompare(expandablesColumn, "flicking", false); |
993 | + } |
994 | + } |
995 | +} |
996 | |
997 | === added file 'tests/unit_x11/tst_components/tst_ExpandablesListView.qml' |
998 | --- tests/unit_x11/tst_components/tst_ExpandablesListView.qml 1970-01-01 00:00:00 +0000 |
999 | +++ tests/unit_x11/tst_components/tst_ExpandablesListView.qml 2014-02-13 10:10:25 +0000 |
1000 | @@ -0,0 +1,170 @@ |
1001 | +/* |
1002 | + * Copyright 2012 Canonical Ltd. |
1003 | + * |
1004 | + * This program is free software; you can redistribute it and/or modify |
1005 | + * it under the terms of the GNU Lesser General Public License as published by |
1006 | + * the Free Software Foundation; version 3. |
1007 | + * |
1008 | + * This program is distributed in the hope that it will be useful, |
1009 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1010 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1011 | + * GNU Lesser General Public License for more details. |
1012 | + * |
1013 | + * You should have received a copy of the GNU Lesser General Public License |
1014 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1015 | + */ |
1016 | + |
1017 | +import QtQuick 2.0 |
1018 | +import QtTest 1.0 |
1019 | +import Ubuntu.Test 0.1 |
1020 | +import Ubuntu.Components 0.1 |
1021 | +import Ubuntu.Components.ListItems 0.1 |
1022 | + |
1023 | +Item { |
1024 | + width: units.gu(40) |
1025 | + height: units.gu(60) |
1026 | + |
1027 | + ListModel { |
1028 | + id: dummyModel |
1029 | + Component.onCompleted: { |
1030 | + for (var i = 0; i < 20; ++i) { |
1031 | + dummyModel.append({idx: i}); |
1032 | + } |
1033 | + } |
1034 | + } |
1035 | + |
1036 | + ExpandablesListView { |
1037 | + id: expandablesListView |
1038 | + anchors { left: parent.left; top: parent.top; right: parent.right } |
1039 | + height: units.gu(60) |
1040 | + clip: true |
1041 | + model: dummyModel |
1042 | + |
1043 | + delegate: Expandable { |
1044 | + id: expandable |
1045 | + objectName: "expandable" + index |
1046 | + expandedHeight: contentColumn.height |
1047 | + |
1048 | + onClicked: expanded = !expanded |
1049 | + |
1050 | + Column { |
1051 | + id: contentColumn |
1052 | + anchors { left: parent.left; right: parent.right; top: parent.top } |
1053 | + Rectangle { |
1054 | + anchors { left: parent.left; right: parent.right} |
1055 | + id: collapsedRect |
1056 | + color: index % 2 == 0 ? "khaki" : "blue" |
1057 | + height: expandable.collapsedHeight |
1058 | + } |
1059 | + Rectangle { |
1060 | + anchors { left: parent.left; right: parent.right } |
1061 | + height: units.gu(40) |
1062 | + color: "orange" |
1063 | + } |
1064 | + } |
1065 | + } |
1066 | + } |
1067 | + |
1068 | + UbuntuTestCase { |
1069 | + name: "ExpandablesListView" |
1070 | + when: windowShown |
1071 | + |
1072 | + function initTestCase() { |
1073 | + tryCompare(dummyModel, "count", 20); |
1074 | + } |
1075 | + |
1076 | + function init() { |
1077 | + waitForRendering(expandablesListView); |
1078 | + } |
1079 | + |
1080 | + function expandItem(item) { |
1081 | + item.expanded = true; |
1082 | + var targetHeight = Math.min(item.expandedHeight, expandablesListView.height - item.collapsedHeight); |
1083 | + tryCompare(item, "height", targetHeight); |
1084 | + } |
1085 | + |
1086 | + function collapse() { |
1087 | + var expandedItem = expandablesListView.expandedItem; |
1088 | + if (expandedItem != undefined && expandedItem != null) { |
1089 | + expandedItem.expanded = false; |
1090 | + tryCompare(expandedItem, "height", expandedItem.collapsedHeight); |
1091 | + } |
1092 | + } |
1093 | + |
1094 | + function test_expandedItem() { |
1095 | + var item = findChild(expandablesListView, "expandable1"); |
1096 | + expandItem(item); |
1097 | + |
1098 | + // expandedItem needs to point to the expanded item |
1099 | + compare(expandablesListView.expandedItem, item); |
1100 | + |
1101 | + collapse(); |
1102 | + |
1103 | + // expandedItem must be unset after collapsing |
1104 | + compare(expandablesListView.expandedItem, null); |
1105 | + } |
1106 | + |
1107 | + function test_noScrollingNeeded() { |
1108 | + var item = findChild(expandablesListView, "expandable1"); |
1109 | + fuzzyCompare(expandablesListView.mapFromItem(item).y, item.collapsedHeight, .5); |
1110 | + |
1111 | + expandItem(item); |
1112 | + |
1113 | + fuzzyCompare(expandablesListView.mapFromItem(item).y, item.collapsedHeight, .5); |
1114 | + } |
1115 | + |
1116 | + function test_scrollToTop() { |
1117 | + expandablesListView.height = units.gu(30); |
1118 | + |
1119 | + var item = findChild(expandablesListView, "expandable1"); |
1120 | + fuzzyCompare(expandablesListView.mapFromItem(item).y, item.collapsedHeight, .5); |
1121 | + |
1122 | + expandItem(item); |
1123 | + |
1124 | + fuzzyCompare(expandablesListView.mapFromItem(item).y, 0, .5); |
1125 | + } |
1126 | + |
1127 | + function test_scrollIntoView() { |
1128 | + var item = findChild(expandablesListView, "expandable9"); |
1129 | + expandItem(item); |
1130 | + |
1131 | + // The item must be scrolled upwards, leaving space for one other item at the bottom |
1132 | + fuzzyCompare(expandablesListView.mapFromItem(item).y, expandablesListView.height - item.collapsedHeight - item.expandedHeight, .5); |
1133 | + } |
1134 | + |
1135 | + function test_collapseByClickingOutside() { |
1136 | + // expand item 0 |
1137 | + var item = findChild(expandablesListView, "expandable0"); |
1138 | + expandItem(item); |
1139 | + |
1140 | + // click on item 1 |
1141 | + var item1 = findChild(expandablesListView, "expandable1"); |
1142 | + mouseClick(item1, item1.width / 2, item1.height / 2); |
1143 | + |
1144 | + // make sure item1 is collapsed |
1145 | + tryCompare(item, "expanded", false); |
1146 | + } |
1147 | + |
1148 | + function test_dimOthers() { |
1149 | + var item = findChild(expandablesListView, "expandable1"); |
1150 | + expandItem(item); |
1151 | + |
1152 | + for (var i = 0; i < expandablesListView.contentItem.children.length; ++i) { |
1153 | + var childItem = expandablesListView.contentItem.children[i]; |
1154 | + if (childItem.hasOwnProperty("expanded")) { |
1155 | + compare(childItem.opacity, childItem.expanded ? 1 : .5) |
1156 | + } |
1157 | + |
1158 | + } |
1159 | + } |
1160 | + |
1161 | + function cleanup() { |
1162 | + // Restore listview height |
1163 | + expandablesListView.height = units.gu(60); |
1164 | + collapse(); |
1165 | + // scroll the ListView back to top |
1166 | + expandablesListView.flick(0, units.gu(500)); |
1167 | + tryCompare(expandablesListView, "flicking", false); |
1168 | + } |
1169 | + } |
1170 | +} |
1171 | |
1172 | === modified file 'tests/unit_x11/tst_components/tst_pickerpanel.qml' |
1173 | --- tests/unit_x11/tst_components/tst_pickerpanel.qml 2014-01-20 07:41:16 +0000 |
1174 | +++ tests/unit_x11/tst_components/tst_pickerpanel.qml 2014-02-13 10:10:25 +0000 |
1175 | @@ -152,6 +152,7 @@ |
1176 | // forced panel tests |
1177 | // these should be executed as last ones |
1178 | function test_2_clickOndefaultMode() { |
1179 | + waitForRendering(PickerPanel); |
1180 | // force panel - this is private specific!!! |
1181 | var privates = findChild(PickerPanel, "PickerPanel_Internals"); |
1182 | privates.isPhone = true; |
1183 | |
1184 | === modified file 'tests/unit_x11/tst_test/tst_ubuntutestcase.qml' |
1185 | --- tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2013-07-24 14:05:48 +0000 |
1186 | +++ tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-02-13 10:10:25 +0000 |
1187 | @@ -52,11 +52,11 @@ |
1188 | |
1189 | function test_findChild() { |
1190 | var child = findChild(root,"myMouseArea"); |
1191 | - compare(child!==undefined,true, "When a child is found, it is returned"); |
1192 | + compare(child!==null,true, "When a child is found, it is returned"); |
1193 | compare(child.objectName,"myMouseArea"); |
1194 | |
1195 | child = findChild(root,"NoSuchChildHere"); |
1196 | - compare(child===undefined,true,"When there is no child, function should return undefined"); |
1197 | + compare(child===null,true,"When there is no child, function should return null"); |
1198 | } |
1199 | } |
1200 | } |
FAILED: Continuous integration, rev:845 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/1265/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 960/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/943/ console jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- amd64-ci/ 213/console jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 213/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/960/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/943/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/1265/ rebuild
http://