on xenial help sign in
Merge see-all-expansion.
67b140dMichał Sawicz
tests/autopilot/.project → .projectrenamed+1−1
@@ -1,6 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
1<?xml version="1.0" encoding="UTF-8"?>
2<projectDescription>
2<projectDescription>
3− <name>Unity8 Autopilot</name>
3+ <name>Unity8</name>
4 <comment></comment>
4 <comment></comment>
5 <projects>
5 <projects>
6 </projects>
6 </projects>
tests/autopilot/.pydevproject → .pydevprojectrenamed+3−1
@@ -1,7 +1,9 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<?eclipse-pydev version="1.0"?><pydev_project>
2<?eclipse-pydev version="1.0"?><pydev_project>
3<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
3<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
4−<path>/Unity8 Autopilot</path>
4+<path>/Unity8/tests/autopilot</path>
5+<path>/Unity8/.bazaar</path>
6+<path>/Unity8/tests/whitespace</path>
5</pydev_pathproperty>
7</pydev_pathproperty>
6<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
8<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
7<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
9<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
.settings/Autopilot List.launchnew file+14
@@ -0,0 +1,14 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
3+<stringAttribute key="bad_container_name" value="/Unity8/.pyd"/>
4+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"/>
5+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"/>
6+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
7+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
8+</listAttribute>
9+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/autopilot"/>
10+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
11+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="list unity8"/>
12+<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
13+<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Unity8"/>
14+</launchConfiguration>
.settings/Autopilot Run.launchnew file+14
@@ -0,0 +1,14 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
3+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"/>
4+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"/>
5+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
6+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
7+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
8+</listAttribute>
9+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/autopilot"/>
10+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
11+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="run ${string_prompt:the test suite to run:unity8}"/>
12+<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
13+<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Unity8"/>
14+</launchConfiguration>
po/unity8.pot+17−9
@@ -8,7 +8,7 @@ msgid ""
8msgstr ""
8msgstr ""
9"Project-Id-Version: unity8\n"
9"Project-Id-Version: unity8\n"
10"Report-Msgid-Bugs-To: \n"
10"Report-Msgid-Bugs-To: \n"
11−"POT-Creation-Date: 2014-07-07 12:15+0100\n"
11+"POT-Creation-Date: 2014-07-11 14:59+0200\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -80,10 +80,6 @@ msgstr ""
80msgid "OK"
80msgid "OK"
81msgstr ""
81msgstr ""
82
82
83−#: qml/Components/PageHeader.qml:366
84−msgid "Recent searches"
85−msgstr ""
86−
87#: qml/Components/PassphraseLockscreen.qml:60
83#: qml/Components/PassphraseLockscreen.qml:60
88#, qt-format
84#, qt-format
89msgid "Hello %1"
85msgid "Hello %1"
@@ -105,7 +101,7 @@ msgstr ""
105msgid "See more"
101msgid "See more"
106msgstr ""
102msgstr ""
107
103
108−#: qml/Components/SeeMore.qml:58
104+#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330
109msgid "See less"
105msgid "See less"
110msgstr ""
106msgstr ""
111
107
@@ -113,6 +109,10 @@ msgstr ""
113msgid "Recent"
109msgid "Recent"
114msgstr ""
110msgstr ""
115
111
112+#: qml/Dash/GenericScopeView.qml:330
113+msgid "See all"
114+msgstr ""
115+
116#: qml/Dash/Previews/PreviewActionCombo.qml:34
116#: qml/Dash/Previews/PreviewActionCombo.qml:34
117msgid "More..."
117msgid "More..."
118msgstr ""
118msgstr ""
@@ -121,15 +121,15 @@ msgstr ""
121msgid "Less..."
121msgid "Less..."
122msgstr ""
122msgstr ""
123
123
124−#: qml/Dash/Previews/PreviewRatingInput.qml:82
124+#: qml/Dash/Previews/PreviewRatingInput.qml:81
125msgid "Rate this"
125msgid "Rate this"
126msgstr ""
126msgstr ""
127
127
128−#: qml/Dash/Previews/PreviewRatingInput.qml:128
128+#: qml/Dash/Previews/PreviewRatingInput.qml:126
129msgid "Add a review"
129msgid "Add a review"
130msgstr ""
130msgstr ""
131
131
132−#: qml/Dash/Previews/PreviewRatingInput.qml:168
132+#: qml/Dash/Previews/PreviewRatingInput.qml:166
133msgid "Send"
133msgid "Send"
134msgstr ""
134msgstr ""
135
135
@@ -165,6 +165,14 @@ msgstr ""
165msgid "Please enter SIM PIN"
165msgid "Please enter SIM PIN"
166msgstr ""
166msgstr ""
167
167
168+#: qml/Panel/ActiveCallHint.qml:77
169+msgid "Tap to return to call..."
170+msgstr ""
171+
172+#: qml/Panel/ActiveCallHint.qml:90
173+msgid "Conference"
174+msgstr ""
175+
168#: qml/Panel/Indicators/MenuItemFactory.qml:583
176#: qml/Panel/Indicators/MenuItemFactory.qml:583
169msgid "In queue…"
177msgid "In queue…"
170msgstr ""
178msgstr ""
qml/Components/FilterGrid.qmldeleted−124
@@ -1,124 +0,0 @@
1−/*
2− * Copyright (C) 2013 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import Ubuntu.Components 0.1
19−import Utils 0.1
20−import "../Components"
21−
22−/*
23− A ResponsiveGridView that can optionally have the number of rows being displayed
24− reduced to collapsedRowCount, in which case a button saying "View all (123)"
25− will be shown at the bottom. If clicked, FilterGrid will them expand vertically
26− to display all rows.
27− */
28−Item {
29− id: root
30−
31− /* Whether, when collapsed, a button should be displayed enabling the user to expand
32− the grid to its full size. */
33− readonly property bool expandable: model.count > rowsWhenCollapsed * iconTileGrid.columns
34−
35− property var model: null
36−
37− /* Maximum number of rows to be show when filter=true. */
38− property int collapsedRowCount: 2
39− property int uncollapsedRowCount: Math.ceil(model.count / columns)
40− /* Never show more rows than model would fill up. */
41− readonly property int rowsWhenCollapsed: Math.min(collapsedRowCount, uncollapsedRowCount)
42− readonly property int collapsedHeight: iconTileGrid.contentHeightForRows(rowsWhenCollapsed)
43− readonly property int uncollapsedHeight: iconTileGrid.contentHeightForRows(uncollapsedRowCount)
44−
45− property alias minimumHorizontalSpacing: iconTileGrid.minimumHorizontalSpacing
46− property alias maximumNumberOfColumns: iconTileGrid.maximumNumberOfColumns
47− property alias columns: iconTileGrid.columns
48− property alias delegateWidth: iconTileGrid.delegateWidth
49− property alias delegateHeight: iconTileGrid.delegateHeight
50− property alias verticalSpacing: iconTileGrid.verticalSpacing
51− readonly property alias margins: iconTileGrid.margins
52− property alias delegate: iconTileGrid.delegate
53− property alias cellWidth: iconTileGrid.cellWidth
54− property alias cellHeight: iconTileGrid.cellHeight
55− property alias displayMarginBeginning: iconTileGrid.displayMarginBeginning
56− property alias displayMarginEnd: iconTileGrid.displayMarginEnd
57− readonly property alias originY: iconTileGrid.originY
58− readonly property alias flicking: iconTileGrid.flicking
59− readonly property alias moving: iconTileGrid.moving
60− readonly property alias pressDelay: iconTileGrid.pressDelay
61− property alias highlightIndex: iconTileGrid.highlightIndex
62− readonly property alias currentItem: iconTileGrid.currentItem
63− readonly property alias filtered: d.filter
64−
65− QtObject {
66− id: d
67− // We do have filter and collapsed properties because we need to decouple
68− // the real filtering with the animation since the closing animation
69− // i.e. setFilter(false. true) we still need to not be filtering until
70− // the animation finishes otherwise we hide the items when the animation
71− // is still running
72− property bool filter: true
73− property bool collapsed: true
74− }
75−
76− height: d.collapsed ? root.collapsedHeight : root.uncollapsedHeight
77− clip: filterAnimation.running
78−
79− Behavior on height {
80− id: heightBehaviour
81− enabled: false
82− NumberAnimation {
83− id: filterAnimation
84− // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
85− // otherwise since both animations can run at the same time you'll get
86− // some visual weirdness.
87− duration: 200
88− easing.type: Easing.InOutQuad
89− onRunningChanged: {
90− if (!running) {
91− d.filter = d.collapsed;
92− }
93− heightBehaviour.enabled = false;
94− }
95− }
96− }
97−
98− function setFilter(filter, animate) {
99− heightBehaviour.enabled = animate;
100− d.collapsed = filter;
101− if (!animate || !filter) {
102− d.filter = filter;
103− }
104− }
105−
106− ResponsiveGridView {
107− id: iconTileGrid
108−
109− anchors { left: parent.left; right: parent.right }
110− height: totalContentHeight
111− interactive: false
112−
113− minimumHorizontalSpacing: units.gu(0.5)
114− maximumNumberOfColumns: 6
115− delegateWidth: units.gu(11)
116− delegateHeight: units.gu(9.5)
117− verticalSpacing: units.gu(2)
118−
119− model: LimitProxyModel {
120− model: root.model
121− limit: d.filter ? rowsWhenCollapsed * iconTileGrid.columns : -1
122− }
123− }
124−}
qml/Components/ResponsiveGridView.qml+2−1
@@ -44,10 +44,11 @@ Item {
44 property alias displayMarginBeginning: gridView.displayMarginBeginning
44 property alias displayMarginBeginning: gridView.displayMarginBeginning
45 property alias displayMarginEnd: gridView.displayMarginEnd
45 property alias displayMarginEnd: gridView.displayMarginEnd
46 property alias highlightIndex: gridView.highlightIndex
46 property alias highlightIndex: gridView.highlightIndex
47+ property alias cacheBuffer: gridView.cacheBuffer
47 readonly property alias currentItem: gridView.currentItem
48 readonly property alias currentItem: gridView.currentItem
48
49
49 function contentHeightForRows(rows) {
50 function contentHeightForRows(rows) {
50− return rows * cellHeight + verticalSpacing
51+ return rows * cellHeight;
51 }
52 }
52
53
53 GridView {
54 GridView {
qml/Dash/CardCarousel.qml+2−7
@@ -21,13 +21,8 @@ import "../Components"
21DashRenderer {
21DashRenderer {
22 id: cardCarousel
22 id: cardCarousel
23
23
24− property alias cacheBuffer: carousel.cacheBuffer
25− property alias itemComponent: carousel.itemComponent
26− property alias minimumTileWidth: carousel.minimumTileWidth
27− property alias selectedItemScaleFactor: carousel.selectedItemScaleFactor
28− property alias tileAspectRatio: carousel.tileAspectRatio
29−
30− height: carousel.implicitHeight + units.gu(6)
24+ expandedHeight: carousel.implicitHeight + units.gu(6)
25+ collapsedHeight: expandedHeight
31
26
32 Carousel {
27 Carousel {
33 id: carousel
28 id: carousel
qml/Dash/CardFilterGrid.qml → qml/Dash/CardGrid.qmlrenamed+21−22
@@ -18,33 +18,32 @@ import QtQuick 2.0
18import "../Components"
18import "../Components"
19
19
20DashRenderer {
20DashRenderer {
21− id: genericFilterGrid
21+ id: root
22
22
23− expandable: filterGrid.expandable
23+ readonly property int collapsedRows: {
24− collapsedHeight: filterGrid.collapsedHeight
24+ if (!cardTool || !cardTool.template || typeof cardTool.template["collapsed-rows"] != "number") return 2;
25− uncollapsedHeight: filterGrid.uncollapsedHeight
25+ return cardTool.template["collapsed-rows"];
26− originY: filterGrid.originY
27− height: filterGrid.height
28− filtered: filterGrid.filtered
29−
30− function setFilter(filter, animate) {
31− filterGrid.setFilter(filter, animate)
32 }
26 }
33
27
34− FilterGrid {
28+ expandedHeight: grid.totalContentHeight
35− id: filterGrid
29+ collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows), expandedHeight)
36− width: genericFilterGrid.width
30+ originY: grid.originY
31+
32+ ResponsiveGridView {
33+ id: grid
34+ anchors.fill: parent
37 minimumHorizontalSpacing: units.gu(1)
35 minimumHorizontalSpacing: units.gu(1)
38 delegateWidth: cardTool.cardWidth
36 delegateWidth: cardTool.cardWidth
39 delegateHeight: cardTool.cardHeight
37 delegateHeight: cardTool.cardHeight
40 verticalSpacing: units.gu(1)
38 verticalSpacing: units.gu(1)
41− model: genericFilterGrid.model
39+ model: root.model
42− collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
40+ displayMarginBeginning: root.displayMarginBeginning
43− displayMarginBeginning: genericFilterGrid.displayMarginBeginning
41+ displayMarginEnd: root.displayMarginEnd
44− displayMarginEnd: genericFilterGrid.displayMarginEnd
42+ cacheBuffer: 0
43+ interactive: false
45 delegate: Item {
44 delegate: Item {
46− width: filterGrid.cellWidth
45+ width: grid.cellWidth
47− height: filterGrid.cellHeight
46+ height: grid.cellHeight
48 Loader {
47 Loader {
49 id: loader
48 id: loader
50 sourceComponent: cardTool.cardComponent
49 sourceComponent: cardTool.cardComponent
@@ -58,12 +57,12 @@ DashRenderer {
58 item.template = Qt.binding(function() { return cardTool.template; });
57 item.template = Qt.binding(function() { return cardTool.template; });
59 item.components = Qt.binding(function() { return cardTool.components; });
58 item.components = Qt.binding(function() { return cardTool.components; });
60 item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
59 item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; });
61− item.scopeStyle = genericFilterGrid.scopeStyle;
60+ item.scopeStyle = root.scopeStyle;
62 }
61 }
63 Connections {
62 Connections {
64 target: loader.item
63 target: loader.item
65− onClicked: genericFilterGrid.clicked(index, result)
64+ onClicked: root.clicked(index, result)
66− onPressAndHold: genericFilterGrid.pressAndHold(index)
65+ onPressAndHold: root.pressAndHold(index)
67 }
66 }
68 }
67 }
69 }
68 }
qml/Dash/CardVerticalJournal.qml+2−21
@@ -23,33 +23,14 @@ DashRenderer {
23
23
24 readonly property double collapseLimit: units.gu(35)
24 readonly property double collapseLimit: units.gu(35)
25
25
26− uncollapsedHeight: cardVerticalJournal.implicitHeight
26+ expandedHeight: Math.max(cardVerticalJournal.implicitHeight, minHeight)
27− collapsedHeight: Math.min(collapseLimit, cardVerticalJournal.implicitHeight)
27+ collapsedHeight: Math.max(Math.min(collapseLimit, cardVerticalJournal.implicitHeight), minHeight)
28− expandable: uncollapsedHeight > collapseLimit
29
28
30 // This minHeight is used as bootstrapper for the height. Vertical Journal
29 // This minHeight is used as bootstrapper for the height. Vertical Journal
31 // is special by the fact that it doesn't know how to calculate its implicit height unless we give it
30 // is special by the fact that it doesn't know how to calculate its implicit height unless we give it
32 // enough height that it can start creating its children so we make sure it has enough height for that
31 // enough height that it can start creating its children so we make sure it has enough height for that
33 // in case the model is non empty
32 // in case the model is non empty
34 readonly property double minHeight: root.model.count >= 1 ? cardVerticalJournal.rowSpacing + 1 : 0
33 readonly property double minHeight: root.model.count >= 1 ? cardVerticalJournal.rowSpacing + 1 : 0
35− height: filtered ? Math.max(collapsedHeight, minHeight) : uncollapsedHeight
36−
37− Behavior on height {
38− id: heightBehaviour
39− enabled: false
40− animation: UbuntuNumberAnimation {
41− onRunningChanged: {
42− if (!running) {
43− heightBehaviour.enabled = false
44− }
45− }
46− }
47− }
48−
49− function setFilter(filter, animate) {
50− heightBehaviour.enabled = animate;
51− filtered = filter;
52− }
53
34
54 ResponsiveVerticalJournal {
35 ResponsiveVerticalJournal {
55 id: cardVerticalJournal
36 id: cardVerticalJournal
qml/Dash/DashRenderer.qml+2−11
@@ -17,15 +17,9 @@
17import QtQuick 2.0
17import QtQuick 2.0
18
18
19Item {
19Item {
20− // Can the item be expanded?
20+ property int collapsedHeight
21− property bool expandable: false
22
21
23− // In case it can be expanded, is it filtered
22+ property int expandedHeight
24− property bool filtered: true
25−
26− property int collapsedHeight: height
27−
28− property int uncollapsedHeight: height
29
23
30 property int displayMarginBeginning: 0
24 property int displayMarginBeginning: 0
31
25
@@ -50,7 +44,4 @@ Item {
50 /// Emitted when the user pressed and held on an item
44 /// Emitted when the user pressed and held on an item
51 /// @param index is the index of the held item
45 /// @param index is the index of the held item
52 signal pressAndHold(int index)
46 signal pressAndHold(int index)
53−
54− function setFilter(filter, animate) {
55− }
56}
47}
qml/Dash/GenericScopeView.qml+104−56
@@ -119,6 +119,7 @@ FocusScope {
119
119
120 model: scopeView.categories
120 model: scopeView.categories
121 forceNoClip: previewListView.open
121 forceNoClip: previewListView.open
122+ pixelAligned: true
122
123
123 property string expandedCategoryId: ""
124 property string expandedCategoryId: ""
124
125
@@ -128,11 +129,21 @@ FocusScope {
128 highlightWhenPressed: false
129 highlightWhenPressed: false
129 showDivider: false
130 showDivider: false
130
131
131− readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
132+ readonly property bool expandable: {
132− readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filtered : true
133+ if (categoryView.model.count === 1) return false;
134+ if (cardTool.template && cardTool.template["collapsed-rows"] === 0) return false;
135+ if (item && item.expandedHeight > item.collapsedHeight) return true;
136+ return false;
137+ }
138+ property bool expanded: false
133 readonly property string category: categoryId
139 readonly property string category: categoryId
134 readonly property var item: rendererLoader.item
140 readonly property var item: rendererLoader.item
135
141
142+ function expand(expand, animate) {
143+ heightBehaviour.enabled = animate;
144+ expanded = expand;
145+ }
146+
136 CardTool {
147 CardTool {
137 id: cardTool
148 id: cardTool
138 objectName: "cardTool"
149 objectName: "cardTool"
@@ -142,6 +153,18 @@ FocusScope {
142 viewWidth: parent.width
153 viewWidth: parent.width
143 }
154 }
144
155
156+ onExpandableChanged: {
157+ // This can happen with the VJ that doesn't know how height it will be on creation
158+ // so doesn't set expandable until a bit too late for onLoaded
159+ if (expandable) {
160+ var shouldExpand = baseItem.category === categoryView.expandedCategoryId;
161+ baseItem.expand(shouldExpand, false /*animate*/);
162+ }
163+ }
164+
165+ onHeightChanged: rendererLoader.updateDelegateCreationRange();
166+ onYChanged: rendererLoader.updateDelegateCreationRange();
167+
145 Loader {
168 Loader {
146 id: rendererLoader
169 id: rendererLoader
147 anchors {
170 anchors {
@@ -151,13 +174,27 @@ FocusScope {
151 topMargin: name != "" ? 0 : units.gu(2)
174 topMargin: name != "" ? 0 : units.gu(2)
152 }
175 }
153
176
177+ Behavior on height {
178+ id: heightBehaviour
179+ enabled: false
180+ animation: UbuntuNumberAnimation {
181+ onRunningChanged: {
182+ if (!running) {
183+ heightBehaviour.enabled = false
184+ }
185+ }
186+ }
187+ }
188+
189+ height: baseItem.expandable && !baseItem.expanded ? item.collapsedHeight : item.expandedHeight
190+
154 source: {
191 source: {
155 switch (cardTool.categoryLayout) {
192 switch (cardTool.categoryLayout) {
156 case "carousel": return "CardCarousel.qml";
193 case "carousel": return "CardCarousel.qml";
157 case "vertical-journal": return "CardVerticalJournal.qml";
194 case "vertical-journal": return "CardVerticalJournal.qml";
158 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
195 case "running-apps": return "Apps/RunningApplicationsGrid.qml";
159 case "grid":
196 case "grid":
160− default: return "CardFilterGrid.qml";
197+ default: return "CardGrid.qml";
161 }
198 }
162 }
199 }
163
200
@@ -176,9 +213,9 @@ FocusScope {
176 }
213 }
177 item.objectName = Qt.binding(function() { return categoryId })
214 item.objectName = Qt.binding(function() { return categoryId })
178 item.scopeStyle = scopeView.scopeStyle;
215 item.scopeStyle = scopeView.scopeStyle;
179− if (item.expandable) {
216+ if (baseItem.expandable) {
180− var shouldFilter = categoryId != categoryView.expandedCategoryId;
217+ var shouldExpand = categoryId === categoryView.expandedCategoryId;
181− item.setFilter(shouldFilter, false /*animate*/);
218+ baseItem.expand(shouldExpand, false /*animate*/);
182 }
219 }
183 updateDelegateCreationRange();
220 updateDelegateCreationRange();
184 item.cardTool = cardTool;
221 item.cardTool = cardTool;
@@ -211,14 +248,6 @@ FocusScope {
211 previewListView.currentIndex = index;
248 previewListView.currentIndex = index;
212 previewListView.open = true
249 previewListView.open = true
213 }
250 }
214− onExpandableChanged: {
215− // This can happen with the VJ that doesn't know how height it will be on creation
216− // so doesn't set expandable until a bit too late for onLoaded
217− if (rendererLoader.item.expandable) {
218− var shouldFilter = baseItem.category != categoryView.expandedCategoryId;
219− rendererLoader.item.setFilter(shouldFilter, false /*animate*/);
220− }
221− }
222 }
251 }
223 Connections {
252 Connections {
224 target: categoryView
253 target: categoryView
@@ -227,17 +256,17 @@ FocusScope {
227 }
256 }
228 function collapseAllButExpandedCategory() {
257 function collapseAllButExpandedCategory() {
229 var item = rendererLoader.item;
258 var item = rendererLoader.item;
230− if (item.expandable) {
259+ if (baseItem.expandable) {
231− var shouldFilter = categoryId != categoryView.expandedCategoryId;
260+ var shouldExpand = categoryId === categoryView.expandedCategoryId;
232− if (shouldFilter != item.filter) {
261+ if (shouldExpand != baseItem.expanded) {
233 // If the filter animation will be seen start it, otherwise, just flip the switch
262 // If the filter animation will be seen start it, otherwise, just flip the switch
234− var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
263+ var shrinkingVisible = !shouldExpand && y + item.collapsedHeight + seeAll.height < categoryView.height;
235− var growingVisible = !shouldFilter && y + height < categoryView.height;
264+ var growingVisible = shouldExpand && y + height < categoryView.height;
236− if (!previewListView.open || !shouldFilter) {
265+ if (!previewListView.open || shouldExpand) {
237 var animate = shrinkingVisible || growingVisible;
266 var animate = shrinkingVisible || growingVisible;
238− item.setFilter(shouldFilter, animate)
267+ baseItem.expand(shouldExpand, animate)
239− if (!shouldFilter && !previewListView.open) {
268+ if (shouldExpand && !previewListView.open) {
240− categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
269+ categoryView.maximizeVisibleArea(index, item.expandedHeight + seeAll.height);
241 }
270 }
242 }
271 }
243 }
272 }
@@ -274,39 +303,69 @@ FocusScope {
274 item.displayMarginEnd = -baseItem.height;
303 item.displayMarginEnd = -baseItem.height;
275 } else {
304 } else {
276 item.displayMarginBeginning = -Math.max(-baseItem.y, 0);
305 item.displayMarginBeginning = -Math.max(-baseItem.y, 0);
277− item.displayMarginEnd = -Math.max(baseItem.height - categoryView.height + baseItem.y, 0)
306+ item.displayMarginEnd = -Math.max(baseItem.height - seeAll.height
307+ - categoryView.height + baseItem.y, 0)
278 }
308 }
279 }
309 }
280 }
310 }
311+ }
281
312
282− Image {
313+ AbstractButton {
283− visible: index != 0
314+ id: seeAll
284− anchors {
315+ objectName: "seeAll"
285− top: parent.top
316+ anchors {
286− left: parent.left
317+ top: rendererLoader.bottom
287− right: parent.right
318+ left: parent.left
319+ right: parent.right
320+ }
321+ height: baseItem.expandable ? seeAllLabel.font.pixelSize + units.gu(6) : 0
322+
323+ onClicked: {
324+ if (categoryView.expandedCategoryId != baseItem.category) {
325+ categoryView.expandedCategoryId = baseItem.category;
326+ } else {
327+ categoryView.expandedCategoryId = "";
288 }
328 }
289− fillMode: Image.Stretch
290− source: "graphics/dash_divider_top_lightgrad.png"
291− z: -1
292 }
329 }
293
330
294− Image {
331+ Label {
295− // FIXME Should not rely on model.count but view.count, but ListViewWithPageHeader doesn't expose it yet.
332+ id: seeAllLabel
296− visible: index != categoryView.model.count - 1
333+ text: baseItem.expanded ? i18n.tr("See less") : i18n.tr("See all")
297 anchors {
334 anchors {
298− bottom: parent.bottom
335+ centerIn: parent
299− left: parent.left
336+ verticalCenterOffset: units.gu(-0.5)
300− right: parent.right
301 }
337 }
302− fillMode: Image.Stretch
338+ fontSize: "small"
303− source: "graphics/dash_divider_top_darkgrad.png"
339+ font.weight: Font.Bold
304− z: -1
340+ color: scopeStyle ? scopeStyle.foreground : "grey"
341+ visible: baseItem.expandable
305 }
342 }
306 }
343 }
307
344
308− onHeightChanged: rendererLoader.updateDelegateCreationRange();
345+ Image {
309− onYChanged: rendererLoader.updateDelegateCreationRange();
346+ visible: index != 0
347+ anchors {
348+ top: parent.top
349+ left: parent.left
350+ right: parent.right
351+ }
352+ fillMode: Image.Stretch
353+ source: "graphics/dash_divider_top_lightgrad.png"
354+ z: -1
355+ }
356+
357+ Image {
358+ // FIXME Should not rely on model.count but view.count, but ListViewWithPageHeader doesn't expose it yet.
359+ visible: index != categoryView.model.count - 1
360+ anchors {
361+ bottom: seeAll.bottom
362+ left: parent.left
363+ right: parent.right
364+ }
365+ fillMode: Image.Stretch
366+ source: "graphics/dash_divider_top_darkgrad.png"
367+ z: -1
368+ }
310 }
369 }
311
370
312 sectionProperty: "name"
371 sectionProperty: "name"
@@ -314,20 +373,9 @@ FocusScope {
314 objectName: "dashSectionHeader" + (delegate ? delegate.category : "")
373 objectName: "dashSectionHeader" + (delegate ? delegate.category : "")
315 property var delegate: categoryView.item(delegateIndex)
374 property var delegate: categoryView.item(delegateIndex)
316 width: categoryView.width
375 width: categoryView.width
376+ height: section != "" ? units.gu(5) : 0
317 text: section
377 text: section
318 textColor: scopeStyle ? scopeStyle.foreground : "grey"
378 textColor: scopeStyle ? scopeStyle.foreground : "grey"
319− image: {
320− if (delegate && delegate.expandable)
321− return delegate.filtered ? "graphics/header_handlearrow.png" : "graphics/header_handlearrow2.png"
322− return "";
323− }
324− onClicked: {
325− if (categoryView.expandedCategoryId != delegate.category)
326− categoryView.expandedCategoryId = delegate.category;
327− else
328− categoryView.expandedCategoryId = "";
329− }
330− height: section != "" ? units.gu(5) : 0
331 }
379 }
332
380
333 pageHeader: PageHeader {
381 pageHeader: PageHeader {
tests/autopilot/unity8/shell/emulators/dash.py+6−3
@@ -40,7 +40,7 @@ class Dash(emulators.UnityEmulatorBase):
40
40
41 def get_applications_grid(self):
41 def get_applications_grid(self):
42 get_grid = self.get_scope('clickscope').wait_select_single(
42 get_grid = self.get_scope('clickscope').wait_select_single(
43− 'CardFilterGrid', objectName='local')
43+ 'CardGrid', objectName='local')
44 return get_grid
44 return get_grid
45
45
46 def get_application_icon(self, text):
46 def get_application_icon(self, text):
@@ -196,9 +196,12 @@ class DashApps(GenericScopeView):
196 category_element = self._get_category_element(category)
196 category_element = self._get_category_element(category)
197 application_cards = category_element.select_many('AbstractButton')
197 application_cards = category_element.select_many('AbstractButton')
198
198
199− # sort by y, x
199+ # sort by y, x, filter those out of view
200+ categoryBottom = category_element.globalRect.y \
201+ + category_element.height
200 application_cards = sorted(
202 application_cards = sorted(
201− application_cards,
203+ (card for card in application_cards
204+ if card.globalRect.y < categoryBottom),
202 key=lambda card: (card.globalRect.y, card.globalRect.x))
205 key=lambda card: (card.globalRect.y, card.globalRect.x))
203
206
204 result = []
207 result = []
tests/autopilot/unity8/shell/tests/test_emulators.py+5−5
@@ -191,9 +191,9 @@ class DashAppsEmulatorTestCase(DashBaseTestCase):
191 def _get_number_of_application_slots(self, category):
191 def _get_number_of_application_slots(self, category):
192 category_element = self.applications_scope._get_category_element(
192 category_element = self.applications_scope._get_category_element(
193 category)
193 category)
194− grid = category_element.select_single('CardFilterGrid')
194+ cardgrid = category_element.select_single('CardGrid')
195− filtergrid = grid.select_single('FilterGrid')
195+ if (category_element.expanded):
196− if (grid.filtered):
196+ return cardgrid.select_single('QQuickGridView').count
197− return filtergrid.collapsedRowCount * filtergrid.columns
198 else:
197 else:
199− return filtergrid.uncollapsedRowCount * filtergrid.columns
198+ return cardgrid.collapsedRows \
199+ * cardgrid.select_single('ResponsiveGridView').columns
tests/mocks/Ubuntu/Telephony/CMakeLists.txt+1−9
@@ -11,12 +11,4 @@ add_library(FakeUbuntuTelephonyQml MODULE ${FakeUbuntuTelephonyQml_SOURCES})
11
11
12qt5_use_modules(FakeUbuntuTelephonyQml Core Quick)
12qt5_use_modules(FakeUbuntuTelephonyQml Core Quick)
13
13
14−# copy files into build directory for shadow builds
15−add_custom_target(UbuntuTelephonyQmlDirFile ALL
16− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
17− DEPENDS qmldir
18−)
19−
20−install(TARGETS FakeUbuntuTelephonyQml
14+add_unity8_mock(Ubuntu.Telephony 0.1 Ubuntu/Telephony TARGETS FakeUbuntuTelephonyQml)
21− DESTINATION ${SHELL_INSTALL_QML}/mocks/Ubuntu/Telephony
22− )
tests/mocks/Unity/fake_categories.cpp+4−1
@@ -145,9 +145,12 @@ Categories::data(const QModelIndex& index, int role) const
145 } else {
145 } else {
146 map["category-layout"] = "carousel";
146 map["category-layout"] = "carousel";
147 map["card-size"] = "medium";
147 map["card-size"] = "medium";
148− map["collapsed-rows"] = 2;
149 map["overlay"] = true;
148 map["overlay"] = true;
150 }
149 }
150+ if (index.row() == 19) {
151+ map["category-layout"] = "grid";
152+ map["collapsed-rows"] = 0;
153+ }
151 map["card-size"] = "small";
154 map["card-size"] = "small";
152 return map;
155 return map;
153 }
156 }
tests/mocks/Unity/fake_scope.cpp+2−2
@@ -24,7 +24,7 @@ Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, parent)
24{
24{
25}
25}
26
26
27−Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent)
27+Scope::Scope(QString const& id, QString const& name, bool visible, QObject* parent, int categories)
28 : unity::shell::scopes::ScopeInterface(parent)
28 : unity::shell::scopes::ScopeInterface(parent)
29 , m_id(id)
29 , m_id(id)
30 , m_name(name)
30 , m_name(name)
@@ -33,7 +33,7 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
33 , m_isActive(false)
33 , m_isActive(false)
34 , m_currentDeparment("root")
34 , m_currentDeparment("root")
35 , m_previewRendererName("preview-generic")
35 , m_previewRendererName("preview-generic")
36− , m_categories(new Categories(20, this))
36+ , m_categories(new Categories(categories, this))
37{
37{
38}
38}
39
39
tests/mocks/Unity/fake_scope.h+1−1
@@ -30,7 +30,7 @@ class Scope : public unity::shell::scopes::ScopeInterface
30
30
31public:
31public:
32 Scope(QObject* parent = 0);
32 Scope(QObject* parent = 0);
33− Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0);
33+ Scope(QString const& id, QString const& name, bool visible, QObject* parent = 0, int categories = 20);
34
34
35 /* getters */
35 /* getters */
36 QString id() const override;
36 QString id() const override;
tests/mocks/Unity/fake_scopes.cpp+1
@@ -46,6 +46,7 @@ void Scopes::updateScopes()
46 addScope(new Scope("MockScope2", "Music", false, this));
46 addScope(new Scope("MockScope2", "Music", false, this));
47 addScope(new Scope("clickscope", "Apps", true, this));
47 addScope(new Scope("clickscope", "Apps", true, this));
48 addScope(new Scope("MockScope5", "Videos", true, this));
48 addScope(new Scope("MockScope5", "Videos", true, this));
49+ addScope(new Scope("SingleCategoryScope", "Single", true, this, 1));
49
50
50 if (!m_loaded) {
51 if (!m_loaded) {
51 m_loaded = true;
52 m_loaded = true;
tests/qmltests/CMakeLists.txt−1
@@ -24,7 +24,6 @@ add_qml_test(. ShellWithPin ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tes
24add_qml_test(Components Carousel)
24add_qml_test(Components Carousel)
25add_qml_test(Components DraggingArea)
25add_qml_test(Components DraggingArea)
26add_qml_test(Components EdgeDemoOverlay)
26add_qml_test(Components EdgeDemoOverlay)
27−add_qml_test(Components FilterGrid)
28add_qml_test(Components LazyImage)
27add_qml_test(Components LazyImage)
29add_qml_test(Components Rating)
28add_qml_test(Components Rating)
30add_qml_test(Components ResponsiveFlowView)
29add_qml_test(Components ResponsiveFlowView)
tests/qmltests/Components/tst_FilterGrid.qmldeleted−190
@@ -1,190 +0,0 @@
1−/*
2− * Copyright 2013 Canonical Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−import QtQuick 2.0
18−import QtTest 1.0
19−import "../../../qml/Components"
20−import Ubuntu.Components.ListItems 0.1 as ListItem
21−import Ubuntu.Components 0.1
22−import Unity.Test 0.1 as UT
23−import Utils 0.1
24−
25−/*
26− You should see 6 green squares (from "A" to "F") and a button "View all (12)".
27− Once you press that button other 6 green squares (from "G" to "L") should show up.
28−*/
29−Rectangle {
30− width: gridRect.width + controls.width
31− height: units.gu(50)
32− color: "white"
33−
34− Column {
35− id: controls
36− width: units.gu(30)
37− height: parent.height
38− anchors.top: parent.top
39− anchors.right: parent.right
40− ListItem.ValueSelector {
41− id: collapsedRowCountSelector
42− text: "collapsedRowCount"
43− values: [1,2,3,4]
44− selectedIndex: 1
45− }
46− Row {
47− spacing: units.gu(1)
48− Label { anchors.verticalCenter: parent.verticalCenter
49− text: "Filter" }
50− CheckBox {
51− id: filterCheckBox
52− checked: true
53− onCheckedChanged: filterGrid.setFilter(checked, false /*animate*/)
54− }
55− }
56− }
57−
58− ListModel {
59− id: fakeModel
60− ListElement { name: "A" }
61− ListElement { name: "B" }
62− ListElement { name: "C" }
63− ListElement { name: "D" }
64− ListElement { name: "E" }
65− ListElement { name: "F" }
66− ListElement { name: "G" }
67− ListElement { name: "H" }
68− ListElement { name: "I" }
69− ListElement { name: "J" }
70− ListElement { name: "K" }
71− ListElement { name: "L" }
72− }
73−
74− ListModel {
75− id: fakeModelTwoItems
76− ListElement { name: "A" }
77− ListElement { name: "B" }
78− }
79−
80− ListModel {
81− id: fakeModelFourItems
82− ListElement { name: "A" }
83− ListElement { name: "B" }
84− ListElement { name: "C" }
85− ListElement { name: "D" }
86− }
87−
88− Rectangle {
89− id: gridRect
90− width: units.gu(30)
91− height: parent.height
92− color: "grey"
93− anchors.top: parent.top
94− anchors.left: parent.left
95−
96− FilterGrid {
97− id: filterGrid
98− anchors.fill: parent
99− model: fakeModel
100− maximumNumberOfColumns: 3
101− collapsedRowCount:
102− collapsedRowCountSelector.values[collapsedRowCountSelector.selectedIndex]
103− minimumHorizontalSpacing: units.gu(1)
104− delegateWidth: units.gu(6)
105− delegateHeight: units.gu(6)
106− verticalSpacing: units.gu(1)
107−
108− delegate: Rectangle {
109− // So that it can be identified by countVisibleDelegates()
110− property bool isGridDelegate: true
111−
112− color: "green"
113− width: units.gu(6)
114− height: units.gu(6)
115− Text {
116− anchors.centerIn: parent
117− text: name
118− }
119− }
120− }
121− }
122−
123− UT.UnityTestCase {
124− name: "FilterGrid"
125− when: windowShown
126−
127− function init() {
128− filterGrid.model = fakeModel
129− }
130−
131− function cleanup() {
132− filterCheckBox.checked = true
133− collapsedRowCountSelector.selectedIndex = 1
134− }
135−
136− function test_turningFilterOffShowsAllElements() {
137− tryCompareFunction(countVisibleDelegates, 6)
138−
139− filterCheckBox.checked = false
140−
141− tryCompareFunction(countVisibleDelegates, 12)
142− }
143−
144− function test_collapsedRowCount() {
145− for (var i = 0; i < 4; ++i) {
146− collapsedRowCountSelector.selectedIndex = i
147− // We have 3 elements per row.
148− // row count == index + 1
149− tryCompareFunction(countVisibleDelegates, 3*(i+1))
150− }
151− }
152−
153− function test_modelSizeAffectsCollapsedRowCount_data() {
154− return [
155− { tag: "2 items, collapsedRows 1", model: fakeModelTwoItems, collapsedRowCountIndex: 0,
156− rowsWhenCollapsed: 1, visibleDelegates: 2 },
157− { tag: "2 items, collapsedRows 2", model: fakeModelTwoItems, collapsedRowCountIndex: 1,
158− rowsWhenCollapsed: 1, visibleDelegates: 2 },
159− { tag: "4 items, collapsedRows 1", model: fakeModelFourItems, collapsedRowCountIndex: 0,
160− rowsWhenCollapsed: 1, visibleDelegates: 3 },
161− { tag: "4 items, collapsedRows 2", model: fakeModelFourItems, collapsedRowCountIndex: 1,
162− rowsWhenCollapsed: 2, visibleDelegates: 4 },
163− ]
164− }
165−
166− function test_modelSizeAffectsCollapsedRowCount(data) {
167− filterGrid.model = data.model
168− collapsedRowCountSelector.selectedIndex = data.collapsedRowCountIndex
169−
170− tryCompare(filterGrid, "rowsWhenCollapsed", data.rowsWhenCollapsed)
171− tryCompareFunction(countVisibleDelegates, data.visibleDelegates)
172− }
173−
174− function countVisibleDelegates() {
175− return __countVisibleDelegates(filterGrid.visibleChildren, 0)
176− }
177−
178− function __countVisibleDelegates(objList, total) {
179− for (var i = 0; i < objList.length; ++i) {
180− var child = objList[i];
181− if (child.isGridDelegate !== undefined) {
182− ++total;
183− } else {
184− total = __countVisibleDelegates(child.visibleChildren, total)
185− }
186− }
187− return total
188− }
189− }
190−}
tests/qmltests/Dash/tst_Dash.qml+1−1
@@ -86,7 +86,7 @@ Item {
86 tryCompare(dashContentList, "count", 0);
86 tryCompare(dashContentList, "count", 0);
87 scopes.load();
87 scopes.load();
88 tryCompare(scopes, "loaded", true);
88 tryCompare(scopes, "loaded", true);
89− tryCompare(dashContentList, "count", 3);
89+ tryCompare(dashContentList, "count", 4);
90
90
91 verify(dashContentList != undefined);
91 verify(dashContentList != undefined);
92 tryCompare(dashContentList, "currentIndex", data.visualIndex);
92 tryCompare(dashContentList, "currentIndex", data.visualIndex);
tests/qmltests/Dash/tst_DashContent.qml+15−6
@@ -61,6 +61,11 @@ Item {
61 signalName: "movementStarted"
61 signalName: "movementStarted"
62 }
62 }
63
63
64+ SignalSpy {
65+ id: loadedSpy
66+ signalName: "loaded"
67+ }
68+
64 UT.UnityTestCase {
69 UT.UnityTestCase {
65 name: "DashContent"
70 name: "DashContent"
66 when: scopesModel.loaded && windowShown
71 when: scopesModel.loaded && windowShown
@@ -78,6 +83,7 @@ Item {
78
83
79 function cleanup() {
84 function cleanup() {
80 movementStartedSpy.clear();
85 movementStartedSpy.clear();
86+ loadedSpy.clear();
81 dashContent.visible = true;
87 dashContent.visible = true;
82
88
83 var dashContentList = findChild(dashContent, "dashContentList");
89 var dashContentList = findChild(dashContent, "dashContentList");
@@ -116,10 +122,11 @@ Item {
116
122
117 function test_show_header_on_list_movement() {
123 function test_show_header_on_list_movement() {
118 var dashContentList = findChild(dashContent, "dashContentList");
124 var dashContentList = findChild(dashContent, "dashContentList");
119− verify(dashContentList != undefined);
125+ verify(dashContentList !== null);
120− var categoryListView = findChild(dashContentList, "categoryListView");
126+ var scope = findChild(dashContent, "MockScope1 loader");
121− verify(categoryListView != undefined);
127+ waitForRendering(scope);
122
128
129+ var categoryListView = findChild(scope, "categoryListView");
123 waitForRendering(categoryListView);
130 waitForRendering(categoryListView);
124
131
125 categoryListView.contentY = units.gu(15);
132 categoryListView.contentY = units.gu(15);
@@ -133,10 +140,12 @@ Item {
133
140
134 function test_set_current_scope_reset() {
141 function test_set_current_scope_reset() {
135 var dashContentList = findChild(dashContent, "dashContentList");
142 var dashContentList = findChild(dashContent, "dashContentList");
136− verify(dashContentList != undefined);
143+ verify(dashContentList, "Couldn't find dashContentList");
137− var categoryListView = findChild(dashContentList, "categoryListView");
144+ var scope = findChild(dashContent, "MockScope1 loader");
138− verify(categoryListView != undefined);
139
145
146+ tryCompare(scope, "status", Loader.Ready);
147+
148+ var categoryListView = findChild(dashContentList, "categoryListView");
140 categoryListView.contentY = units.gu(10);
149 categoryListView.contentY = units.gu(10);
141
150
142 compare(dashContentList.currentItem.item.objectName, "MockScope1")
151 compare(dashContentList.currentItem.item.objectName, "MockScope1")
tests/qmltests/Dash/tst_GenericScopeView.qml+62−43
@@ -59,7 +59,7 @@ Item {
59 genericScopeView.scope = scopes.getScope(1)
59 genericScopeView.scope = scopes.getScope(1)
60 shell.width = units.gu(120)
60 shell.width = units.gu(120)
61 genericScopeView.categoryView.positionAtBeginning();
61 genericScopeView.categoryView.positionAtBeginning();
62− tryCompare(genericScopeView.categoryView, "contentY", 0)
62+ waitForRendering(genericScopeView.categoryView);
63 }
63 }
64
64
65 function test_isActive() {
65 function test_isActive() {
@@ -104,84 +104,103 @@ Item {
104 tryCompare(genericScopeView.scope, "searchQuery", "test")
104 tryCompare(genericScopeView.scope, "searchQuery", "test")
105 }
105 }
106
106
107− function test_filter_expand_collapse() {
107+ function test_expand_collapse() {
108− // wait for the item to be there
109− waitForRendering(genericScopeView);
110 tryCompareFunction(function() { return findChild(genericScopeView, "dashSectionHeader0") != null; }, true);
108 tryCompareFunction(function() { return findChild(genericScopeView, "dashSectionHeader0") != null; }, true);
111
109
112− var header = findChild(genericScopeView, "dashSectionHeader0")
113 var category = findChild(genericScopeView, "dashCategory0")
110 var category = findChild(genericScopeView, "dashCategory0")
111+ var seeAll = findChild(category, "seeAll")
114
112
115− waitForRendering(header);
113+ waitForRendering(seeAll);
116 verify(category.expandable);
114 verify(category.expandable);
117− verify(category.filtered);
115+ verify(!category.expanded);
118
116
119 var initialHeight = category.height;
117 var initialHeight = category.height;
120− var middleHeight;
121− mouseClick(header, header.width / 2, header.height / 2);
118+ mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
119+ verify(category.expanded);
122− tryCompareFunction(function() { middleHeight = category.height; return category.height > initialHeight; }, true);
120+ tryCompareFunction(function() { return category.height > initialHeight; }, true);
123− tryCompare(category, "filtered", false);
124− tryCompareFunction(function() { return category.height > middleHeight; }, true);
125
121
126− mouseClick(header, header.width / 2, header.height / 2);
122+ mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
127− verify(category.expandable);
123+ verify(!category.expanded);
128− tryCompare(category, "filtered", true);
129 }
124 }
130
125
131− function test_filter_expand_expand_collapse() {
126+ function test_expand_expand_collapse() {
132 // wait for the item to be there
127 // wait for the item to be there
133 tryCompareFunction(function() { return findChild(genericScopeView, "dashSectionHeader2") != null; }, true);
128 tryCompareFunction(function() { return findChild(genericScopeView, "dashSectionHeader2") != null; }, true);
134
129
135 var categoryListView = findChild(genericScopeView, "categoryListView");
130 var categoryListView = findChild(genericScopeView, "categoryListView");
136 categoryListView.contentY = categoryListView.height;
131 categoryListView.contentY = categoryListView.height;
137
132
138− var header2 = findChild(genericScopeView, "dashSectionHeader2")
139 var category2 = findChild(genericScopeView, "dashCategory2")
133 var category2 = findChild(genericScopeView, "dashCategory2")
140− var category2FilterGrid = category2.children[1].children[2];
134+ var seeAll2 = findChild(category2, "seeAll")
141− verify(UT.Util.isInstanceOf(category2FilterGrid, "CardFilterGrid"));
142
135
143− waitForRendering(header2);
136+ waitForRendering(seeAll2);
144 verify(category2.expandable);
137 verify(category2.expandable);
145− verify(category2.filtered);
138+ verify(!category2.expanded);
146
139
147− mouseClick(header2, header2.width / 2, header2.height / 2);
140+ mouseClick(seeAll2, seeAll2.width / 2, seeAll2.height / 2);
148− tryCompare(category2, "filtered", false);
141+ tryCompare(category2, "expanded", true);
149− tryCompare(category2FilterGrid, "filtered", false);
150
142
151 categoryListView.positionAtBeginning();
143 categoryListView.positionAtBeginning();
152
144
153− var header0 = findChild(genericScopeView, "dashSectionHeader0")
154 var category0 = findChild(genericScopeView, "dashCategory0")
145 var category0 = findChild(genericScopeView, "dashCategory0")
146+ var seeAll0 = findChild(category0, "seeAll")
155− mouseClick(header0, header0.width / 2, header0.height / 2);
147+ mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
156− tryCompare(category0, "filtered", false);
148+ tryCompare(category0, "expanded", true);
157− tryCompare(category2, "filtered", true);
149+ tryCompare(category2, "expanded", false);
158− tryCompare(category2FilterGrid, "filtered", true);
159− mouseClick(header0, header0.width / 2, header0.height / 2);
150+ mouseClick(seeAll0, seeAll0.width / 2, seeAll0.height / 2);
160− tryCompare(category0, "filtered", true);
151+ tryCompare(category0, "expanded", false);
161− tryCompare(category2, "filtered", true);
152+ tryCompare(category2, "expanded", false);
162 }
153 }
163
154
164 function test_narrow_delegate_ranges_expand() {
155 function test_narrow_delegate_ranges_expand() {
165− tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
156+ tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") !== null; }, true);
166 var category = findChild(genericScopeView, "dashCategory0")
157 var category = findChild(genericScopeView, "dashCategory0")
167− tryCompare(category, "filtered", true);
158+ tryCompare(category, "expanded", false);
168
159
169 shell.width = units.gu(20)
160 shell.width = units.gu(20)
170 var categoryListView = findChild(genericScopeView, "categoryListView");
161 var categoryListView = findChild(genericScopeView, "categoryListView");
171 categoryListView.contentY = units.gu(20);
162 categoryListView.contentY = units.gu(20);
172− var header0 = findChild(genericScopeView, "dashSectionHeader0")
163+ var seeAll = findChild(category, "seeAll")
173− mouseClick(header0, header0.width / 2, header0.height / 2);
164+ mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
174− tryCompare(category, "filtered", false);
165+ tryCompare(category, "expanded", true);
175 tryCompareFunction(function() { return category.item.height == genericScopeView.height - category.item.displayMarginBeginning - category.item.displayMarginEnd; }, true);
166 tryCompareFunction(function() { return category.item.height == genericScopeView.height - category.item.displayMarginBeginning - category.item.displayMarginEnd; }, true);
176− mouseClick(header0, header0.width / 2, header0.height / 2);
167+ mouseClick(seeAll, seeAll.width / 2, seeAll.height / 2);
177− tryCompare(category, "filtered", true);
168+ tryCompare(category, "expanded", false);
169+ }
170+
171+ function test_forced_category_expansion() {
172+ tryCompareFunction(function() {
173+ mouseFlick(genericScopeView, genericScopeView.width/2, genericScopeView.height,
174+ genericScopeView.width/2, genericScopeView.y)
175+ return findChild(genericScopeView, "dashCategory19") !== null;
176+ }, true);
177+ var category = findChild(genericScopeView, "dashCategory19")
178+ compare(category.expandable, false, "Category with collapsed-rows: 0 should not be expandable");
179+
180+ var grid = findChild(category, "19");
181+ verify(grid, "Could not find the category renderer.");
182+
183+ compare(grid.height, grid.expandedHeight, "Category with collapsed-rows: 0 should always be expanded.");
184+ }
185+
186+ function test_single_category_expansion() {
187+ genericScopeView.scope = scopes.getScope(4);
188+
189+ tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true);
190+ var category = findChild(genericScopeView, "dashCategory0")
191+ compare(category.expandable, false, "Only category should not be expandable.");
192+
193+ var grid = findChild(category, "0");
194+ verify(grid, "Could not find the category renderer.");
195+
196+ compare(grid.height, grid.expandedHeight, "Only category should always be expanded");
178 }
197 }
179
198
180 function openPreview() {
199 function openPreview() {
181 tryCompareFunction(function() {
200 tryCompareFunction(function() {
182− var filterGrid = findChild(genericScopeView, "0");
201+ var cardGrid = findChild(genericScopeView, "0");
183− if (filterGrid != null) {
202+ if (cardGrid != null) {
184− var tile = findChild(filterGrid, "delegate0");
203+ var tile = findChild(cardGrid, "delegate0");
185 return tile != null;
204 return tile != null;
186 }
205 }
187 return false;
206 return false;
@@ -257,7 +276,7 @@ Item {
257 closePreview();
276 closePreview();
258 }
277 }
259
278
260− function test_haeder_logo() {
279+ function test_header_logo() {
261 genericScopeView.scope = scopes.getScope(3);
280 genericScopeView.scope = scopes.getScope(3);
262
281
263 var image = findChild(genericScopeView, "titleImage");
282 var image = findChild(genericScopeView, "titleImage");