Merge lp:~mzanetti/ubuntu-ui-toolkit/expandable-and-column into lp:ubuntu-ui-toolkit

Proposed by Michael Zanetti
Status: Merged
Approved by: Zsombor Egri
Approved revision: 953
Merged at revision: 956
Proposed branch: lp:~mzanetti/ubuntu-ui-toolkit/expandable-and-column
Merge into: lp:ubuntu-ui-toolkit
Prerequisite: lp:~mzanetti/ubuntu-ui-toolkit/children-to-data
Diff against target: 752 lines (+705/-0)
7 files modified
components.api (+13/-0)
examples/ubuntu-ui-toolkit-gallery/ListItems.qml (+84/-0)
modules/Ubuntu/Components/ListItems/Expandable.qml (+194/-0)
modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml (+136/-0)
modules/Ubuntu/Components/ListItems/qmldir (+2/-0)
tests/unit_x11/tst_components/tst_expandable.qml (+119/-0)
tests/unit_x11/tst_components/tst_expandablescolumn.qml (+157/-0)
To merge this branch: bzr merge lp:~mzanetti/ubuntu-ui-toolkit/expandable-and-column
Reviewer Review Type Date Requested Status
Zsombor Egri Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+206154@code.launchpad.net

This proposal supersedes a proposal from 2014-02-13.

Commit message

Added Expandable and ExpandablesColumn to implement the expanding Design Pattern.

To post a comment you must log in.
939. By Michael Zanetti

make it a default property

Revision history for this message
Michael Zanetti (mzanetti) wrote :

Zsombor's feedback on the original MP:

> For ListItems.Expandable:
> - provide property which configures the possibility to collapse the Expandable while clicked on its "header"

done.

> - 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)

This really doesn't belong in here imo... Adding that here would make it unusable for everything except OptionSelector and ComboBox. This is really intended to handle the expansion pattern without dictating the users (as in developer) what he has to put inside of it.

940. By Michael Zanetti

add Expandable and ExpandablesColumn to the gallery

Revision history for this message
Michael Zanetti (mzanetti) wrote :

> Expandable:
> 287 + /*!
> 288 + \internal
> 289 + Reparent any content to inside the Flickable
> 290 + */
> 291 + property alias children: flickableContent.data
>
> Shouldn't this be a default property? It should also be a public one.

Made it a default prop. It already was public...

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
Zsombor Egri (zsombi) wrote :

216 + /*!
217 + \internal
218 + Reparent any content to inside the Flickable
219 + */
220 + default property alias children: flickableContent.data

416 + /*!
417 + \internal
418 + Reparent any content to inside the Column.
419 + */
420 + default property alias children: column.data

Please remove the \internal tag. This property is still internal from the documentation's point of view.
Also, please remove all \preliminary tags from the documentation.

472 + * Copyright 2012 Canonical Ltd.
:) 2014.

tst_expandable:
I do not see test case when the item is used in ListView (not UbuntuListView) or Column. Shouldn't we have tests for those?

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

Nice work otherwise! Let me know when you've updated all, so we can land.

941. By Michael Zanetti

remove internal tag from Expandable*'s default property docs

942. By Michael Zanetti

copyright 2012 -> 2014

943. By Michael Zanetti

rename files to be lowercase, like the rest of the tests

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
944. By Michael Zanetti

update api file

945. By Michael Zanetti

merge prerequisite

946. By Michael Zanetti

merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
947. By Michael Zanetti

use findInvisibleChild instead of findChild

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
948. By Michael Zanetti

merge trunk

949. By Michael Zanetti

fix api docs

950. By Michael Zanetti

cleanup a little

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)
951. By Michael Zanetti

don't link to UbuntuListView in this branch yet, Jenkins doesn't like that.

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

One small comment: please add \default tag to the default properties. After that we're done with this.

review: Needs Fixing
952. By Michael Zanetti

added \default tag to default properties docstring

Revision history for this message
Michael Zanetti (mzanetti) wrote :

> One small comment: please add \default tag to the default properties. After
> that we're done with this.

done.

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

Nice stuff, glad to see such contribs to UITK :)

review: Approve
953. By Michael Zanetti

fix className in gallery

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

CI@home is green with it.

review: Approve

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 2014-02-13 17:22:21 +0000
3+++ components.api 2014-02-26 09:45:48 +0000
4@@ -106,6 +106,19 @@
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 bool collapseOnClick
14+ default property QtObject children
15+modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml
16+Flickable
17+ readonly property Item expandedItem
18+ function expandItem(item)
19+ function collapse()
20+ default property QtObject children
21 modules/Ubuntu/Components/ListItems/Header.qml
22 Item
23 property string text
24
25=== modified file 'examples/ubuntu-ui-toolkit-gallery/ListItems.qml'
26--- examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2013-11-22 14:49:12 +0000
27+++ examples/ubuntu-ui-toolkit-gallery/ListItems.qml 2014-02-26 09:45:48 +0000
28@@ -222,4 +222,88 @@
29 }
30 }
31 }
32+
33+ TemplateSection {
34+ title: i18n.tr("ExpandablesColumn")
35+ className: "ExpandablesColumn"
36+
37+ ListItem.ExpandablesColumn {
38+ anchors { left: parent.left; right: parent.right }
39+ clip: true
40+ height: units.gu(24)
41+
42+ Repeater {
43+ model: 8
44+ ListItem.Expandable {
45+ id: expandingColumnItem
46+ expandedHeight: contentColumn1.height + units.gu(1)
47+ collapseOnClick: index % 2 == 0
48+
49+ onClicked: {
50+ expanded = true;
51+ }
52+
53+ Column {
54+ id: contentColumn1
55+ anchors { left: parent.left; right: parent.right }
56+ Item {
57+ anchors { left: parent.left; right: parent.right}
58+ height: expandingColumnItem.collapsedHeight
59+ Toolkit.Label {
60+ anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter}
61+ text: "Item " + index + (expandingColumnItem.collapseOnClick ? " (with collapseOnClick)" : "")
62+ }
63+ }
64+
65+ Toolkit.UbuntuShape {
66+ anchors { left: parent.left; right: parent.right }
67+ height: index % 2 == 0 ? units.gu(6) : units.gu(18)
68+ color: "khaki"
69+ }
70+ }
71+ }
72+ }
73+ }
74+ }
75+
76+ TemplateSection {
77+ title: i18n.tr("Expandable")
78+ className: "Expandable"
79+
80+ Column {
81+ anchors { left: parent.left; right: parent.right }
82+ clip: true
83+
84+ Repeater {
85+ model: 2
86+ ListItem.Expandable {
87+ id: expandingItem1
88+ expandedHeight: contentCol1.height + units.gu(1)
89+
90+ onClicked: {
91+ expanded = !expanded;
92+ }
93+
94+ Column {
95+ id: contentCol1
96+ anchors { left: parent.left; right: parent.right }
97+ Item {
98+ anchors { left: parent.left; right: parent.right}
99+ height: expandingItem1.collapsedHeight
100+ Toolkit.Label {
101+ anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter}
102+ text: "Item " + index
103+ }
104+ }
105+
106+ Toolkit.UbuntuShape {
107+ anchors { left: parent.left; right: parent.right }
108+ height: index % 2 == 0 ? units.gu(6) : units.gu(18)
109+ color: "khaki"
110+ }
111+ }
112+ }
113+ }
114+ }
115+ }
116 }
117
118=== added file 'modules/Ubuntu/Components/ListItems/Expandable.qml'
119--- modules/Ubuntu/Components/ListItems/Expandable.qml 1970-01-01 00:00:00 +0000
120+++ modules/Ubuntu/Components/ListItems/Expandable.qml 2014-02-26 09:45:48 +0000
121@@ -0,0 +1,194 @@
122+/*
123+ * Copyright 2014 Canonical Ltd.
124+ *
125+ * This program is free software; you can redistribute it and/or modify
126+ * it under the terms of the GNU Lesser General Public License as published by
127+ * the Free Software Foundation; version 3.
128+ *
129+ * This program is distributed in the hope that it will be useful,
130+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
131+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132+ * GNU Lesser General Public License for more details.
133+ *
134+ * You should have received a copy of the GNU Lesser General Public License
135+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
136+ */
137+import QtQuick 2.0
138+import Ubuntu.Components 0.1
139+
140+/*!
141+ \qmltype Expandable
142+ \inqmlmodule Ubuntu.Components.ListItems 0.1
143+ \ingroup ubuntu-listitems
144+ \brief An expandable list item with no contents.
145+ The Expandable class can be used for generic list items containing other
146+ components such as buttons. It subclasses \l Empty and thus brings all that
147+ functionality, but additionally provides means to expand and collapse the item.
148+
149+ When used together with an UbuntuListView or \l ExpandablesColumn it
150+ can coordinate with other items in the list to make sure it is scrolled while
151+ expanding to be fully visible in the view. Additionally it is made sure that
152+ only one Expandable item is expanded at a time and it is collapsed when the
153+ user clicks outside the item.
154+
155+ You can set \l expanded to true/false to expand/collapse the item.
156+
157+ Examples:
158+ \qml
159+ import Ubuntu.Components 0.1
160+ import Ubuntu.Components.ListItems 0.1 as ListItem
161+
162+ Item {
163+ ListModel {
164+ id: listModel
165+ }
166+
167+ ListItem.UbuntuListView {
168+ anchors { left: parent.left; right: parent.right }
169+ height: units.gu(24)
170+ model: listModel
171+
172+ delegate: ListItem.Expandable {
173+ id: expandingItem
174+
175+ expandedHeight: units.gu(30)
176+
177+ onClicked: {
178+ expanded = true;
179+ }
180+ }
181+ }
182+ }
183+ \endqml
184+
185+ \b{This component is under heavy development.}
186+*/
187+
188+Empty {
189+ id: root
190+ implicitHeight: expanded ? priv.maxExpandedHeight : collapsedHeight
191+
192+ /*!
193+ Reflects the expanded state. Set this to true/false to expand/collapse the item.
194+ */
195+ property bool expanded: false
196+
197+ /*!
198+ The collapsed (normal) height of the item. Defaults to the standard height for list items.
199+ */
200+ property real collapsedHeight: __height
201+
202+ /*!
203+ The expanded height of the item's content. Defaults to the same as collapsedHeight which
204+ disables the expanding feature. In order for the item to be expandable, set this to the
205+ expanded size. Note that the actual expanded size can be smaller if there is not enough
206+ space in the containing list. In that case the item becomes flickable automatically.
207+ */
208+ property real expandedHeight: collapsedHeight
209+
210+ /*!
211+ If set to true, the item will collapse again when the user clicks somewhere in the always
212+ visible (when collapsed) area.
213+ */
214+ property bool collapseOnClick: false
215+
216+ /*!
217+ Reparent any content to inside the Flickable
218+ \qmlproperty QtObject children
219+ \default
220+ */
221+ default property alias children: flickableContent.data
222+
223+ /*! \internal */
224+ QtObject {
225+ id: priv
226+
227+ /*!
228+ \internal
229+ Points to the containing ExpandablesListView or ExpandablesColumn
230+ */
231+ property Item view: root.ListView.view ? root.ListView.view : (root.parent.parent.parent.hasOwnProperty("expandItem") ? root.parent.parent.parent : null)
232+
233+ /*! \internal
234+ Gives information whether this item is inside a ExpandablesListView or ExpandablesColumn
235+ */
236+ readonly property bool isInExpandableList: view && view !== undefined && view.hasOwnProperty("expandItem") && view.hasOwnProperty("collapse")
237+
238+ /*! \internal
239+ Gives information if there is another item expanded in the containing ExpandablesListView or ExpandablesColumn
240+ */
241+ readonly property bool otherExpanded: isInExpandableList && view.expandedItem !== null && view.expandedItem !== undefined && view.expandedItem !== root
242+
243+ /*! \internal
244+ Gives information about the maximum expanded height, in case that is limited by the containing ExpandablesListView or ExpandablesColumn
245+ */
246+ readonly property real maxExpandedHeight: isInExpandableList ? Math.min(view.height - collapsedHeight, expandedHeight) : expandedHeight
247+ }
248+
249+ states: [
250+ State {
251+ name: ""
252+ PropertyChanges { target: root; opacity: 1 }
253+ },
254+ State {
255+ name: "otherExpanded"; when: priv.otherExpanded
256+ PropertyChanges { target: root; opacity: .5 }
257+ },
258+ State {
259+ name: "expanded"; when: expanded
260+ PropertyChanges { target: root; z: 3 }
261+ }
262+ ]
263+
264+ /*! \internal */
265+ onExpandedChanged: {
266+ if (!expanded) {
267+ contentFlickable.contentY = 0;
268+ }
269+
270+ if (priv.isInExpandableList) {
271+ if (expanded) {
272+ priv.view.expandItem(root);
273+ } else {
274+ priv.view.collapse();
275+ }
276+ }
277+ }
278+
279+ Behavior on height {
280+ UbuntuNumberAnimation {}
281+ }
282+ Behavior on opacity {
283+ UbuntuNumberAnimation {}
284+ }
285+
286+ Flickable {
287+ id: contentFlickable
288+ objectName: "__expandableContentFlickable"
289+ anchors { fill: parent; leftMargin: root.__contentsMargins; rightMargin: __contentsMargins; bottomMargin: divider.height }
290+ interactive: root.expanded && contentHeight > height + root.divider.height
291+ contentHeight: root.expandedHeight
292+ flickableDirection: Flickable.VerticalFlick
293+ clip: true
294+
295+ Behavior on contentY {
296+ UbuntuNumberAnimation {}
297+ }
298+
299+ Item {
300+ id: flickableContent
301+ anchors {
302+ left: parent.left
303+ right: parent.right
304+ }
305+ height: childrenRect.height
306+ }
307+ }
308+
309+ MouseArea {
310+ anchors { left: parent.left; top: parent.top; right: parent.right }
311+ enabled: root.collapseOnClick && root.expanded
312+ height: root.collapsedHeight
313+ onClicked: root.expanded = false;
314+ }
315+}
316
317=== added file 'modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml'
318--- modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml 1970-01-01 00:00:00 +0000
319+++ modules/Ubuntu/Components/ListItems/ExpandablesColumn.qml 2014-02-26 09:45:48 +0000
320@@ -0,0 +1,136 @@
321+/*
322+ * Copyright 2014 Canonical Ltd.
323+ *
324+ * This program is free software; you can redistribute it and/or modify
325+ * it under the terms of the GNU Lesser General Public License as published by
326+ * the Free Software Foundation; version 3.
327+ *
328+ * This program is distributed in the hope that it will be useful,
329+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
330+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
331+ * GNU Lesser General Public License for more details.
332+ *
333+ * You should have received a copy of the GNU Lesser General Public License
334+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
335+ */
336+
337+import QtQuick 2.0
338+import Ubuntu.Components 0.1
339+
340+/*!
341+ \qmltype ExpandablesColumn
342+ \inqmlmodule Ubuntu.Components.ListItems 0.1
343+ \ingroup ubuntu-listitems
344+ \brief A column to be used together with the \l Expandable item.
345+ This lays out its content just like a regular Column inside a Flickable but
346+ when used together with items of type \l Expandable it provides additional features
347+ like automatically positioning the expanding item when it expands and collapsing
348+ it again when the user taps outside of it.
349+
350+ Examples:
351+ \qml
352+ import Ubuntu.Components 0.1
353+ import Ubuntu.Components.ListItems 0.1 as ListItem
354+
355+ ListItem.ExpandablesColumn {
356+ anchors { left: parent.left; right: parent.right }
357+ height: units.gu(24)
358+
359+ Repeater {
360+ model: 8
361+ ListItem.Expandable {
362+ expandedHeight: units.gu(30)
363+
364+ onClicked: {
365+ expanded = true;
366+ }
367+ }
368+ }
369+ }
370+ \endqml
371+
372+ \b{This component is under heavy development.}
373+*/
374+
375+Flickable {
376+ id: root
377+ contentHeight: column.height
378+
379+ /*!
380+ \preliminary
381+ Points to the currently expanded item. Null if no item is expanded.
382+ \qmlproperty Item expandedItem
383+ */
384+ readonly property alias expandedItem: priv.expandedItem
385+
386+ /*!
387+ \preliminary
388+ Expand the given item. The item must be a child of this ListView.
389+ */
390+ function expandItem(item) {
391+ if (!item.hasOwnProperty("expandedHeight") || !item.hasOwnProperty("collapsedHeight")) {
392+ return;
393+ }
394+
395+ if (priv.expandedItem != null) {
396+ priv.expandedItem.expanded = false;
397+ }
398+ priv.expandedItem = item;
399+
400+ var maxExpandedHeight = root.height - item.collapsedHeight;
401+ var expandedItemHeight = Math.min(item.expandedHeight, maxExpandedHeight);
402+ var bottomIntersect = root.mapFromItem(item).y + expandedItemHeight - maxExpandedHeight;
403+ if (bottomIntersect > 0) {
404+ contentY += bottomIntersect;
405+ }
406+ }
407+
408+ /*!
409+ \preliminary
410+ Collapse the currently expanded item. If there isn't any item expanded, this function does nothing.
411+ */
412+ function collapse() {
413+ priv.expandedItem.expanded = false;
414+ priv.expandedItem = null;
415+ }
416+
417+ /*!
418+ Reparent any content to inside the Column.
419+ \qmlproperty QtObject children
420+ \default
421+ */
422+ default property alias children: column.data
423+
424+ /*! \internal */
425+ QtObject {
426+ id: priv
427+
428+ /*! \internal
429+ Points to the currently expanded item. Null if no item is expanded.
430+ */
431+ property var expandedItem: null
432+ }
433+
434+ Behavior on contentY {
435+ UbuntuNumberAnimation { }
436+ }
437+
438+ Column {
439+ id: column
440+ anchors { left: parent.left; right: parent.right }
441+ }
442+
443+ MouseArea {
444+ anchors { left: parent.left; right: parent.right; top: parent.top }
445+ height: root.mapFromItem(priv.expandedItem).y + root.contentY
446+ enabled: priv.expandedItem != null
447+ onClicked: root.collapse();
448+ }
449+
450+ MouseArea {
451+ anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
452+ height: priv.expandedItem != null ? root.contentHeight - (root.mapFromItem(priv.expandedItem).y + root.contentY + priv.expandedItem.height) : 0
453+ enabled: priv.expandedItem != null
454+ onClicked: root.collapse();
455+ }
456+}
457
458=== modified file 'modules/Ubuntu/Components/ListItems/qmldir'
459--- modules/Ubuntu/Components/ListItems/qmldir 2013-11-29 14:15:51 +0000
460+++ modules/Ubuntu/Components/ListItems/qmldir 2014-02-26 09:45:48 +0000
461@@ -14,3 +14,5 @@
462 Subtitled 0.1 Subtitled.qml
463 SingleControl 0.1 SingleControl.qml
464 ThinDivider 0.1 ThinDivider.qml
465+Expandable 0.1 Expandable.qml
466+ExpandablesColumn 0.1 ExpandablesColumn.qml
467
468=== added file 'tests/unit_x11/tst_components/tst_expandable.qml'
469--- tests/unit_x11/tst_components/tst_expandable.qml 1970-01-01 00:00:00 +0000
470+++ tests/unit_x11/tst_components/tst_expandable.qml 2014-02-26 09:45:48 +0000
471@@ -0,0 +1,119 @@
472+/*
473+ * Copyright 2014 Canonical Ltd.
474+ *
475+ * This program is free software; you can redistribute it and/or modify
476+ * it under the terms of the GNU Lesser General Public License as published by
477+ * the Free Software Foundation; version 3.
478+ *
479+ * This program is distributed in the hope that it will be useful,
480+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
481+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
482+ * GNU Lesser General Public License for more details.
483+ *
484+ * You should have received a copy of the GNU Lesser General Public License
485+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
486+ */
487+
488+import QtQuick 2.0
489+import QtTest 1.0
490+import Ubuntu.Test 0.1
491+import Ubuntu.Components 0.1
492+import Ubuntu.Components.ListItems 0.1
493+
494+Item {
495+ width: units.gu(40)
496+ height: units.gu(60)
497+
498+ ExpandablesColumn {
499+ id: expandablesColumn
500+ anchors { left: parent.left; top: parent.top; right: parent.right }
501+ height: units.gu(60)
502+
503+ Expandable {
504+ id: expandable
505+ expandedHeight: contentColumn.height
506+
507+ onClicked: expanded = !expanded
508+
509+ Column {
510+ id: contentColumn
511+ anchors { left: parent.left; right: parent.right; top: parent.top }
512+ Rectangle {
513+ anchors { left: parent.left; right: parent.right}
514+ id: collapsedRect
515+ color: "khaki"
516+ height: expandable.collapsedHeight
517+ }
518+ Rectangle {
519+ anchors { left: parent.left; right: parent.right }
520+ height: units.gu(40)
521+ color: "orange"
522+ }
523+ }
524+ }
525+ }
526+
527+ UbuntuTestCase {
528+ name: "Expandable"
529+ when: windowShown
530+
531+ function test_expanding_collapsing() {
532+ waitForRendering(expandable);
533+ // expand it and make sure it eventually reaches the expandedHeight
534+ expandable.expanded = true;
535+ tryCompare(expandable, "height", contentColumn.height);
536+
537+ // Item's flickable must not be interactive when the full expandedHeight fits
538+ var flickable = findInvisibleChild(expandable, "__expandableContentFlickable");
539+ compare(flickable.interactive, false);
540+
541+ // collapse it and make sure it eventually reaches the collapsedHeight
542+ expandable.expanded = false;
543+ tryCompare(expandable, "height", expandable.collapsedHeight);
544+ }
545+
546+ function test_maxExpandingHeight() {
547+ // resize the column to something smaller
548+ expandablesColumn.height = units.gu(30);
549+
550+ // Item's flickable must not be interactive when collapsed
551+ var flickable = findInvisibleChild(expandable, "__expandableContentFlickable");
552+ compare(flickable.interactive, false);
553+
554+ expandable.expanded = true;
555+ tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight);
556+
557+ // Now that we're expanded and don't fit into the parent, flicking must be enabled
558+ compare(flickable.interactive, true);
559+ }
560+
561+ function test_restoreCollapsingFlickable() {
562+ // resize the column to something smaller
563+ expandablesColumn.height = units.gu(30);
564+
565+ expandable.expanded = true;
566+ tryCompare(expandable, "height", expandablesColumn.height - expandable.collapsedHeight);
567+
568+ var flickable = findInvisibleChild(expandable, "__expandableContentFlickable");
569+ flickable.flick(0, -units.gu(500))
570+ tryCompare(flickable, "flicking", false);
571+
572+ // contentY should be off the grid now
573+ verify(flickable.contentY != 0);
574+
575+ // Now collapse and make sure that the contentY ends up again at 0
576+ expandable.expanded = false;
577+ tryCompare(expandable, "height", expandable.collapsedHeight);
578+ compare(flickable.contentY, 0);
579+ }
580+
581+ function cleanup() {
582+ // Restore listview height
583+ expandablesColumn.height = units.gu(60);
584+
585+ // restore collapsed state
586+ expandable.expanded = false;
587+ tryCompare(expandable, "height", expandable.collapsedHeight);
588+ }
589+ }
590+}
591
592=== added file 'tests/unit_x11/tst_components/tst_expandablescolumn.qml'
593--- tests/unit_x11/tst_components/tst_expandablescolumn.qml 1970-01-01 00:00:00 +0000
594+++ tests/unit_x11/tst_components/tst_expandablescolumn.qml 2014-02-26 09:45:48 +0000
595@@ -0,0 +1,157 @@
596+/*
597+ * Copyright 2014 Canonical Ltd.
598+ *
599+ * This program is free software; you can redistribute it and/or modify
600+ * it under the terms of the GNU Lesser General Public License as published by
601+ * the Free Software Foundation; version 3.
602+ *
603+ * This program is distributed in the hope that it will be useful,
604+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
605+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
606+ * GNU Lesser General Public License for more details.
607+ *
608+ * You should have received a copy of the GNU Lesser General Public License
609+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
610+ */
611+
612+import QtQuick 2.0
613+import QtTest 1.0
614+import Ubuntu.Test 0.1
615+import Ubuntu.Components 0.1
616+import Ubuntu.Components.ListItems 0.1
617+
618+Item {
619+ width: units.gu(40)
620+ height: units.gu(60)
621+
622+ ExpandablesColumn {
623+ id: expandablesColumn
624+ anchors { left: parent.left; top: parent.top; right: parent.right }
625+ height: units.gu(60)
626+ clip: true
627+
628+ Repeater {
629+ id: repeater
630+ model: 20
631+ delegate: Expandable {
632+ id: expandable
633+ objectName: "expandable" + index
634+ expandedHeight: contentColumn.height
635+
636+ onClicked: expanded = !expanded
637+
638+ Column {
639+ id: contentColumn
640+ anchors { left: parent.left; right: parent.right; top: parent.top }
641+ Rectangle {
642+ anchors { left: parent.left; right: parent.right}
643+ id: collapsedRect
644+ color: index % 2 == 0 ? "khaki" : "blue"
645+ height: expandable.collapsedHeight
646+ }
647+ Rectangle {
648+ anchors { left: parent.left; right: parent.right }
649+ height: units.gu(40)
650+ color: "orange"
651+ }
652+ }
653+ }
654+ }
655+ }
656+
657+ UbuntuTestCase {
658+ name: "ExpandablesColumn"
659+ when: windowShown
660+
661+ function init() {
662+ waitForRendering(expandablesColumn);
663+ }
664+
665+ function expandItem(item) {
666+ item.expanded = true;
667+ var targetHeight = Math.min(item.expandedHeight, expandablesColumn.height - item.collapsedHeight);
668+ tryCompare(item, "height", targetHeight);
669+ }
670+
671+ function collapse() {
672+ var expandedItem = expandablesColumn.expandedItem;
673+ if (expandedItem != undefined) {
674+ expandedItem.expanded = false;
675+ tryCompare(expandedItem, "height", expandedItem.collapsedHeight);
676+ }
677+ }
678+
679+ function test_expandedItem() {
680+ var item = findChild(expandablesColumn, "expandable1");
681+ expandItem(item);
682+
683+ // expandedItem needs to point to the expanded item
684+ compare(expandablesColumn.expandedItem, item);
685+
686+ collapse();
687+
688+ // expandedItem must be unset after collapsing
689+ compare(expandablesColumn.expandedItem, undefined);
690+ }
691+
692+ function test_noScrollingNeeded() {
693+ var item = findChild(expandablesColumn, "expandable1");
694+ compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight);
695+
696+ expandItem(item);
697+
698+ compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight);
699+ }
700+
701+ function test_scrollToTop() {
702+ expandablesColumn.height = units.gu(30);
703+
704+ var item = findChild(expandablesColumn, "expandable1");
705+ compare(expandablesColumn.mapFromItem(item).y, item.collapsedHeight);
706+
707+ expandItem(item);
708+
709+ compare(expandablesColumn.mapFromItem(item).y, 0);
710+ }
711+
712+ function test_scrollIntoView() {
713+ var item = findChild(expandablesColumn, "expandable9");
714+ expandItem(item);
715+
716+ // The item must be scrolled upwards, leaving space for one other item at the bottom
717+ compare(expandablesColumn.mapFromItem(item).y, expandablesColumn.height - item.collapsedHeight - item.expandedHeight);
718+ }
719+
720+ function test_collapseByClickingOutside() {
721+ // expand item 0
722+ var item = findChild(expandablesColumn, "expandable0");
723+ expandItem(item);
724+
725+ // click on item 1
726+ var item1 = findChild(expandablesColumn, "expandable1");
727+ mouseClick(item1, item1.width / 2, item1.height / 2);
728+
729+ // make sure item1 is collapsed
730+ tryCompare(item, "expanded", false);
731+ }
732+
733+ function test_dimOthers() {
734+ var item = findChild(expandablesColumn, "expandable1");
735+ expandItem(item);
736+
737+ for (var i = 0; i < repeater.count; ++i) {
738+ var isCurrent = (repeater.itemAt(i) === expandablesColumn.expandedItem)
739+ compare(repeater.itemAt(i).opacity, isCurrent ? 1 : .5)
740+ }
741+ }
742+
743+ function cleanup() {
744+ // Restore listview height
745+ expandablesColumn.height = units.gu(60);
746+ collapse();
747+ // scroll the column back to top
748+ expandablesColumn.flick(0, units.gu(500));
749+ tryCompare(expandablesColumn, "flicking", false);
750+ }
751+ }
752+}

Subscribers

People subscribed via source and target branches

to status/vote changes: