Merge lp:~cimi/unity8/card_emblems_2 into lp:unity8
- card_emblems_2
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~cimi/unity8/card_emblems_2 |
Merge into: | lp:unity8 |
Prerequisite: | lp:~cimi/unity8/card_touchdown_2 |
Diff against target: |
4134 lines (+2313/-477) 52 files modified
data/unity8-dash.conf (+1/-1) plugins/Dash/CardCreator.js (+187/-154) plugins/Dash/ScopeStyle.qml (+3/-2) plugins/Dash/listviewwithpageheader.cpp (+10/-2) plugins/Dash/listviewwithpageheader.h (+3/-0) po/hu.po (+6/-5) po/sl.po (+4/-3) po/unity8.pot (+80/-44) qml/Components/PageHeader.qml (+3/-1) qml/Components/ResponsiveGridView.qml (+3/-3) qml/Dash/CardCarousel.qml (+2/-2) qml/Dash/CardGrid.qml (+13/-2) qml/Dash/CardVerticalJournal.qml (+1/-1) qml/Dash/Dash.qml (+171/-13) qml/Dash/DashBackground.qml (+24/-0) qml/Dash/DashContent.qml (+10/-4) qml/Dash/DashRenderer.qml (+3/-1) qml/Dash/GenericScopeView.qml (+86/-48) qml/Dash/PreviewListView.qml (+1/-1) qml/Dash/ScopesOverview.qml (+531/-0) qml/Dash/ScopesOverviewAll.qml (+54/-0) qml/Dash/ScopesOverviewFavorites.qml (+73/-0) qml/Dash/ScopesOverviewTab.qml (+74/-0) tests/autopilot/unity8/shell/tests/test_emulators.py (+1/-1) tests/mocks/Unity/CMakeLists.txt (+1/-0) tests/mocks/Unity/fake_categories.cpp (+6/-2) tests/mocks/Unity/fake_resultsmodel.cpp (+2/-1) tests/mocks/Unity/fake_scope.cpp (+17/-5) tests/mocks/Unity/fake_scope.h (+6/-3) tests/mocks/Unity/fake_scopes.cpp (+46/-7) tests/mocks/Unity/fake_scopes.h (+8/-1) tests/mocks/Unity/fake_scopesoverview.cpp (+281/-0) tests/mocks/Unity/fake_scopesoverview.h (+104/-0) tests/plugins/Dash/cardcreator/1.res (+6/-6) tests/plugins/Dash/cardcreator/1.tst (+1/-1) tests/plugins/Dash/cardcreator/2.res (+27/-19) tests/plugins/Dash/cardcreator/2.tst (+1/-1) tests/plugins/Dash/cardcreator/3.res (+12/-12) tests/plugins/Dash/cardcreator/3.tst (+1/-1) tests/plugins/Dash/cardcreator/4.res (+23/-15) tests/plugins/Dash/cardcreator/4.tst (+1/-1) tests/plugins/Dash/cardcreator/5.res (+21/-19) tests/plugins/Dash/cardcreator/5.tst (+1/-1) tests/plugins/Dash/cardcreator/6.res (+98/-45) tests/plugins/Dash/cardcreator/6.tst (+2/-2) tests/plugins/Dash/cardcreator/7.res (+35/-23) tests/plugins/Dash/tst_ScopeStyle.qml (+1/-1) tests/qmltests/Dash/CardHelpers.js (+1/-0) tests/qmltests/Dash/tst_Card.qml (+19/-1) tests/qmltests/Dash/tst_Dash.qml (+229/-7) tests/qmltests/Dash/tst_DashContent.qml (+7/-6) tests/qmltests/Dash/tst_GenericScopeView.qml (+12/-9) |
To merge this branch: | bzr merge lp:~cimi/unity8/card_emblems_2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Michał Sawicz | Needs Fixing | ||
Review via email: mp+229046@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-08-08.
Commit message
Add emblems
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
N/A
- 1094. By Andrea Cimitan
-
Fixed tests
- 1095. By Andrea Cimitan
-
Fixed test
- 1096. By Andrea Cimitan
-
Added test
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1096
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Andrea Cimitan (cimi) wrote : | # |
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
N/A
Ying-Chun Liu (paulliu) wrote : | # |
Ying-Chun Liu (paulliu) wrote : | # |
cardTool?
- 1097. By Andrea Cimitan
-
More fixes
Ying-Chun Liu (paulliu) wrote : | # |
In the diff there's conflict. Seems we need a re-merge trunk here?
- 1098. By Andrea Cimitan
-
[ Gerry Boland ]
* Fix the run.sh script - pretend to be running with qtmir and emit
SIGSTOP at the right time
[ Ying-Chun Liu ]
* Implement Attribute UI. (LP: #1282460)
[ Albert Astals ]
* Hide search history popup as soon as you start typing As discussed
with Mike and Saviq
* Compile with for scopes-v3 unity-api
* PageHeader: Unfocus search field when search entry is selected
* Show search field if the search query changes
* Test: Add a condition for art.height being > 0 means stuff has
already been layouted a bit without it it can happen that we get 0
for everything at startup and tests still pass
* Remove leftover in test of an old headerless implementation
[ Michael Zanetti ]
* Drop Recent apps category from Dash (LP: #1281092)
* update launcher count emblems to match new spec (LP: #1338984)
[ Bill Filler ]
* disable predictive text for dash search field (LP: #1340409)
[ CI bot ]
* Resync trunk
[ Antti Kaijanmäki ]
* DefaultIndicatorPage: use Loader status to determine the visible
property. (LP: #1350555) - 1099. By Andrea Cimitan
-
Merge
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1097
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1099
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1099
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1100. By Andrea Cimitan
-
merged trunk
- 1101. By Andrea Cimitan
-
Fix categories with attributes
- 1102. By Andrea Cimitan
-
Moar fixes
- 1103. By Andrea Cimitan
-
Fixed whitespaces
- 1104. By Andrea Cimitan
-
merged overview
Michał Sawicz (saviq) wrote : | # |
When emblem is declared, but invalid, there's no right text margin.
You should use StatusIcon (like attributes do) for the emblem, and colourize it with the foreground color.
- 1105. By Andrea Cimitan
-
Fixed right padding
- 1106. By Andrea Cimitan
-
Fixed issue of spacing when the touchdown is on the art only
- 1107. By Andrea Cimitan
-
Fixed another review erequest
- 1108. By Andrea Cimitan
-
Add colorisation
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1100
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1109. By Andrea Cimitan
-
Fix issue in reviewy
Unmerged revisions
Preview Diff
1 | === modified file 'data/unity8-dash.conf' |
2 | --- data/unity8-dash.conf 2014-07-29 11:35:10 +0000 |
3 | +++ data/unity8-dash.conf 2014-08-08 14:57:17 +0000 |
4 | @@ -13,7 +13,7 @@ |
5 | pre-start script |
6 | if [ -z "$UNITY_SCOPES_LIST" ]; then |
7 | # FIXME: remove once we have this in dconf |
8 | - initctl set-env UNITY_SCOPES_LIST="scopes;clickscope;musicaggregator;videoaggregator" |
9 | + initctl set-env UNITY_SCOPES_LIST="clickscope;musicaggregator;videoaggregator" |
10 | fi |
11 | |
12 | initctl emit scope-ui-starting |
13 | |
14 | === modified file 'plugins/Dash/CardCreator.js' |
15 | --- plugins/Dash/CardCreator.js 2014-08-06 19:39:39 +0000 |
16 | +++ plugins/Dash/CardCreator.js 2014-08-08 14:57:17 +0000 |
17 | @@ -108,6 +108,7 @@ |
18 | sourceComponent: ShaderEffect { \n\ |
19 | id: overlay; \n\ |
20 | height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); \n\ |
21 | + property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b; \n\ |
22 | property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\ |
23 | property var source: ShaderEffectSource { \n\ |
24 | id: shaderSource; \n\ |
25 | @@ -137,69 +138,43 @@ |
26 | } \n\ |
27 | }\n'; |
28 | |
29 | -// %1 is used as anchors of row |
30 | -// %2 is used as first child of the row |
31 | -// %3 is used as second child of the row |
32 | -var kHeaderRow2Code = 'Row { \n\ |
33 | - id: row; \n\ |
34 | - objectName: "outerRow"; \n\ |
35 | - property real margins: units.gu(1); \n\ |
36 | - spacing: margins; \n\ |
37 | - height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\ |
38 | - anchors { %1 } \n\ |
39 | - anchors.right: parent.right; \n\ |
40 | - anchors.margins: margins;\n\ |
41 | - data: [ %2\n\ |
42 | - ,\n\ |
43 | - %3 \n\ |
44 | - ] \n\ |
45 | - }\n'; |
46 | - |
47 | -// %1 is used as anchors of row |
48 | -// %2 is used as first child of the row |
49 | -// %3 is used as second child of the row |
50 | -// %4 is used as third child of the row |
51 | -var kHeaderRow3Code = 'Row { \n\ |
52 | - id: row; \n\ |
53 | - objectName: "outerRow"; \n\ |
54 | - property real margins: units.gu(1); \n\ |
55 | - spacing: margins; \n\ |
56 | - height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\ |
57 | - anchors { %1 } \n\ |
58 | - anchors.right: parent.right; \n\ |
59 | - anchors.margins: margins;\n\ |
60 | - data: [ %2\n\ |
61 | - ,\n\ |
62 | - %3 \n\ |
63 | - ,\n\ |
64 | - %4 \n\ |
65 | - ] \n\ |
66 | - }\n'; |
67 | - |
68 | -// %1 is used as first child of the column |
69 | -// %2 is used as second child of the column |
70 | -var kHeaderColumnCode = 'Column { \n\ |
71 | - anchors.verticalCenter: parent.verticalCenter; \n\ |
72 | - spacing: units.dp(2); \n\ |
73 | - width: parent.width - x;\n\ |
74 | - data: [ %1\n\ |
75 | - ,\n\ |
76 | - %2 \n\ |
77 | - ] \n\ |
78 | +// multiple row version of HeaderRowCode |
79 | +function kHeaderRowCodeGenerator() { |
80 | +var kHeaderRowCodeTemplate = 'Row { \n\ |
81 | + id: row; \n\ |
82 | + objectName: "outerRow"; \n\ |
83 | + property real margins: units.gu(1); \n\ |
84 | + spacing: margins; \n\ |
85 | + height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; \n\ |
86 | + anchors { %1 } \n\ |
87 | + anchors.right: parent.right; \n\ |
88 | + anchors.margins: margins; \n\ |
89 | + anchors.rightMargin: 0; \n\ |
90 | + data: [ \n\ |
91 | + %2 \n\ |
92 | + ] \n\ |
93 | + }\n'; |
94 | + var args = Array.prototype.slice.call(arguments); |
95 | + var HeaderRowAnchors = args.shift(); |
96 | + var code = kHeaderRowCodeTemplate.arg(HeaderRowAnchors).arg(args.join(',\n')); |
97 | + return code; |
98 | +} |
99 | + |
100 | +// multiple item version of kHeaderContainerCode |
101 | +function kHeaderContainerCodeGenerator() { |
102 | + var headerContainerCodeTemplate = 'Item { \n\ |
103 | + id: headerTitleContainer; \n\ |
104 | + anchors { %1 } \n\ |
105 | + width: parent.width - x; \n\ |
106 | + implicitHeight: %2; \n\ |
107 | + data: [ \n\ |
108 | + %3 \n\ |
109 | + ]\n\ |
110 | }\n'; |
111 | - |
112 | -// multiple column version of kHeaderColumnCode. |
113 | -function kHeaderColumnCodeGenerator() { |
114 | - var headerColumnCodeTemplate = 'Column { \n\ |
115 | - anchors.verticalCenter: parent.verticalCenter; \n\ |
116 | - spacing: units.dp(2); \n\ |
117 | - width: parent.width - x;\n\ |
118 | - data: [ \n\ |
119 | - %1 \n\ |
120 | - ]\n\ |
121 | - }\n'; |
122 | var args = Array.prototype.slice.call(arguments); |
123 | - var code = headerColumnCodeTemplate.arg(args.join(',\n')); |
124 | + var headerContainerAnchors = args.shift(); |
125 | + var headerContainerHeight = args.shift(); |
126 | + var code = headerContainerCodeTemplate.arg(headerContainerAnchors).arg(headerContainerHeight).arg(args.join(',\n')); |
127 | return code; |
128 | } |
129 | |
130 | @@ -223,7 +198,7 @@ |
131 | objectName: "mascotImage"; \n\ |
132 | anchors { %1 } \n\ |
133 | readonly property int maxSize: Math.max(width, height) * 4; \n\ |
134 | - source: cardData && cardData["mascot"]; \n\ |
135 | + source: cardData && cardData["mascot"] || ""; \n\ |
136 | width: units.gu(6); \n\ |
137 | height: units.gu(5.625); \n\ |
138 | sourceSize { width: maxSize; height: maxSize } \n\ |
139 | @@ -252,6 +227,20 @@ |
140 | horizontalAlignment: root.headerAlignment; \n\ |
141 | }\n'; |
142 | |
143 | +var kEmblemImageCode = 'Image { \n\ |
144 | + id: emblemImage; \n\ |
145 | + objectName: "emblemImage"; \n\ |
146 | + anchors { \n\ |
147 | + bottom: titleLabel.baseline; \n\ |
148 | + right: parent.right; \n\ |
149 | + rightMargin: status === Image.Ready ? units.gu(1) : 0; \n\ |
150 | + } \n\ |
151 | + source: cardData && cardData["emblem"] || ""; \n\ |
152 | + width: height; \n\ |
153 | + height: status === Image.Ready ? titleLabel.font.pixelSize : 0; \n\ |
154 | + fillMode: Image.PreserveAspectFit; \n\ |
155 | + }\n'; |
156 | + |
157 | // %1 is used as anchors of touchdown effect |
158 | var kTouchdownCode = 'UbuntuShape { \n\ |
159 | id: touchdown; \n\ |
160 | @@ -268,6 +257,7 @@ |
161 | id: subtitleLabel; \n\ |
162 | objectName: "subtitleLabel"; \n\ |
163 | anchors { %1 } \n\ |
164 | + anchors.topMargin: units.dp(2); \n\ |
165 | elide: Text.ElideRight; \n\ |
166 | fontSize: "small"; \n\ |
167 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\ |
168 | @@ -284,7 +274,7 @@ |
169 | objectName: "attributesRow"; \n\ |
170 | anchors { %1 } \n\ |
171 | color: %2; \n\ |
172 | - model: cardData["attributes"]; \n\ |
173 | + model: cardData && cardData["attributes"]; \n\ |
174 | }\n'; |
175 | |
176 | // %1 is used as top anchor of summary |
177 | @@ -334,10 +324,11 @@ |
178 | var hasBackground = !isHorizontal && (template["card-background"] || components["background"] || artAndSummary); |
179 | var hasTitle = components["title"] || false; |
180 | var hasMascot = components["mascot"] || false; |
181 | + var hasEmblem = components["emblem"] && !(hasMascot && template["card-size"] === "small") || false; |
182 | var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot); |
183 | var hasSubtitle = hasTitle && components["subtitle"] || false; |
184 | var hasHeaderRow = hasMascot && hasTitle; |
185 | - var hasAttributes = hasTitle && components["attributes"] || false; |
186 | + var hasAttributes = hasTitle && components["attributes"]["field"] || false; |
187 | |
188 | if (hasBackground) { |
189 | code += kBackgroundLoaderCode; |
190 | @@ -348,9 +339,9 @@ |
191 | code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n'; |
192 | |
193 | var widthCode, heightCode; |
194 | - var anchors; |
195 | + var artAnchors; |
196 | if (isHorizontal) { |
197 | - anchors = 'left: parent.left'; |
198 | + artAnchors = 'left: parent.left'; |
199 | if (hasMascot || hasTitle) { |
200 | widthCode = 'height * artShape.aspect' |
201 | heightCode = 'headerHeight + 2 * units.gu(1)'; |
202 | @@ -361,12 +352,12 @@ |
203 | heightCode = 'units.gu(7.625)'; |
204 | } |
205 | } else { |
206 | - anchors = 'horizontalCenter: parent.horizontalCenter;'; |
207 | + artAnchors = 'horizontalCenter: parent.horizontalCenter;'; |
208 | widthCode = 'root.width' |
209 | heightCode = 'width / artShape.aspect'; |
210 | } |
211 | |
212 | - code += kArtShapeHolderCode.arg(anchors).arg(widthCode).arg(heightCode); |
213 | + code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode); |
214 | } else { |
215 | code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n' |
216 | } |
217 | @@ -423,155 +414,194 @@ |
218 | code += 'readonly property int headerHeight: 0;\n' |
219 | } |
220 | |
221 | - var mascotShapeCode = ""; |
222 | - var mascotCode = ""; |
223 | + var mascotShapeCode = ''; |
224 | + var mascotCode = ''; |
225 | if (hasMascot) { |
226 | var useMascotShape = !hasBackground && !headerAsOverlay; |
227 | - var anchors = ""; |
228 | + var mascotAnchors = ''; |
229 | if (!hasHeaderRow) { |
230 | - anchors += headerLeftAnchor; |
231 | - anchors += headerVerticalAnchors; |
232 | + mascotAnchors += headerLeftAnchor; |
233 | + mascotAnchors += headerVerticalAnchors; |
234 | if (!headerLeftAnchorHasMargin) { |
235 | - anchors += 'leftMargin: units.gu(1);\n' |
236 | + mascotAnchors += 'leftMargin: units.gu(1);\n' |
237 | } |
238 | } else { |
239 | - anchors = "verticalCenter: parent.verticalCenter;" |
240 | + mascotAnchors = 'verticalCenter: parent.verticalCenter;' |
241 | } |
242 | |
243 | if (useMascotShape) { |
244 | - mascotShapeCode = kMascotShapeLoaderCode.arg(anchors); |
245 | + mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors); |
246 | } |
247 | |
248 | var mascotImageVisible = useMascotShape ? 'false' : 'showHeader'; |
249 | - mascotCode = kMascotImageCode.arg(anchors).arg(mascotImageVisible); |
250 | + mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible); |
251 | } |
252 | |
253 | - var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey")'; |
254 | + var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey")'; |
255 | |
256 | - var titleSubtitleCode = ""; |
257 | + var hasTitleContainer = hasTitle && (hasEmblem || (hasMascot && (hasSubtitle || hasAttributes))); |
258 | + var titleSubtitleCode = ''; |
259 | if (hasTitle) { |
260 | - var color; |
261 | + var titleColor; |
262 | if (headerAsOverlay) { |
263 | - color = '"white"'; |
264 | + titleColor = 'overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey")'; |
265 | } else if (hasSummary) { |
266 | - color = 'summary.color'; |
267 | + titleColor = 'summary.color'; |
268 | } else if (hasBackground) { |
269 | - color = summaryColorWithBackground; |
270 | + titleColor = summaryColorWithBackground; |
271 | } else { |
272 | - color = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"'; |
273 | + titleColor = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"'; |
274 | } |
275 | |
276 | var titleAnchors; |
277 | var subtitleAnchors; |
278 | var attributesAnchors; |
279 | - if (hasMascot && (hasSubtitle || hasAttributes)) { |
280 | - // Using row + column |
281 | - titleAnchors = 'left: parent.left; right: parent.right'; |
282 | - subtitleAnchors = titleAnchors; |
283 | - attributesAnchors = subtitleAnchors; |
284 | + var titleContainerAnchors; |
285 | + var titleRightAnchor; |
286 | + |
287 | + if (hasMascot) { |
288 | + titleContainerAnchors = 'verticalCenter: parent.verticalCenter; '; |
289 | + } else { |
290 | + titleContainerAnchors = 'right: parent.right; '; |
291 | + titleContainerAnchors += headerLeftAnchor; |
292 | + titleContainerAnchors += headerVerticalAnchors; |
293 | + if (!headerLeftAnchorHasMargin) { |
294 | + titleContainerAnchors += 'leftMargin: units.gu(1);\n'; |
295 | + } |
296 | + } |
297 | + if (hasEmblem) { |
298 | + titleRightAnchor = 'right: emblemImage.left; \n\ |
299 | + rightMargin: emblemImage.width > 0 ? units.gu(0.5) : 0; \n'; |
300 | + } else { |
301 | + titleRightAnchor = 'right: parent.right; \n\ |
302 | + rightMargin: units.gu(1); \n'; |
303 | + } |
304 | + |
305 | + if (hasTitleContainer) { |
306 | + // Using headerTitleContainer |
307 | + titleAnchors = titleRightAnchor; |
308 | + titleAnchors += 'left: parent.left; \n\ |
309 | + top: parent.top;'; |
310 | + subtitleAnchors = 'right: parent.right; \n\ |
311 | + left: parent.left; \n\ |
312 | + rightMargin: units.gu(1); \n'; |
313 | + if (hasSubtitle) { |
314 | + attributesAnchors = subtitleAnchors + 'top: subtitleLabel.bottom;\n'; |
315 | + subtitleAnchors += 'top: titleLabel.bottom;\n'; |
316 | + } else { |
317 | + attributesAnchors = subtitleAnchors + 'top: titleLabel.bottom;\n'; |
318 | + } |
319 | } else if (hasMascot) { |
320 | - // Using row + label |
321 | - titleAnchors = 'verticalCenter: parent.verticalCenter;\n' |
322 | + // Using row + titleContainer |
323 | + titleAnchors = 'verticalCenter: parent.verticalCenter;\n'; |
324 | } else { |
325 | if (headerAsOverlay) { |
326 | // Using anchors to the overlay |
327 | - titleAnchors = 'left: parent.left; \n\ |
328 | - leftMargin: units.gu(1); \n\ |
329 | - right: parent.right; \n\ |
330 | - rightMargin: units.gu(1); \n\ |
331 | - top: overlayLoader.top; \n\ |
332 | - topMargin: units.gu(1);\n'; |
333 | + titleAnchors = titleRightAnchor; |
334 | + titleAnchors += 'left: parent.left; \n\ |
335 | + leftMargin: units.gu(1); \n\ |
336 | + top: overlayLoader.top; \n\ |
337 | + topMargin: units.gu(1);\n'; |
338 | } else { |
339 | // Using anchors to the mascot/parent |
340 | - titleAnchors = "right: parent.right;\n"; |
341 | - titleAnchors += "rightMargin: units.gu(1);\n"; |
342 | + titleAnchors = titleRightAnchor; |
343 | titleAnchors += headerLeftAnchor; |
344 | titleAnchors += headerVerticalAnchors; |
345 | if (!headerLeftAnchorHasMargin) { |
346 | - titleAnchors += 'leftMargin: units.gu(1);\n' |
347 | + titleAnchors += 'leftMargin: units.gu(1);\n'; |
348 | } |
349 | } |
350 | subtitleAnchors = 'left: titleLabel.left; \n\ |
351 | leftMargin: titleLabel.leftMargin; \n\ |
352 | - right: titleLabel.right; \n\ |
353 | - rightMargin: titleLabel.rightMargin; \n\ |
354 | - top: titleLabel.bottom; \n\ |
355 | - topMargin: units.dp(2);\n'; |
356 | + rightMargin: units.gu(1); \n'; |
357 | + if (hasEmblem) { |
358 | + // using container |
359 | + subtitleAnchors += 'right: parent.right; \n'; |
360 | + } else { |
361 | + subtitleAnchors += 'right: titleLabel.right; \n'; |
362 | + } |
363 | + |
364 | if (hasSubtitle) { |
365 | - attributesAnchors = 'left: subtitleLabel.left; \n\ |
366 | - leftMargin: subtitleLabel.leftMargin; \n\ |
367 | - right: subtitleLabel.right; \n\ |
368 | - rightMargin: subtitleLabel.rightMargin; \n\ |
369 | - top: subtitleLabel.bottom; \n\ |
370 | - topMargin: units.dp(2);\n'; |
371 | + attributesAnchors = subtitleAnchors + 'top: subtitleLabel.bottom;\n'; |
372 | + subtitleAnchors += 'top: titleLabel.bottom;\n'; |
373 | } else { |
374 | - attributesAnchors = subtitleAnchors; |
375 | + attributesAnchors = subtitleAnchors + 'top: titleLabel.bottom;\n'; |
376 | } |
377 | } |
378 | |
379 | + // code for different elements |
380 | var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': ''); |
381 | - var titleCode = kTitleLabelCode.arg(titleAnchors).arg(color).arg(titleLabelVisibleExtra); |
382 | - var subtitleCode = ""; |
383 | + var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra); |
384 | + var subtitleCode; |
385 | + var attributesCode; |
386 | + var emblemCode; |
387 | + |
388 | + // code for the title container |
389 | + var containerCode = []; |
390 | + var containerHeight = 'titleLabel.height'; |
391 | + containerCode.push(titleCode); |
392 | if (hasSubtitle) { |
393 | - subtitleCode += kSubtitleLabelCode.arg(subtitleAnchors).arg(color); |
394 | + subtitleCode = kSubtitleLabelCode.arg(subtitleAnchors).arg(titleColor); |
395 | + containerCode.push(subtitleCode); |
396 | + containerHeight += ' + subtitleLabel.height'; |
397 | + } |
398 | + if (hasEmblem) { |
399 | + containerCode.push(kEmblemImageCode); |
400 | + } |
401 | + if (hasAttributes) { |
402 | + attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(titleColor); |
403 | + containerCode.push(kAttributesRowCode.arg(attributesAnchors).arg(titleColor)); |
404 | + containerHeight += ' + attributesRow.height'; |
405 | } |
406 | |
407 | - if (hasMascot && (hasSubtitle || hasAttributes)) { |
408 | - // If using row + column wrap the code in the column |
409 | - titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode); |
410 | - if (hasSubtitle && hasAttributes) { |
411 | - var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color); |
412 | - titleSubtitleCode = kHeaderColumnCodeGenerator(titleCode, subtitleCode, attributesCode); |
413 | - } else if (hasSubtitle) { |
414 | - titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(subtitleCode); |
415 | - } else if (hasAttributes) { |
416 | - var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color); |
417 | - titleSubtitleCode = kHeaderColumnCode.arg(titleCode).arg(attributesCode); |
418 | - } |
419 | + if (hasTitleContainer) { |
420 | + // use container |
421 | + titleSubtitleCode = kHeaderContainerCodeGenerator(titleContainerAnchors, containerHeight, containerCode); |
422 | } else { |
423 | + // no container |
424 | titleSubtitleCode = titleCode; |
425 | if (hasSubtitle) { |
426 | - titleSubtitleCode = titleSubtitleCode + subtitleCode; |
427 | + titleSubtitleCode += subtitleCode; |
428 | } |
429 | if (hasAttributes) { |
430 | - var attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(color); |
431 | - titleSubtitleCode = titleSubtitleCode + attributesCode; |
432 | + titleSubtitleCode += attributesCode; |
433 | } |
434 | } |
435 | } |
436 | |
437 | if (hasHeaderRow) { |
438 | - if (mascotShapeCode != "") { |
439 | - code += kHeaderRow3Code.arg(headerVerticalAnchors + headerLeftAnchor).arg(mascotShapeCode).arg(mascotCode).arg(titleSubtitleCode); |
440 | - } else { |
441 | - code += kHeaderRow2Code.arg(headerVerticalAnchors + headerLeftAnchor).arg(mascotCode).arg(titleSubtitleCode); |
442 | + var rowCode = [mascotCode, titleSubtitleCode]; |
443 | + if (mascotShapeCode != '') { |
444 | + rowCode.unshift(mascotShapeCode); |
445 | } |
446 | + code += kHeaderRowCodeGenerator(headerVerticalAnchors + headerLeftAnchor, rowCode) |
447 | } else { |
448 | code += mascotShapeCode + mascotCode + titleSubtitleCode; |
449 | } |
450 | |
451 | if (hasSummary) { |
452 | var summaryTopAnchor; |
453 | - if (isHorizontal && hasArt) summaryTopAnchor = "artShapeHolder.bottom"; |
454 | - else if (headerAsOverlay && hasArt) summaryTopAnchor = "artShapeHolder.bottom"; |
455 | - else if (hasHeaderRow) summaryTopAnchor = "row.bottom"; |
456 | - else if (hasMascot) summaryTopAnchor = "mascotImage.bottom"; |
457 | - else if (hasAttributes) summaryTopAnchor = "attributesRow.bottom"; |
458 | - else if (hasSubtitle) summaryTopAnchor = "subtitleLabel.bottom"; |
459 | - else if (hasTitle) summaryTopAnchor = "titleLabel.bottom"; |
460 | - else if (hasArt) summaryTopAnchor = "artShapeHolder.bottom"; |
461 | - else summaryTopAnchor = "parent.top"; |
462 | + if (isHorizontal && hasArt) summaryTopAnchor = 'artShapeHolder.bottom'; |
463 | + else if (headerAsOverlay && hasArt) summaryTopAnchor = 'artShapeHolder.bottom'; |
464 | + else if (hasHeaderRow) summaryTopAnchor = 'row.bottom'; |
465 | + else if (hasTitleContainer) summaryTopAnchor = 'headerTitleContainer.bottom'; |
466 | + else if (hasMascot) summaryTopAnchor = 'mascotImage.bottom'; |
467 | + else if (hasAttributes) summaryTopAnchor = 'attributesRow.bottom'; |
468 | + else if (hasSubtitle) summaryTopAnchor = 'subtitleLabel.bottom'; |
469 | + else if (hasTitle) summaryTopAnchor = 'titleLabel.bottom'; |
470 | + else if (hasArt) summaryTopAnchor = 'artShapeHolder.bottom'; |
471 | + else summaryTopAnchor = 'parent.top'; |
472 | |
473 | - var color; |
474 | + var summaryColor; |
475 | if (hasBackground) { |
476 | - color = summaryColorWithBackground; |
477 | + summaryColor = summaryColorWithBackground; |
478 | } else { |
479 | - color = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"'; |
480 | + summaryColor = 'root.scopeStyle ? root.scopeStyle.foreground : "grey"'; |
481 | } |
482 | |
483 | var summaryTopMargin = (hasMascot || hasSubtitle || hasAttributes ? 'anchors.margins' : '0'); |
484 | |
485 | - code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(color); |
486 | + code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(summaryColor); |
487 | } |
488 | |
489 | var touchdownAnchors; |
490 | @@ -584,23 +614,26 @@ |
491 | } |
492 | code += kTouchdownCode.arg(touchdownAnchors); |
493 | |
494 | + var implicitHeight = 'implicitHeight: '; |
495 | if (hasSummary) { |
496 | - code += 'implicitHeight: summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n'; |
497 | + implicitHeight += 'summary.y + summary.height + (summary.text ? units.gu(1) : 0);\n'; |
498 | } else if (hasHeaderRow) { |
499 | - code += 'implicitHeight: row.y + row.height + units.gu(1);\n'; |
500 | + implicitHeight += 'row.y + row.height + units.gu(1);\n'; |
501 | } else if (hasMascot) { |
502 | - code += 'implicitHeight: mascotImage.y + mascotImage.height;\n'; |
503 | + implicitHeight += 'mascotImage.y + mascotImage.height;\n'; |
504 | + } else if (hasTitleContainer) { |
505 | + implicitHeight += 'headerTitleContainer.y + headerTitleContainer.height + units.gu(1);\n'; |
506 | } else if (hasAttributes) { |
507 | - code += 'implicitHeight: attributesRow.y + attributesRow.height + units.gu(1);\n'; |
508 | + implicitHeight += 'attributesRow.y + attributesRow.height + units.gu(1);\n'; |
509 | } else if (hasSubtitle) { |
510 | - code += 'implicitHeight: subtitleLabel.y + subtitleLabel.height + units.gu(1);\n'; |
511 | + implicitHeight += 'subtitleLabel.y + subtitleLabel.height + units.gu(1);\n'; |
512 | } else if (hasTitle) { |
513 | - code += 'implicitHeight: titleLabel.y + titleLabel.height + units.gu(1);\n'; |
514 | + implicitHeight += 'titleLabel.y + titleLabel.height + units.gu(1);\n'; |
515 | } else if (hasArt) { |
516 | - code += 'implicitHeight: artShapeHolder.height;\n'; |
517 | + implicitHeight += 'artShapeHolder.height;\n'; |
518 | } |
519 | // Close the AbstractButton |
520 | - code += '}\n'; |
521 | + code += implicitHeight + '}\n'; |
522 | |
523 | return code; |
524 | } |
525 | |
526 | === modified file 'plugins/Dash/ScopeStyle.qml' |
527 | --- plugins/Dash/ScopeStyle.qml 2014-07-25 11:42:06 +0000 |
528 | +++ plugins/Dash/ScopeStyle.qml 2014-08-08 14:57:17 +0000 |
529 | @@ -49,9 +49,10 @@ |
530 | |
531 | /*! \brief Luminance threshold for switching between fore and background color |
532 | |
533 | - \note If background colour is not fully opaque, it's not taken into account. |
534 | + \note If background colour is not fully opaque, the defaultLightLuminance it's taken into account instead of it. |
535 | */ |
536 | - readonly property real threshold: background.a !== 1.0 ? foregroundLuminance : (foregroundLuminance + backgroundLuminance) / 2 |
537 | + readonly property real threshold: background.a !== 1.0 ? (foregroundLuminance + d.defaultLightLuminance) / 2 |
538 | + : (foregroundLuminance + backgroundLuminance) / 2 |
539 | |
540 | /*! \brief The lighter of foreground and background colors |
541 | |
542 | |
543 | === modified file 'plugins/Dash/listviewwithpageheader.cpp' |
544 | --- plugins/Dash/listviewwithpageheader.cpp 2014-07-25 10:47:08 +0000 |
545 | +++ plugins/Dash/listviewwithpageheader.cpp 2014-08-08 14:57:17 +0000 |
546 | @@ -330,6 +330,11 @@ |
547 | return m_topSectionItem ? m_topSectionItem->height() : 0; |
548 | } |
549 | |
550 | +qreal ListViewWithPageHeader::headerItemShownHeight() const |
551 | +{ |
552 | + return m_headerItemShownHeight; |
553 | +} |
554 | + |
555 | void ListViewWithPageHeader::positionAtBeginning() |
556 | { |
557 | if (m_delegateModel->count() <= 0) |
558 | @@ -396,6 +401,7 @@ |
559 | firstItem->setY(firstItem->y() - m_headerItemShownHeight); |
560 | layout(); |
561 | } |
562 | + Q_EMIT headerItemShownHeightChanged(); |
563 | } |
564 | m_contentYAnimation->setTo(to); |
565 | contentYAnimationType = ContentYAnimationShowHeader; |
566 | @@ -544,6 +550,7 @@ |
567 | m_headerItem->setY(-m_minYExtent); |
568 | } |
569 | } |
570 | + Q_EMIT headerItemShownHeightChanged(); |
571 | } else { |
572 | // Stick the header item to the top when dragging down |
573 | m_headerItem->setY(contentY()); |
574 | @@ -822,8 +829,8 @@ |
575 | ListItem *nextItem = itemAtIndex(modelIndex + 1); |
576 | if (nextItem) { |
577 | listItem->setY(nextItem->y() - listItem->height()); |
578 | - } else if (modelIndex == 0 && m_headerItem) { |
579 | - listItem->setY(m_headerItem->height()); |
580 | + } else if (modelIndex == 0) { |
581 | + listItem->setY(m_headerItem ? m_headerItem->height() : 0); |
582 | } else if (!m_visibleItems.isEmpty()) { |
583 | lostItem = true; |
584 | } |
585 | @@ -1096,6 +1103,7 @@ |
586 | m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, newHeaderHeight); |
587 | updateClipItem(); |
588 | adjustMinYExtent(); |
589 | + Q_EMIT headerItemShownHeightChanged(); |
590 | } else { |
591 | if (oldHeaderY + oldHeaderHeight > contentY()) { |
592 | // If the header is shown because its position |
593 | |
594 | === modified file 'plugins/Dash/listviewwithpageheader.h' |
595 | --- plugins/Dash/listviewwithpageheader.h 2014-06-12 14:08:54 +0000 |
596 | +++ plugins/Dash/listviewwithpageheader.h 2014-08-08 14:57:17 +0000 |
597 | @@ -53,6 +53,7 @@ |
598 | Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged) |
599 | Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged) |
600 | Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged) |
601 | + Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged) |
602 | |
603 | friend class ListViewWithPageHeaderTest; |
604 | friend class ListViewWithPageHeaderTestSection; |
605 | @@ -81,6 +82,7 @@ |
606 | void setForceNoClip(bool noClip); |
607 | |
608 | int stickyHeaderHeight() const; |
609 | + qreal headerItemShownHeight() const; |
610 | |
611 | Q_INVOKABLE void positionAtBeginning(); |
612 | Q_INVOKABLE void showHeader(); |
613 | @@ -100,6 +102,7 @@ |
614 | void sectionPropertyChanged(); |
615 | void forceNoClipChanged(); |
616 | void stickyHeaderHeightChanged(); |
617 | + void headerItemShownHeightChanged(); |
618 | |
619 | protected: |
620 | void componentComplete() override; |
621 | |
622 | === modified file 'po/hu.po' |
623 | --- po/hu.po 2014-08-08 07:07:33 +0000 |
624 | +++ po/hu.po 2014-08-08 14:57:17 +0000 |
625 | @@ -6,16 +6,17 @@ |
626 | msgid "" |
627 | msgstr "" |
628 | "Project-Id-Version: unity\n" |
629 | -"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" |
630 | +"Report-Msgid-Bugs-To: \n" |
631 | "POT-Creation-Date: 2014-07-11 14:59+0200\n" |
632 | "PO-Revision-Date: 2014-08-06 07:41+0000\n" |
633 | "Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n" |
634 | "Language-Team: Hungarian <hu@li.org>\n" |
635 | +"Language: hu\n" |
636 | "MIME-Version: 1.0\n" |
637 | "Content-Type: text/plain; charset=UTF-8\n" |
638 | "Content-Transfer-Encoding: 8bit\n" |
639 | -"X-Launchpad-Export-Date: 2014-08-08 07:07+0000\n" |
640 | -"X-Generator: Launchpad (build 17156)\n" |
641 | +"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n" |
642 | +"X-Generator: Launchpad (build 17147)\n" |
643 | |
644 | #: plugins/Unity/Launcher/launcheritem.cpp:43 |
645 | #: plugins/Unity/Launcher/launcheritem.cpp:73 |
646 | @@ -73,8 +74,8 @@ |
647 | "You have now mastered the edge gestures and can start using the " |
648 | "phone<br><br>Tap on the screen to start" |
649 | msgstr "" |
650 | -"Elsajátította a gesztusokat, és megkezdheti a telefon " |
651 | -"használatát.<br><br>Koppintson a képernyőre a kezdéshez." |
652 | +"Elsajátította a gesztusokat, és megkezdheti a telefon használatát." |
653 | +"<br><br>Koppintson a képernyőre a kezdéshez." |
654 | |
655 | #: qml/Components/Lockscreen.qml:214 |
656 | msgid "Emergency Call" |
657 | |
658 | === modified file 'po/sl.po' |
659 | --- po/sl.po 2014-08-08 07:07:33 +0000 |
660 | +++ po/sl.po 2014-08-08 14:57:17 +0000 |
661 | @@ -6,16 +6,17 @@ |
662 | msgid "" |
663 | msgstr "" |
664 | "Project-Id-Version: unity\n" |
665 | -"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" |
666 | +"Report-Msgid-Bugs-To: \n" |
667 | "POT-Creation-Date: 2014-07-11 14:59+0200\n" |
668 | "PO-Revision-Date: 2014-08-06 06:11+0000\n" |
669 | "Last-Translator: Damir Jerovšek <Unknown>\n" |
670 | "Language-Team: Slovenian <sl@li.org>\n" |
671 | +"Language: sl\n" |
672 | "MIME-Version: 1.0\n" |
673 | "Content-Type: text/plain; charset=UTF-8\n" |
674 | "Content-Transfer-Encoding: 8bit\n" |
675 | -"X-Launchpad-Export-Date: 2014-08-08 07:07+0000\n" |
676 | -"X-Generator: Launchpad (build 17156)\n" |
677 | +"X-Launchpad-Export-Date: 2014-08-07 06:27+0000\n" |
678 | +"X-Generator: Launchpad (build 17147)\n" |
679 | |
680 | #: plugins/Unity/Launcher/launcheritem.cpp:43 |
681 | #: plugins/Unity/Launcher/launcheritem.cpp:73 |
682 | |
683 | === modified file 'po/unity8.pot' |
684 | --- po/unity8.pot 2014-07-11 14:20:12 +0000 |
685 | +++ po/unity8.pot 2014-08-08 14:57:17 +0000 |
686 | @@ -8,7 +8,7 @@ |
687 | msgstr "" |
688 | "Project-Id-Version: unity8\n" |
689 | "Report-Msgid-Bugs-To: \n" |
690 | -"POT-Creation-Date: 2014-07-11 14:59+0200\n" |
691 | +"POT-Creation-Date: 2014-08-08 11:17+0200\n" |
692 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
693 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
694 | "Language-Team: LANGUAGE <LL@li.org>\n" |
695 | @@ -26,66 +26,82 @@ |
696 | msgid "Unpin shortcut" |
697 | msgstr "" |
698 | |
699 | +#: qml/Components/Dialogs.qml:142 |
700 | +msgid "Are you sure you would like to turn power off?" |
701 | +msgstr "" |
702 | + |
703 | +#: qml/Components/Dialogs.qml:144 |
704 | +msgid "Power off" |
705 | +msgstr "" |
706 | + |
707 | +#: qml/Components/Dialogs.qml:153 |
708 | +msgid "Restart" |
709 | +msgstr "" |
710 | + |
711 | +#: qml/Components/Dialogs.qml:162 |
712 | +msgid "Cancel" |
713 | +msgstr "" |
714 | + |
715 | #: qml/Components/EdgeDemoOverlay.qml:151 |
716 | msgid "Skip intro" |
717 | msgstr "" |
718 | |
719 | +#: qml/Components/EdgeDemo.qml:112 |
720 | +msgid "Right edge" |
721 | +msgstr "" |
722 | + |
723 | #: qml/Components/EdgeDemo.qml:113 |
724 | -msgid "Right edge" |
725 | -msgstr "" |
726 | - |
727 | -#: qml/Components/EdgeDemo.qml:114 |
728 | msgid "Try swiping from the right edge to unlock the phone" |
729 | msgstr "" |
730 | |
731 | +#: qml/Components/EdgeDemo.qml:144 |
732 | +msgid "Top edge" |
733 | +msgstr "" |
734 | + |
735 | #: qml/Components/EdgeDemo.qml:145 |
736 | -msgid "Top edge" |
737 | -msgstr "" |
738 | - |
739 | -#: qml/Components/EdgeDemo.qml:146 |
740 | msgid "Try swiping from the top edge to access the indicators" |
741 | msgstr "" |
742 | |
743 | +#: qml/Components/EdgeDemo.qml:170 |
744 | +msgid "Close" |
745 | +msgstr "" |
746 | + |
747 | #: qml/Components/EdgeDemo.qml:171 |
748 | -msgid "Close" |
749 | -msgstr "" |
750 | - |
751 | -#: qml/Components/EdgeDemo.qml:172 |
752 | msgid "Swipe up again to close the settings screen" |
753 | msgstr "" |
754 | |
755 | +#: qml/Components/EdgeDemo.qml:198 |
756 | +msgid "Left edge" |
757 | +msgstr "" |
758 | + |
759 | #: qml/Components/EdgeDemo.qml:199 |
760 | -msgid "Left edge" |
761 | -msgstr "" |
762 | - |
763 | -#: qml/Components/EdgeDemo.qml:200 |
764 | msgid "Swipe from the left to reveal the launcher for quick access to apps" |
765 | msgstr "" |
766 | |
767 | +#: qml/Components/EdgeDemo.qml:226 |
768 | +msgid "Well done" |
769 | +msgstr "" |
770 | + |
771 | #: qml/Components/EdgeDemo.qml:227 |
772 | -msgid "Well done" |
773 | -msgstr "" |
774 | - |
775 | -#: qml/Components/EdgeDemo.qml:228 |
776 | msgid "" |
777 | "You have now mastered the edge gestures and can start using the " |
778 | "phone<br><br>Tap on the screen to start" |
779 | msgstr "" |
780 | |
781 | -#: qml/Components/Lockscreen.qml:214 |
782 | +#: qml/Components/Lockscreen.qml:220 |
783 | msgid "Emergency Call" |
784 | msgstr "" |
785 | |
786 | -#: qml/Components/Lockscreen.qml:231 |
787 | +#: qml/Components/Lockscreen.qml:243 |
788 | msgid "OK" |
789 | msgstr "" |
790 | |
791 | -#: qml/Components/PassphraseLockscreen.qml:60 |
792 | +#: qml/Components/PassphraseLockscreen.qml:62 |
793 | #, qt-format |
794 | msgid "Hello %1" |
795 | msgstr "" |
796 | |
797 | -#: qml/Components/PassphraseLockscreen.qml:60 |
798 | +#: qml/Components/PassphraseLockscreen.qml:62 |
799 | msgid "Hello" |
800 | msgstr "" |
801 | |
802 | @@ -97,19 +113,11 @@ |
803 | msgid "DONE" |
804 | msgstr "" |
805 | |
806 | -#: qml/Components/SeeMore.qml:35 |
807 | -msgid "See more" |
808 | -msgstr "" |
809 | - |
810 | -#: qml/Components/SeeMore.qml:58 qml/Dash/GenericScopeView.qml:330 |
811 | +#: qml/Dash/GenericScopeView.qml:358 |
812 | msgid "See less" |
813 | msgstr "" |
814 | |
815 | -#: qml/Dash/DashApps.qml:37 |
816 | -msgid "Recent" |
817 | -msgstr "" |
818 | - |
819 | -#: qml/Dash/GenericScopeView.qml:330 |
820 | +#: qml/Dash/GenericScopeView.qml:358 |
821 | msgid "See all" |
822 | msgstr "" |
823 | |
824 | @@ -133,6 +141,26 @@ |
825 | msgid "Send" |
826 | msgstr "" |
827 | |
828 | +#: qml/Dash/ScopesOverview.qml:200 |
829 | +msgid "Manage Dash" |
830 | +msgstr "" |
831 | + |
832 | +#: qml/Dash/ScopesOverview.qml:405 |
833 | +msgid "Done" |
834 | +msgstr "" |
835 | + |
836 | +#: qml/Dash/ScopesOverview.qml:431 |
837 | +msgid "Store" |
838 | +msgstr "" |
839 | + |
840 | +#: qml/Dash/ScopesOverviewTab.qml:36 |
841 | +msgid "Favorites" |
842 | +msgstr "" |
843 | + |
844 | +#: qml/Dash/ScopesOverviewTab.qml:54 |
845 | +msgid "All" |
846 | +msgstr "" |
847 | + |
848 | #: qml/Greeter/Greeter.qml:157 |
849 | msgid "Swipe to unlock" |
850 | msgstr "" |
851 | @@ -157,11 +185,11 @@ |
852 | msgid "Speaking..." |
853 | msgstr "" |
854 | |
855 | -#: qml/Notifications/NotificationMenuItemFactory.qml:91 |
856 | +#: qml/Notifications/NotificationMenuItemFactory.qml:100 |
857 | msgid "Show password" |
858 | msgstr "" |
859 | |
860 | -#: qml/Notifications/NotificationMenuItemFactory.qml:103 |
861 | +#: qml/Notifications/NotificationMenuItemFactory.qml:115 |
862 | msgid "Please enter SIM PIN" |
863 | msgstr "" |
864 | |
865 | @@ -173,35 +201,43 @@ |
866 | msgid "Conference" |
867 | msgstr "" |
868 | |
869 | -#: qml/Panel/Indicators/MenuItemFactory.qml:583 |
870 | +#: qml/Panel/Indicators/MenuItemFactory.qml:651 |
871 | msgid "In queue…" |
872 | msgstr "" |
873 | |
874 | -#: qml/Panel/Indicators/MenuItemFactory.qml:587 |
875 | +#: qml/Panel/Indicators/MenuItemFactory.qml:655 |
876 | msgid "Downloading" |
877 | msgstr "" |
878 | |
879 | -#: qml/Panel/Indicators/MenuItemFactory.qml:589 |
880 | +#: qml/Panel/Indicators/MenuItemFactory.qml:657 |
881 | msgid "Paused, tap to resume" |
882 | msgstr "" |
883 | |
884 | -#: qml/Panel/Indicators/MenuItemFactory.qml:591 |
885 | +#: qml/Panel/Indicators/MenuItemFactory.qml:659 |
886 | msgid "Canceled" |
887 | msgstr "" |
888 | |
889 | -#: qml/Panel/Indicators/MenuItemFactory.qml:593 |
890 | +#: qml/Panel/Indicators/MenuItemFactory.qml:661 |
891 | msgid "Finished" |
892 | msgstr "" |
893 | |
894 | -#: qml/Panel/Indicators/MenuItemFactory.qml:595 |
895 | +#: qml/Panel/Indicators/MenuItemFactory.qml:663 |
896 | msgid "Failed, tap to retry" |
897 | msgstr "" |
898 | |
899 | +#: qml/Panel/Indicators/ModemInfoItem.qml:105 |
900 | +msgid "Unlock SIM" |
901 | +msgstr "" |
902 | + |
903 | +#: qml/Panel/Indicators/RoamingIndication.qml:27 |
904 | +msgid "Roaming" |
905 | +msgstr "" |
906 | + |
907 | #: qml/Panel/SearchIndicator.qml:27 |
908 | msgid "Search" |
909 | msgstr "" |
910 | |
911 | -#: qml/Shell.qml:359 |
912 | +#: qml/Shell.qml:256 |
913 | #, qt-format |
914 | msgid "Please enter %1" |
915 | msgstr "" |
916 | |
917 | === modified file 'qml/Components/PageHeader.qml' |
918 | --- qml/Components/PageHeader.qml 2014-08-06 19:39:30 +0000 |
919 | +++ qml/Components/PageHeader.qml 2014-08-08 14:57:17 +0000 |
920 | @@ -24,7 +24,7 @@ |
921 | Item { |
922 | id: root |
923 | objectName: "pageHeader" |
924 | - implicitHeight: headerContainer.height + units.gu(2) + bottomContainer.height |
925 | + implicitHeight: headerContainer.height + bottomContainer.height + (showSignatureLine ? units.gu(2) : 0) |
926 | |
927 | property bool showBackButton: false |
928 | property string title |
929 | @@ -32,6 +32,7 @@ |
930 | property bool searchEntryEnabled: false |
931 | property ListModel searchHistory: SearchHistoryModel |
932 | property alias searchQuery: searchTextField.text |
933 | + property alias showSignatureLine: bottomBorder.visible |
934 | |
935 | property alias bottomItem: bottomContainer.children |
936 | property int paginationCount: 0 |
937 | @@ -251,6 +252,7 @@ |
938 | |
939 | actions: [ |
940 | Action { |
941 | + objectName: "search" |
942 | iconName: "search" |
943 | visible: root.searchEntryEnabled |
944 | onTriggered: { |
945 | |
946 | === modified file 'qml/Components/ResponsiveGridView.qml' |
947 | --- qml/Components/ResponsiveGridView.qml 2014-07-11 12:12:50 +0000 |
948 | +++ qml/Components/ResponsiveGridView.qml 2014-08-08 14:57:17 +0000 |
949 | @@ -34,7 +34,7 @@ |
950 | readonly property int cellWidth: gridView.cellWidth |
951 | readonly property int cellHeight: gridView.cellHeight |
952 | readonly property int totalContentHeight: { |
953 | - return contentHeightForRows(Math.ceil(gridView.model.count / columns)) |
954 | + return contentHeightForRows(Math.ceil(gridView.model.count / columns), cellHeight) |
955 | } |
956 | property alias interactive: gridView.interactive |
957 | readonly property alias flicking: gridView.flicking |
958 | @@ -47,8 +47,8 @@ |
959 | property alias cacheBuffer: gridView.cacheBuffer |
960 | readonly property alias currentItem: gridView.currentItem |
961 | |
962 | - function contentHeightForRows(rows) { |
963 | - return rows * cellHeight; |
964 | + function contentHeightForRows(rows, height) { |
965 | + return rows * height |
966 | } |
967 | |
968 | GridView { |
969 | |
970 | === removed directory 'qml/Dash/Apps' |
971 | === modified file 'qml/Dash/CardCarousel.qml' |
972 | --- qml/Dash/CardCarousel.qml 2014-07-11 12:13:08 +0000 |
973 | +++ qml/Dash/CardCarousel.qml 2014-08-08 14:57:17 +0000 |
974 | @@ -48,8 +48,8 @@ |
975 | |
976 | objectName: "carouselDelegate" + index |
977 | |
978 | - function clicked() { cardCarousel.clicked(index, model.result) } |
979 | - function pressAndHold() { cardCarousel.pressAndHold(index, model.result) } |
980 | + function clicked() { cardCarousel.clicked(index, model.result, loader.item, model) } |
981 | + function pressAndHold() { cardCarousel.pressAndHold(index) } |
982 | |
983 | sourceComponent: cardTool.cardComponent |
984 | onLoaded: { |
985 | |
986 | === modified file 'qml/Dash/CardGrid.qml' |
987 | --- qml/Dash/CardGrid.qml 2014-07-18 11:35:47 +0000 |
988 | +++ qml/Dash/CardGrid.qml 2014-08-08 14:57:17 +0000 |
989 | @@ -26,10 +26,20 @@ |
990 | } |
991 | |
992 | expandedHeight: grid.totalContentHeight |
993 | - collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows), expandedHeight) |
994 | + collapsedHeight: Math.min(grid.contentHeightForRows(collapsedRows, grid.cellHeight), expandedHeight) |
995 | collapsedItemCount: collapsedRows * grid.columns |
996 | originY: grid.originY |
997 | |
998 | + function cardPosition(index) { |
999 | + var pos = {}; |
1000 | + var row = Math.floor(index / grid.columns); |
1001 | + var column = index % grid.columns; |
1002 | + // Bit sad this is not symmetrical |
1003 | + pos.x = column * grid.cellWidth + grid.margins; |
1004 | + pos.y = row * grid.cellHeight; |
1005 | + return pos; |
1006 | + } |
1007 | + |
1008 | ResponsiveGridView { |
1009 | id: grid |
1010 | anchors.fill: parent |
1011 | @@ -53,6 +63,7 @@ |
1012 | item.objectName = "delegate" + index; |
1013 | item.width = Qt.binding(function() { return cardTool.cardWidth; }); |
1014 | item.height = Qt.binding(function() { return cardTool.cardHeight; }); |
1015 | + item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; }); |
1016 | item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; }); |
1017 | item.cardData = Qt.binding(function() { return model; }); |
1018 | item.template = Qt.binding(function() { return cardTool.template; }); |
1019 | @@ -62,7 +73,7 @@ |
1020 | } |
1021 | Connections { |
1022 | target: loader.item |
1023 | - onClicked: root.clicked(index, result) |
1024 | + onClicked: root.clicked(index, result, loader.item, model) |
1025 | onPressAndHold: root.pressAndHold(index) |
1026 | } |
1027 | } |
1028 | |
1029 | === modified file 'qml/Dash/CardVerticalJournal.qml' |
1030 | --- qml/Dash/CardVerticalJournal.qml 2014-07-22 12:17:34 +0000 |
1031 | +++ qml/Dash/CardVerticalJournal.qml 2014-08-08 14:57:17 +0000 |
1032 | @@ -61,7 +61,7 @@ |
1033 | } |
1034 | Connections { |
1035 | target: loader.item |
1036 | - onClicked: root.clicked(index, result) |
1037 | + onClicked: root.clicked(index, result, loader.item, model) |
1038 | onPressAndHold: root.pressAndHold(index) |
1039 | } |
1040 | } |
1041 | |
1042 | === modified file 'qml/Dash/Dash.qml' |
1043 | --- qml/Dash/Dash.qml 2014-08-06 19:39:30 +0000 |
1044 | +++ qml/Dash/Dash.qml 2014-08-08 14:57:17 +0000 |
1045 | @@ -16,6 +16,7 @@ |
1046 | |
1047 | import QtQuick 2.2 |
1048 | import Ubuntu.Components 0.1 |
1049 | +import Ubuntu.Gestures 0.1 |
1050 | import Unity 0.2 |
1051 | import Utils 0.1 |
1052 | import Unity.DashCommunicator 0.1 |
1053 | @@ -73,26 +74,104 @@ |
1054 | id: scopes |
1055 | } |
1056 | |
1057 | - Image { |
1058 | + QtObject { |
1059 | + id: overviewController |
1060 | + objectName: "overviewController" |
1061 | + |
1062 | + property alias enableAnimation: progressAnimation.enabled |
1063 | + property real progress: 0 |
1064 | + Behavior on progress { |
1065 | + id: progressAnimation |
1066 | + UbuntuNumberAnimation { } |
1067 | + } |
1068 | + } |
1069 | + |
1070 | + ScopesOverview { |
1071 | + id: scopesOverview |
1072 | + objectName: "scopesOverview" |
1073 | anchors.fill: parent |
1074 | - source: parent.width > parent.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png" |
1075 | - fillMode: Image.PreserveAspectCrop |
1076 | - horizontalAlignment: Image.AlignRight |
1077 | - verticalAlignment: Image.AlignTop |
1078 | + scope: scopes.overviewScope |
1079 | + progress: overviewController.progress |
1080 | + scopeScale: scopeItem.scope ? 0.4 : (1 - overviewController.progress * 0.6) |
1081 | + visible: scopeScale != 1 |
1082 | + currentIndex: dashContent.currentIndex |
1083 | + onDone: { |
1084 | + if (currentTab == 1) { |
1085 | + animateDashFromAll(dashContent.currentScopeId); |
1086 | + } |
1087 | + hide(); |
1088 | + } |
1089 | + onFavoriteSelected: { |
1090 | + setCurrentScope(scopeId, false, false); |
1091 | + dashContentCache.scheduleUpdate(); |
1092 | + hide(); |
1093 | + } |
1094 | + onAllFavoriteSelected: { |
1095 | + setCurrentScope(scopeId, false, false); |
1096 | + dashContentCache.scheduleUpdate(); |
1097 | + animateDashFromAll(dashContent.currentScopeId); |
1098 | + hide(); |
1099 | + } |
1100 | + onSearchSelected: { |
1101 | + var scopeIndex = -1; |
1102 | + for (var i = 0; i < scopes.count; ++i) { |
1103 | + if (scopes.getScope(i).id == scopeId) { |
1104 | + scopeIndex = i; |
1105 | + break; |
1106 | + } |
1107 | + } |
1108 | + if (scopeIndex >= 0) { |
1109 | + // Is a favorite one |
1110 | + setCurrentScope(scopeId, false, false); |
1111 | + dashContentCache.scheduleUpdate(); |
1112 | + showDashFromPos(pos, size); |
1113 | + hide(); |
1114 | + } else { |
1115 | + // Is not a favorite one, activate and get openScope |
1116 | + scope.activate(result); |
1117 | + } |
1118 | + } |
1119 | + function hide() { |
1120 | + overviewController.enableAnimation = true; |
1121 | + overviewController.progress = 0; |
1122 | + } |
1123 | + onProgressChanged: { |
1124 | + if (progress == 0) { |
1125 | + currentTab = scopeItem.scope ? 1 : 0; |
1126 | + } |
1127 | + } |
1128 | + } |
1129 | + |
1130 | + ShaderEffectSource { |
1131 | + id: dashContentCache |
1132 | + parent: scopesOverview.dashItemEater |
1133 | + z: 1 |
1134 | + sourceItem: dashContent |
1135 | + height: sourceItem.height |
1136 | + width: sourceItem.width |
1137 | + opacity: 1 - overviewController.progress |
1138 | + visible: overviewController.progress != 0 && scopeItem.scope === null |
1139 | + live: false |
1140 | } |
1141 | |
1142 | DashContent { |
1143 | id: dashContent |
1144 | + |
1145 | + property var scopeThatOpenedScope: null |
1146 | + |
1147 | objectName: "dashContent" |
1148 | - width: parent.width |
1149 | - height: parent.height |
1150 | + width: dash.width |
1151 | + height: dash.height |
1152 | scopes: scopes |
1153 | - visible: x != -width |
1154 | + visible: !scopesOverview.showingNonFavoriteScope && x != -width |
1155 | onGotoScope: { |
1156 | dash.setCurrentScope(scopeId, true, false); |
1157 | } |
1158 | onOpenScope: { |
1159 | + scopeThatOpenedScope = currentScope; |
1160 | scopeItem.scope = scope; |
1161 | + scopesOverview.currentTab = 1; |
1162 | + scopesOverview.ensureAllScopeVisible(scope.id); |
1163 | x = -width; |
1164 | } |
1165 | onScopeLoaded: { |
1166 | @@ -102,25 +181,63 @@ |
1167 | } |
1168 | } |
1169 | scale: dash.contentScale |
1170 | - clip: scale != 1.0 || scopeItem.visible |
1171 | + clip: scale != 1.0 || scopeItem.visible || overviewController.progress != 0 |
1172 | Behavior on x { |
1173 | UbuntuNumberAnimation { |
1174 | + duration: overviewController.progress != 0 ? 0 : UbuntuAnimation.FastDuration |
1175 | onRunningChanged: { |
1176 | if (!running && dashContent.x == 0) { |
1177 | - dashContent.closeScope(scopeItem.scope); |
1178 | + dashContent.scopeThatOpenedScope.closeScope(scopeItem.scope); |
1179 | scopeItem.scope = null; |
1180 | + if (overviewController.progress == 0) { |
1181 | + // Set tab to Favorites only if we are not showing the overview |
1182 | + scopesOverview.currentTab = 0; |
1183 | + } |
1184 | } |
1185 | } |
1186 | } |
1187 | } |
1188 | + |
1189 | + enabled: overviewController.progress == 0 |
1190 | + opacity: enabled ? 1 : 0 |
1191 | + } |
1192 | + |
1193 | + DashBackground |
1194 | + { |
1195 | + anchors.fill: scopeItem |
1196 | + visible: scopeItem.visible |
1197 | + parent: scopeItem.parent |
1198 | + scale: scopeItem.scale |
1199 | + opacity: scopeItem.opacity |
1200 | } |
1201 | |
1202 | GenericScopeView { |
1203 | id: scopeItem |
1204 | - anchors.left: dashContent.right |
1205 | + objectName: "dashTempScopeItem" |
1206 | + |
1207 | + readonly property real targetOverviewScale: { |
1208 | + if (scopesOverview.currentTab == 0) { |
1209 | + return 0.4; |
1210 | + } else { |
1211 | + return scopesOverview.allCardSize.width / scopeItem.width; |
1212 | + } |
1213 | + } |
1214 | + readonly property real overviewProgressScale: (1 - overviewController.progress * (1 - targetOverviewScale)) |
1215 | + readonly property var targetOverviewPosition: scope ? scopesOverview.allScopeCardPosition(scope.id) : null |
1216 | + readonly property real overviewProgressX: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ? |
1217 | + overviewController.progress * (targetOverviewPosition.x - (width - scopesOverview.allCardSize.width) / 2) |
1218 | + : 0 |
1219 | + readonly property real overviewProgressY: scope && scopesOverview.currentTab == 1 && targetOverviewPosition ? |
1220 | + overviewController.progress * (targetOverviewPosition.y - (height - scopesOverview.allCardSize.height) / 2) |
1221 | + : 0 |
1222 | + |
1223 | + x: overviewController.progress == 0 ? dashContent.x + width : overviewProgressX |
1224 | + y: overviewController.progress == 0 ? dashContent.y : overviewProgressY |
1225 | width: parent.width |
1226 | height: parent.height |
1227 | - scale: dash.contentScale |
1228 | + scale: dash.contentScale * overviewProgressScale |
1229 | + enabled: opacity == 1 |
1230 | + opacity: 1 - overviewController.progress |
1231 | clip: scale != 1.0 |
1232 | visible: scope != null |
1233 | hasBackAction: true |
1234 | @@ -154,7 +271,7 @@ |
1235 | opacity: 0 |
1236 | visible: opacity > 0 |
1237 | |
1238 | - readonly property bool processing: dashContent.processing || scopeItem.processing |
1239 | + readonly property bool processing: dashContent.processing || scopeItem.processing || scopesOverview.processing |
1240 | |
1241 | Behavior on opacity { |
1242 | UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration } |
1243 | @@ -207,4 +324,45 @@ |
1244 | } |
1245 | } |
1246 | |
1247 | + Image { |
1248 | + source: "graphics/overview_hint.png" |
1249 | + anchors.horizontalCenter: parent.horizontalCenter |
1250 | + opacity: (scopeItem.scope ? scopeItem.pageHeaderTotallyVisible : dashContent.pageHeaderTotallyVisible) && |
1251 | + (overviewDragHandle.enabled || overviewController.progress != 0) ? 1 : 0 |
1252 | + Behavior on opacity { |
1253 | + enabled: overviewController.progress == 0 |
1254 | + UbuntuNumberAnimation {} |
1255 | + } |
1256 | + y: parent.height - height * (1 - overviewController.progress * 4) |
1257 | + } |
1258 | + |
1259 | + EdgeDragArea { |
1260 | + id: overviewDragHandle |
1261 | + objectName: "overviewDragHandle" |
1262 | + z: 1 |
1263 | + direction: Direction.Upwards |
1264 | + enabled: !dashContent.previewShown && |
1265 | + dashContent.currentScope && |
1266 | + dashContent.currentScope.searchQuery == "" && |
1267 | + (overviewController.progress == 0 || dragging) |
1268 | + |
1269 | + readonly property real fullMovement: units.gu(20) |
1270 | + |
1271 | + anchors { left: parent.left; right: parent.right; bottom: parent.bottom } |
1272 | + height: units.gu(2) |
1273 | + |
1274 | + onSceneDistanceChanged: { |
1275 | + if (overviewController.enableAnimation) { |
1276 | + dashContentCache.scheduleUpdate(); |
1277 | + } |
1278 | + overviewController.enableAnimation = false; |
1279 | + overviewController.progress = Math.max(0, Math.min(1, sceneDistance / fullMovement)); |
1280 | + } |
1281 | + |
1282 | + onDraggingChanged: { |
1283 | + overviewController.enableAnimation = true; |
1284 | + overviewController.progress = (overviewController.progress > 0.7) ? 1 : 0; |
1285 | + } |
1286 | + } |
1287 | + |
1288 | } |
1289 | |
1290 | === added file 'qml/Dash/DashBackground.qml' |
1291 | --- qml/Dash/DashBackground.qml 1970-01-01 00:00:00 +0000 |
1292 | +++ qml/Dash/DashBackground.qml 2014-08-08 14:57:17 +0000 |
1293 | @@ -0,0 +1,24 @@ |
1294 | +/* |
1295 | + * Copyright (C) 2013, 2014 Canonical, Ltd. |
1296 | + * |
1297 | + * This program is free software; you can redistribute it and/or modify |
1298 | + * it under the terms of the GNU General Public License as published by |
1299 | + * the Free Software Foundation; version 3. |
1300 | + * |
1301 | + * This program is distributed in the hope that it will be useful, |
1302 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1303 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1304 | + * GNU General Public License for more details. |
1305 | + * |
1306 | + * You should have received a copy of the GNU General Public License |
1307 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1308 | + */ |
1309 | + |
1310 | +import QtQuick 2.0 |
1311 | + |
1312 | +Image { |
1313 | + source: anchors.fill.width > anchors.fill.height ? "graphics/paper_landscape.png" : "graphics/paper_portrait.png" |
1314 | + fillMode: Image.PreserveAspectCrop |
1315 | + horizontalAlignment: Image.AlignRight |
1316 | + verticalAlignment: Image.AlignTop |
1317 | +} |
1318 | |
1319 | === modified file 'qml/Dash/DashContent.qml' |
1320 | --- qml/Dash/DashContent.qml 2014-08-06 19:39:30 +0000 |
1321 | +++ qml/Dash/DashContent.qml 2014-08-08 14:57:17 +0000 |
1322 | @@ -25,8 +25,14 @@ |
1323 | |
1324 | property alias scopes: dashContentList.model |
1325 | readonly property alias currentIndex: dashContentList.currentIndex |
1326 | + readonly property string currentScopeId: dashContentList.currentItem ? dashContentList.currentItem.scopeId : "" |
1327 | + readonly property var currentScope: dashContentList.currentItem ? dashContentList.currentItem.theScope : null |
1328 | + readonly property bool previewShown: dashContentList.currentItem && dashContentList.currentItem.item ? |
1329 | + dashContentList.currentItem.item.previewShown : false |
1330 | readonly property bool processing: dashContentList.currentItem && dashContentList.currentItem.item |
1331 | && dashContentList.currentItem.item.processing || false |
1332 | + readonly property bool pageHeaderTotallyVisible: dashContentList.currentItem && dashContentList.currentItem.item |
1333 | + && dashContentList.currentItem.item.pageHeaderTotallyVisible || false |
1334 | |
1335 | signal scopeLoaded(string scopeId) |
1336 | signal gotoScope(string scopeId) |
1337 | @@ -77,15 +83,15 @@ |
1338 | } |
1339 | } |
1340 | |
1341 | - function closeScope(scope) { |
1342 | - dashContentList.currentItem.theScope.closeScope(scope) |
1343 | - } |
1344 | - |
1345 | Item { |
1346 | id: dashContentListHolder |
1347 | |
1348 | anchors.fill: parent |
1349 | |
1350 | + DashBackground { |
1351 | + anchors.fill: parent |
1352 | + } |
1353 | + |
1354 | ListView { |
1355 | id: dashContentList |
1356 | objectName: "dashContentList" |
1357 | |
1358 | === modified file 'qml/Dash/DashRenderer.qml' |
1359 | --- qml/Dash/DashRenderer.qml 2014-07-22 12:17:34 +0000 |
1360 | +++ qml/Dash/DashRenderer.qml 2014-08-08 14:57:17 +0000 |
1361 | @@ -41,7 +41,9 @@ |
1362 | /// Emitted when the user clicked on an item |
1363 | /// @param index is the index of the clicked item |
1364 | /// @param result result model of the cliked item, used for activation |
1365 | - signal clicked(int index, var result) |
1366 | + /// @param item item that has been clicked |
1367 | + /// @param itemModel model of the item |
1368 | + signal clicked(int index, var result, var item, var itemModel) |
1369 | |
1370 | /// Emitted when the user pressed and held on an item |
1371 | /// @param index is the index of the held item |
1372 | |
1373 | === modified file 'qml/Dash/GenericScopeView.qml' |
1374 | --- qml/Dash/GenericScopeView.qml 2014-08-06 19:39:30 +0000 |
1375 | +++ qml/Dash/GenericScopeView.qml 2014-08-08 14:57:17 +0000 |
1376 | @@ -25,7 +25,7 @@ |
1377 | FocusScope { |
1378 | id: scopeView |
1379 | |
1380 | - readonly property alias navigationShown: dashNavigation.showList |
1381 | + readonly property bool navigationShown: pageHeaderLoader.item ? pageHeaderLoader.item.bottomItem[0].showList : false |
1382 | property var scope: null |
1383 | property SortFilterProxyModel categories: categoryFilter |
1384 | property bool isCurrent: false |
1385 | @@ -33,8 +33,11 @@ |
1386 | property bool hasBackAction: false |
1387 | property bool enableHeightBehaviorOnNextCreation: false |
1388 | property var categoryView: categoryView |
1389 | - property alias paginationCount: pageHeader.paginationCount |
1390 | - property alias paginationIndex: pageHeader.paginationIndex |
1391 | + property bool showPageHeader: true |
1392 | + readonly property alias previewShown: previewListView.open |
1393 | + property int paginationCount: 0 |
1394 | + property int paginationIndex: 0 |
1395 | + property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible |
1396 | |
1397 | property var scopeStyle: ScopeStyle { |
1398 | style: scope ? scope.customizations : {} |
1399 | @@ -56,6 +59,34 @@ |
1400 | previewListView.open = false; |
1401 | } |
1402 | |
1403 | + function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) { |
1404 | + if (scope.id === "scopes" || scope.id == "clickscope") { |
1405 | + // TODO Technically it is possible that calling activate() will make the scope emit |
1406 | + // previewRequested so that we show a preview but there's no scope that does that yet |
1407 | + // so it's not implemented |
1408 | + scope.activate(result) |
1409 | + } else { |
1410 | + openPreview(index, resultsModel, limitedCategoryItemCount); |
1411 | + } |
1412 | + } |
1413 | + |
1414 | + function itemPressedAndHeld(index, resultsModel, limitedCategoryItemCount) { |
1415 | + openPreview(index, resultsModel, limitedCategoryItemCount); |
1416 | + } |
1417 | + |
1418 | + function openPreview(index, resultsModel, limitedCategoryItemCount) { |
1419 | + if (limitedCategoryItemCount > 0) { |
1420 | + previewLimitModel.model = resultsModel; |
1421 | + previewLimitModel.limit = limitedCategoryItemCount; |
1422 | + previewListView.model = previewLimitModel; |
1423 | + } else { |
1424 | + previewListView.model = resultsModel; |
1425 | + } |
1426 | + previewListView.currentIndex = -1; |
1427 | + previewListView.currentIndex = index; |
1428 | + previewListView.open = true; |
1429 | + } |
1430 | + |
1431 | Binding { |
1432 | target: scope |
1433 | property: "isActive" |
1434 | @@ -72,22 +103,24 @@ |
1435 | } |
1436 | |
1437 | onIsCurrentChanged: { |
1438 | - pageHeader.resetSearch(); |
1439 | + if (showPageHeader) { |
1440 | + pageHeaderLoader.item.resetSearch(); |
1441 | + } |
1442 | previewListView.open = false; |
1443 | } |
1444 | |
1445 | Binding { |
1446 | target: scopeView.scope |
1447 | property: "searchQuery" |
1448 | - value: pageHeader.searchQuery |
1449 | - when: isCurrent |
1450 | + value: pageHeaderLoader.item ? pageHeaderLoader.item.searchQuery : "" |
1451 | + when: isCurrent && showPageHeader |
1452 | } |
1453 | |
1454 | Binding { |
1455 | - target: pageHeader |
1456 | + target: pageHeaderLoader.item |
1457 | property: "searchQuery" |
1458 | value: scopeView.scope ? scopeView.scope.searchQuery : "" |
1459 | - when: isCurrent |
1460 | + when: isCurrent && showPageHeader |
1461 | } |
1462 | |
1463 | Connections { |
1464 | @@ -114,10 +147,13 @@ |
1465 | model: scopeView.categories |
1466 | forceNoClip: previewListView.open |
1467 | pixelAligned: true |
1468 | - interactive: !dashNavigation.showList |
1469 | + interactive: !navigationShown |
1470 | |
1471 | property string expandedCategoryId: "" |
1472 | |
1473 | + readonly property bool pageHeaderTotallyVisible: scopeView.showPageHeader && |
1474 | + ((headerItemShownHeight == 0 && categoryView.contentY <= categoryView.originY) || (headerItemShownHeight == pageHeaderLoader.item.height)) |
1475 | + |
1476 | delegate: ListItems.Base { |
1477 | id: baseItem |
1478 | objectName: "dashCategory" + category |
1479 | @@ -223,28 +259,19 @@ |
1480 | Connections { |
1481 | target: rendererLoader.item |
1482 | onClicked: { |
1483 | - if (scopeView.scope.id === "scopes" || scopeView.scope.id == "clickscope") { |
1484 | - // TODO Technically it is possible that calling activate() will make the scope emit |
1485 | - // previewRequested so that we show a preview but there's no scope that does that yet |
1486 | - // so it's not implemented |
1487 | - scopeView.scope.activate(result) |
1488 | - } else { |
1489 | - openPreview(index); |
1490 | - } |
1491 | - } |
1492 | - onPressAndHold: openPreview(index) |
1493 | - |
1494 | - function openPreview(index) { |
1495 | + scopeView.itemClicked(index, result, item, itemModel, target.model, categoryItemCount()); |
1496 | + } |
1497 | + |
1498 | + onPressAndHold: { |
1499 | + scopeView.itemPressedAndHeld(index, target.model, categoryItemCount()); |
1500 | + } |
1501 | + |
1502 | + function categoryItemCount() { |
1503 | + var categoryItemCount = -1; |
1504 | if (!rendererLoader.expanded && !seeAllLabel.visible && target.collapsedItemCount > 0) { |
1505 | - previewLimitModel.model = target.model; |
1506 | - previewLimitModel.limit = target.collapsedItemCount; |
1507 | - previewListView.model = previewLimitModel; |
1508 | - } else { |
1509 | - previewListView.model = target.model; |
1510 | + categoryItemCount = target.collapsedItemCount; |
1511 | } |
1512 | - previewListView.currentIndex = -1; |
1513 | - previewListView.currentIndex = index; |
1514 | - previewListView.open = true; |
1515 | + return categoryItemCount; |
1516 | } |
1517 | } |
1518 | Connections { |
1519 | @@ -380,26 +407,35 @@ |
1520 | } |
1521 | } |
1522 | |
1523 | - pageHeader: PageHeader { |
1524 | - id: pageHeader |
1525 | - objectName: "scopePageHeader" |
1526 | + pageHeader: scopeView.showPageHeader ? pageHeaderLoader : null |
1527 | + Loader { |
1528 | + id: pageHeaderLoader |
1529 | width: parent.width |
1530 | - title: scopeView.scope ? scopeView.scope.name : "" |
1531 | - showBackButton: scopeView.hasBackAction |
1532 | - searchEntryEnabled: true |
1533 | - scopeStyle: scopeView.scopeStyle |
1534 | - |
1535 | - bottomItem: DashNavigation { |
1536 | - id: dashNavigation |
1537 | - scope: scopeView.scope |
1538 | - width: parent.width <= units.gu(60) ? parent.width : units.gu(40) |
1539 | - anchors.right: parent.right |
1540 | - windowHeight: scopeView.height |
1541 | - windowWidth: scopeView.width |
1542 | - scopeStyle: scopeView.scopeStyle |
1543 | + sourceComponent: scopeView.showPageHeader ? pageHeaderComponent : undefined |
1544 | + Component { |
1545 | + id: pageHeaderComponent |
1546 | + PageHeader { |
1547 | + objectName: "scopePageHeader" |
1548 | + width: parent.width |
1549 | + title: scopeView.scope ? scopeView.scope.name : "" |
1550 | + showBackButton: scopeView.hasBackAction |
1551 | + searchEntryEnabled: true |
1552 | + scopeStyle: scopeView.scopeStyle |
1553 | + paginationCount: scopeView.paginationCount |
1554 | + paginationIndex: scopeView.paginationIndex |
1555 | + |
1556 | + bottomItem: DashNavigation { |
1557 | + scope: scopeView.scope |
1558 | + width: parent.width <= units.gu(60) ? parent.width : units.gu(40) |
1559 | + anchors.right: parent.right |
1560 | + windowHeight: scopeView.height |
1561 | + windowWidth: scopeView.width |
1562 | + scopeStyle: scopeView.scopeStyle |
1563 | + } |
1564 | + |
1565 | + onBackClicked: scopeView.backClicked() |
1566 | + } |
1567 | } |
1568 | - |
1569 | - onBackClicked: scopeView.backClicked() |
1570 | } |
1571 | } |
1572 | |
1573 | @@ -418,7 +454,9 @@ |
1574 | anchors.left: categoryView.right |
1575 | |
1576 | onOpenChanged: { |
1577 | - pageHeader.unfocus(); |
1578 | + if (showPageHeader) { |
1579 | + pageHeaderLoader.item.unfocus(); |
1580 | + } |
1581 | } |
1582 | } |
1583 | |
1584 | |
1585 | === modified file 'qml/Dash/PreviewListView.qml' |
1586 | --- qml/Dash/PreviewListView.qml 2014-07-30 15:46:44 +0000 |
1587 | +++ qml/Dash/PreviewListView.qml 2014-08-08 14:57:17 +0000 |
1588 | @@ -108,7 +108,7 @@ |
1589 | anchors { |
1590 | left: parent.left |
1591 | right: parent.right |
1592 | - top: pageHeader.bottom |
1593 | + top: header.bottom |
1594 | bottom: parent.bottom |
1595 | } |
1596 | |
1597 | |
1598 | === added file 'qml/Dash/ScopesOverview.qml' |
1599 | --- qml/Dash/ScopesOverview.qml 1970-01-01 00:00:00 +0000 |
1600 | +++ qml/Dash/ScopesOverview.qml 2014-08-08 14:57:17 +0000 |
1601 | @@ -0,0 +1,531 @@ |
1602 | +/* |
1603 | + * Copyright (C) 2014 Canonical, Ltd. |
1604 | + * |
1605 | + * This program is free software; you can redistribute it and/or modify |
1606 | + * it under the terms of the GNU General Public License as published by |
1607 | + * the Free Software Foundation; version 3. |
1608 | + * |
1609 | + * This program is distributed in the hope that it will be useful, |
1610 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1611 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1612 | + * GNU General Public License for more details. |
1613 | + * |
1614 | + * You should have received a copy of the GNU General Public License |
1615 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1616 | + */ |
1617 | + |
1618 | +import QtQuick 2.0 |
1619 | +import Dash 0.1 |
1620 | +import Ubuntu.Components 0.1 |
1621 | +import "../Components" |
1622 | + |
1623 | +Item { |
1624 | + id: root |
1625 | + |
1626 | + // Properties set by parent |
1627 | + property real progress: 0 |
1628 | + property var scope: null |
1629 | + property int currentIndex: 0 |
1630 | + property real scopeScale: 1 |
1631 | + |
1632 | + // Properties set and used by parent |
1633 | + property alias currentTab: tabBar.currentTab |
1634 | + |
1635 | + // Properties used by parent |
1636 | + readonly property bool processing: searchResultsViewer.processing || tempScopeItem.processing |
1637 | + property bool growingDashFromPos: false |
1638 | + readonly property bool searching: scope && scope.searchQuery == "" |
1639 | + readonly property bool showingNonFavoriteScope: tempScopeItem.scope != null |
1640 | + readonly property var dashItemEater: { |
1641 | + if (!forceXYScalerEater && tabBar.currentTab == 0 && middleItems.count > 0) { |
1642 | + var loaderItem = middleItems.itemAt(0).item; |
1643 | + return loaderItem && loaderItem.currentItem ? loaderItem.currentItem : null; |
1644 | + } |
1645 | + return scopesOverviewXYScaler; |
1646 | + } |
1647 | + readonly property size allCardSize: { |
1648 | + if (middleItems.count > 1) { |
1649 | + var loaderItem = middleItems.itemAt(1).item; |
1650 | + if (loaderItem) { |
1651 | + var cardTool = loaderItem.cardTool; |
1652 | + return Qt.size(cardTool.cardWidth, cardTool.cardHeight); |
1653 | + } |
1654 | + } |
1655 | + return Qt.size(0, 0); |
1656 | + } |
1657 | + |
1658 | + // Internal properties |
1659 | + property bool forceXYScalerEater: false |
1660 | + |
1661 | + signal done() |
1662 | + signal favoriteSelected(var scopeId) |
1663 | + signal allFavoriteSelected(var scopeId) |
1664 | + signal searchSelected(var scopeId, var result, var pos, var size) |
1665 | + |
1666 | + Connections { |
1667 | + target: scope |
1668 | + onOpenScope: { |
1669 | + var itemPos = scopesOverviewXYScaler.restorePosition; |
1670 | + var itemSize = scopesOverviewXYScaler.restoreSize; |
1671 | + scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width; |
1672 | + if (itemPos) { |
1673 | + scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2; |
1674 | + scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2; |
1675 | + } else { |
1676 | + scopesOverviewXYScaler.x = 0; |
1677 | + scopesOverviewXYScaler.y = 0; |
1678 | + } |
1679 | + scopesOverviewXYScaler.opacity = 0; |
1680 | + tempScopeItem.scope = scope; |
1681 | + middleItems.overrideOpacity = 0; |
1682 | + scopesOverviewXYScaler.scale = 1; |
1683 | + scopesOverviewXYScaler.x = 0; |
1684 | + scopesOverviewXYScaler.y = 0; |
1685 | + scopesOverviewXYScaler.opacity = 1; |
1686 | + } |
1687 | + onGotoScope: { |
1688 | + if (tabBar.currentTab == 0) { |
1689 | + root.favoriteSelected(scopeId); |
1690 | + } else { |
1691 | + root.allFavoriteSelected(scopeId); |
1692 | + } |
1693 | + } |
1694 | + } |
1695 | + |
1696 | + Binding { |
1697 | + target: scope |
1698 | + property: "isActive" |
1699 | + value: progress === 1 |
1700 | + } |
1701 | + |
1702 | + function animateDashFromAll(scopeId) { |
1703 | + var currentScopePos = allScopeCardPosition(scopeId); |
1704 | + if (currentScopePos) { |
1705 | + showDashFromPos(currentScopePos, allCardSize); |
1706 | + } else { |
1707 | + console.log("Warning: Could not find Dash OverView All card position for scope", dashContent.currentScopeId); |
1708 | + } |
1709 | + } |
1710 | + |
1711 | + function showDashFromPos(itemPos, itemSize) { |
1712 | + scopesOverviewXYScaler.scale = itemSize.width / scopesOverviewXYScaler.width; |
1713 | + scopesOverviewXYScaler.x = itemPos.x -(scopesOverviewXYScaler.width - scopesOverviewXYScaler.width * scopesOverviewXYScaler.scale) / 2; |
1714 | + scopesOverviewXYScaler.y = itemPos.y -(scopesOverviewXYScaler.height - scopesOverviewXYScaler.height * scopesOverviewXYScaler.scale) / 2; |
1715 | + scopesOverviewXYScaler.opacity = 0; |
1716 | + root.growingDashFromPos = true; |
1717 | + scopesOverviewXYScaler.scale = 1; |
1718 | + scopesOverviewXYScaler.x = 0; |
1719 | + scopesOverviewXYScaler.y = 0; |
1720 | + scopesOverviewXYScaler.opacity = 1; |
1721 | + } |
1722 | + |
1723 | + function allScopeCardPosition(scopeId) { |
1724 | + if (middleItems.count > 1) { |
1725 | + var loaderItem = middleItems.itemAt(1).item; |
1726 | + if (loaderItem) { |
1727 | + var pos = loaderItem.scopeCardPosition(scopeId); |
1728 | + return loaderItem.mapToItem(null, pos.x, pos.y); |
1729 | + } |
1730 | + } |
1731 | + } |
1732 | + |
1733 | + function ensureAllScopeVisible(scopeId) { |
1734 | + if (middleItems.count > 1) { |
1735 | + var loaderItem = middleItems.itemAt(1).item; |
1736 | + if (loaderItem) { |
1737 | + var pos = loaderItem.scopeCardPosition(scopeId); |
1738 | + loaderItem.contentY = Math.min(pos.y, loaderItem.contentHeight - loaderItem.height); |
1739 | + } |
1740 | + } |
1741 | + } |
1742 | + |
1743 | + onProgressChanged: { |
1744 | + if (progress == 0) { |
1745 | + pageHeader.resetSearch(); |
1746 | + pageHeader.unfocus(); // Shouldn't the previous call do this too? |
1747 | + } |
1748 | + } |
1749 | + |
1750 | + ScopeStyle { |
1751 | + id: overviewScopeStyle |
1752 | + style: { "foreground-color" : "white", "background-color" : "transparent" } |
1753 | + } |
1754 | + |
1755 | + DashBackground { |
1756 | + anchors.fill: parent |
1757 | + source: "graphics/dark_background.jpg" |
1758 | + } |
1759 | + |
1760 | + Connections { |
1761 | + target: pageHeader |
1762 | + onSearchQueryChanged: { |
1763 | + // Need this in order, otherwise something gets unhappy in rendering |
1764 | + // of the overlay in carousels because the parent of the dash dies for |
1765 | + // a moment, this way we make sure it's reparented first |
1766 | + // by forceXYScalerEater making dashItemEater return scopesOverviewXYScaler |
1767 | + // before we kill the previous parent by scope.searchQuery |
1768 | + root.forceXYScalerEater = true; |
1769 | + root.scope.searchQuery = pageHeader.searchQuery; |
1770 | + root.forceXYScalerEater = false; |
1771 | + } |
1772 | + } |
1773 | + |
1774 | + Binding { |
1775 | + target: pageHeader |
1776 | + property: "searchQuery" |
1777 | + value: scope ? scope.searchQuery : "" |
1778 | + } |
1779 | + |
1780 | + Item { |
1781 | + id: scopesOverviewContent |
1782 | + x: previewListView.open ? -width : 0 |
1783 | + Behavior on x { UbuntuNumberAnimation { } } |
1784 | + width: parent.width |
1785 | + height: parent.height |
1786 | + |
1787 | + PageHeader { |
1788 | + id: pageHeader |
1789 | + objectName: "scopesOverviewPageHeader" |
1790 | + |
1791 | + readonly property real yDisplacement: pageHeader.height + tabBar.height + tabBar.anchors.margins |
1792 | + |
1793 | + y: { |
1794 | + if (root.progress < 0.5) { |
1795 | + return -yDisplacement; |
1796 | + } else { |
1797 | + return -yDisplacement + (root.progress - 0.5) * yDisplacement * 2; |
1798 | + } |
1799 | + } |
1800 | + width: parent.width |
1801 | + clip: true |
1802 | + title: i18n.tr("Manage Dash") |
1803 | + scopeStyle: overviewScopeStyle |
1804 | + showSignatureLine: false |
1805 | + searchEntryEnabled: true |
1806 | + } |
1807 | + |
1808 | + ScopesOverviewTab { |
1809 | + id: tabBar |
1810 | + anchors { |
1811 | + left: parent.left |
1812 | + right: parent.right |
1813 | + top: pageHeader.bottom |
1814 | + margins: units.gu(2) |
1815 | + } |
1816 | + height: units.gu(4) |
1817 | + |
1818 | + enabled: opacity == 1 |
1819 | + opacity: !scope || scope.searchQuery == "" ? 1 : 0 |
1820 | + Behavior on opacity { UbuntuNumberAnimation { } } |
1821 | + } |
1822 | + |
1823 | + Repeater { |
1824 | + id: middleItems |
1825 | + objectName: "scopesOverviewRepeater" |
1826 | + property real overrideOpacity: -1 |
1827 | + model: scope && scope.searchQuery == "" ? scope.categories : null |
1828 | + delegate: Loader { |
1829 | + id: loader |
1830 | + objectName: "scopesOverviewRepeaterChild" + index |
1831 | + |
1832 | + height: { |
1833 | + if (index == 0) { |
1834 | + return root.height; |
1835 | + } else { |
1836 | + return root.height - pageHeader.height - tabBar.height - tabBar.anchors.margins - units.gu(2); |
1837 | + } |
1838 | + } |
1839 | + width: { |
1840 | + if (index == 0) { |
1841 | + return root.width / scopeScale; |
1842 | + } else { |
1843 | + return root.width; |
1844 | + } |
1845 | + } |
1846 | + x: { |
1847 | + if (index == 0) { |
1848 | + return (root.width - width) / 2; |
1849 | + } else { |
1850 | + return 0; |
1851 | + } |
1852 | + } |
1853 | + anchors { |
1854 | + bottom: scopesOverviewContent.bottom |
1855 | + } |
1856 | + |
1857 | + scale: index == 0 ? scopeScale : 1 |
1858 | + |
1859 | + opacity: { |
1860 | + if (middleItems.overrideOpacity >= 0) |
1861 | + return middleItems.overrideOpacity; |
1862 | + |
1863 | + if (tabBar.currentTab != index) |
1864 | + return 0; |
1865 | + |
1866 | + return index == 0 ? 1 : root.progress; |
1867 | + } |
1868 | + Behavior on opacity { |
1869 | + enabled: root.progress == 1 |
1870 | + UbuntuNumberAnimation { } |
1871 | + } |
1872 | + enabled: opacity == 1 |
1873 | + |
1874 | + clip: index == 1 |
1875 | + |
1876 | + CardTool { |
1877 | + id: cardTool |
1878 | + objectName: "cardTool" |
1879 | + count: results.count |
1880 | + template: model.renderer |
1881 | + components: model.components |
1882 | + viewWidth: parent.width |
1883 | + } |
1884 | + |
1885 | + source: { |
1886 | + if (index == 0 && categoryId == "favorites") return "ScopesOverviewFavorites.qml"; |
1887 | + else if (index == 1 && categoryId == "all") return "ScopesOverviewAll.qml"; |
1888 | + else return ""; |
1889 | + } |
1890 | + |
1891 | + onLoaded: { |
1892 | + item.model = Qt.binding(function() { return results; }); |
1893 | + item.cardTool = cardTool; |
1894 | + if (index == 0) { |
1895 | + item.scopeWidth = Qt.binding(function() { return root.width; }); |
1896 | + item.scopeHeight = Qt.binding(function() { return root.height; }); |
1897 | + item.appliedScale = Qt.binding(function() { return loader.scale }); |
1898 | + item.currentIndex = Qt.binding(function() { return root.currentIndex }); |
1899 | + } else if (index == 1) { |
1900 | + item.extraHeight = bottomBar.height; |
1901 | + } |
1902 | + } |
1903 | + |
1904 | + Connections { |
1905 | + target: loader.item |
1906 | + onClicked: { |
1907 | + if (tabBar.currentTab == 0) { |
1908 | + root.favoriteSelected(itemModel.scopeId); |
1909 | + } else { |
1910 | + var favoriteScopesItem = middleItems.itemAt(0).item; |
1911 | + var scopeIndex = favoriteScopesItem.model.scopeIndex(itemModel.scopeId); |
1912 | + if (scopeIndex >= 0) { |
1913 | + root.allFavoriteSelected(itemModel.scopeId); |
1914 | + } else { |
1915 | + // Will result in an openScope from root.scope |
1916 | + scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0); |
1917 | + scopesOverviewXYScaler.restoreSize = allCardSize; |
1918 | + root.scope.activate(result); |
1919 | + } |
1920 | + } |
1921 | + } |
1922 | + onPressAndHold: { |
1923 | + // Preview can call openScope so make sure restorePosition and restoreSize are set |
1924 | + scopesOverviewXYScaler.restorePosition = undefined; |
1925 | + scopesOverviewXYScaler.restoreSize = allCardSize; |
1926 | + |
1927 | + previewListView.model = target.model; |
1928 | + previewListView.currentIndex = -1; |
1929 | + previewListView.currentIndex = index; |
1930 | + previewListView.open = true; |
1931 | + } |
1932 | + } |
1933 | + } |
1934 | + } |
1935 | + |
1936 | + GenericScopeView { |
1937 | + id: searchResultsViewer |
1938 | + objectName: "searchResultsViewer" |
1939 | + anchors { |
1940 | + top: pageHeader.bottom |
1941 | + right: parent.right |
1942 | + left: parent.left |
1943 | + bottom: parent.bottom |
1944 | + } |
1945 | + scope: root.scope && root.scope.searchQuery != "" ? root.scope : null |
1946 | + scopeStyle: overviewScopeStyle |
1947 | + enabled: opacity == 1 |
1948 | + showPageHeader: false |
1949 | + clip: true |
1950 | + opacity: searchResultsViewer.scope ? 1 : 0 |
1951 | + isCurrent: true |
1952 | + Behavior on opacity { UbuntuNumberAnimation { } } |
1953 | + |
1954 | + function itemClicked(index, result, item, itemModel, resultsModel, limitedCategoryItemCount) { |
1955 | + pageHeader.closePopup(); |
1956 | + if (itemModel.scopeId) { |
1957 | + // This can end up in openScope so save restorePosition and restoreSize |
1958 | + scopesOverviewXYScaler.restorePosition = item.mapToItem(null, 0, 0); |
1959 | + scopesOverviewXYScaler.restoreSize = Qt.size(item.width, item.height); |
1960 | + root.searchSelected(itemModel.scopeId, result, item.mapToItem(null, 0, 0), Qt.size(item.width, item.height)); |
1961 | + } else { |
1962 | + // Not a scope, just activate it |
1963 | + searchResultsViewer.scope.activate(result); |
1964 | + } |
1965 | + } |
1966 | + |
1967 | + function itemPressedAndHeld(index, resultsModel, limitedCategoryItemCount) { |
1968 | + // Do nothing |
1969 | + } |
1970 | + } |
1971 | + |
1972 | + Rectangle { |
1973 | + id: bottomBar |
1974 | + color: "black" |
1975 | + height: units.gu(8) |
1976 | + width: parent.width |
1977 | + enabled: opacity == 1 |
1978 | + opacity: scope && scope.searchQuery == "" ? 1 : 0 |
1979 | + Behavior on opacity { UbuntuNumberAnimation { } } |
1980 | + y: { |
1981 | + if (root.progress < 0.5) { |
1982 | + return parent.height; |
1983 | + } else { |
1984 | + return parent.height - (root.progress - 0.5) * height * 2; |
1985 | + } |
1986 | + } |
1987 | + |
1988 | + AbstractButton { |
1989 | + objectName: "scopesOverviewDoneButton" |
1990 | + width: Math.max(label.width + units.gu(2), units.gu(10)) |
1991 | + height: units.gu(4) |
1992 | + anchors { |
1993 | + left: parent.left |
1994 | + leftMargin: units.gu(2) |
1995 | + verticalCenter: parent.verticalCenter |
1996 | + } |
1997 | + Rectangle { |
1998 | + anchors.fill: parent |
1999 | + border.color: "white" |
2000 | + border.width: units.dp(1) |
2001 | + radius: units.dp(10) |
2002 | + color: parent.pressed ? "gray" : "transparent" |
2003 | + } |
2004 | + Label { |
2005 | + id: label |
2006 | + anchors.centerIn: parent |
2007 | + text: i18n.tr("Done") |
2008 | + color: parent.pressed ? "black" : "white" |
2009 | + } |
2010 | + onClicked: root.done(); |
2011 | + } |
2012 | + |
2013 | + AbstractButton { |
2014 | + objectName: "scopesOverviewStoreButton" |
2015 | + width: Math.max(storeLabel.width, units.gu(10)) |
2016 | + height: units.gu(4) |
2017 | + anchors { |
2018 | + right: parent.right |
2019 | + verticalCenter: parent.verticalCenter |
2020 | + } |
2021 | + Icon { |
2022 | + id: storeImage |
2023 | + name: "ubuntu-store-symbolic" |
2024 | + color: "white" |
2025 | + anchors.horizontalCenter: parent.horizontalCenter |
2026 | + width: units.gu(2) |
2027 | + height: units.gu(2) |
2028 | + } |
2029 | + Label { |
2030 | + id: storeLabel |
2031 | + anchors.horizontalCenter: parent.horizontalCenter |
2032 | + anchors.top: storeImage.bottom |
2033 | + text: i18n.tr("Store") |
2034 | + color: "white" |
2035 | + } |
2036 | + onClicked: { |
2037 | + // Just zoom from the middle |
2038 | + scopesOverviewXYScaler.restorePosition = undefined; |
2039 | + scopesOverviewXYScaler.restoreSize = allCardSize; |
2040 | + scope.performQuery("scope://com.canonical.scopes.clickstore"); |
2041 | + } |
2042 | + } |
2043 | + } |
2044 | + } |
2045 | + |
2046 | + PreviewListView { |
2047 | + id: previewListView |
2048 | + objectName: "scopesOverviewPreviewListView" |
2049 | + scope: root.scope |
2050 | + scopeStyle: overviewScopeStyle |
2051 | + visible: x != width |
2052 | + width: parent.width |
2053 | + height: parent.height |
2054 | + anchors.left: scopesOverviewContent.right |
2055 | + } |
2056 | + |
2057 | + |
2058 | + |
2059 | + Item { |
2060 | + id: scopesOverviewXYScaler |
2061 | + width: parent.width |
2062 | + height: parent.height |
2063 | + |
2064 | + clip: scale != 1.0 |
2065 | + enabled: scale == 1 |
2066 | + |
2067 | + property bool animationsEnabled: root.showingNonFavoriteScope || root.growingDashFromPos |
2068 | + |
2069 | + property var restorePosition |
2070 | + property var restoreSize |
2071 | + |
2072 | + Behavior on x { |
2073 | + enabled: scopesOverviewXYScaler.animationsEnabled |
2074 | + UbuntuNumberAnimation { } |
2075 | + } |
2076 | + Behavior on y { |
2077 | + enabled: scopesOverviewXYScaler.animationsEnabled |
2078 | + UbuntuNumberAnimation { } |
2079 | + } |
2080 | + Behavior on opacity { |
2081 | + enabled: scopesOverviewXYScaler.animationsEnabled |
2082 | + UbuntuNumberAnimation { } |
2083 | + } |
2084 | + Behavior on scale { |
2085 | + enabled: scopesOverviewXYScaler.animationsEnabled |
2086 | + UbuntuNumberAnimation { |
2087 | + onRunningChanged: { |
2088 | + if (!running) { |
2089 | + if (root.showingNonFavoriteScope && scopesOverviewXYScaler.scale != 1) { |
2090 | + root.scope.closeScope(tempScopeItem.scope); |
2091 | + tempScopeItem.scope = null; |
2092 | + } else if (root.growingDashFromPos) { |
2093 | + root.growingDashFromPos = false; |
2094 | + } |
2095 | + } |
2096 | + } |
2097 | + } |
2098 | + } |
2099 | + |
2100 | + DashBackground { |
2101 | + anchors.fill: tempScopeItem |
2102 | + visible: tempScopeItem.visible |
2103 | + parent: tempScopeItem.parent |
2104 | + } |
2105 | + |
2106 | + GenericScopeView { |
2107 | + id: tempScopeItem |
2108 | + objectName: "scopesOverviewTempScopeItem" |
2109 | + |
2110 | + width: parent.width |
2111 | + height: parent.height |
2112 | + scale: dash.contentScale |
2113 | + clip: scale != 1.0 |
2114 | + visible: scope != null |
2115 | + hasBackAction: true |
2116 | + isCurrent: visible |
2117 | + onBackClicked: { |
2118 | + var v = scopesOverviewXYScaler.restoreSize.width / tempScopeItem.width; |
2119 | + scopesOverviewXYScaler.scale = v; |
2120 | + if (scopesOverviewXYScaler.restorePosition) { |
2121 | + scopesOverviewXYScaler.x = scopesOverviewXYScaler.restorePosition.x -(tempScopeItem.width - tempScopeItem.width * v) / 2; |
2122 | + scopesOverviewXYScaler.y = scopesOverviewXYScaler.restorePosition.y -(tempScopeItem.height - tempScopeItem.height * v) / 2; |
2123 | + } else { |
2124 | + scopesOverviewXYScaler.x = 0; |
2125 | + scopesOverviewXYScaler.y = 0; |
2126 | + } |
2127 | + scopesOverviewXYScaler.opacity = 0; |
2128 | + middleItems.overrideOpacity = -1; |
2129 | + } |
2130 | + } |
2131 | + } |
2132 | +} |
2133 | |
2134 | === added file 'qml/Dash/ScopesOverviewAll.qml' |
2135 | --- qml/Dash/ScopesOverviewAll.qml 1970-01-01 00:00:00 +0000 |
2136 | +++ qml/Dash/ScopesOverviewAll.qml 2014-08-08 14:57:17 +0000 |
2137 | @@ -0,0 +1,54 @@ |
2138 | +/* |
2139 | + * Copyright (C) 2014 Canonical, Ltd. |
2140 | + * |
2141 | + * This program is free software; you can redistribute it and/or modify |
2142 | + * it under the terms of the GNU General Public License as published by |
2143 | + * the Free Software Foundation; version 3. |
2144 | + * |
2145 | + * This program is distributed in the hope that it will be useful, |
2146 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2147 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2148 | + * GNU General Public License for more details. |
2149 | + * |
2150 | + * You should have received a copy of the GNU General Public License |
2151 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2152 | + */ |
2153 | + |
2154 | +import QtQuick 2.0 |
2155 | +import Ubuntu.Components 0.1 |
2156 | + |
2157 | +Flickable { |
2158 | + id: root |
2159 | + |
2160 | + property alias model: cardGrid.model |
2161 | + property alias cardTool: cardGrid.cardTool |
2162 | + |
2163 | + property real extraHeight: 0 |
2164 | + |
2165 | + signal clicked(int index, var result, var item, var itemModel) |
2166 | + signal pressAndHold(int index) |
2167 | + |
2168 | + contentHeight: cardGrid.expandedHeight + extraHeight |
2169 | + contentWidth: cardGrid.width |
2170 | + flickableDirection: Flickable.VerticalFlick |
2171 | + |
2172 | + function scopeCardPosition(scopeId) { |
2173 | + var index = model.scopeIndex(scopeId); |
2174 | + var pos = cardGrid.cardPosition(index); |
2175 | + pos.y = pos.y - root.contentY; |
2176 | + return pos; |
2177 | + } |
2178 | + |
2179 | + CardGrid { |
2180 | + id: cardGrid |
2181 | + width: root.width |
2182 | + height: parent.height |
2183 | + |
2184 | + onClicked: { |
2185 | + root.clicked(index, result, item, itemModel); |
2186 | + } |
2187 | + onPressAndHold: { |
2188 | + root.pressAndHold(index); |
2189 | + } |
2190 | + } |
2191 | +} |
2192 | |
2193 | === added file 'qml/Dash/ScopesOverviewFavorites.qml' |
2194 | --- qml/Dash/ScopesOverviewFavorites.qml 1970-01-01 00:00:00 +0000 |
2195 | +++ qml/Dash/ScopesOverviewFavorites.qml 2014-08-08 14:57:17 +0000 |
2196 | @@ -0,0 +1,73 @@ |
2197 | +/* |
2198 | + * Copyright (C) 2014 Canonical, Ltd. |
2199 | + * |
2200 | + * This program is free software; you can redistribute it and/or modify |
2201 | + * it under the terms of the GNU General Public License as published by |
2202 | + * the Free Software Foundation; version 3. |
2203 | + * |
2204 | + * This program is distributed in the hope that it will be useful, |
2205 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2206 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2207 | + * GNU General Public License for more details. |
2208 | + * |
2209 | + * You should have received a copy of the GNU General Public License |
2210 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2211 | + */ |
2212 | + |
2213 | +import QtQuick 2.0 |
2214 | + |
2215 | +Flickable { |
2216 | + id: root |
2217 | + |
2218 | + signal clicked(int index, var result, var itemModel) |
2219 | + signal pressAndHold(int index) |
2220 | + |
2221 | + property var cardTool: null |
2222 | + property real scopeHeight: 0 |
2223 | + property real scopeWidth: 0 |
2224 | + property real appliedScale: 1 |
2225 | + property int currentIndex: -1 |
2226 | + property var currentItem: currentIndex < repeater.count ? repeater.itemAt(currentIndex) : null |
2227 | + |
2228 | + property alias model: repeater.model |
2229 | + |
2230 | + contentHeight: height |
2231 | + contentWidth: repeater.count * root.scopeWidth + units.gu(2) / appliedScale * (repeater.count - 1) |
2232 | + |
2233 | + contentX: { |
2234 | + var indexX = currentIndex * scopeWidth + units.gu(2) / appliedScale * currentIndex; |
2235 | + var newContentX = indexX - (width - scopeWidth) / 2; |
2236 | + newContentX = Math.min(Math.max(newContentX, 0), contentWidth - width); |
2237 | + return newContentX; |
2238 | + } |
2239 | + |
2240 | + Repeater { |
2241 | + id: repeater |
2242 | + objectName: "scopesOverviewFavoritesRepeater" |
2243 | + |
2244 | + delegate: Loader { |
2245 | + id: loader |
2246 | + |
2247 | + x: index * root.scopeWidth + units.gu(2) / appliedScale * index |
2248 | + asynchronous: true |
2249 | + |
2250 | + sourceComponent: cardTool.cardComponent |
2251 | + onLoaded: { |
2252 | + item.fixedArtShapeSize = Qt.binding(function() { return Qt.size(root.scopeWidth, root.scopeHeight); }); |
2253 | + item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight / appliedScale; }); |
2254 | + item.fontScale = Qt.binding(function() { return 1 / appliedScale; }); |
2255 | + item.height = Qt.binding(function() { return root.scopeHeight; }); |
2256 | + item.width = Qt.binding(function() { return root.scopeWidth; }); |
2257 | + item.cardData = Qt.binding(function() { return model; }); |
2258 | + item.template = Qt.binding(function() { return cardTool.template; }); |
2259 | + item.components = Qt.binding(function() { return cardTool.components; }); |
2260 | + item.headerAlignment = Qt.binding(function() { return cardTool.headerAlignment; }); |
2261 | + } |
2262 | + |
2263 | + Connections { |
2264 | + target: loader.item |
2265 | + onClicked: root.clicked(index, result, model) |
2266 | + } |
2267 | + } |
2268 | + } |
2269 | +} |
2270 | |
2271 | === added file 'qml/Dash/ScopesOverviewTab.qml' |
2272 | --- qml/Dash/ScopesOverviewTab.qml 1970-01-01 00:00:00 +0000 |
2273 | +++ qml/Dash/ScopesOverviewTab.qml 2014-08-08 14:57:17 +0000 |
2274 | @@ -0,0 +1,74 @@ |
2275 | +/* |
2276 | + * Copyright (C) 2014 Canonical, Ltd. |
2277 | + * |
2278 | + * This program is free software; you can redistribute it and/or modify |
2279 | + * it under the terms of the GNU General Public License as published by |
2280 | + * the Free Software Foundation; version 3. |
2281 | + * |
2282 | + * This program is distributed in the hope that it will be useful, |
2283 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2284 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2285 | + * GNU General Public License for more details. |
2286 | + * |
2287 | + * You should have received a copy of the GNU General Public License |
2288 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2289 | + */ |
2290 | + |
2291 | +import QtQuick 2.3 |
2292 | +import Ubuntu.Components 0.1 |
2293 | + |
2294 | +Item { |
2295 | + id: root |
2296 | + |
2297 | + property int currentTab: 0 |
2298 | + |
2299 | + AbstractButton { |
2300 | + id: tab1 |
2301 | + height: parent.height |
2302 | + width: parent.width / 2 |
2303 | + Rectangle { |
2304 | + anchors.fill: parent |
2305 | + color: root.currentTab == 0 && root.enabled ? "white" : "transparent" |
2306 | + radius: units.dp(10) |
2307 | + } |
2308 | + Label { |
2309 | + anchors.centerIn: parent |
2310 | + text: i18n.tr("Favorites") |
2311 | + color: root.currentTab == 0 && root.enabled ? "black" : "white" |
2312 | + } |
2313 | + onClicked: root.currentTab = 0 |
2314 | + } |
2315 | + AbstractButton { |
2316 | + id: tab2 |
2317 | + objectName: "scopesOverviewAllTabButton" |
2318 | + x: width |
2319 | + height: parent.height |
2320 | + width: parent.width / 2 |
2321 | + Rectangle { |
2322 | + anchors.fill: parent |
2323 | + color: root.currentTab == 1 && root.enabled ? "white" : "transparent" |
2324 | + radius: units.dp(10) |
2325 | + } |
2326 | + Label { |
2327 | + anchors.centerIn: parent |
2328 | + text: i18n.tr("All") |
2329 | + color: root.currentTab == 1 && root.enabled ? "black" : "white" |
2330 | + } |
2331 | + onClicked: root.currentTab = 1 |
2332 | + } |
2333 | + Rectangle { |
2334 | + id: centerPiece |
2335 | + width: root.enabled ? units.dp(10) : units.dp(1) |
2336 | + height: parent.height |
2337 | + color: "white" |
2338 | + x: root.currentTab == 1 ? tab2.x : tab2.x - width |
2339 | + } |
2340 | + Rectangle { |
2341 | + id: border |
2342 | + anchors.fill: parent |
2343 | + radius: units.dp(10) |
2344 | + color: "transparent" |
2345 | + border.color: centerPiece.color |
2346 | + border.width: units.dp(1) |
2347 | + } |
2348 | +} |
2349 | |
2350 | === added file 'qml/Dash/graphics/dark_background.jpg' |
2351 | Binary files qml/Dash/graphics/dark_background.jpg 1970-01-01 00:00:00 +0000 and qml/Dash/graphics/dark_background.jpg 2014-08-08 14:57:17 +0000 differ |
2352 | === added file 'qml/Dash/graphics/overview_hint@27.png' |
2353 | Binary files qml/Dash/graphics/overview_hint@27.png 1970-01-01 00:00:00 +0000 and qml/Dash/graphics/overview_hint@27.png 2014-08-08 14:57:17 +0000 differ |
2354 | === modified file 'tests/autopilot/unity8/shell/tests/test_emulators.py' |
2355 | --- tests/autopilot/unity8/shell/tests/test_emulators.py 2014-07-30 20:01:30 +0000 |
2356 | +++ tests/autopilot/unity8/shell/tests/test_emulators.py 2014-08-08 14:57:17 +0000 |
2357 | @@ -122,7 +122,7 @@ |
2358 | self._assert_scope_is_opened(scope, scope_id) |
2359 | |
2360 | def test_open_generic_scope(self): |
2361 | - scope_id = 'scopes' |
2362 | + scope_id = 'musicaggregator' |
2363 | scope = self.dash.open_scope(scope_id) |
2364 | self._assert_scope_is_opened(scope, scope_id) |
2365 | self.assertIsInstance(scope, dash_emulators.GenericScopeView) |
2366 | |
2367 | === modified file 'tests/mocks/Unity/CMakeLists.txt' |
2368 | --- tests/mocks/Unity/CMakeLists.txt 2014-08-06 19:38:57 +0000 |
2369 | +++ tests/mocks/Unity/CMakeLists.txt 2014-08-08 14:57:17 +0000 |
2370 | @@ -22,6 +22,7 @@ |
2371 | set(UnityQML_SOURCES |
2372 | fake_scope.cpp |
2373 | fake_scopes.cpp |
2374 | + fake_scopesoverview.cpp |
2375 | fake_categories.cpp |
2376 | fake_navigation.cpp |
2377 | fake_resultsmodel.cpp |
2378 | |
2379 | === modified file 'tests/mocks/Unity/fake_categories.cpp' |
2380 | --- tests/mocks/Unity/fake_categories.cpp 2014-07-18 11:35:47 +0000 |
2381 | +++ tests/mocks/Unity/fake_categories.cpp 2014-08-08 14:57:17 +0000 |
2382 | @@ -109,11 +109,13 @@ |
2383 | } |
2384 | case RoleComponents: |
2385 | { |
2386 | - QVariantMap map, artMap; |
2387 | + QVariantMap map, artMap, attributeMap; |
2388 | artMap["aspect-ratio"] = "1.0"; |
2389 | artMap["field"] = "art"; |
2390 | map["art"] = artMap; |
2391 | map["title"] = "HOLA"; |
2392 | + attributeMap["field"] = "attribute"; |
2393 | + map["attributes"] = attributeMap; |
2394 | return map; |
2395 | } |
2396 | case RoleHeaderLink: |
2397 | @@ -156,7 +158,7 @@ |
2398 | } |
2399 | case RoleComponents: |
2400 | { |
2401 | - QVariantMap map, artMap; |
2402 | + QVariantMap map, artMap, attributeMap; |
2403 | if (index.row() % 2 != 0) { |
2404 | artMap["aspect-ratio"] = QString("1.%1").arg(index.row()); |
2405 | } else { |
2406 | @@ -166,6 +168,8 @@ |
2407 | map["art"] = artMap; |
2408 | map["title"] = "HOLA"; |
2409 | map["subtitle"] = "HOLA"; |
2410 | + attributeMap["field"] = "attribute"; |
2411 | + map["attributes"] = attributeMap; |
2412 | return map; |
2413 | } |
2414 | case RoleHeaderLink: |
2415 | |
2416 | === modified file 'tests/mocks/Unity/fake_resultsmodel.cpp' |
2417 | --- tests/mocks/Unity/fake_resultsmodel.cpp 2014-05-20 10:29:20 +0000 |
2418 | +++ tests/mocks/Unity/fake_resultsmodel.cpp 2014-08-08 14:57:17 +0000 |
2419 | @@ -58,8 +58,9 @@ |
2420 | case RoleUri: |
2421 | case RoleCategoryId: |
2422 | case RoleDndUri: |
2423 | + return QString(); |
2424 | case RoleResult: |
2425 | - return QString(); |
2426 | + return QString("Result.%1.%2").arg(m_categoryId).arg(index.row()); |
2427 | case RoleTitle: |
2428 | return QString("Title.%1.%2").arg(m_categoryId).arg(index.row()); |
2429 | case RoleArt: |
2430 | |
2431 | === modified file 'tests/mocks/Unity/fake_scope.cpp' |
2432 | --- tests/mocks/Unity/fake_scope.cpp 2014-08-06 10:03:55 +0000 |
2433 | +++ tests/mocks/Unity/fake_scope.cpp 2014-08-08 14:57:17 +0000 |
2434 | @@ -18,14 +18,16 @@ |
2435 | #include <QUrl> |
2436 | |
2437 | #include "fake_scope.h" |
2438 | + |
2439 | #include "fake_navigation.h" |
2440 | #include "fake_resultsmodel.h" |
2441 | +#include "fake_scopes.h" |
2442 | |
2443 | -Scope::Scope(QObject* parent) : Scope(QString(), QString(), false, parent) |
2444 | +Scope::Scope(Scopes* parent) : Scope(QString(), QString(), false, parent) |
2445 | { |
2446 | } |
2447 | |
2448 | -Scope::Scope(QString const& id, QString const& name, bool favorite, QObject* parent, int categories) |
2449 | +Scope::Scope(QString const& id, QString const& name, bool favorite, Scopes* parent, int categories) |
2450 | : unity::shell::scopes::ScopeInterface(parent) |
2451 | , m_id(id) |
2452 | , m_name(name) |
2453 | @@ -36,6 +38,7 @@ |
2454 | , m_currentAltNavigationId("altroot") |
2455 | , m_previewRendererName("preview-generic") |
2456 | , m_categories(new Categories(categories, this)) |
2457 | + , m_openScope(nullptr) |
2458 | { |
2459 | } |
2460 | |
2461 | @@ -158,7 +161,12 @@ |
2462 | |
2463 | void Scope::activate(QVariant const& result) |
2464 | { |
2465 | - Q_UNUSED(result); |
2466 | + qDebug() << "Called activate on scope" << m_id << "with result" << result; |
2467 | + if (result.toString() == "Result.2.2") { |
2468 | + Scopes *scopes = dynamic_cast<Scopes*>(parent()); |
2469 | + m_openScope = scopes->getScopeFromAll("MockScope9"); |
2470 | + Q_EMIT openScope(m_openScope); |
2471 | + } |
2472 | } |
2473 | |
2474 | PreviewStack* Scope::preview(QVariant const& result) |
2475 | @@ -174,9 +182,13 @@ |
2476 | { |
2477 | } |
2478 | |
2479 | -void Scope::closeScope(unity::shell::scopes::ScopeInterface* /*scope*/) |
2480 | +void Scope::closeScope(unity::shell::scopes::ScopeInterface* scope) |
2481 | { |
2482 | - qFatal("Scope::closeScope is not implemented"); |
2483 | + if (scope != m_openScope) { |
2484 | + qDebug() << scope << m_openScope; |
2485 | + qFatal("Scope::closeScope got wrong scope in closeScope"); |
2486 | + } |
2487 | + m_openScope = nullptr; |
2488 | } |
2489 | |
2490 | QString Scope::currentNavigationId() const |
2491 | |
2492 | === modified file 'tests/mocks/Unity/fake_scope.h' |
2493 | --- tests/mocks/Unity/fake_scope.h 2014-08-06 10:03:55 +0000 |
2494 | +++ tests/mocks/Unity/fake_scope.h 2014-08-08 14:57:17 +0000 |
2495 | @@ -24,13 +24,15 @@ |
2496 | |
2497 | #include <QTimer> |
2498 | |
2499 | +class Scopes; |
2500 | + |
2501 | class Scope : public unity::shell::scopes::ScopeInterface |
2502 | { |
2503 | Q_OBJECT |
2504 | |
2505 | public: |
2506 | - Scope(QObject* parent = 0); |
2507 | - Scope(QString const& id, QString const& name, bool favorite, QObject* parent = 0, int categories = 20); |
2508 | + Scope(Scopes* parent = 0); |
2509 | + Scope(QString const& id, QString const& name, bool favorite, Scopes* parent = 0, int categories = 20); |
2510 | |
2511 | /* getters */ |
2512 | QString id() const override; |
2513 | @@ -92,7 +94,8 @@ |
2514 | |
2515 | QString m_previewRendererName; |
2516 | |
2517 | - Categories* m_categories; |
2518 | + unity::shell::scopes::CategoriesInterface* m_categories; |
2519 | + unity::shell::scopes::ScopeInterface* m_openScope; |
2520 | }; |
2521 | |
2522 | #endif // FAKE_SCOPE_H |
2523 | |
2524 | === modified file 'tests/mocks/Unity/fake_scopes.cpp' |
2525 | --- tests/mocks/Unity/fake_scopes.cpp 2014-08-06 19:38:57 +0000 |
2526 | +++ tests/mocks/Unity/fake_scopes.cpp 2014-08-08 14:57:17 +0000 |
2527 | @@ -18,6 +18,7 @@ |
2528 | |
2529 | // Self |
2530 | #include "fake_scopes.h" |
2531 | +#include "fake_scopesoverview.h" |
2532 | |
2533 | // TODO: Implement remaining pieces, like Categories (i.e. LensView now gives warnings) |
2534 | |
2535 | @@ -26,6 +27,7 @@ |
2536 | |
2537 | Scopes::Scopes(QObject *parent) |
2538 | : unity::shell::scopes::ScopesInterface(parent) |
2539 | + , m_scopesOverview(nullptr) |
2540 | , m_loaded(false) |
2541 | , timer(this) |
2542 | { |
2543 | @@ -52,10 +54,17 @@ |
2544 | addScope(new Scope("clickscope", "Apps", true, this)); |
2545 | addScope(new Scope("MockScope5", "Videos", true, this)); |
2546 | addScope(new Scope("SingleCategoryScope", "Single", true, this, 1)); |
2547 | + addScope(new Scope("MockScope4", "MS4", true, this)); |
2548 | + addScope(new Scope("MockScope6", "MS6", true, this)); |
2549 | + addScope(new Scope("MockScope7", "MS7", false, this)); |
2550 | + addScope(new Scope("MockScope8", "MS8", false, this)); |
2551 | + addScope(new Scope("MockScope9", "MS9", false, this)); |
2552 | + m_scopesOverview = new ScopesOverview(this); |
2553 | |
2554 | if (!m_loaded) { |
2555 | m_loaded = true; |
2556 | Q_EMIT loadedChanged(); |
2557 | + Q_EMIT overviewScopeChanged(); |
2558 | } |
2559 | } |
2560 | |
2561 | @@ -64,10 +73,13 @@ |
2562 | timer.stop(); |
2563 | if (m_scopes.size() > 0) { |
2564 | beginRemoveRows(QModelIndex(), 0, m_scopes.count()-1); |
2565 | - qDeleteAll(m_scopes); |
2566 | + qDeleteAll(m_allScopes); |
2567 | + m_allScopes.clear(); |
2568 | m_scopes.clear(); |
2569 | endRemoveRows(); |
2570 | } |
2571 | + delete m_scopesOverview; |
2572 | + m_scopesOverview = nullptr; |
2573 | |
2574 | if (m_loaded) { |
2575 | m_loaded = false; |
2576 | @@ -113,8 +125,22 @@ |
2577 | return m_scopes[row]; |
2578 | } |
2579 | |
2580 | -unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const&) const |
2581 | -{ |
2582 | +unity::shell::scopes::ScopeInterface* Scopes::getScope(QString const &scope_id) const |
2583 | +{ |
2584 | + // According to mh3 Scopes::getScope should only return favorite scopes (i.e the ones in the model) |
2585 | + for (Scope *scope : m_scopes) { |
2586 | + if (scope->id() == scope_id) |
2587 | + return scope; |
2588 | + } |
2589 | + return nullptr; |
2590 | +} |
2591 | + |
2592 | +Scope* Scopes::getScopeFromAll(const QString& scope_id) const |
2593 | +{ |
2594 | + for (Scope *scope : m_allScopes) { |
2595 | + if (scope->id() == scope_id) |
2596 | + return scope; |
2597 | + } |
2598 | return nullptr; |
2599 | } |
2600 | |
2601 | @@ -135,13 +161,26 @@ |
2602 | |
2603 | unity::shell::scopes::ScopeInterface* Scopes::overviewScope() const |
2604 | { |
2605 | - return nullptr; |
2606 | + return m_scopesOverview; |
2607 | +} |
2608 | + |
2609 | +QList<Scope*> Scopes::scopes() const |
2610 | +{ |
2611 | + return m_scopes; |
2612 | +} |
2613 | + |
2614 | +QList<Scope*> Scopes::allScopes() const |
2615 | +{ |
2616 | + return m_allScopes; |
2617 | } |
2618 | |
2619 | void Scopes::addScope(Scope* scope) |
2620 | { |
2621 | int index = rowCount(); |
2622 | - beginInsertRows(QModelIndex(), index, index); |
2623 | - m_scopes.append(scope); |
2624 | - endInsertRows(); |
2625 | + if (scope->favorite()) { |
2626 | + beginInsertRows(QModelIndex(), index, index); |
2627 | + m_scopes.append(scope); |
2628 | + endInsertRows(); |
2629 | + } |
2630 | + m_allScopes.append(scope); |
2631 | } |
2632 | |
2633 | === modified file 'tests/mocks/Unity/fake_scopes.h' |
2634 | --- tests/mocks/Unity/fake_scopes.h 2014-08-06 19:38:57 +0000 |
2635 | +++ tests/mocks/Unity/fake_scopes.h 2014-08-08 14:57:17 +0000 |
2636 | @@ -53,11 +53,18 @@ |
2637 | int count() const override; |
2638 | unity::shell::scopes::ScopeInterface* overviewScope() const override; |
2639 | |
2640 | + // This is used as part of implementation of the other C++ code, not API |
2641 | + QList<Scope*> scopes() const; |
2642 | + QList<Scope*> allScopes() const; |
2643 | + Scope* getScopeFromAll(const QString& scope_id) const; |
2644 | + |
2645 | private Q_SLOTS: |
2646 | void updateScopes(); |
2647 | |
2648 | private: |
2649 | - QList<Scope*> m_scopes; |
2650 | + QList<Scope*> m_scopes; // the favorite ones |
2651 | + QList<Scope*> m_allScopes; |
2652 | + Scope *m_scopesOverview; |
2653 | bool m_loaded; |
2654 | QTimer timer; |
2655 | }; |
2656 | |
2657 | === added file 'tests/mocks/Unity/fake_scopesoverview.cpp' |
2658 | --- tests/mocks/Unity/fake_scopesoverview.cpp 1970-01-01 00:00:00 +0000 |
2659 | +++ tests/mocks/Unity/fake_scopesoverview.cpp 2014-08-08 14:57:17 +0000 |
2660 | @@ -0,0 +1,281 @@ |
2661 | +/* |
2662 | + * Copyright (C) 2014 Canonical, Ltd. |
2663 | + * |
2664 | + * This program is free software; you can redistribute it and/or modify |
2665 | + * it under the terms of the GNU General Public License as published by |
2666 | + * the Free Software Foundation; version 3. |
2667 | + * |
2668 | + * This program is distributed in the hope that it will be useful, |
2669 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2670 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2671 | + * GNU General Public License for more details. |
2672 | + * |
2673 | + * You should have received a copy of the GNU General Public License |
2674 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2675 | + */ |
2676 | + |
2677 | +#include "fake_scopesoverview.h" |
2678 | + |
2679 | +#include "fake_scopes.h" |
2680 | + |
2681 | +#include <paths.h> |
2682 | + |
2683 | +ScopesOverview::ScopesOverview(Scopes* parent) |
2684 | + : Scope("scopesOverview", "Scopes Overview", false, parent) |
2685 | +{ |
2686 | + delete m_categories; // delete the usual categories, we're not going to use it |
2687 | + m_scopesOverviewCategories = new ScopesOverviewCategories(parent, this); |
2688 | + m_searchCategories = new ScopesOverviewSearchCategories(parent, this); |
2689 | + m_categories = m_scopesOverviewCategories; |
2690 | +} |
2691 | + |
2692 | +void ScopesOverview::setSearchQuery(const QString& search_query) |
2693 | +{ |
2694 | + Scope::setSearchQuery(search_query); |
2695 | + |
2696 | + auto origCategories = m_categories; |
2697 | + if (search_query.isEmpty()) m_categories = m_scopesOverviewCategories; |
2698 | + else m_categories = m_searchCategories; |
2699 | + |
2700 | + if (m_categories != origCategories) |
2701 | + Q_EMIT categoriesChanged(); |
2702 | +} |
2703 | + |
2704 | +Q_INVOKABLE void ScopesOverview::activate(QVariant const& result) |
2705 | +{ |
2706 | + Scopes *scopes = dynamic_cast<Scopes*>(parent()); |
2707 | + m_openScope = scopes->getScopeFromAll(result.toString()); |
2708 | + Q_EMIT openScope(m_openScope); |
2709 | +} |
2710 | + |
2711 | +ScopesOverviewCategories::ScopesOverviewCategories(Scopes *scopes, QObject* parent) |
2712 | + : unity::shell::scopes::CategoriesInterface(parent) |
2713 | + , m_scopes(scopes) |
2714 | +{ |
2715 | +} |
2716 | + |
2717 | +int ScopesOverviewCategories::rowCount(const QModelIndex& /*parent*/) const |
2718 | +{ |
2719 | + return 2; |
2720 | +} |
2721 | + |
2722 | +void ScopesOverviewCategories::addSpecialCategory(QString const&, QString const&, QString const&, QString const&, QObject*) |
2723 | +{ |
2724 | + qFatal("Using un-implemented ScopesOverviewCategories::addSpecialCategory"); |
2725 | +} |
2726 | + |
2727 | +bool ScopesOverviewCategories::overrideCategoryJson(QString const& /* categoryId */, QString const& /* json */) |
2728 | +{ |
2729 | + qFatal("Using un-implemented ScopesOverviewCategories::overrideCategoryJson"); |
2730 | +} |
2731 | + |
2732 | +QVariant |
2733 | +ScopesOverviewCategories::data(const QModelIndex& index, int role) const |
2734 | +{ |
2735 | + if (!index.isValid()) { |
2736 | + return QVariant(); |
2737 | + } |
2738 | + |
2739 | + const QString categoryId = index.row() == 0 ? "favorites" : "all"; |
2740 | + |
2741 | + unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()]; |
2742 | + if (!resultsModel) { |
2743 | + QObject *that = const_cast<ScopesOverviewCategories*>(this); |
2744 | + QList<Scope*> scopes = index.row() == 0 ? m_scopes->scopes() : m_scopes->allScopes(); |
2745 | + resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that); |
2746 | + m_resultsModels[index.row()] = resultsModel; |
2747 | + } |
2748 | + switch (role) { |
2749 | + case RoleCategoryId: |
2750 | + return categoryId; |
2751 | + case RoleName: |
2752 | + return index.row() == 0 ? "Favorites" : "All"; |
2753 | + case RoleIcon: |
2754 | + return QVariant(); |
2755 | + case RoleRawRendererTemplate: |
2756 | + qFatal("Using un-implemented RoleRawRendererTemplate Categories role"); |
2757 | + return QVariant(); |
2758 | + case RoleRenderer: |
2759 | + { |
2760 | + QVariantMap map; |
2761 | + map["category-layout"] = "grid"; |
2762 | + map["card-size"] = "small"; |
2763 | + map["overlay"] = true; |
2764 | + return map; |
2765 | + } |
2766 | + case RoleComponents: |
2767 | + { |
2768 | + QVariantMap map, artMap; |
2769 | + artMap["aspect-ratio"] = "0.5"; |
2770 | + artMap["field"] = "art"; |
2771 | + map["art"] = artMap; |
2772 | + map["title"] = "HOLA"; |
2773 | + return map; |
2774 | + } |
2775 | + case RoleResults: |
2776 | + return QVariant::fromValue(resultsModel); |
2777 | + case RoleCount: |
2778 | + return resultsModel->rowCount(); |
2779 | + case RoleHeaderLink: |
2780 | + return QString(); |
2781 | + default: |
2782 | + qFatal("Using un-implemented Categories role"); |
2783 | + return QVariant(); |
2784 | + } |
2785 | +} |
2786 | + |
2787 | + |
2788 | + |
2789 | +ScopesOverviewSearchCategories::ScopesOverviewSearchCategories(Scopes *scopes, QObject* parent) |
2790 | + : unity::shell::scopes::CategoriesInterface(parent) |
2791 | + , m_scopes(scopes) |
2792 | +{ |
2793 | +} |
2794 | + |
2795 | +int ScopesOverviewSearchCategories::rowCount(const QModelIndex& /*parent*/) const |
2796 | +{ |
2797 | + return 2; |
2798 | +} |
2799 | + |
2800 | +void ScopesOverviewSearchCategories::addSpecialCategory(QString const&, QString const&, QString const&, QString const&, QObject*) |
2801 | +{ |
2802 | + qFatal("Using un-implemented ScopesOverviewSearchCategories::addSpecialCategory"); |
2803 | +} |
2804 | + |
2805 | +bool ScopesOverviewSearchCategories::overrideCategoryJson(QString const& /* categoryId */, QString const& /* json */) |
2806 | +{ |
2807 | + qFatal("Using un-implemented ScopesOverviewSearchCategories::overrideCategoryJson"); |
2808 | +} |
2809 | + |
2810 | +QVariant |
2811 | +ScopesOverviewSearchCategories::data(const QModelIndex& index, int role) const |
2812 | +{ |
2813 | + if (!index.isValid()) { |
2814 | + return QVariant(); |
2815 | + } |
2816 | + |
2817 | + const QString categoryId = index.row() == 0 ? "searchA" : "searchB"; |
2818 | + |
2819 | + unity::shell::scopes::ResultsModelInterface *resultsModel = m_resultsModels[index.row()]; |
2820 | + if (!resultsModel) { |
2821 | + QObject *that = const_cast<ScopesOverviewSearchCategories*>(this); |
2822 | + QList<Scope *> scopes; |
2823 | + if (index.row() == 0) { |
2824 | + scopes << m_scopes->getScopeFromAll("clickscope") << nullptr << m_scopes->getScopeFromAll("MockScope2"); |
2825 | + } else { |
2826 | + scopes << nullptr << m_scopes->getScopeFromAll("MockScope7") << nullptr << m_scopes->getScopeFromAll("MockScope1"); |
2827 | + } |
2828 | + resultsModel = new ScopesOverviewResultsModel(scopes, categoryId, that); |
2829 | + m_resultsModels[index.row()] = resultsModel; |
2830 | + } |
2831 | + switch (role) { |
2832 | + case RoleCategoryId: |
2833 | + return categoryId; |
2834 | + case RoleName: |
2835 | + return index.row() == 0 ? "SearchA" : "SearchB"; |
2836 | + case RoleIcon: |
2837 | + return QVariant(); |
2838 | + case RoleRawRendererTemplate: |
2839 | + qFatal("Using un-implemented RoleRawRendererTemplate Categories role"); |
2840 | + return QVariant(); |
2841 | + case RoleRenderer: |
2842 | + { |
2843 | + QVariantMap map; |
2844 | + map["category-layout"] = "grid"; |
2845 | + map["card-size"] = "small"; |
2846 | + map["overlay"] = true; |
2847 | + return map; |
2848 | + } |
2849 | + case RoleComponents: |
2850 | + { |
2851 | + QVariantMap map, artMap; |
2852 | + artMap["aspect-ratio"] = "1"; |
2853 | + artMap["field"] = "art"; |
2854 | + map["art"] = artMap; |
2855 | + map["title"] = "HOLA"; |
2856 | + return map; |
2857 | + } |
2858 | + case RoleResults: |
2859 | + return QVariant::fromValue(resultsModel); |
2860 | + case RoleCount: |
2861 | + return resultsModel->rowCount(); |
2862 | + case RoleHeaderLink: |
2863 | + return QString(); |
2864 | + default: |
2865 | + qFatal("Using un-implemented Categories role"); |
2866 | + return QVariant(); |
2867 | + } |
2868 | +} |
2869 | + |
2870 | + |
2871 | +ScopesOverviewResultsModel::ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent) |
2872 | + : unity::shell::scopes::ResultsModelInterface(parent) |
2873 | + , m_scopes(scopes) |
2874 | + , m_categoryId(categoryId) |
2875 | +{ |
2876 | +} |
2877 | + |
2878 | +QString ScopesOverviewResultsModel::categoryId() const |
2879 | +{ |
2880 | + return m_categoryId; |
2881 | +} |
2882 | + |
2883 | +void ScopesOverviewResultsModel::setCategoryId(QString const& /*id*/) |
2884 | +{ |
2885 | + qFatal("Calling un-implemented ScopesOverviewResultsModel::setCategoryId"); |
2886 | +} |
2887 | + |
2888 | +int ScopesOverviewResultsModel::scopeIndex(QString const& id) const |
2889 | +{ |
2890 | + const int scopeCount = count(); |
2891 | + for (int i = 0; i < scopeCount; ++i) { |
2892 | + if (m_scopes[i]->id() == id) |
2893 | + return i; |
2894 | + } |
2895 | + return -1; |
2896 | +} |
2897 | + |
2898 | +QHash<int, QByteArray> ScopesOverviewResultsModel::roleNames() const |
2899 | +{ |
2900 | + QHash<int, QByteArray> roles = unity::shell::scopes::ResultsModelInterface::roleNames(); |
2901 | + roles[RoleBackground + 1] = "scopeId"; |
2902 | + return roles; |
2903 | +} |
2904 | + |
2905 | +int ScopesOverviewResultsModel::rowCount(const QModelIndex& parent) const |
2906 | +{ |
2907 | + Q_UNUSED(parent); |
2908 | + |
2909 | + return m_scopes.count(); |
2910 | +} |
2911 | + |
2912 | +int ScopesOverviewResultsModel::count() const |
2913 | +{ |
2914 | + return rowCount(); |
2915 | +} |
2916 | + |
2917 | +QVariant |
2918 | +ScopesOverviewResultsModel::data(const QModelIndex& index, int role) const |
2919 | +{ |
2920 | + unity::shell::scopes::ScopeInterface *scope = m_scopes[index.row()]; |
2921 | + switch (role) { |
2922 | + case RoleUri: |
2923 | + case RoleCategoryId: |
2924 | + case RoleDndUri: |
2925 | + return QString(); |
2926 | + case RoleResult: |
2927 | + return scope ? scope->id() : QString("Result.%1.%2").arg(categoryId()).arg(index.row()); |
2928 | + case RoleTitle: |
2929 | + return scope ? scope->name() : QString("Title.%1.%2").arg(categoryId()).arg(index.row()); |
2930 | + case RoleArt: |
2931 | + return qmlDirectory() + "graphics/applicationIcons/dash.png"; |
2932 | + case RoleMascot: |
2933 | + case RoleEmblem: |
2934 | + case RoleSummary: |
2935 | + case RoleBackground + 1: // scopeId |
2936 | + return scope ? scope->id() : nullptr; |
2937 | + break; |
2938 | + default: |
2939 | + return QVariant(); |
2940 | + } |
2941 | +} |
2942 | |
2943 | === added file 'tests/mocks/Unity/fake_scopesoverview.h' |
2944 | --- tests/mocks/Unity/fake_scopesoverview.h 1970-01-01 00:00:00 +0000 |
2945 | +++ tests/mocks/Unity/fake_scopesoverview.h 2014-08-08 14:57:17 +0000 |
2946 | @@ -0,0 +1,104 @@ |
2947 | +/* |
2948 | + * Copyright (C) 2014 Canonical, Ltd. |
2949 | + * |
2950 | + * This program is free software; you can redistribute it and/or modify |
2951 | + * it under the terms of the GNU General Public License as published by |
2952 | + * the Free Software Foundation; version 3. |
2953 | + * |
2954 | + * This program is distributed in the hope that it will be useful, |
2955 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2956 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2957 | + * GNU General Public License for more details. |
2958 | + * |
2959 | + * You should have received a copy of the GNU General Public License |
2960 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2961 | + */ |
2962 | + |
2963 | +#ifndef FAKE_SCOPESOVERVIEW_H |
2964 | +#define FAKE_SCOPESOVERVIEW_H |
2965 | + |
2966 | +#include "fake_scope.h" |
2967 | +#include <unity/shell/scopes/ResultsModelInterface.h> |
2968 | + |
2969 | +class Scopes; |
2970 | + |
2971 | +class ScopesOverview : public Scope |
2972 | +{ |
2973 | + Q_OBJECT |
2974 | + |
2975 | +public: |
2976 | + ScopesOverview(Scopes* parent = 0); |
2977 | + |
2978 | + void setSearchQuery(const QString& search_query) override; |
2979 | + Q_INVOKABLE void activate(QVariant const& result) override; |
2980 | + |
2981 | +private: |
2982 | + unity::shell::scopes::CategoriesInterface *m_scopesOverviewCategories; |
2983 | + unity::shell::scopes::CategoriesInterface *m_searchCategories; |
2984 | +}; |
2985 | + |
2986 | +class ScopesOverviewCategories : public unity::shell::scopes::CategoriesInterface |
2987 | +{ |
2988 | + Q_OBJECT |
2989 | + |
2990 | +public: |
2991 | + ScopesOverviewCategories(Scopes *scopes, QObject* parent = 0); |
2992 | + |
2993 | + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
2994 | + int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
2995 | + |
2996 | + Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override; |
2997 | + Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; |
2998 | + |
2999 | +private: |
3000 | + mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels; |
3001 | + |
3002 | + Scopes *m_scopes; |
3003 | +}; |
3004 | + |
3005 | +class ScopesOverviewSearchCategories : public unity::shell::scopes::CategoriesInterface |
3006 | +{ |
3007 | + Q_OBJECT |
3008 | + |
3009 | +public: |
3010 | + ScopesOverviewSearchCategories(Scopes *scopes, QObject* parent = 0); |
3011 | + |
3012 | + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
3013 | + int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
3014 | + |
3015 | + Q_INVOKABLE void addSpecialCategory(QString const& categoryId, QString const& name, QString const& icon, QString const& rawTemplate, QObject* countObject) override; |
3016 | + Q_INVOKABLE bool overrideCategoryJson(QString const& categoryId, QString const& json) override; |
3017 | + |
3018 | +private: |
3019 | + mutable QHash<int, unity::shell::scopes::ResultsModelInterface*> m_resultsModels; |
3020 | + |
3021 | + Scopes *m_scopes; |
3022 | +}; |
3023 | + |
3024 | +class ScopesOverviewResultsModel : public unity::shell::scopes::ResultsModelInterface |
3025 | +{ |
3026 | + Q_OBJECT |
3027 | + |
3028 | +public: |
3029 | + explicit ScopesOverviewResultsModel(const QList<Scope *> &scopes, const QString &categoryId, QObject* parent = 0); |
3030 | + |
3031 | + int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
3032 | + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
3033 | + |
3034 | + /* getters */ |
3035 | + QString categoryId() const override; |
3036 | + int count() const override; |
3037 | + |
3038 | + /* setters */ |
3039 | + void setCategoryId(QString const& id) override; |
3040 | + |
3041 | + /* Special API */ |
3042 | + Q_INVOKABLE int scopeIndex(QString const& id) const; |
3043 | + QHash<int, QByteArray> roleNames() const override; |
3044 | + |
3045 | +private: |
3046 | + QList<Scope *> m_scopes; |
3047 | + QString m_categoryId; |
3048 | +}; |
3049 | + |
3050 | +#endif // FAKE_SCOPESOVERVIEW_H |
3051 | |
3052 | === modified file 'tests/plugins/Dash/cardcreator/1.res' |
3053 | --- tests/plugins/Dash/cardcreator/1.res 2014-08-05 22:51:17 +0000 |
3054 | +++ tests/plugins/Dash/cardcreator/1.res 2014-08-08 14:57:17 +0000 |
3055 | @@ -61,12 +61,12 @@ |
3056 | id: titleLabel; |
3057 | objectName: "titleLabel"; |
3058 | anchors { right: parent.right; |
3059 | -rightMargin: units.gu(1); |
3060 | -left: parent.left; |
3061 | -top: artShapeHolder.bottom; |
3062 | - topMargin: units.gu(1); |
3063 | -leftMargin: units.gu(1); |
3064 | - } |
3065 | + rightMargin: units.gu(1); |
3066 | + left: parent.left; |
3067 | + top: artShapeHolder.bottom; |
3068 | + topMargin: units.gu(1); |
3069 | + leftMargin: units.gu(1); |
3070 | + } |
3071 | elide: Text.ElideRight; |
3072 | fontSize: "small"; |
3073 | wrapMode: Text.Wrap; |
3074 | |
3075 | === modified file 'tests/plugins/Dash/cardcreator/1.tst' |
3076 | --- tests/plugins/Dash/cardcreator/1.tst 2014-07-28 15:09:45 +0000 |
3077 | +++ tests/plugins/Dash/cardcreator/1.tst 2014-08-08 14:57:17 +0000 |
3078 | @@ -1,3 +1,3 @@ |
3079 | template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2} |
3080 | -components: {"art":{"aspect-ratio":1.6,"field":"art"},"title":{"field":"title"}} |
3081 | +components: {"art":{"aspect-ratio":1.6,"field":"art"},"title":{"field":"title"},"attributes":{}} |
3082 | result: 1.res |
3083 | |
3084 | === modified file 'tests/plugins/Dash/cardcreator/2.res' |
3085 | --- tests/plugins/Dash/cardcreator/2.res 2014-07-31 13:33:56 +0000 |
3086 | +++ tests/plugins/Dash/cardcreator/2.res 2014-08-08 14:57:17 +0000 |
3087 | @@ -55,17 +55,19 @@ |
3088 | spacing: margins; |
3089 | height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; |
3090 | anchors { top: parent.top; |
3091 | - topMargin: units.gu(1); |
3092 | -left: parent.left; |
3093 | - } |
3094 | + topMargin: units.gu(1); |
3095 | + left: parent.left; |
3096 | + } |
3097 | anchors.right: parent.right; |
3098 | anchors.margins: margins; |
3099 | - data: [ Image { |
3100 | + anchors.rightMargin: 0; |
3101 | + data: [ |
3102 | +Image { |
3103 | id: mascotImage; |
3104 | objectName: "mascotImage"; |
3105 | anchors { verticalCenter: parent.verticalCenter; } |
3106 | readonly property int maxSize: Math.max(width, height) * 4; |
3107 | - source: cardData && cardData["mascot"]; |
3108 | + source: cardData && cardData["mascot"] || ""; |
3109 | width: units.gu(6); |
3110 | height: units.gu(5.625); |
3111 | sourceSize { width: maxSize; height: maxSize } |
3112 | @@ -74,37 +76,43 @@ |
3113 | verticalAlignment: Image.AlignVCenter; |
3114 | visible: showHeader; |
3115 | } |
3116 | - |
3117 | - , |
3118 | - Column { |
3119 | - anchors.verticalCenter: parent.verticalCenter; |
3120 | - spacing: units.dp(2); |
3121 | - width: parent.width - x; |
3122 | - data: [ Label { |
3123 | +,Item { |
3124 | + id: headerTitleContainer; |
3125 | + anchors { verticalCenter: parent.verticalCenter; } |
3126 | + width: parent.width - x; |
3127 | + implicitHeight: titleLabel.height + subtitleLabel.height; |
3128 | + data: [ |
3129 | + Label { |
3130 | id: titleLabel; |
3131 | objectName: "titleLabel"; |
3132 | - anchors { left: parent.left; right: parent.right } |
3133 | + anchors { right: parent.right; |
3134 | + rightMargin: units.gu(1); |
3135 | + left: parent.left; |
3136 | + top: parent.top; } |
3137 | elide: Text.ElideRight; |
3138 | fontSize: "small"; |
3139 | wrapMode: Text.Wrap; |
3140 | maximumLineCount: 2; |
3141 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3142 | - color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey"); |
3143 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3144 | visible: showHeader ; |
3145 | text: root.title; |
3146 | font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; |
3147 | horizontalAlignment: root.headerAlignment; |
3148 | } |
3149 | - |
3150 | - , |
3151 | - Label { |
3152 | + ,Label { |
3153 | id: subtitleLabel; |
3154 | objectName: "subtitleLabel"; |
3155 | - anchors { left: parent.left; right: parent.right } |
3156 | + anchors { right: parent.right; |
3157 | + left: parent.left; |
3158 | + rightMargin: units.gu(1); |
3159 | + top: titleLabel.bottom; |
3160 | + } |
3161 | + anchors.topMargin: units.dp(2); |
3162 | elide: Text.ElideRight; |
3163 | fontSize: "small"; |
3164 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3165 | - color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey"); |
3166 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3167 | visible: titleLabel.visible && titleLabel.text; |
3168 | text: cardData && cardData["subtitle"] || ""; |
3169 | font.weight: Font.Light; |
3170 | |
3171 | === modified file 'tests/plugins/Dash/cardcreator/2.tst' |
3172 | --- tests/plugins/Dash/cardcreator/2.tst 2014-07-28 15:09:45 +0000 |
3173 | +++ tests/plugins/Dash/cardcreator/2.tst 2014-08-08 14:57:17 +0000 |
3174 | @@ -1,3 +1,3 @@ |
3175 | template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2} |
3176 | -components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"}} |
3177 | +components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{}} |
3178 | result: 2.res |
3179 | |
3180 | === modified file 'tests/plugins/Dash/cardcreator/3.res' |
3181 | --- tests/plugins/Dash/cardcreator/3.res 2014-08-05 22:51:17 +0000 |
3182 | +++ tests/plugins/Dash/cardcreator/3.res 2014-08-08 14:57:17 +0000 |
3183 | @@ -61,12 +61,12 @@ |
3184 | id: titleLabel; |
3185 | objectName: "titleLabel"; |
3186 | anchors { right: parent.right; |
3187 | -rightMargin: units.gu(1); |
3188 | -left: parent.left; |
3189 | -top: artShapeHolder.bottom; |
3190 | - topMargin: units.gu(1); |
3191 | -leftMargin: units.gu(1); |
3192 | - } |
3193 | + rightMargin: units.gu(1); |
3194 | + left: parent.left; |
3195 | + top: artShapeHolder.bottom; |
3196 | + topMargin: units.gu(1); |
3197 | + leftMargin: units.gu(1); |
3198 | + } |
3199 | elide: Text.ElideRight; |
3200 | fontSize: "small"; |
3201 | wrapMode: Text.Wrap; |
3202 | @@ -82,12 +82,12 @@ |
3203 | id: subtitleLabel; |
3204 | objectName: "subtitleLabel"; |
3205 | anchors { left: titleLabel.left; |
3206 | - leftMargin: titleLabel.leftMargin; |
3207 | - right: titleLabel.right; |
3208 | - rightMargin: titleLabel.rightMargin; |
3209 | - top: titleLabel.bottom; |
3210 | - topMargin: units.dp(2); |
3211 | - } |
3212 | + leftMargin: titleLabel.leftMargin; |
3213 | + rightMargin: units.gu(1); |
3214 | + right: titleLabel.right; |
3215 | + top: titleLabel.bottom; |
3216 | + } |
3217 | + anchors.topMargin: units.dp(2); |
3218 | elide: Text.ElideRight; |
3219 | fontSize: "small"; |
3220 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3221 | |
3222 | === modified file 'tests/plugins/Dash/cardcreator/3.tst' |
3223 | --- tests/plugins/Dash/cardcreator/3.tst 2014-07-28 15:09:45 +0000 |
3224 | +++ tests/plugins/Dash/cardcreator/3.tst 2014-08-08 14:57:17 +0000 |
3225 | @@ -1,3 +1,3 @@ |
3226 | template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2} |
3227 | -components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"}} |
3228 | +components: {"art":{"aspect-ratio":0.75,"field":"art"},"subtitle":{"field":"price"},"title":{"field":"title"},"attributes":{}} |
3229 | result: 3.res |
3230 | |
3231 | === modified file 'tests/plugins/Dash/cardcreator/4.res' |
3232 | --- tests/plugins/Dash/cardcreator/4.res 2014-07-25 13:41:19 +0000 |
3233 | +++ tests/plugins/Dash/cardcreator/4.res 2014-08-08 14:57:17 +0000 |
3234 | @@ -27,7 +27,9 @@ |
3235 | } |
3236 | anchors.right: parent.right; |
3237 | anchors.margins: margins; |
3238 | -data: [ Loader { |
3239 | + anchors.rightMargin: 0; |
3240 | +data: [ |
3241 | +Loader { |
3242 | id: mascotShapeLoader; |
3243 | objectName: "mascotShapeLoader"; |
3244 | asynchronous: root.asynchronous; |
3245 | @@ -39,13 +41,12 @@ |
3246 | anchors { verticalCenter: parent.verticalCenter; } |
3247 | } |
3248 | |
3249 | -, |
3250 | -Image { |
3251 | +,Image { |
3252 | id: mascotImage; |
3253 | objectName: "mascotImage"; |
3254 | anchors { verticalCenter: parent.verticalCenter; } |
3255 | readonly property int maxSize: Math.max(width, height) * 4; |
3256 | - source: cardData && cardData["mascot"]; |
3257 | + source: cardData && cardData["mascot"] || ""; |
3258 | width: units.gu(6); |
3259 | height: units.gu(5.625); |
3260 | sourceSize { width: maxSize; height: maxSize } |
3261 | @@ -55,15 +56,19 @@ |
3262 | visible: false; |
3263 | } |
3264 | |
3265 | -, |
3266 | -Column { |
3267 | - anchors.verticalCenter: parent.verticalCenter; |
3268 | - spacing: units.dp(2); |
3269 | - width: parent.width - x; |
3270 | -data: [ Label { |
3271 | +,Item { |
3272 | + id: headerTitleContainer; |
3273 | + anchors { verticalCenter: parent.verticalCenter; } |
3274 | + width: parent.width - x; |
3275 | + implicitHeight: titleLabel.height + subtitleLabel.height; |
3276 | + data: [ |
3277 | +Label { |
3278 | id: titleLabel; |
3279 | objectName: "titleLabel"; |
3280 | - anchors { left: parent.left; right: parent.right } |
3281 | + anchors { right: parent.right; |
3282 | + rightMargin: units.gu(1); |
3283 | + left: parent.left; |
3284 | + top: parent.top; } |
3285 | elide: Text.ElideRight; |
3286 | fontSize: "small"; |
3287 | wrapMode: Text.Wrap; |
3288 | @@ -75,12 +80,15 @@ |
3289 | font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; |
3290 | horizontalAlignment: root.headerAlignment; |
3291 | } |
3292 | -, |
3293 | -Label { |
3294 | +,Label { |
3295 | id: subtitleLabel; |
3296 | objectName: "subtitleLabel"; |
3297 | - anchors { left: parent.left; right: parent.right } |
3298 | - |
3299 | + anchors { right: parent.right; |
3300 | + left: parent.left; |
3301 | + rightMargin: units.gu(1); |
3302 | + top: titleLabel.bottom; |
3303 | + } |
3304 | + anchors.topMargin: units.dp(2); |
3305 | elide: Text.ElideRight; |
3306 | fontSize: "small"; |
3307 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3308 | |
3309 | === modified file 'tests/plugins/Dash/cardcreator/4.tst' |
3310 | --- tests/plugins/Dash/cardcreator/4.tst 2014-07-28 15:09:45 +0000 |
3311 | +++ tests/plugins/Dash/cardcreator/4.tst 2014-08-08 14:57:17 +0000 |
3312 | @@ -1,3 +1,3 @@ |
3313 | template: {"card-layout":"horizontal","card-size":"large","category-layout":"grid","collapsed-rows":2} |
3314 | -components: {"art":{"aspect-ratio":1},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"}} |
3315 | +components: {"art":{"aspect-ratio":1},"mascot":{"field":"mascot"},"subtitle":{"field":"domain"},"title":{"field":"title"},"attributes":{}} |
3316 | result: 4.res |
3317 | |
3318 | === modified file 'tests/plugins/Dash/cardcreator/5.res' |
3319 | --- tests/plugins/Dash/cardcreator/5.res 2014-08-05 22:51:17 +0000 |
3320 | +++ tests/plugins/Dash/cardcreator/5.res 2014-08-08 14:57:17 +0000 |
3321 | @@ -68,8 +68,9 @@ |
3322 | visible: showHeader && status == Loader.Ready; |
3323 | sourceComponent: ShaderEffect { |
3324 | id: overlay; |
3325 | - height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); |
3326 | - opacity: 0.6; |
3327 | + height: (fixedHeaderHeight > 0 ? fixedHeaderHeight : headerHeight) + units.gu(2); |
3328 | + property real luminance: 0.2126 * overlayColor.r + 0.7152 * overlayColor.g + 0.0722 * overlayColor.b; |
3329 | + property color overlayColor: cardData && cardData["overlayColor"] || "#99000000"; |
3330 | property var source: ShaderEffectSource { |
3331 | id: shaderSource; |
3332 | sourceItem: artShapeLoader.item; |
3333 | @@ -90,29 +91,30 @@ |
3334 | varying highp vec2 coord; |
3335 | uniform sampler2D source; |
3336 | uniform lowp float qt_Opacity; |
3337 | + uniform highp vec4 overlayColor; |
3338 | void main() { |
3339 | lowp vec4 tex = texture2D(source, coord); |
3340 | - gl_FragColor = vec4(0, 0, 0, tex.a) * qt_Opacity; |
3341 | + gl_FragColor = vec4(overlayColor.r, overlayColor.g, overlayColor.b, 1) * qt_Opacity * overlayColor.a * tex.a; |
3342 | }"; |
3343 | } |
3344 | } |
3345 | readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin; |
3346 | Label { |
3347 | - id: titleLabel; |
3348 | + id: titleLabel; |
3349 | objectName: "titleLabel"; |
3350 | - anchors { left: parent.left; |
3351 | - leftMargin: units.gu(1); |
3352 | - right: parent.right; |
3353 | - rightMargin: units.gu(1); |
3354 | - top: overlayLoader.top; |
3355 | - topMargin: units.gu(1); |
3356 | - } |
3357 | + anchors { right: parent.right; |
3358 | + rightMargin: units.gu(1); |
3359 | + left: parent.left; |
3360 | + leftMargin: units.gu(1); |
3361 | + top: overlayLoader.top; |
3362 | + topMargin: units.gu(1); |
3363 | + } |
3364 | elide: Text.ElideRight; |
3365 | fontSize: "small"; |
3366 | wrapMode: Text.Wrap; |
3367 | maximumLineCount: 2; |
3368 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3369 | - color: "white"; |
3370 | + color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3371 | visible: showHeader && overlayLoader.active; |
3372 | text: root.title; |
3373 | font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; |
3374 | @@ -122,16 +124,16 @@ |
3375 | id: subtitleLabel; |
3376 | objectName: "subtitleLabel"; |
3377 | anchors { left: titleLabel.left; |
3378 | - leftMargin: titleLabel.leftMargin; |
3379 | - right: titleLabel.right; |
3380 | - rightMargin: titleLabel.rightMargin; |
3381 | - top: titleLabel.bottom; |
3382 | - topMargin: units.dp(2); |
3383 | - } |
3384 | + leftMargin: titleLabel.leftMargin; |
3385 | + rightMargin: units.gu(1); |
3386 | + right: titleLabel.right; |
3387 | + top: titleLabel.bottom; |
3388 | + } |
3389 | + anchors.topMargin: units.dp(2); |
3390 | elide: Text.ElideRight; |
3391 | fontSize: "small"; |
3392 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3393 | - color: "white"; |
3394 | + color: overlayLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3395 | visible: titleLabel.visible && titleLabel.text; |
3396 | text: cardData && cardData["subtitle"] || ""; |
3397 | font.weight: Font.Light; |
3398 | |
3399 | === modified file 'tests/plugins/Dash/cardcreator/5.tst' |
3400 | --- tests/plugins/Dash/cardcreator/5.tst 2014-07-28 15:09:45 +0000 |
3401 | +++ tests/plugins/Dash/cardcreator/5.tst 2014-08-08 14:57:17 +0000 |
3402 | @@ -1,3 +1,3 @@ |
3403 | template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true} |
3404 | -components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"}} |
3405 | +components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}} |
3406 | result: 5.res |
3407 | |
3408 | === modified file 'tests/plugins/Dash/cardcreator/6.res' |
3409 | --- tests/plugins/Dash/cardcreator/6.res 2014-08-05 22:51:17 +0000 |
3410 | +++ tests/plugins/Dash/cardcreator/6.res 2014-08-08 14:57:17 +0000 |
3411 | @@ -13,57 +13,110 @@ |
3412 | property bool asynchronous: true; |
3413 | property bool showHeader: true; |
3414 | implicitWidth: childrenRect.width; |
3415 | -onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; } |
3416 | -readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1); |
3417 | -Item { |
3418 | - id: artShapeHolder; |
3419 | - height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; |
3420 | - width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width; |
3421 | - anchors { horizontalCenter: parent.horizontalCenter; } |
3422 | - Loader { |
3423 | - id: artShapeLoader; |
3424 | - objectName: "artShapeLoader"; |
3425 | - active: cardData && cardData["art"] || false; |
3426 | - asynchronous: root.asynchronous; |
3427 | - visible: status == Loader.Ready; |
3428 | - sourceComponent: UbuntuShape { |
3429 | - id: artShape; |
3430 | - objectName: "artShape"; |
3431 | - radius: "medium"; |
3432 | - visible: image.status == Image.Ready; |
3433 | - readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; |
3434 | - readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : components !== undefined ? components["art"]["aspect-ratio"] : 1; |
3435 | - Component.onCompleted: { updateWidthHeightBindings(); if (artShapeBorderSource !== undefined) borderSource = artShapeBorderSource; } |
3436 | - Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } |
3437 | - function updateWidthHeightBindings() { |
3438 | - if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { |
3439 | - width = root.fixedArtShapeSize.width; |
3440 | - height = root.fixedArtShapeSize.height; |
3441 | - } else { |
3442 | - width = Qt.binding(function() { return !visible ? 0 : image.width }); |
3443 | - height = Qt.binding(function() { return !visible ? 0 : image.height }); |
3444 | - } |
3445 | - } |
3446 | - image: Image { |
3447 | - objectName: "artImage"; |
3448 | - source: cardData && cardData["art"] || ""; |
3449 | - cache: true; |
3450 | - asynchronous: root.asynchronous; |
3451 | - fillMode: Image.PreserveAspectCrop; |
3452 | - width: root.width; |
3453 | - height: width / artShape.aspect; |
3454 | - } |
3455 | - } |
3456 | +Loader { |
3457 | + id: backgroundLoader; |
3458 | + objectName: "backgroundLoader"; |
3459 | + anchors.fill: parent; |
3460 | + asynchronous: root.asynchronous; |
3461 | + visible: status == Loader.Ready; |
3462 | + sourceComponent: UbuntuShape { |
3463 | + objectName: "background"; |
3464 | + radius: "medium"; |
3465 | + color: getColor(0) || "white"; |
3466 | + gradientColor: getColor(1) || color; |
3467 | + anchors.fill: parent; |
3468 | + image: backgroundImage.source ? backgroundImage : null; |
3469 | + property real luminance: 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; |
3470 | + property Image backgroundImage: Image { |
3471 | + objectName: "backgroundImage"; |
3472 | + source: { |
3473 | + if (cardData && typeof cardData["background"] === "string") return cardData["background"]; |
3474 | + else if (template && typeof template["card-background"] === "string") return template["card-background"]; |
3475 | + else return ""; |
3476 | + } |
3477 | + } |
3478 | + function getColor(index) { |
3479 | + if (cardData && typeof cardData["background"] === "object" |
3480 | + && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { |
3481 | + return cardData["background"]["elements"][index]; |
3482 | + } else if (template && typeof template["card-background"] === "object" |
3483 | + && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { |
3484 | + return template["card-background"]["elements"][index]; |
3485 | + } else return undefined; |
3486 | + } |
3487 | + } |
3488 | + } |
3489 | +readonly property size artShapeSize: Qt.size(-1, -1); |
3490 | +readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin; |
3491 | +Item { |
3492 | + id: headerTitleContainer; |
3493 | + anchors { right: parent.right; left: parent.left; |
3494 | + top: parent.top; |
3495 | + topMargin: units.gu(1); |
3496 | + leftMargin: units.gu(1); |
3497 | + } |
3498 | + width: parent.width - x; |
3499 | + implicitHeight: titleLabel.height + subtitleLabel.height; |
3500 | + data: [ |
3501 | + Label { |
3502 | + id: titleLabel; |
3503 | + objectName: "titleLabel"; |
3504 | + anchors { right: emblemImage.left; |
3505 | + rightMargin: emblemImage.width > 0 ? units.gu(0.5) : 0; |
3506 | + left: parent.left; |
3507 | + top: parent.top; } |
3508 | + elide: Text.ElideRight; |
3509 | + fontSize: "small"; |
3510 | + wrapMode: Text.Wrap; |
3511 | + maximumLineCount: 2; |
3512 | + font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3513 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3514 | + visible: showHeader ; |
3515 | + text: root.title; |
3516 | + font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; |
3517 | + horizontalAlignment: root.headerAlignment; |
3518 | } |
3519 | - } |
3520 | -readonly property int headerHeight: 0; |
3521 | +,Label { |
3522 | + id: subtitleLabel; |
3523 | + objectName: "subtitleLabel"; |
3524 | + anchors { right: parent.right; |
3525 | + left: parent.left; |
3526 | + rightMargin: units.gu(1); |
3527 | + top: titleLabel.bottom; |
3528 | + } |
3529 | + anchors.topMargin: units.dp(2); |
3530 | + elide: Text.ElideRight; |
3531 | + fontSize: "small"; |
3532 | + font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3533 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3534 | + visible: titleLabel.visible && titleLabel.text; |
3535 | + text: cardData && cardData["subtitle"] || ""; |
3536 | + font.weight: Font.Light; |
3537 | + horizontalAlignment: root.headerAlignment; |
3538 | + } |
3539 | +,Image { |
3540 | + id: emblemImage; |
3541 | + objectName: "emblemImage"; |
3542 | + anchors { |
3543 | + bottom: titleLabel.baseline; |
3544 | + right: parent.right; |
3545 | + rightMargin: status === Image.Ready ? units.gu(1) : 0; |
3546 | + } |
3547 | + source: cardData && cardData["emblem"] || ""; |
3548 | + width: height; |
3549 | + height: status === Image.Ready ? titleLabel.font.pixelSize : 0; |
3550 | + fillMode: Image.PreserveAspectFit; |
3551 | + } |
3552 | + |
3553 | + ] |
3554 | + } |
3555 | UbuntuShape { |
3556 | id: touchdown; |
3557 | objectName: "touchdown"; |
3558 | - anchors { fill: artShapeHolder } |
3559 | + anchors { fill: backgroundLoader } |
3560 | visible: root.pressed; |
3561 | radius: "medium"; |
3562 | borderSource: "radius_pressed.sci" |
3563 | } |
3564 | -implicitHeight: artShapeHolder.height; |
3565 | +implicitHeight: headerTitleContainer.y + headerTitleContainer.height + units.gu(1); |
3566 | } |
3567 | |
3568 | === modified file 'tests/plugins/Dash/cardcreator/6.tst' |
3569 | --- tests/plugins/Dash/cardcreator/6.tst 2014-07-28 15:09:45 +0000 |
3570 | +++ tests/plugins/Dash/cardcreator/6.tst 2014-08-08 14:57:17 +0000 |
3571 | @@ -1,3 +1,3 @@ |
3572 | -template: {"card-layout":"vertical","card-size":"small","category-layout":"grid","collapsed-rows":2} |
3573 | -components: {"art":{"aspect-ratio":1.6,"field":"art"}} |
3574 | +template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2} |
3575 | +components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"subtitle":{"field":"author"},"title":{"field":"title"},"emblem":{"field":"source"},"attributes":{}} |
3576 | result: 6.res |
3577 | |
3578 | === modified file 'tests/plugins/Dash/cardcreator/7.res' |
3579 | --- tests/plugins/Dash/cardcreator/7.res 2014-08-05 22:51:17 +0000 |
3580 | +++ tests/plugins/Dash/cardcreator/7.res 2014-08-08 14:57:17 +0000 |
3581 | @@ -55,17 +55,19 @@ |
3582 | spacing: margins; |
3583 | height: root.fixedHeaderHeight != -1 ? root.fixedHeaderHeight : implicitHeight; |
3584 | anchors { top: parent.top; |
3585 | - topMargin: units.gu(1); |
3586 | -left: parent.left; |
3587 | - } |
3588 | + topMargin: units.gu(1); |
3589 | + left: parent.left; |
3590 | + } |
3591 | anchors.right: parent.right; |
3592 | anchors.margins: margins; |
3593 | - data: [ Image { |
3594 | + anchors.rightMargin: 0; |
3595 | + data: [ |
3596 | +Image { |
3597 | id: mascotImage; |
3598 | objectName: "mascotImage"; |
3599 | anchors { verticalCenter: parent.verticalCenter; } |
3600 | readonly property int maxSize: Math.max(width, height) * 4; |
3601 | - source: cardData && cardData["mascot"]; |
3602 | + source: cardData && cardData["mascot"] || ""; |
3603 | width: units.gu(6); |
3604 | height: units.gu(5.625); |
3605 | sourceSize { width: maxSize; height: maxSize } |
3606 | @@ -75,48 +77,58 @@ |
3607 | visible: showHeader; |
3608 | } |
3609 | |
3610 | - , |
3611 | - Column { |
3612 | - anchors.verticalCenter: parent.verticalCenter; |
3613 | - spacing: units.dp(2); |
3614 | - width: parent.width - x; |
3615 | - data: [ |
3616 | - Label { |
3617 | +,Item { |
3618 | + id: headerTitleContainer; |
3619 | + anchors { verticalCenter: parent.verticalCenter; } |
3620 | + width: parent.width - x; |
3621 | + implicitHeight: titleLabel.height + subtitleLabel.height + attributesRow.height; |
3622 | + data: [ |
3623 | + Label { |
3624 | id: titleLabel; |
3625 | objectName: "titleLabel"; |
3626 | - anchors { left: parent.left; right: parent.right } |
3627 | + anchors { right: parent.right; |
3628 | + rightMargin: units.gu(1); |
3629 | + left: parent.left; |
3630 | + top: parent.top; } |
3631 | elide: Text.ElideRight; |
3632 | fontSize: "small"; |
3633 | wrapMode: Text.Wrap; |
3634 | maximumLineCount: 2; |
3635 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3636 | - color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey"); |
3637 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3638 | visible: showHeader ; |
3639 | text: root.title; |
3640 | font.weight: components && components["subtitle"] ? Font.DemiBold : Font.Normal; |
3641 | horizontalAlignment: root.headerAlignment; |
3642 | } |
3643 | -, |
3644 | -Label { |
3645 | +,Label { |
3646 | id: subtitleLabel; |
3647 | objectName: "subtitleLabel"; |
3648 | - anchors { left: parent.left; right: parent.right } |
3649 | + anchors { right: parent.right; |
3650 | + left: parent.left; |
3651 | + rightMargin: units.gu(1); |
3652 | + top: titleLabel.bottom; |
3653 | + } |
3654 | + anchors.topMargin: units.dp(2); |
3655 | elide: Text.ElideRight; |
3656 | fontSize: "small"; |
3657 | font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); |
3658 | - color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey"); |
3659 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3660 | visible: titleLabel.visible && titleLabel.text; |
3661 | text: cardData && cardData["subtitle"] || ""; |
3662 | font.weight: Font.Light; |
3663 | horizontalAlignment: root.headerAlignment; |
3664 | } |
3665 | -, |
3666 | -CardAttributes { |
3667 | +,CardAttributes { |
3668 | id: attributesRow; |
3669 | objectName: "attributesRow"; |
3670 | - anchors { left: parent.left; right: parent.right } |
3671 | - color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < 0.7 ? "white" : (root.scopeStyle ? root.scopeStyle.foreground : "grey"); |
3672 | - model: cardData["attributes"]; |
3673 | + anchors { right: parent.right; |
3674 | + left: parent.left; |
3675 | + rightMargin: units.gu(1); |
3676 | + top: subtitleLabel.bottom; |
3677 | + } |
3678 | + color: backgroundLoader.active && backgroundLoader.item && backgroundLoader.item.luminance < (root.scopeStyle ? root.scopeStyle.threshold : 0.7) ? (root.scopeStyle ? root.scopeStyle.light : "white") : (root.scopeStyle ? root.scopeStyle.dark : "grey"); |
3679 | + model: cardData && cardData["attributes"]; |
3680 | } |
3681 | |
3682 | ] |
3683 | |
3684 | === modified file 'tests/plugins/Dash/tst_ScopeStyle.qml' |
3685 | --- tests/plugins/Dash/tst_ScopeStyle.qml 2014-07-25 11:42:06 +0000 |
3686 | +++ tests/plugins/Dash/tst_ScopeStyle.qml 2014-08-08 14:57:17 +0000 |
3687 | @@ -101,7 +101,7 @@ |
3688 | |
3689 | function test_threshold_data() { |
3690 | return [ |
3691 | - { tag: "default", index: 0, threshold: 0.5020 }, |
3692 | + { tag: "default", index: 0, threshold: 0.7510 }, |
3693 | { tag: "red on black", index: 1, threshold: 0.1063 }, |
3694 | { tag: "green on white", index: 2, threshold: 0.6795 }, |
3695 | { tag: "blue on darkgrey", index: 3, threshold: 0.3675 }, |
3696 | |
3697 | === modified file 'tests/qmltests/Dash/CardHelpers.js' |
3698 | --- tests/qmltests/Dash/CardHelpers.js 2014-08-06 19:38:16 +0000 |
3699 | +++ tests/qmltests/Dash/CardHelpers.js 2014-08-08 14:57:17 +0000 |
3700 | @@ -60,6 +60,7 @@ |
3701 | "art": "art", \ |
3702 | "subtitle": "subtitle", \ |
3703 | "mascot": "mascot", \ |
3704 | + "emblem": "emblem", \ |
3705 | "overlayColor": "overlayColor", \ |
3706 | "summary": "summary", \ |
3707 | "attributes": "attributes" \ |
3708 | |
3709 | === added file 'tests/qmltests/Dash/artwork/emblem.png' |
3710 | Binary files tests/qmltests/Dash/artwork/emblem.png 1970-01-01 00:00:00 +0000 and tests/qmltests/Dash/artwork/emblem.png 2014-08-08 14:57:17 +0000 differ |
3711 | === modified file 'tests/qmltests/Dash/tst_Card.qml' |
3712 | --- tests/qmltests/Dash/tst_Card.qml 2014-08-05 22:51:17 +0000 |
3713 | +++ tests/qmltests/Dash/tst_Card.qml 2014-08-08 14:57:17 +0000 |
3714 | @@ -31,6 +31,7 @@ |
3715 | { |
3716 | "art": "../../../tests/qmltests/Dash/artwork/music-player-design.png", |
3717 | "mascot": "../../../tests/qmltests/Dash/artwork/avatar.png", |
3718 | + "emblem": "../../../tests/qmltests/Dash/artwork/emblem.png", |
3719 | "title": "foo", |
3720 | "subtitle": "bar", |
3721 | "summary": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", |
3722 | @@ -270,7 +271,7 @@ |
3723 | { tag: "Large", width: units.gu(38), index: 2 }, |
3724 | { tag: "Wide", height: units.gu(19), size: "large", index: 3 }, |
3725 | { tag: "Tall", height: units.gu(38) / 0.7, size: "large", width: units.gu(38), index: 4 }, |
3726 | - { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) * 2 }, index: 0 }, |
3727 | + { tag: "VerticalWidth", width: function() { return headerRow.width + units.gu(1) }, index: 0 }, |
3728 | { tag: "HorizontalHeight", height: function() { return headerRow.height + units.gu(1) * 2 }, index: 5 }, |
3729 | { tag: "HorizontalWidth", width: function() { return headerRow.x - units.gu(1) }, index: 5 }, |
3730 | ] |
3731 | @@ -458,6 +459,23 @@ |
3732 | tryCompareFunction(function() { return Qt.colorEqual(subtitle.color, fontColor); }, true); |
3733 | } |
3734 | |
3735 | + function test_emblemImage_data() { |
3736 | + return [ |
3737 | + { tag: "Art and summary", emblem: true, index: 0 }, |
3738 | + { tag: "Art and summary, small", emblem: false, index: 1 }, |
3739 | + { tag: "No header", emblem: false, index: 7 }, |
3740 | + { tag: "With background", emblem: true, index: 10 }, |
3741 | + ]; |
3742 | + } |
3743 | + |
3744 | + function test_emblemImage(data) { |
3745 | + selector.selectedIndex = data.index; |
3746 | + waitForRendering(card); |
3747 | + |
3748 | + var emblemImage = findChild(card, "emblemImage"); |
3749 | + compare(emblemImage !== null, data.emblem); |
3750 | + } |
3751 | + |
3752 | function test_mascotShape_data() { |
3753 | return [ |
3754 | { tag: "Art and summary", shape: false, index: 0 }, |
3755 | |
3756 | === modified file 'tests/qmltests/Dash/tst_Dash.qml' |
3757 | --- tests/qmltests/Dash/tst_Dash.qml 2014-08-06 14:50:25 +0000 |
3758 | +++ tests/qmltests/Dash/tst_Dash.qml 2014-08-08 14:57:17 +0000 |
3759 | @@ -20,8 +20,6 @@ |
3760 | import Ubuntu.Components 0.1 |
3761 | import Unity.Test 0.1 as UT |
3762 | |
3763 | -// TODO We don't have any tests for the overlay scope functionality. |
3764 | - |
3765 | Item { |
3766 | id: shell |
3767 | width: units.gu(40) |
3768 | @@ -61,9 +59,9 @@ |
3769 | function get_scope_data() { |
3770 | return [ |
3771 | { tag: "MockScope1", visualIndex: 0 }, |
3772 | - { tag: "MockScope2", visualIndex: 1 }, |
3773 | - { tag: "clickscope", visualIndex: 2 }, |
3774 | - { tag: "MockScope5", visualIndex: 3 }, |
3775 | + { tag: "MockScope2", visualIndex: -1 }, |
3776 | + { tag: "clickscope", visualIndex: 1 }, |
3777 | + { tag: "MockScope5", visualIndex: 2 }, |
3778 | ] |
3779 | } |
3780 | |
3781 | @@ -79,10 +77,234 @@ |
3782 | tryCompare(dashContentList, "count", 0); |
3783 | scopes.load(); |
3784 | tryCompare(scopes, "loaded", true); |
3785 | - tryCompare(dashContentList, "count", 5); |
3786 | + tryCompare(dashContentList, "count", 6); |
3787 | |
3788 | verify(dashContentList != undefined); |
3789 | - tryCompare(dashContentList, "currentIndex", data.visualIndex); |
3790 | + if (data.visualIndex == -1) { |
3791 | + tryCompare(dashContentList, "currentIndex", 0); |
3792 | + expectFail(data.tag, "non favorite scopes should not be visble in the scopes model"); |
3793 | + compare(dashContentList.currentItem.scopeId, data.tag); // this should fail |
3794 | + } else { |
3795 | + tryCompare(dashContentList, "currentIndex", data.visualIndex); |
3796 | + compare(dashContentList.currentItem.scopeId, data.tag); |
3797 | + } |
3798 | + } |
3799 | + |
3800 | + function test_dash_overview_show_select_same_favorite() { |
3801 | + // Wait for stuff to be loaded |
3802 | + tryCompare(scopes, "loaded", true); |
3803 | + var dashContentList = findChild(dash, "dashContentList"); |
3804 | + tryCompare(dashContentList, "count", 6); |
3805 | + var mockScope1Loader = findChild(dash, "MockScope1 loader"); |
3806 | + tryCompareFunction(function() { return mockScope1Loader.item != null; }, true); |
3807 | + |
3808 | + // Show the overview |
3809 | + touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); |
3810 | + var overviewController = findInvisibleChild(dash, "overviewController"); |
3811 | + tryCompare(overviewController, "progress", 1); |
3812 | + |
3813 | + // Make sure tab is where it should |
3814 | + var scopesOverview = findChild(dash, "scopesOverview"); |
3815 | + compare(scopesOverview.currentTab, 0); |
3816 | + |
3817 | + // Make sure stuff is loaded |
3818 | + var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); |
3819 | + tryCompare(scopesOverviewFavoritesRepeater, "count", 6); |
3820 | + tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); |
3821 | + waitForRendering(scopesOverviewFavoritesRepeater.itemAt(0).item); |
3822 | + |
3823 | + // Click in first item |
3824 | + mouseClick(scopesOverviewFavoritesRepeater.itemAt(0).item, 0, 0); |
3825 | + |
3826 | + // Make sure animation went back |
3827 | + tryCompare(overviewController, "progress", 0); |
3828 | + compare(dashContentList.currentIndex, 0); |
3829 | + } |
3830 | + |
3831 | + function test_dash_overview_show_select_different_favorite() { |
3832 | + // Wait for stuff to be loaded |
3833 | + tryCompare(scopes, "loaded", true); |
3834 | + var dashContentList = findChild(dash, "dashContentList"); |
3835 | + tryCompare(dashContentList, "count", 6); |
3836 | + var mockScope1Loader = findChild(dash, "MockScope1 loader"); |
3837 | + tryCompareFunction(function() { return mockScope1Loader.item != null; }, true); |
3838 | + |
3839 | + // Show the overview |
3840 | + touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); |
3841 | + var overviewController = findInvisibleChild(dash, "overviewController"); |
3842 | + tryCompare(overviewController, "progress", 1); |
3843 | + |
3844 | + // Make sure tab is where it should |
3845 | + var scopesOverview = findChild(dash, "scopesOverview"); |
3846 | + compare(scopesOverview.currentTab, 0); |
3847 | + |
3848 | + // Make sure stuff is loaded |
3849 | + var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); |
3850 | + tryCompare(scopesOverviewFavoritesRepeater, "count", 6); |
3851 | + tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); |
3852 | + waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item); |
3853 | + |
3854 | + // Click in first item |
3855 | + mouseClick(scopesOverviewFavoritesRepeater.itemAt(1).item, 0, 0); |
3856 | + |
3857 | + // Make sure animation went back |
3858 | + tryCompare(overviewController, "progress", 0); |
3859 | + compare(dashContentList.currentIndex, 1); |
3860 | + } |
3861 | + |
3862 | + function test_dash_overview_all_temp_scope_done_from_all() { |
3863 | + // Wait for stuff to be loaded |
3864 | + tryCompare(scopes, "loaded", true); |
3865 | + var dashContentList = findChild(dash, "dashContentList"); |
3866 | + tryCompare(dashContentList, "count", 6); |
3867 | + var mockScope1Loader = findChild(dash, "MockScope1 loader"); |
3868 | + tryCompareFunction(function() { return mockScope1Loader.item != null; }, true); |
3869 | + |
3870 | + // Show the overview |
3871 | + touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); |
3872 | + var overviewController = findInvisibleChild(dash, "overviewController"); |
3873 | + tryCompare(overviewController, "progress", 1); |
3874 | + |
3875 | + // Make sure tab is where it should |
3876 | + var scopesOverview = findChild(dash, "scopesOverview"); |
3877 | + compare(scopesOverview.currentTab, 0); |
3878 | + |
3879 | + // Make sure stuff is loaded |
3880 | + var scopesOverviewFavoritesRepeater = findChild(dash, "scopesOverviewFavoritesRepeater"); |
3881 | + tryCompare(scopesOverviewFavoritesRepeater, "count", 6); |
3882 | + tryCompareFunction(function() { return scopesOverviewFavoritesRepeater.itemAt(0).item != null; }, true); |
3883 | + waitForRendering(scopesOverviewFavoritesRepeater.itemAt(1).item); |
3884 | + |
3885 | + // Click on the all tab |
3886 | + var scopesOverviewAllTabButton = findChild(dash, "scopesOverviewAllTabButton"); |
3887 | + mouseClick(scopesOverviewAllTabButton, 0, 0); |
3888 | + |
3889 | + // Wait for all tab to be enabled (animation finish) |
3890 | + var scopesOverviewAllView = findChild(dash, "scopesOverviewRepeaterChild1"); |
3891 | + tryCompare(scopesOverviewAllView, "enabled", true); |
3892 | + |
3893 | + // Click on a temp scope |
3894 | + var tempScopeCard = findChild(scopesOverviewAllView, "delegate1"); |
3895 | + mouseClick(tempScopeCard, 0, 0); |
3896 | + |
3897 | + // Check the bottom edge (overview) is disabled from temp scope |
3898 | + var overviewDragHandle = findChild(dash, "overviewDragHandle"); |
3899 | + compare(overviewDragHandle.enabled, false); |
3900 | + |
3901 | + // Check temp scope is there |
3902 | + var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); |
3903 | + tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true); |
3904 | + tryCompare(scopesOverviewTempScopeItem, "enabled", true); |
3905 | + |
3906 | + // Go back |
3907 | + var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader"); |
3908 | + var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton"); |
3909 | + mouseClick(backButton, 0, 0); |
3910 | + |
3911 | + // Check temp scope is gone |
3912 | + var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); |
3913 | + tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true); |
3914 | + tryCompare(scopesOverviewTempScopeItem, "enabled", false); |
3915 | + |
3916 | + // Press on done |
3917 | + var scopesOverviewDoneButton = findChild(scopesOverview, "scopesOverviewDoneButton"); |
3918 | + mouseClick(scopesOverviewDoneButton, 0, 0); |
3919 | + |
3920 | + // Check the dash overview is gone |
3921 | + tryCompare(overviewController, "progress", 0); |
3922 | + |
3923 | + // Original list is still on 0 |
3924 | + compare(dashContentList.currentIndex, 0); |
3925 | + } |
3926 | + |
3927 | + function test_temp_scope_dash_overview_all_search_temp_scope_favorite_from_all() { |
3928 | + // Wait for stuff to be loaded |
3929 | + tryCompare(scopes, "loaded", true); |
3930 | + var dashContentList = findChild(dash, "dashContentList"); |
3931 | + tryCompare(dashContentList, "count", 6); |
3932 | + var mockScope1Loader = findChild(dash, "MockScope1 loader"); |
3933 | + tryCompareFunction(function() { return mockScope1Loader.item != null; }, true); |
3934 | + |
3935 | + // Swipe right to Apps scope |
3936 | + touchFlick(dash, dash.width - 1, units.gu(1), dash.width - units.gu(10), units.gu(1)); |
3937 | + tryCompare(dashContentList, "contentX", dashContentList.width); |
3938 | + tryCompare(dashContentList, "currentIndex", 1); |
3939 | + |
3940 | + // Click on card that opens temp scope |
3941 | + var categoryListView = findChild(dashContentList.currentItem, "categoryListView"); |
3942 | + var dashCategory2 = findChild(categoryListView, "dashCategory2"); |
3943 | + tryCompareFunction(function() { |
3944 | + var d = findChild(dashCategory2, "delegate2"); |
3945 | + if (d) return true; |
3946 | + categoryListView.contentY += 100; |
3947 | + return false; |
3948 | + }, true); |
3949 | + var card2 = findChild(dashCategory2, "delegate2"); |
3950 | + waitForRendering(card2); |
3951 | + mouseClick(card2, card2.width / 2, card2.height / 2); |
3952 | + |
3953 | + // Wait for temp scope to be there |
3954 | + var dashTempScopeItem = findChild(dash, "dashTempScopeItem"); |
3955 | + tryCompare(dashTempScopeItem, "x", 0); |
3956 | + |
3957 | + // Show the overview |
3958 | + touchFlick(dash, dash.width / 2, dash.height - 1, dash.width / 2, dash.height - units.gu(18)); |
3959 | + var overviewController = findInvisibleChild(dash, "overviewController"); |
3960 | + tryCompare(overviewController, "progress", 1); |
3961 | + |
3962 | + // Make sure tab is where it should |
3963 | + var scopesOverview = findChild(dash, "scopesOverview"); |
3964 | + compare(scopesOverview.currentTab, 1); |
3965 | + |
3966 | + // Do a search |
3967 | + var scopesOverviewPageHeader = findChild(scopesOverview, "scopesOverviewPageHeader"); |
3968 | + var searchButton = findChild(scopesOverviewPageHeader, "search_header_button"); |
3969 | + mouseClick(searchButton, 0, 0); |
3970 | + |
3971 | + // Type something |
3972 | + keyClick(Qt.Key_H); |
3973 | + |
3974 | + // Check results grid is there and the other lists are not |
3975 | + var searchResultsViewer = findChild(scopesOverview, "searchResultsViewer"); |
3976 | + var scopesOverviewRepeater = findChild(dash, "scopesOverviewRepeater"); |
3977 | + tryCompare(searchResultsViewer, "opacity", 1); |
3978 | + tryCompare(scopesOverviewRepeater, "count", 0); |
3979 | + |
3980 | + // Click on a temp scope in the search |
3981 | + var dashCategorysearchA = findChild(searchResultsViewer, "dashCategorysearchA"); |
3982 | + var cardTempScope = findChild(dashCategorysearchA, "delegate2"); |
3983 | + waitForRendering(cardTempScope); |
3984 | + mouseClick(cardTempScope, cardTempScope.width / 2, cardTempScope.height / 2); |
3985 | + |
3986 | + // Check the bottom edge (overview) is disabled from temp scope |
3987 | + var overviewDragHandle = findChild(dash, "overviewDragHandle"); |
3988 | + compare(overviewDragHandle.enabled, false); |
3989 | + |
3990 | + // Check temp scope is there |
3991 | + var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); |
3992 | + tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope != null; }, true); |
3993 | + tryCompare(scopesOverviewTempScopeItem, "enabled", true); |
3994 | + |
3995 | + // Go back |
3996 | + var scopesOverviewTempScopeItemHeader = findChild(scopesOverviewTempScopeItem, "scopePageHeader"); |
3997 | + var backButton = findChild(findChild(scopesOverviewTempScopeItemHeader, "innerPageHeader"), "backButton"); |
3998 | + mouseClick(backButton, 0, 0); |
3999 | + |
4000 | + // Check temp scope is gone |
4001 | + var scopesOverviewTempScopeItem = findChild(dash, "scopesOverviewTempScopeItem"); |
4002 | + tryCompareFunction( function() { return scopesOverviewTempScopeItem.scope == null; }, true); |
4003 | + tryCompare(scopesOverviewTempScopeItem, "enabled", false); |
4004 | + |
4005 | + // Press on a favorite |
4006 | + var dashCategorysearchB = findChild(searchResultsViewer, "dashCategorysearchB"); |
4007 | + var cardFavSearch = findChild(dashCategorysearchB, "delegate3"); |
4008 | + mouseClick(cardFavSearch, 0, 0); |
4009 | + |
4010 | + // Check the dash overview is gone |
4011 | + tryCompare(overviewController, "progress", 0); |
4012 | + |
4013 | + // Original list went to the favorite |
4014 | + compare(dashContentList.currentIndex, 0); |
4015 | } |
4016 | |
4017 | function test_setCurrentScope() { |
4018 | |
4019 | === modified file 'tests/qmltests/Dash/tst_DashContent.qml' |
4020 | --- tests/qmltests/Dash/tst_DashContent.qml 2014-08-06 10:16:59 +0000 |
4021 | +++ tests/qmltests/Dash/tst_DashContent.qml 2014-08-08 14:57:17 +0000 |
4022 | @@ -70,7 +70,7 @@ |
4023 | function loadScopes() { |
4024 | scopeLoadedSpy.clear(); |
4025 | scopesModel.load(); |
4026 | - tryCompare(scopeLoadedSpy, "count", 4); |
4027 | + tryCompare(scopeLoadedSpy, "count", 6); |
4028 | } |
4029 | |
4030 | function init() { |
4031 | @@ -114,7 +114,8 @@ |
4032 | |
4033 | loadScopes(); |
4034 | |
4035 | - verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < 5); |
4036 | + compare(dashContentList.count, 6); |
4037 | + verify(dashContentList.currentIndex >= 0 && dashContentList.currentIndex < dashContentList.count); |
4038 | } |
4039 | |
4040 | function test_show_header_on_list_movement() { |
4041 | @@ -170,7 +171,7 @@ |
4042 | |
4043 | // test greater than scope count. |
4044 | var currentScopeIndex = dashContent.currentIndex; |
4045 | - dashContent.setCurrentScopeAtIndex(8, true, false); |
4046 | + dashContent.setCurrentScopeAtIndex(18, true, false); |
4047 | compare(dashContent.currentIndex, currentScopeIndex, "Scope should not change if changing to greater index than count"); |
4048 | } |
4049 | |
4050 | @@ -189,9 +190,9 @@ |
4051 | function test_scope_mapping_data() { |
4052 | return [ |
4053 | {tag: "index0", index: 0, objectName: "MockScope1"}, |
4054 | - {tag: "index1", index: 1, objectName: "MockScope2"}, |
4055 | - {tag: "index2", index: 2, objectName: "clickscope"}, |
4056 | - {tag: "index3", index: 3, objectName: "MockScope5"} |
4057 | + {tag: "index1", index: 1, objectName: "clickscope"}, |
4058 | + {tag: "index2", index: 2, objectName: "MockScope5"}, |
4059 | + {tag: "index3", index: 3, objectName: "SingleCategoryScope"} |
4060 | ] |
4061 | } |
4062 | |
4063 | |
4064 | === modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml' |
4065 | --- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-06 19:39:30 +0000 |
4066 | +++ tests/qmltests/Dash/tst_GenericScopeView.qml 2014-08-08 14:57:17 +0000 |
4067 | @@ -61,8 +61,8 @@ |
4068 | property Item header: findChild(genericScopeView, "scopePageHeader") |
4069 | |
4070 | function init() { |
4071 | - genericScopeView.scope = scopes.getScope(1) |
4072 | - shell.width = units.gu(120) |
4073 | + genericScopeView.scope = scopes.getScope(2); |
4074 | + shell.width = units.gu(120); |
4075 | genericScopeView.categoryView.positionAtBeginning(); |
4076 | waitForRendering(genericScopeView.categoryView); |
4077 | } |
4078 | @@ -88,13 +88,13 @@ |
4079 | |
4080 | function test_showDash() { |
4081 | testCase.previewListView.open = true; |
4082 | - scopes.getScope(1).showDash(); |
4083 | + genericScopeView.scope.showDash(); |
4084 | tryCompare(testCase.previewListView, "open", false); |
4085 | } |
4086 | |
4087 | function test_hideDash() { |
4088 | testCase.previewListView.open = true; |
4089 | - scopes.getScope(1).hideDash(); |
4090 | + genericScopeView.scope.hideDash(); |
4091 | tryCompare(testCase.previewListView, "open", false); |
4092 | } |
4093 | |
4094 | @@ -111,8 +111,9 @@ |
4095 | |
4096 | function test_changeScope() { |
4097 | genericScopeView.scope.searchQuery = "test" |
4098 | - genericScopeView.scope = scopes.getScope(2) |
4099 | - genericScopeView.scope = scopes.getScope(1) |
4100 | + var originalScopeId = genericScopeView.scope.id; |
4101 | + genericScopeView.scope = scopes.getScope(originalScopeId + 1) |
4102 | + genericScopeView.scope = scopes.getScope(originalScopeId) |
4103 | tryCompare(genericScopeView.scope, "searchQuery", "test") |
4104 | } |
4105 | |
4106 | @@ -198,6 +199,8 @@ |
4107 | openPreview(4, 0); |
4108 | |
4109 | compare(testCase.previewListView.count, 12, "There should only be 12 items in preview."); |
4110 | + |
4111 | + closePreview(); |
4112 | } |
4113 | |
4114 | function test_narrow_delegate_ranges_expand() { |
4115 | @@ -232,7 +235,7 @@ |
4116 | } |
4117 | |
4118 | function test_single_category_expansion() { |
4119 | - genericScopeView.scope = scopes.getScope(4); |
4120 | + genericScopeView.scope = scopes.getScope(3); |
4121 | |
4122 | tryCompareFunction(function() { return findChild(genericScopeView, "dashCategory0") != undefined; }, true); |
4123 | var category = findChild(genericScopeView, "dashCategory0") |
4124 | @@ -329,8 +332,8 @@ |
4125 | function test_header_style_data() { |
4126 | return [ |
4127 | { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" }, |
4128 | - { tag: "Foreground", index: 2, foreground: "yellow", background: "", logo: "" }, |
4129 | - { tag: "Logo+Background", index: 3, foreground: "grey", background: "gradient:///lightgrey/grey", |
4130 | + { tag: "Foreground", index: 1, foreground: "yellow", background: "", logo: "" }, |
4131 | + { tag: "Logo+Background", index: 2, foreground: "grey", background: "gradient:///lightgrey/grey", |
4132 | logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") }, |
4133 | ]; |
4134 | } |
FAILED: Continuous integration, rev:1093 /code.launchpad .net/~cimi/ unity8/ card_emblems_ 2/+merge/ 229046/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ unity8- ci/3707/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/2833 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- utopic/ 709 jenkins. qa.ubuntu. com/job/ unity8- utopic- amd64-ci/ 801 jenkins. qa.ubuntu. com/job/ unity8- utopic- armhf-ci/ 801 jenkins. qa.ubuntu. com/job/ unity8- utopic- armhf-ci/ 801/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity8- utopic- i386-ci/ 801 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/2913 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4076 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4076/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 10782
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/3707/ rebuild
http://