on xenial help sign in
update/add more tests for PageHeader, rename from PageHeaderLabel
commita1ab52fe0cd306eb09a011cf5ca120e49814c82e authorMichael Zanetti <michael.zanetti@canonical.com> dateFri 27 Jun 2014, 20:44 (12 years ago) parent6c9d92e
7 files changed+185−63
qml/Components/PageHeader.qml+48−7 qml/Dash/GenericScopeView.qml+1−1 qml/Dash/PreviewListView.qml−1 tests/qmltests/CMakeLists.txt+1−1 tests/qmltests/Components/tst_PageHeaderLabel.qml → tests/qmltests/Components/tst_PageHeader.qml+74−52 tests/qmltests/Components/tst_PageHeader/logo-ubuntu-orange.svg+60 tests/qmltests/Dash/tst_GenericScopeView.qml+1−1
qml/Components/PageHeader.qml+48−7
@@ -27,11 +27,12 @@ Item {
2727
2828 property bool showBackButton: false
2929 property string title
30− property var scope: null
30+ property string imageSource
3131
3232 property bool searchEntryEnabled: false
3333 property ListModel searchHistory
3434 property alias searchQuery: searchTextField.text
35+ property bool searchInProgress: false
3536
3637 property alias bottomItem: bottomContainer.children
3738
@@ -53,20 +54,20 @@ Item {
5354 unfocus();
5455 }
5556 searchTextField.text = "";
57+ if (headerContainer.popover != null) {
58+ PopupUtils.close(headerContainer.popover);
59+ }
5660 }
5761
5862 function unfocus() {
59− print("unfocusing field")
6063 searchTextField.focus = false;
6164 }
6265
6366 function openSearchHistory() {
64− print("should open search history")
6567 if (openSearchAnimation.running) {
66− print("huh! animation is running")
6768 openSearchAnimation.openSearchHistory = true
68− } else if (root.searchHistory.count > 0) {
69− PopupUtils.open(popoverComponent, searchTextField,
69+ } else if (root.searchHistory.count > 0 && headerContainer.popover == null) {
70+ headerContainer.popover = PopupUtils.open(popoverComponent, searchTextField,
7071 {
7172 "contentWidth": searchTextField.width,
7273 "edgeMargins": units.gu(1)
@@ -75,8 +76,18 @@ Item {
7576 }
7677 }
7778
79+ onImageSourceChanged: {
80+ if (imageSource.length > 0) {
81+ header.contents = imageComponent.createObject();
82+ } else {
83+ header.contents.destroy();
84+ header.contents = null
85+ }
86+ }
87+
7888 Flickable {
7989 id: headerContainer
90+ objectName: "headerContainer"
8091 clip: true
8192 anchors { left: parent.left; top: parent.top; right: parent.right }
8293 height: units.gu(6.5)
@@ -85,6 +96,7 @@ Item {
8596 contentY: showSearch ? 0 : height
8697
8798 property bool showSearch: false
99+ property var popover: null
88100
89101 Behavior on contentY {
90102 UbuntuNumberAnimation {
@@ -138,17 +150,20 @@ Item {
138150 width: height
139151
140152 Image {
153+ objectName: "clearIcon"
141154 anchors.fill: parent
142155 anchors.margins: units.gu(.75)
143156 source: "image://theme/clear"
144157 opacity: searchTextField.text.length > 0 && !searchActivityIndicator.running
158+ visible: opacity > 0
145159 }
146160
147161 ActivityIndicator {
148162 id: searchActivityIndicator
163+ objectName: "searchIndicator"
149164 anchors.fill: parent
150165 anchors.margins: units.gu(.75)
151− running: root.scope && root.scope.searchInProgress
166+ running: root.searchInProgress
152167 opacity: running ? 1 : 0
153168 Behavior on opacity {
154169 UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
@@ -199,6 +214,28 @@ Item {
199214 }
200215 ]
201216 }
217+
218+ property var contents: null
219+ Component.onCompleted: {
220+ if (root.imageSource.length > 0) {
221+ header.contents = imageComponent.createObject();
222+ }
223+ }
224+ Component {
225+ id: imageComponent
226+
227+ Item {
228+ anchors { fill: parent; topMargin: units.gu(1); bottomMargin: units.gu(1) }
229+ clip: true
230+ Image {
231+ objectName: "titleImage"
232+ anchors.fill: parent
233+ source: root.imageSource
234+ fillMode: Image.PreserveAspectFit
235+ horizontalAlignment: Image.AlignLeft
236+ }
237+ }
238+ }
202239 }
203240 }
204241 }
@@ -208,6 +245,10 @@ Item {
208245 Popover {
209246 id: popover
210247
248+ Component.onDestruction: {
249+ headerContainer.popover = null
250+ }
251+
211252 // FIXME: this should go into the first item below, but enable: false
212253 // prevents mouse events propagation
213254 AbstractButton {
qml/Dash/GenericScopeView.qml+1−1
@@ -315,10 +315,10 @@ FocusScope {
315315 id: pageHeader
316316 width: parent.width
317317 title: scopeView.title
318− scope: scopeView.scope
319318 searchHistory: scopeView.searchHistory
320319 showBackButton: scopeView.hasBackAction
321320 searchEntryEnabled: true
321+ searchInProgress: root.scope.searchInProgress
322322
323323 bottomItem: DashDepartments {
324324 scope: scopeView.scope
qml/Dash/PreviewListView.qml−1
@@ -38,7 +38,6 @@ Item {
3838 title: scope.name
3939 showBackButton: true
4040 searchEntryEnabled: false
41− scope: root.scope
4241
4342 onBackClicked: root.open = false
4443 }
tests/qmltests/CMakeLists.txt+1−1
@@ -32,7 +32,7 @@ add_qml_test(Components ResponsiveGridView)
3232add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
3333add_qml_test(Components SeeMore)
3434add_qml_test(Components Showable)
35−add_qml_test(Components PageHeaderLabel)
35+add_qml_test(Components PageHeader)
3636add_qml_test(Components ZoomableImage)
3737add_qml_test(Dash Dash)
3838add_qml_test(Dash DashContent)
tests/qmltests/Components/tst_PageHeaderLabel.qml → tests/qmltests/Components/tst_PageHeader.qmlrenamed+74−52
@@ -26,10 +26,6 @@ Item {
2626 width: units.gu(110)
2727 height: units.gu(30)
2828
29− MockScope {
30− id: scopeMock
31− }
32−
3329 UT.UnityTestCase {
3430 name: "PageHeaderLabelTest"
3531 when: windowShown
@@ -82,33 +78,6 @@ Item {
8278 compare(searchQuery, "", "Reset search did not reset searchQuery correctly.")
8379 }
8480
85− function test_move_search_by_width()
86− {
87− searchEnabled = true
88− pageHeader.resetSearch()
89−
90− var searchContainer = findChild(pageHeader, "searchContainer")
91−
92− parent.width = units.gu(40)
93−
94− verify(searchContainer !== undefined)
95− verify(searchContainer.y <= 0)
96−
97− pageHeader.triggerSearch()
98− verify(searchContainer.y >= 0)
99−
100− pageHeader.resetSearch()
101− verify(searchContainer.y <= 0)
102−
103− parent.width = units.gu(110)
104− verify(searchContainer.y >= 0)
105−
106− pageHeader.triggerSearch()
107− tryCompare(searchContainer, "narrowMode", false)
108− tryCompare(searchContainer, "state", "active")
109− tryCompare(searchContainer, "width", units.gu(40))
110− }
111−
11281 function test_history() {
11382 pageHeader.searchHistory.clear()
11483 compare(pageHeader.searchHistory.count, 0)
@@ -144,21 +113,41 @@ Item {
144113
145114 function test_search_indicator() {
146115 var searchIndicator = findChild(pageHeader, "searchIndicator")
147− var primaryImage = findChild(pageHeader, "primaryImage")
116+ var clearIcon = findChild(pageHeader, "clearIcon")
148117
149118 pageHeader.triggerSearch()
150119
151− scopeMock.setSearchInProgress(false);
120+ tryCompare(clearIcon, "visible", false)
121+ pageHeader.searchQuery = "ubuntu"
122+ tryCompare(clearIcon, "visible", true)
123+
124+ pageHeader.searchInProgress = false
152125 compare(searchIndicator.running, false, "Search indicator is running.")
153− tryCompare(primaryImage, "visible", true)
126+ tryCompare(clearIcon, "visible", true)
154127
155− scopeMock.setSearchInProgress(true);
128+ pageHeader.searchInProgress = true
156129 compare(searchIndicator.running, true, "Search indicator isn't running.")
157− tryCompare(primaryImage, "visible", false)
130+ tryCompare(clearIcon, "visible", false)
131+
132+ pageHeader.searchInProgress = false;
133+ compare(searchIndicator.running, false, "Search indicator is running.")
134+ tryCompare(clearIcon, "visible", true)
135+ }
136+
137+ function test_titleImage() {
138+
139+ var titleImage = findChild(pageHeader, "titleImage");
140+ verify(titleImage == null);
141+
142+ showImageCheckBox.checked = true;
143+
144+ titleImage = findChild(pageHeader, "titleImage");
145+ verify(titleImage !== null);
146+ compare(titleImage.source, pageHeader.titleImageSource);
147+
158148 }
159149
160150 function cleanup() {
161− scopeMock.setSearchInProgress(false);
162151 pageHeader.resetSearch();
163152 }
164153
@@ -171,14 +160,14 @@ Item {
171160
172161 pageHeader.triggerSearch();
173162
174− var searchContainer = findChild(pageHeader, "searchContainer");
175− verify(searchContainer !== undefined, "searchContainer != undefined");
176− tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
163+ var headerContainer = findChild(pageHeader, "headerContainer");
164+ verify(headerContainer !== null, "headerContainer != null");
165+ tryCompareFunction(function() { return headerContainer.popover !== null; }, true);
177166
178− tryCompare(searchContainer.popover, "visible", true);
167+ tryCompare(headerContainer.popover, "visible", true);
179168 }
180169
181− function test_resetSearch_onPopupClose() {
170+ function test_resetSearch_closes_popup() {
182171 searchEnabled = true;
183172 pageHeader.searchHistory.clear();
184173
@@ -187,16 +176,16 @@ Item {
187176
188177 pageHeader.triggerSearch();
189178
190− var searchContainer = findChild(pageHeader, "searchContainer");
191− verify(searchContainer !== undefined, "searchContainer != undefined");
192− tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
193− compare(searchContainer.popover.visible, true);
179+ var headerContainer = findChild(pageHeader, "headerContainer");
180+ verify(headerContainer !== null, "headerContainer != null");
181+ tryCompareFunction(function() { return headerContainer.popover !== null; }, true);
182+ compare(headerContainer.popover.visible, true);
194183
195184 pageHeader.searchQuery = "test";
196− tryCompareFunction( function() { return (searchContainer.popover===null || !searchContainer.popover.visible) }, true);
185+ tryCompareFunction( function() { return (headerContainer.popover===null || !headerContainer.popover.visible) }, true);
197186
198187 pageHeader.resetSearch();
199− compare((searchContainer.popover===null || !searchContainer.popover.visible), true);
188+ compare((headerContainer.popover===null || !headerContainer.popover.visible), true);
200189 }
201190 }
202191
@@ -204,18 +193,22 @@ Item {
204193 anchors.fill: parent
205194 spacing: units.gu(1)
206195
207− PageHeaderLabel {
196+ PageHeader {
208197 id: pageHeader
209198 anchors {
210199 left: parent.left
211200 right: parent.right
212201 }
213202
214− scope: scopeMock
215−
216203 searchEntryEnabled: true
217204 searchHistory: SearchHistoryModel {}
218− text: "%^$%^%^&%^&%^$%GHR%"
205+ title: "%^$%^%^&%^&%^$%GHR%"
206+ imageSource: showImageCheckBox.checked ? titleImageSource : ""
207+ showBackButton: showBackButtonCheckBox.checked
208+
209+ property string titleImageSource: Qt.resolvedUrl("tst_PageHeader/logo-ubuntu-orange.svg")
210+ property date lastBackClicked
211+ onBackClicked: lastBackClicked = new Date()
219212 }
220213
221214 Row {
@@ -251,5 +244,34 @@ Item {
251244 anchors.verticalCenter: parent.verticalCenter
252245 }
253246 }
247+ Row {
248+ spacing: units.gu(1)
249+ anchors {
250+ left: parent.left
251+ right: parent.right
252+ }
253+ CheckBox {
254+ id: showBackButtonCheckBox
255+ }
256+ Label {
257+ text: "Back button enabled (Last clicked: " + Qt.formatTime(pageHeader.lastBackClicked, "hh:mm:ss") + ")"
258+ anchors.verticalCenter: parent.verticalCenter
259+ }
260+ }
261+
262+ Row {
263+ spacing: units.gu(1)
264+ anchors {
265+ left: parent.left
266+ right: parent.right
267+ }
268+ CheckBox {
269+ id: showImageCheckBox
270+ }
271+ Label {
272+ text: "Show image instead of title"
273+ anchors.verticalCenter: parent.verticalCenter
274+ }
275+ }
254276 }
255277}
tests/qmltests/Components/tst_PageHeader/logo-ubuntu-orange.svgnew file+60
@@ -0,0 +1,60 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!-- Generator: Adobe Illustrator 17.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5+ width="107px" height="25px" viewBox="0 0 107 25" enable-background="new 0 0 107 25" xml:space="preserve">
6+<g id="BK">
7+</g>
8+<g id="Comp">
9+ <circle fill="#DD4814" cx="100.596" cy="7.374" r="6.403"/>
10+ <path fill="#FFFFFF" d="M96.6,6.605c-0.424,0-0.768,0.344-0.768,0.77c0,0.423,0.344,0.768,0.768,0.768
11+ c0.425,0,0.772-0.345,0.772-0.768C97.371,6.949,97.025,6.605,96.6,6.605z M102.094,10.103c-0.365,0.211-0.492,0.682-0.282,1.047
12+ c0.214,0.372,0.685,0.497,1.051,0.284c0.369-0.21,0.496-0.682,0.281-1.05C102.932,10.014,102.462,9.889,102.094,10.103z
13+ M98.272,7.375c0-0.76,0.378-1.434,0.956-1.839l-0.562-0.944c-0.675,0.451-1.176,1.138-1.384,1.943
14+ c0.246,0.2,0.398,0.501,0.398,0.84c0,0.337-0.152,0.639-0.398,0.838c0.208,0.805,0.709,1.492,1.384,1.941l0.562-0.941
15+ C98.65,8.807,98.272,8.134,98.272,7.375z M100.518,5.125c1.177,0,2.14,0.902,2.24,2.052l1.098-0.019
16+ c-0.055-0.846-0.425-1.61-0.994-2.166c-0.295,0.108-0.634,0.093-0.925-0.078c-0.292-0.168-0.473-0.452-0.524-0.761
17+ c-0.285-0.077-0.584-0.12-0.895-0.12c-0.53,0-1.032,0.125-1.48,0.345l0.535,0.958C99.86,5.201,100.182,5.125,100.518,5.125z
18+ M100.518,9.622c-0.336,0-0.658-0.076-0.945-0.21l-0.535,0.958c0.447,0.221,0.95,0.344,1.48,0.344c0.312,0,0.61-0.039,0.895-0.119
19+ c0.051-0.311,0.232-0.596,0.524-0.763c0.294-0.168,0.63-0.186,0.925-0.073c0.569-0.562,0.938-1.323,0.994-2.17l-1.098-0.015
20+ C102.658,8.721,101.695,9.622,100.518,9.622z M102.094,4.646c0.368,0.213,0.838,0.088,1.051-0.282
21+ c0.214-0.367,0.087-0.839-0.281-1.052c-0.366-0.211-0.837-0.085-1.051,0.283C101.601,3.962,101.728,4.433,102.094,4.646z"/>
22+ <path fill="#DD4814" d="M12.807,24.177c-0.649,0.162-1.509,0.337-2.577,0.518c-1.068,0.184-2.304,0.276-3.704,0.276
23+ c-1.222,0-2.247-0.179-3.082-0.535c-0.833-0.355-1.503-0.858-2.01-1.509c-0.509-0.65-0.875-1.419-1.098-2.302
24+ C0.11,19.739,0,18.76,0,17.68V8.778h2.835v8.293c0,1.932,0.304,3.315,0.916,4.147c0.61,0.834,1.636,1.249,3.079,1.249
25+ c0.304,0,0.62-0.01,0.945-0.031c0.326-0.02,0.632-0.045,0.914-0.075C8.974,22.33,9.234,22.3,9.468,22.27
26+ c0.234-0.032,0.401-0.065,0.504-0.108V8.778h2.835V24.177L12.807,24.177z"/>
27+ <path fill="#DD4814" d="M19.728,9.478c0.347-0.222,0.871-0.458,1.572-0.7c0.7-0.243,1.507-0.367,2.424-0.367
28+ c1.137,0,2.148,0.205,3.033,0.609c0.886,0.406,1.632,0.977,2.243,1.709c0.607,0.731,1.069,1.605,1.385,2.622
29+ c0.317,1.016,0.474,2.135,0.474,3.355c0,1.279-0.187,2.433-0.565,3.461c-0.377,1.025-0.909,1.894-1.6,2.605
30+ c-0.692,0.714-1.524,1.26-2.502,1.647C25.219,24.807,24.121,25,22.899,25c-1.321,0-2.49-0.093-3.506-0.276
31+ c-1.016-0.183-1.849-0.367-2.501-0.549V1.46l2.837-0.488L19.728,9.478L19.728,9.478z M19.728,22.162
32+ c0.285,0.084,0.686,0.159,1.206,0.23c0.517,0.073,1.161,0.107,1.935,0.107c1.523,0,2.746-0.504,3.659-1.509
33+ c0.915-1.007,1.373-2.435,1.373-4.284c0-0.813-0.081-1.575-0.245-2.288c-0.163-0.712-0.428-1.326-0.793-1.845
34+ c-0.366-0.519-0.839-0.923-1.416-1.219c-0.582-0.297-1.278-0.444-2.09-0.444c-0.774,0-1.484,0.133-2.135,0.395
35+ c-0.651,0.267-1.149,0.541-1.495,0.825v10.032H19.728z"/>
36+ <path fill="#DD4814" d="M46.684,24.177c-0.651,0.162-1.509,0.337-2.576,0.518c-1.067,0.184-2.303,0.276-3.707,0.276
37+ c-1.219,0-2.246-0.179-3.079-0.535c-0.833-0.355-1.504-0.858-2.011-1.509c-0.511-0.65-0.875-1.419-1.098-2.302
38+ c-0.224-0.886-0.335-1.865-0.335-2.944V8.778h2.835v8.293c0,1.932,0.304,3.315,0.914,4.147c0.611,0.834,1.636,1.249,3.08,1.249
39+ c0.305,0,0.622-0.01,0.947-0.031c0.325-0.02,0.629-0.045,0.915-0.075c0.284-0.032,0.544-0.062,0.779-0.092
40+ c0.232-0.032,0.4-0.065,0.503-0.108V8.778h2.835v15.399H46.684z"/>
41+ <path fill="#DD4814" d="M50.769,9.236c0.651-0.164,1.514-0.335,2.593-0.521c1.077-0.18,2.316-0.272,3.719-0.272
42+ c1.263,0,2.308,0.178,3.142,0.533c0.834,0.356,1.499,0.853,1.997,1.494c0.498,0.64,0.849,1.408,1.053,2.3
43+ c0.202,0.898,0.304,1.882,0.304,2.959v8.905h-2.836V16.34c0-0.977-0.067-1.809-0.198-2.501c-0.132-0.693-0.351-1.249-0.656-1.676
44+ c-0.303-0.429-0.712-0.738-1.221-0.93c-0.506-0.197-1.139-0.292-1.888-0.292c-0.306,0-0.622,0.012-0.944,0.032
45+ c-0.326,0.021-0.637,0.046-0.931,0.076c-0.298,0.03-0.56,0.067-0.794,0.107c-0.235,0.041-0.402,0.072-0.503,0.091v13.386h-2.837
46+ L50.769,9.236L50.769,9.236z"/>
47+ <path fill="#DD4814" d="M70.132,8.778h6.008v2.378h-6.008v7.319c0,0.792,0.062,1.45,0.185,1.966
48+ c0.121,0.52,0.304,0.927,0.548,1.221c0.244,0.292,0.549,0.501,0.914,0.625c0.367,0.122,0.794,0.182,1.28,0.182
49+ c0.874,0,1.565-0.096,2.076-0.29c0.507-0.193,0.853-0.329,1.035-0.412l0.609,2.32c-0.283,0.142-0.787,0.324-1.508,0.547
50+ c-0.722,0.225-1.539,0.338-2.454,0.338c-1.078,0-1.968-0.137-2.669-0.413c-0.701-0.275-1.265-0.685-1.692-1.234
51+ c-0.427-0.548-0.727-1.224-0.898-2.027c-0.175-0.805-0.26-1.734-0.26-2.79V4.356l2.833-0.489v4.911H70.132z"/>
52+ <path fill="#DD4814" d="M91.57,24.177c-0.653,0.162-1.51,0.337-2.579,0.518c-1.067,0.184-2.3,0.276-3.701,0.276
53+ c-1.222,0-2.247-0.179-3.081-0.535c-0.836-0.355-1.506-0.858-2.013-1.509c-0.509-0.65-0.873-1.419-1.1-2.302
54+ c-0.221-0.886-0.335-1.865-0.335-2.944V8.778h2.838v8.293c0,1.932,0.305,3.315,0.914,4.147c0.609,0.834,1.637,1.249,3.081,1.249
55+ c0.304,0,0.618-0.01,0.945-0.031c0.323-0.02,0.629-0.045,0.914-0.075c0.284-0.032,0.546-0.062,0.777-0.092
56+ c0.234-0.032,0.403-0.065,0.505-0.108V8.778h2.837v15.399H91.57z"/>
57+</g>
58+<g id="Grid" display="none">
59+</g>
60+</svg>
tests/qmltests/Dash/tst_GenericScopeView.qml+1−1
@@ -48,7 +48,7 @@ Item {
4848 signal mainStageFocusedApplicationChanged()
4949 }
5050
51− PageHeaderLabel {
51+ PageHeader {
5252 id: testPageHeader
5353 searchHistory: SearchHistoryModel {}
5454 text: genericScopeView.scope ? genericScopeView.scope.name : ""