Merge lp:~saviq/unity8/dash-header-style into lp:unity8

Proposed by Michał Sawicz
Status: Merged
Approved by: Michał Sawicz
Approved revision: 1066
Merged at revision: 1077
Proposed branch: lp:~saviq/unity8/dash-header-style
Merge into: lp:unity8
Prerequisite: lp:~saviq/unity8/drop-filtergrid
Diff against target: 352 lines (+239/-12)
8 files modified
plugins/Dash/ScopeStyle.qml (+6/-0)
qml/Components/Background.qml (+77/-0)
qml/Components/PageHeader.qml (+6/-1)
tests/mocks/Unity/fake_scope.cpp (+6/-4)
tests/plugins/Dash/tst_ScopeStyle.qml (+27/-2)
tests/qmltests/CMakeLists.txt (+1/-0)
tests/qmltests/Components/tst_Background.qml (+90/-0)
tests/qmltests/Dash/tst_GenericScopeView.qml (+26/-5)
To merge this branch: bzr merge lp:~saviq/unity8/dash-header-style
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Pending
Albert Astals Cid Pending
Review via email: mp+227652@code.launchpad.net

This proposal supersedes a proposal from 2014-07-21.

Commit message

Add dash PageHeader styling.

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.
prerequisite:
https://code.launchpad.net/~saviq/unity8/drop-filtergrid/+merge/226415

 * 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

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Yes

 * Did CI run pass? If not, please explain why.
No, but the failing tests are known to fail/be unstable so that's fine.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/Dash/ScopeStyle.qml'
2--- plugins/Dash/ScopeStyle.qml 2014-07-08 08:30:46 +0000
3+++ plugins/Dash/ScopeStyle.qml 2014-07-21 23:39:16 +0000
4@@ -70,6 +70,12 @@
5 /// Source of the logo image for the header
6 readonly property url headerLogo: "logo" in d.headerStyle ? d.headerStyle["logo"] : ""
7
8+ /// Background style for the header
9+ readonly property url headerBackground: "background" in d.headerStyle ? d.headerStyle["background"] : ""
10+
11+ /// Foreground color for the header
12+ readonly property color headerForeground: "foreground-color" in d.headerStyle ? d.headerStyle["foreground-color"] : foreground
13+
14 //! @cond
15 property var d: QtObject {
16 readonly property real foregroundLuminance: luminance(foreground)
17
18=== added file 'qml/Components/Background.qml'
19--- qml/Components/Background.qml 1970-01-01 00:00:00 +0000
20+++ qml/Components/Background.qml 2014-07-21 23:39:16 +0000
21@@ -0,0 +1,77 @@
22+/*
23+ * Copyright (C) 2014 Canonical, Ltd.
24+ *
25+ * This program is free software; you can redistribute it and/or modify
26+ * it under the terms of the GNU General Public License as published by
27+ * the Free Software Foundation; version 3.
28+ *
29+ * This program is distributed in the hope that it will be useful,
30+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32+ * GNU General Public License for more details.
33+ *
34+ * You should have received a copy of the GNU General Public License
35+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36+ */
37+
38+import QtQuick 2.0
39+
40+Loader {
41+ id: root
42+ anchors.fill: parent
43+
44+ property url style
45+ readonly property var parsedStyle: String(style)
46+ .match(/^(color|gradient):\/\/\/(?:(#(?:[0-9a-f]{3,4}){1,2}|[a-z]{3,}))(?:\/(#(?:[0-9a-f]{3,4}){1,2}|[a-z]{3,}))?\/?$/i)
47+
48+ sourceComponent: {
49+ if (style == "") return null;
50+ if (!parsedStyle) return image;
51+ if (parsedStyle[1] === "color") return solid
52+ if (parsedStyle[1] === "gradient") return gradient
53+ }
54+
55+ onLoaded: if (item.hasOwnProperty("parsedStyle")) {
56+ item.parsedStyle = Qt.binding(function() { return root.parsedStyle } );
57+ }
58+
59+ Component {
60+ id: solid
61+
62+ Rectangle {
63+ objectName: "solid"
64+
65+ property var parsedStyle
66+
67+ color: parsedStyle ? parsedStyle[2] : "#ffffff"
68+ }
69+ }
70+
71+ Component {
72+ id: gradient
73+
74+ Rectangle {
75+ objectName: "gradient"
76+
77+ property var parsedStyle
78+
79+ gradient: Gradient {
80+ GradientStop { position: 0; color: parsedStyle ? parsedStyle[2] : "#000000" }
81+ GradientStop { position: 1; color: parsedStyle ? parsedStyle[3] : "#000000" }
82+ }
83+ }
84+ }
85+
86+ Component {
87+ id: image
88+
89+ Image {
90+ objectName: "image"
91+
92+ source: width > 0 && height > 0 && root.style
93+
94+ sourceSize.width: width
95+ sourceSize.height: height
96+ }
97+ }
98+}
99
100=== modified file 'qml/Components/PageHeader.qml'
101--- qml/Components/PageHeader.qml 2014-07-09 19:44:02 +0000
102+++ qml/Components/PageHeader.qml 2014-07-21 23:39:16 +0000
103@@ -127,6 +127,11 @@
104 property bool showSearch: false
105 property var popover: null
106
107+ Background {
108+ objectName: "headerBackground"
109+ style: scopeStyle.headerBackground
110+ }
111+
112 Behavior on contentY {
113 UbuntuNumberAnimation {
114 id: openSearchAnimation
115@@ -225,7 +230,7 @@
116 height: headerContainer.height
117 contentHeight: height
118 separatorSource: ""
119- textColor: root.scopeStyle ? root.scopeStyle.foreground : "grey"
120+ textColor: root.scopeStyle ? root.scopeStyle.headerForeground : "grey"
121 property var styledItem: header
122 property string title: root.title
123 property var config: PageHeadConfiguration {
124
125=== modified file 'tests/mocks/Unity/fake_scope.cpp'
126--- tests/mocks/Unity/fake_scope.cpp 2014-07-21 23:39:16 +0000
127+++ tests/mocks/Unity/fake_scope.cpp 2014-07-21 23:39:16 +0000
128@@ -182,14 +182,16 @@
129
130 QVariantMap Scope::customizations() const
131 {
132- QVariantMap m;
133+ QVariantMap m, h;
134 if (m_id == "clickscope") {
135+ h["foreground-color"] = "yellow";
136 m["background-color"] = "red";
137 m["foreground-color"] = "blue";
138+ m["page-header"] = h;
139 } else if (m_id == "MockScope5") {
140- QVariantMap pageHeader;
141- pageHeader["logo"] = QUrl("../../../tests/qmltests/Components/tst_PageHeader/logo-ubuntu-orange.svg");
142- m["page-header"] = pageHeader;
143+ h["background"] = "gradient:///lightgrey/grey";
144+ h["logo"] = QUrl("../../../tests/qmltests/Components/tst_PageHeader/logo-ubuntu-orange.svg");
145+ m["page-header"] = h;
146 }
147 return m;
148 }
149
150=== modified file 'tests/plugins/Dash/tst_ScopeStyle.qml'
151--- tests/plugins/Dash/tst_ScopeStyle.qml 2014-07-08 08:30:46 +0000
152+++ tests/plugins/Dash/tst_ScopeStyle.qml 2014-07-21 23:39:16 +0000
153@@ -36,8 +36,8 @@
154 property var styles: [
155 {},
156 { "foreground-color": "red", "background-color": "black", "page-header": { "logo": "/foo/bar" } },
157- { "foreground-color": "green", "background-color": "white" },
158- { "foreground-color": "blue", "background-color": "darkgrey" },
159+ { "foreground-color": "green", "background-color": "white", "page-header": { "foreground-color": "black" } },
160+ { "foreground-color": "blue", "background-color": "darkgrey", "page-header": { "background": "gradient:///white/blue" } },
161 ]
162
163 function cleanup() {
164@@ -147,5 +147,30 @@
165 tool.style = testCase.styles[data.index];
166 compare(tool.headerLogo, data.headerLogo, "Header logo was incorrect.");
167 }
168+
169+ function test_headerForeground_data() {
170+ return [
171+ { tag: "default", index: 0, headerForeground: "grey" },
172+ { tag: "black", index: 2, headerForeground: "black" },
173+ ];
174+ }
175+
176+ function test_headerForeground(data) {
177+ tool.style = testCase.styles[data.index];
178+ verify(Qt.colorEqual(tool.headerForeground, data.headerForeground),
179+ "Header foreground not equal: %1 != %2".arg(tool.headerForeground).arg(data.headerForeground));
180+ }
181+
182+ function test_headerBackground_data() {
183+ return [
184+ { tag: "default", index: 0, headerBackground: "" },
185+ { tag: "black", index: 3, headerBackground: "gradient:///white/blue" },
186+ ];
187+ }
188+
189+ function test_headerBackground(data) {
190+ tool.style = testCase.styles[data.index];
191+ compare(tool.headerBackground, data.headerBackground, "Header background was incorrect.");
192+ }
193 }
194 }
195
196=== modified file 'tests/qmltests/CMakeLists.txt'
197--- tests/qmltests/CMakeLists.txt 2014-07-21 23:39:16 +0000
198+++ tests/qmltests/CMakeLists.txt 2014-07-21 23:39:16 +0000
199@@ -21,6 +21,7 @@
200
201 add_qml_test(. Shell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
202 add_qml_test(. ShellWithPin ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single-pin")
203+add_qml_test(Components Background)
204 add_qml_test(Components Carousel)
205 add_qml_test(Components DraggingArea)
206 add_qml_test(Components EdgeDemoOverlay)
207
208=== added file 'tests/qmltests/Components/tst_Background.qml'
209--- tests/qmltests/Components/tst_Background.qml 1970-01-01 00:00:00 +0000
210+++ tests/qmltests/Components/tst_Background.qml 2014-07-21 23:39:16 +0000
211@@ -0,0 +1,90 @@
212+/*
213+ * Copyright (C) 2014 Canonical, Ltd.
214+ *
215+ * This program is free software; you can redistribute it and/or modify
216+ * it under the terms of the GNU General Public License as published by
217+ * the Free Software Foundation; version 3.
218+ *
219+ * This program is distributed in the hope that it will be useful,
220+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
221+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
222+ * GNU General Public License for more details.
223+ *
224+ * You should have received a copy of the GNU General Public License
225+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
226+ */
227+
228+import QtQuick 2.2
229+import QtTest 1.0
230+import Unity.Test 0.1
231+
232+import "../../../qml/Components"
233+
234+Rectangle {
235+ width: units.gu(40)
236+ height: units.gu(71)
237+
238+ Background {
239+ id: background
240+ }
241+
242+ UnityTestCase {
243+ id: testCase
244+ name: "Background"
245+ when: windowShown
246+
247+ SignalSpy {
248+ id: loadedSpy
249+ target: background
250+ signalName: "loaded"
251+ }
252+
253+ function cleanup() {
254+ background.style = "";
255+ loadedSpy.clear();
256+ }
257+
258+ function test_style_data() {
259+ return [
260+ { tag: "empty", style: "" },
261+ { tag: "solid", style: "color:///black" },
262+ { tag: "gradient", style: "gradient:///black/red" },
263+ { tag: "image", style: "/some/path" },
264+ ];
265+ }
266+
267+ function test_style(data) {
268+ background.style = data.style;
269+ expectFail("empty", "Empty style should not create a background.");
270+ loadedSpy.wait();
271+ compare(background.item.objectName, data.tag, "Background should be %1".arg(data.style));
272+ }
273+
274+ function test_solid() {
275+ background.style = "color:///black";
276+ loadedSpy.wait();
277+
278+ verify(Qt.colorEqual(background.item.color, "black"),
279+ "Solid color not equal: %1 != black".arg(background.item.color));
280+ }
281+
282+ function test_gradient() {
283+ background.style = "gradient:///black/red";
284+ loadedSpy.wait();
285+
286+ var stops = background.item.gradient.stops;
287+
288+ verify(Qt.colorEqual(stops[0].color, "black"),
289+ "Top gradient color not equal: %1 != black".arg(stops[0].color));
290+ verify(Qt.colorEqual(stops[1].color, "red"),
291+ "Bottom gradient color not equal: %1 != black".arg(stops[1].color));
292+ }
293+
294+ function test_image() {
295+ background.style = "/some/path";
296+ loadedSpy.wait();
297+
298+ compare(background.item.source, Qt.resolvedUrl("/some/path"), "Image path is incorrect.");
299+ }
300+ }
301+}
302
303=== modified file 'tests/qmltests/Dash/tst_GenericScopeView.qml'
304--- tests/qmltests/Dash/tst_GenericScopeView.qml 2014-07-21 23:39:16 +0000
305+++ tests/qmltests/Dash/tst_GenericScopeView.qml 2014-07-21 23:39:16 +0000
306@@ -54,6 +54,7 @@
307 when: scopes.loaded && windowShown
308
309 property Item previewListView: findChild(genericScopeView, "previewListView")
310+ property Item header: findChild(genericScopeView, "scopePageHeader")
311
312 function init() {
313 genericScopeView.scope = scopes.getScope(1)
314@@ -279,13 +280,33 @@
315 closePreview();
316 }
317
318- function test_header_logo() {
319- genericScopeView.scope = scopes.getScope(3);
320+ function test_header_style_data() {
321+ return [
322+ { tag: "Default", index: 0, foreground: "grey", background: "", logo: "" },
323+ { tag: "Foreground", index: 2, foreground: "yellow", background: "", logo: "" },
324+ { tag: "Logo+Background", index: 3, foreground: "grey", background: "gradient:///lightgrey/grey",
325+ logo: Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg") },
326+ ];
327+ }
328+
329+ function test_header_style(data) {
330+ genericScopeView.scope = scopes.getScope(data.index);
331+ waitForRendering(genericScopeView);
332+ verify(header, "Could not find the header.");
333+
334+ var innerHeader = findChild(header, "innerPageHeader");
335+ verify(innerHeader, "Could not find the inner header");
336+ verify(Qt.colorEqual(innerHeader.textColor, data.foreground),
337+ "Foreground color not equal: %1 != %2".arg(innerHeader.textColor).arg(data.foreground));
338+
339+ var background = findChild(header, "headerBackground");
340+ verify(background, "Could not find the background");
341+ compare(background.style, data.background);
342
343 var image = findChild(genericScopeView, "titleImage");
344- verify(image, "Could not find the title image");
345- compare(image.source, Qt.resolvedUrl("../Components/tst_PageHeader/logo-ubuntu-orange.svg"), "Title image has the wrong source");
346-
347+ if (data.logo == "") expectFail(data.tag, "Title image should not exist.");
348+ verify(image, "Could not find the title image.");
349+ compare(image.source, data.logo, "Title image has the wrong source");
350 }
351 }
352 }

Subscribers

People subscribed via source and target branches