Merge lp:~ahayzen/ubuntu-weather-app/uc1.3-migrations into lp:ubuntu-weather-app

Proposed by Andrew Hayzen on 2016-07-19
Status: Merged
Approved by: Andrew Hayzen on 2017-04-13
Approved revision: 257
Merged at revision: 267
Proposed branch: lp:~ahayzen/ubuntu-weather-app/uc1.3-migrations
Merge into: lp:ubuntu-weather-app
Diff against target: 1319 lines (+287/-683)
17 files modified
app/components/CMakeLists.txt (+1/-0)
app/components/ExpandableListItem.qml (+3/-0)
app/components/FakeHeader.qml (+0/-39)
app/components/HeadState/CMakeLists.txt (+4/-0)
app/components/HeadState/LocationsHeadState.qml (+57/-0)
app/components/HeadState/MultiSelectHeadState.qml (+51/-40)
app/components/PageWithBottomEdge.qml (+0/-472)
app/components/StandardListItem.qml (+4/-0)
app/ui/AddLocationPage.qml (+29/-22)
app/ui/HomePage.qml (+28/-7)
app/ui/LocationsPage.qml (+10/-22)
app/ui/SettingsPage.qml (+2/-0)
debian/changelog (+2/-0)
po/com.ubuntu.weather.pot (+20/-18)
tests/autopilot/ubuntu_weather_app/__init__.py (+49/-47)
tests/autopilot/ubuntu_weather_app/tests/__init__.py (+26/-15)
tests/autopilot/ubuntu_weather_app/tests/test_settings_page.py (+1/-1)
To merge this branch: bzr merge lp:~ahayzen/ubuntu-weather-app/uc1.3-migrations
Reviewer Review Type Date Requested Status
Michael Sheldon (community) Approve on 2017-04-13
Jenkins Bot continuous-integration Approve on 2017-04-13
Ubuntu Weather Developers 2016-07-19 Pending
Review via email: mp+300508@code.launchpad.net

Commit message

* Migrate to use new uc1.3 page headers - also fixes topMargin on bottom edge page
* Migrate to use sdk bottom edge

Description of the change

* Migrate to use new uc1.3 page headers - also fixes topMargin on bottom edge page
* Migrate to use sdk bottom edge

To post a comment you must log in.
review: Approve (continuous-integration)
249. By Andrew Hayzen on 2016-07-19

* Show hint text on desktop

review: Approve (continuous-integration)
250. By Andrew Hayzen on 2016-07-19

* Leave text out for now as it causes issues

review: Approve (continuous-integration)
251. By Andrew Hayzen on 2016-07-20

* Prepare for when bottomedgehint works with a mouse

review: Needs Fixing (continuous-integration)
252. By Andrew Hayzen on 2016-07-20

* Merge of trunk

253. By Andrew Hayzen on 2016-07-20

* Fix changelog :-)

review: Approve (continuous-integration)
254. By Andrew Hayzen on 2017-04-12

* Pull of upstream

review: Approve (continuous-integration)
255. By Andrew Hayzen on 2017-04-12

* Fix content going behind bottom edge hint
* Remove unneeded height/width in LocationsPage.qml and comment on what pop() is used for

review: Approve (continuous-integration)
256. By Andrew Hayzen on 2017-04-13

* Fix autopilot tests

review: Approve (continuous-integration)
257. By Andrew Hayzen on 2017-04-13

* Remove old components

Andrew Hayzen (ahayzen) wrote :

All tests now pass :-D

$ autopilot3 run ubuntu_weather_app
Loading tests from: /home/andrew/Workspace/Work/Canonical/code/ubuntu-weather-app/uc1.3-migrations/tests/autopilot

Tests running...

Ran 15 tests in 94.413s
OK
$ pep8 .
$ pyflakes .

review: Approve (continuous-integration)
Michael Sheldon (michael-sheldon) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/components/CMakeLists.txt'
2--- app/components/CMakeLists.txt 2015-03-03 18:37:59 +0000
3+++ app/components/CMakeLists.txt 2017-04-13 10:51:15 +0000
4@@ -1,3 +1,4 @@
5+add_subdirectory(HeadState)
6 add_subdirectory(ListItemActions)
7
8 file(GLOB COMPONENTS_QML_JS_FILES *.qml *.js)
9
10=== modified file 'app/components/ExpandableListItem.qml'
11--- app/components/ExpandableListItem.qml 2016-02-28 22:58:51 +0000
12+++ app/components/ExpandableListItem.qml 2017-04-13 10:51:15 +0000
13@@ -35,6 +35,9 @@
14 property alias subText: expandableHeader.subtitle
15 property alias listViewHeight: expandableList.height
16
17+ // For autopilot
18+ readonly property double expansionHeight: expansion.height
19+
20 highlightColor: "Transparent"
21 height: expandableHeader.height + divider.height
22 expansion.height: contentColumn.height
23
24=== removed file 'app/components/FakeHeader.qml'
25--- app/components/FakeHeader.qml 2015-11-02 21:28:34 +0000
26+++ app/components/FakeHeader.qml 1970-01-01 00:00:00 +0000
27@@ -1,39 +0,0 @@
28-/*
29- * Copyright (C) 2014 Canonical Ltd
30- *
31- * This file is part of Ubuntu Clock App
32- *
33- * Ubuntu Clock App is free software: you can redistribute it and/or modify
34- * it under the terms of the GNU General Public License version 3 as
35- * published by the Free Software Foundation.
36- *
37- * Ubuntu Clock App is distributed in the hope that it will be useful,
38- * but WITHOUT ANY WARRANTY; without even the implied warranty of
39- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40- * GNU General Public License for more details.
41- *
42- * You should have received a copy of the GNU General Public License
43- * along with this program. If not, see <http://www.gnu.org/licenses/>.
44- */
45-
46-import QtQuick 2.4
47-import Ubuntu.Components 1.3
48-
49-Column {
50- id: fakeHeader
51-
52- height: units.gu(6.125)
53-
54- Rectangle {
55- height: units.gu(6)
56- width: parent.width
57- color: Theme.palette.normal.background
58- }
59-
60- Rectangle {
61- color: "#C9C9C9"
62- height: units.gu(0.125)
63- anchors.left: parent.left
64- anchors.right: parent.right
65- }
66-}
67
68=== added directory 'app/components/HeadState'
69=== added file 'app/components/HeadState/CMakeLists.txt'
70--- app/components/HeadState/CMakeLists.txt 1970-01-01 00:00:00 +0000
71+++ app/components/HeadState/CMakeLists.txt 2017-04-13 10:51:15 +0000
72@@ -0,0 +1,4 @@
73+# make the qml files visible on qtcreator
74+file(GLOB HEAD_STATE_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml)
75+
76+add_custom_target(com_ubuntu_music_HEAD_STATE_QMLFiles ALL SOURCES ${HEAD_STATE_QML_FILES})
77
78=== added file 'app/components/HeadState/LocationsHeadState.qml'
79--- app/components/HeadState/LocationsHeadState.qml 1970-01-01 00:00:00 +0000
80+++ app/components/HeadState/LocationsHeadState.qml 2017-04-13 10:51:15 +0000
81@@ -0,0 +1,57 @@
82+/*
83+ * Copyright (C) 2016
84+ * Andrew Hayzen <ahayzen@gmail.com>
85+ * Victor Thompson <victor.thompson@gmail.com>
86+ *
87+ * This program is free software; you can redistribute it and/or modify
88+ * it under the terms of the GNU General Public License as published by
89+ * the Free Software Foundation; version 3.
90+ *
91+ * This program is distributed in the hope that it will be useful,
92+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
93+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
94+ * GNU General Public License for more details.
95+ *
96+ * You should have received a copy of the GNU General Public License
97+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
98+ */
99+
100+import QtQuick 2.4
101+import Ubuntu.Components 1.3
102+
103+
104+State {
105+ name: "default"
106+
107+ property PageHeader thisHeader: PageHeader {
108+ flickable: thisPage.flickable
109+ leadingActionBar {
110+ actions: [
111+ Action {
112+ iconName: "down"
113+ objectName: "back"
114+ onTriggered: thisPage.pop()
115+ }
116+ ]
117+ objectName: "locationsLeadingActionBar"
118+ }
119+ title: i18n.tr("Locations")
120+ trailingActionBar {
121+ actions: [
122+ Action {
123+ iconName: "add"
124+ objectName: "addLocation"
125+ onTriggered: mainPageStack.push(Qt.resolvedUrl("../../ui/AddLocationPage.qml"))
126+ }
127+ ]
128+ objectName: "locationsTrailingActionBar"
129+ }
130+ visible: thisPage.state === "default"
131+ }
132+ property Item thisPage
133+
134+ PropertyChanges {
135+ target: thisPage
136+ header: thisHeader
137+ }
138+}
139
140=== renamed file 'app/components/MultiSelectHeadState.qml' => 'app/components/HeadState/MultiSelectHeadState.qml'
141--- app/components/MultiSelectHeadState.qml 2015-11-02 21:28:34 +0000
142+++ app/components/HeadState/MultiSelectHeadState.qml 2017-04-13 10:51:15 +0000
143@@ -19,49 +19,55 @@
144 import QtQuick 2.4
145 import Ubuntu.Components 1.3
146
147-PageHeadState {
148+
149+State {
150 id: selectionState
151- actions: [
152- Action {
153- iconName: "select"
154- text: i18n.tr("Select All")
155- onTriggered: {
156- if (listview.selectedItems.length === listview.model.count) {
157- listview.clearSelection()
158- } else {
159- listview.selectAll()
160- }
161- }
162- },
163- Action {
164- enabled: listview.selectedItems.length > 0
165- iconName: "delete"
166- text: i18n.tr("Delete")
167- visible: removable
168-
169- onTriggered: {
170- removed(listview.selectedItems)
171-
172- listview.closeSelection()
173- }
174- }
175-
176- ]
177- backAction: Action {
178- text: i18n.tr("Cancel selection")
179- iconName: "back"
180- onTriggered: {
181- listview.clearSelection()
182- listview.state = "normal"
183- }
184- }
185- head: thisPage.head
186 name: "selection"
187
188- PropertyChanges {
189- target: thisPage.head
190- backAction: selectionState.backAction
191- actions: selectionState.actions
192+ property PageHeader thisHeader: PageHeader {
193+ flickable: thisPage.flickable
194+ leadingActionBar {
195+ actions: [
196+ Action {
197+ text: i18n.tr("Cancel selection")
198+ iconName: "back"
199+ onTriggered: {
200+ listview.clearSelection()
201+ listview.state = "normal"
202+ }
203+ }
204+ ]
205+ }
206+ title: i18n.tr("Locations")
207+ trailingActionBar {
208+ actions: [
209+ Action {
210+ iconName: "select"
211+ text: i18n.tr("Select All")
212+ onTriggered: {
213+ if (listview.selectedItems.length === listview.model.count) {
214+ listview.clearSelection()
215+ } else {
216+ listview.selectAll()
217+ }
218+ }
219+ },
220+ Action {
221+ enabled: listview.selectedItems.length > 0
222+ iconName: "delete"
223+ text: i18n.tr("Delete")
224+ visible: removable
225+
226+ onTriggered: {
227+ removed(listview.selectedItems)
228+
229+ listview.closeSelection()
230+ }
231+ }
232+
233+ ]
234+ }
235+ visible: thisPage.state === "selection"
236 }
237
238 property ListView listview
239@@ -69,4 +75,9 @@
240 property Page thisPage
241
242 signal removed(var selectedItems)
243+
244+ PropertyChanges {
245+ target: thisPage
246+ header: thisHeader
247+ }
248 }
249
250=== removed file 'app/components/PageWithBottomEdge.qml'
251--- app/components/PageWithBottomEdge.qml 2015-11-26 02:38:29 +0000
252+++ app/components/PageWithBottomEdge.qml 1970-01-01 00:00:00 +0000
253@@ -1,472 +0,0 @@
254-/*
255- * Copyright (C) 2014, 2015 Canonical, Ltd.
256- *
257- * This program is free software; you can redistribute it and/or modify
258- * it under the terms of the GNU General Public License as published by
259- * the Free Software Foundation; version 3.
260- *
261- * This program is distributed in the hope that it will be useful,
262- * but WITHOUT ANY WARRANTY; without even the implied warranty of
263- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
264- * GNU General Public License for more details.
265- *
266- * You should have received a copy of the GNU General Public License
267- * along with this program. If not, see <http://www.gnu.org/licenses/>.
268- */
269-
270-/*
271- Example:
272-
273- MainView {
274- objectName: "mainView"
275-
276- applicationName: "com.ubuntu.developer.boiko.bottomedge"
277-
278- width: units.gu(100)
279- height: units.gu(75)
280-
281- Component {
282- id: pageComponent
283-
284- PageWithBottomEdge {
285- id: mainPage
286- title: i18n.tr("Main Page")
287-
288- Rectangle {
289- anchors.fill: parent
290- color: "white"
291- }
292-
293- bottomEdgePageComponent: Page {
294- title: "Contents"
295- anchors.fill: parent
296- //anchors.topMargin: contentsPage.flickable.contentY
297-
298- ListView {
299- anchors.fill: parent
300- model: 50
301- delegate: ListItems.Standard {
302- text: "One Content Item: " + index
303- }
304- }
305- }
306- bottomEdgeTitle: i18n.tr("Bottom edge action")
307- }
308- }
309-
310- PageStack {
311- id: stack
312- Component.onCompleted: stack.push(pageComponent)
313- }
314- }
315-
316-*/
317-
318-import QtQuick 2.4
319-import Ubuntu.Components 1.3
320-
321-Page {
322- id: page
323-
324- property alias bottomEdgePageComponent: edgeLoader.sourceComponent
325- property alias bottomEdgePageSource: edgeLoader.source
326- property alias bottomEdgeTitle: tipLabel.text
327- property bool bottomEdgeEnabled: true
328- property int bottomEdgeExpandThreshold: page.height * 0.2
329- property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
330- property bool reloadBottomEdgePage: true
331-
332- readonly property alias bottomEdgePage: edgeLoader.item
333- // FIXME: 6.125 is the header.height
334- readonly property bool isReady: ((bottomEdge.y === units.gu(6.125)) && bottomEdgePageLoaded && edgeLoader.item.active) // CUSTOM change to flag to allow for FakeHeader height
335- readonly property bool isCollapsed: (bottomEdge.y === page.height)
336- readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
337-
338- property bool _showEdgePageWhenReady: false
339- property int _areaWhenExpanded: 0
340-
341- // CUSTOM properties to allow changing of color
342- property alias tipColor: tip.backgroundColor // CUSTOM color => backgroundColor
343- property alias tipLabelColor: tipLabel.color
344-
345- signal bottomEdgeReleased()
346- signal bottomEdgeDismissed()
347-
348- function showBottomEdgePage(source, properties)
349- {
350- edgeLoader.setSource(source, properties)
351- _showEdgePageWhenReady = true
352- }
353-
354- function setBottomEdgePage(source, properties)
355- {
356- edgeLoader.setSource(source, properties)
357- }
358-
359- function _pushPage()
360- {
361- if (edgeLoader.status === Loader.Ready) {
362- edgeLoader.item.active = true
363- page.pageStack.push(edgeLoader.item)
364- if (edgeLoader.item.flickable) {
365- edgeLoader.item.flickable.contentY = -units.gu(6.125) // FIXME: 6.125 is the header.height
366- edgeLoader.item.flickable.returnToBounds()
367- }
368- if (edgeLoader.item.ready)
369- edgeLoader.item.ready()
370- }
371- }
372-
373-
374- Component.onCompleted: {
375- // avoid a binding on the expanded height value
376- var expandedHeight = height;
377- _areaWhenExpanded = expandedHeight;
378- }
379-
380- onActiveChanged: {
381- if (active) {
382- bottomEdge.state = "collapsed"
383- }
384- }
385-
386- onBottomEdgePageLoadedChanged: {
387- if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
388- bottomEdge.state = "expanded"
389- _showEdgePageWhenReady = false
390- }
391- }
392-
393- Rectangle {
394- id: bgVisual
395-
396- color: "black"
397- anchors.fill: page
398- opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
399- z: 1
400- }
401-
402- UbuntuShape {
403- id: tip
404- objectName: "bottomEdgeTip"
405-
406- property bool hidden: (activeFocus === false) || ((bottomEdge.y - units.gu(1)) < tip.y)
407-
408- // CUSTOM
409- property bool isAnimating: true
410-
411- enabled: mouseArea.enabled
412- visible: page.bottomEdgeEnabled
413- anchors {
414- bottom: parent.bottom
415- horizontalCenter: bottomEdge.horizontalCenter
416- bottomMargin: hidden ? - height + units.gu(1) : -units.gu(1)
417- Behavior on bottomMargin {
418- SequentialAnimation {
419- // wait some msecs in case of the focus change again, to avoid flickering
420- PauseAnimation {
421- duration: 300
422- }
423- UbuntuNumberAnimation {
424- duration: UbuntuAnimation.SnapDuration
425- }
426- // CUSTOM
427- ScriptAction {
428- script: tip.isAnimating = false
429- }
430- }
431- }
432- }
433-
434- z: 1
435- width: tipLabel.paintedWidth + units.gu(6)
436- height: bottomEdge.tipHeight + units.gu(1)
437- backgroundColor: Theme.palette.normal.overlay // CUSTOM color => backgroundColor
438- Label {
439- id: tipLabel
440-
441- anchors {
442- top: parent.top
443- left: parent.left
444- right: parent.right
445- }
446- height: bottomEdge.tipHeight
447- verticalAlignment: Text.AlignVCenter
448- horizontalAlignment: Text.AlignHCenter
449- opacity: tip.hidden ? 0.0 : 1.0
450- Behavior on opacity {
451- UbuntuNumberAnimation {
452- duration: UbuntuAnimation.SnapDuration
453- }
454- }
455- }
456- }
457-
458- Rectangle {
459- id: shadow
460-
461- anchors {
462- left: parent.left
463- right: parent.right
464- bottom: parent.bottom
465- }
466- height: units.gu(1)
467- z: 1
468- opacity: 0.0
469- gradient: Gradient {
470- GradientStop { position: 0.0; color: "transparent" }
471- GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
472- }
473- }
474-
475- MouseArea {
476- id: mouseArea
477-
478- property real previousY: -1
479- property string dragDirection: "None"
480-
481- preventStealing: true
482- drag {
483- axis: Drag.YAxis
484- target: bottomEdge
485- minimumY: bottomEdge.pageStartY
486- maximumY: page.height
487- }
488- enabled: edgeLoader.status == Loader.Ready
489- visible: page.bottomEdgeEnabled
490-
491- anchors {
492- left: parent.left
493- right: parent.right
494- bottom: parent.bottom
495- }
496- height: bottomEdge.tipHeight
497- z: 1
498-
499- onReleased: {
500- page.bottomEdgeReleased()
501- if ((dragDirection === "BottomToTop") &&
502- bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
503- bottomEdge.state = "expanded"
504- } else {
505- bottomEdge.state = "collapsed"
506- }
507- previousY = -1
508- dragDirection = "None"
509- }
510-
511- onPressed: {
512- previousY = mouse.y
513- tip.forceActiveFocus()
514- }
515-
516- onMouseYChanged: {
517- var yOffset = previousY - mouseY
518- // skip if was a small move
519- if (Math.abs(yOffset) <= units.gu(2)) {
520- return
521- }
522- previousY = mouseY
523- dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom"
524- }
525- }
526-
527- // CUSTOM fake header to make the page with bottom edge transition smoother
528- FakeHeader {
529- id: fakeHeader
530-
531- anchors {
532- left: parent.left
533- right: parent.right
534- }
535- // FIXME: 6.125 is the header.height
536- y: -units.gu(6.125) + (units.gu(6.125) * (page.height - bottomEdge.y)) / (page.height - units.gu(6.125))
537- z: bgVisual.z + 1
538-
539- Behavior on y {
540- UbuntuNumberAnimation {
541- duration: UbuntuAnimation.SnapDuration
542- }
543- }
544- }
545-
546- Rectangle {
547- id: bottomEdge
548- objectName: "bottomEdge"
549-
550- readonly property int tipHeight: units.gu(3)
551- // CUSTOM value
552- readonly property int pageStartY: units.gu(6.125) // FIXME: 6.125 is the header.height
553-
554- z: 1
555- color: Theme.palette.normal.background
556- clip: true
557- anchors {
558- left: parent.left
559- right: parent.right
560- }
561- height: page.height
562- y: height
563-
564- visible: !page.isCollapsed
565- state: "collapsed"
566- states: [
567- State {
568- name: "collapsed"
569- PropertyChanges {
570- target: bottomEdge
571- y: bottomEdge.height
572- }
573- // CUSTOM
574- PropertyChanges {
575- target: fakeHeader
576- y: -units.gu(6.125) // FIXME: 6.125 is the header.height
577- }
578- },
579- State {
580- name: "expanded"
581- PropertyChanges {
582- target: bottomEdge
583- y: bottomEdge.pageStartY
584- }
585- // CUSTOM
586- PropertyChanges {
587- target: fakeHeader
588- y: 0
589- }
590- },
591- State {
592- name: "floating"
593- when: mouseArea.drag.active
594- PropertyChanges {
595- target: shadow
596- opacity: 1.0
597- }
598- }
599- ]
600-
601- transitions: [
602- Transition {
603- to: "expanded"
604- SequentialAnimation {
605- alwaysRunToEnd: true
606- ParallelAnimation {
607- SmoothedAnimation {
608- target: bottomEdge
609- property: "y"
610- duration: UbuntuAnimation.FastDuration
611- easing.type: Easing.Linear
612- }
613- // CUSTOM
614- SmoothedAnimation {
615- target: fakeHeader
616- property: "y"
617- duration: UbuntuAnimation.FastDuration
618- easing.type: Easing.Linear
619- }
620- }
621- SmoothedAnimation {
622- target: edgeLoader
623- property: "anchors.topMargin"
624- // CUSTOM make small to reduce 'bump' when pushing
625- to: -0.1 // FIXME: 6.125 is header height
626- duration: UbuntuAnimation.FastDuration
627- easing.type: Easing.Linear
628- }
629- SmoothedAnimation {
630- target: edgeLoader
631- property: "anchors.topMargin"
632- to: 0
633- duration: UbuntuAnimation.FastDuration
634- easing: UbuntuAnimation.StandardEasing
635- }
636- ScriptAction {
637- script: page._pushPage()
638- }
639- }
640- },
641- Transition {
642- from: "expanded"
643- to: "collapsed"
644- SequentialAnimation {
645- alwaysRunToEnd: true
646-
647- ScriptAction {
648- script: {
649- Qt.inputMethod.hide()
650- edgeLoader.item.parent = edgeLoader
651- edgeLoader.item.anchors.fill = edgeLoader
652- edgeLoader.item.active = false
653- }
654- }
655- ParallelAnimation {
656- SmoothedAnimation {
657- target: bottomEdge
658- property: "y"
659- duration: UbuntuAnimation.SlowDuration
660- }
661- // CUSTOM
662- SmoothedAnimation {
663- target: fakeHeader
664- property: "y"
665- duration: UbuntuAnimation.SlowDuration
666- }
667- }
668- ScriptAction {
669- script: {
670- // destroy current bottom page
671- if (page.reloadBottomEdgePage) {
672- edgeLoader.active = false
673- } else {
674- tip.forceActiveFocus()
675- }
676-
677- // CUSTOM reset the topMargin for next pull
678- edgeLoader.anchors.topMargin = units.gu(6.125)
679-
680- // notify
681- page.bottomEdgeDismissed()
682-
683- edgeLoader.active = true
684- }
685- }
686- }
687- },
688- Transition {
689- from: "floating"
690- to: "collapsed"
691- // MODIFIED
692- UbuntuNumberAnimation {
693- target: bottomEdge
694- property: "opacity"
695- }
696- }
697- ]
698-
699- Loader {
700- id: edgeLoader
701-
702- asynchronous: true
703- anchors {
704- fill: parent
705- topMargin: units.gu(6.125) // CUSTOM
706- }
707- //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
708- /* // CUSTOM
709- Binding {
710- target: edgeLoader.status === Loader.Ready ? edgeLoader : null
711- property: "anchors.topMargin"
712- value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
713- when: !page.isReady
714- }
715- */
716-
717- onLoaded: {
718- tip.forceActiveFocus()
719- if (page.isReady && edgeLoader.item.active !== true) {
720- page._pushPage()
721- }
722- }
723- }
724- }
725-}
726
727=== modified file 'app/components/StandardListItem.qml'
728--- app/components/StandardListItem.qml 2016-02-28 22:49:32 +0000
729+++ app/components/StandardListItem.qml 2017-04-13 10:51:15 +0000
730@@ -25,6 +25,10 @@
731 property alias title: listitemlayout.title
732 property alias icon: _icon
733
734+ // For autopilot
735+ readonly property bool iconVisible: icon.visible
736+ readonly property string titleValue: title.text
737+
738 height: listitemlayout.height + divider.height
739
740 ListItemLayout {
741
742=== modified file 'app/ui/AddLocationPage.qml'
743--- app/ui/AddLocationPage.qml 2016-02-28 22:12:22 +0000
744+++ app/ui/AddLocationPage.qml 2017-04-13 10:51:15 +0000
745@@ -42,35 +42,42 @@
746 */
747 flickable: null
748 visible: addLocationPage.header === standardHeader
749- trailingActionBar.actions: [
750- Action {
751- iconName: "search"
752- objectName: "search"
753- text: i18n.tr("City")
754- onTriggered: {
755- addLocationPage.header = searchHeader
756- searchComponentLoader.sourceComponent = searchComponent
757- searchComponentLoader.item.forceActiveFocus()
758+ trailingActionBar {
759+ actions: [
760+ Action {
761+ iconName: "search"
762+ objectName: "search"
763+ text: i18n.tr("City")
764+ onTriggered: {
765+ addLocationPage.header = searchHeader
766+ searchComponentLoader.sourceComponent = searchComponent
767+ searchComponentLoader.item.forceActiveFocus()
768+ }
769 }
770- }
771- ]
772+ ]
773+ objectName: "addLocationTrailingActionBar"
774+ }
775 }
776
777 PageHeader {
778 id: searchHeader
779 visible: addLocationPage.header === searchHeader
780- leadingActionBar.actions: [
781- Action {
782- iconName: "back"
783- text: i18n.tr("Back")
784- onTriggered: {
785- locationList.forceActiveFocus()
786- searchComponentLoader.item.text = ""
787- addLocationPage.header = standardHeader
788- searchComponentLoader.sourceComponent = undefined
789+ leadingActionBar {
790+ actions: [
791+ Action {
792+ iconName: "back"
793+ objectName: "pagestack_back_action_button"
794+ text: i18n.tr("Back")
795+
796+ onTriggered: {
797+ locationList.forceActiveFocus()
798+ searchComponentLoader.item.text = ""
799+ addLocationPage.header = standardHeader
800+ searchComponentLoader.sourceComponent = undefined
801+ }
802 }
803- }
804- ]
805+ ]
806+ }
807 contents: Loader {
808 id: searchComponentLoader
809 anchors {
810
811=== modified file 'app/ui/HomePage.qml'
812--- app/ui/HomePage.qml 2016-08-25 07:47:46 +0000
813+++ app/ui/HomePage.qml 2017-04-13 10:51:15 +0000
814@@ -22,16 +22,35 @@
815 import "../data/keys.js" as Keys
816
817
818-PageWithBottomEdge {
819+Page {
820 // Set to null otherwise the header is shown (but blank) over the top of the listview
821 id: locationPage
822 objectName: "homePage"
823 flickable: null
824
825- bottomEdgePageSource: Qt.resolvedUrl("LocationsPage.qml")
826- bottomEdgeTitle: i18n.tr("Locations")
827- tipColor: UbuntuColors.orange
828- tipLabelColor: "#FFF"
829+ BottomEdge {
830+ id: bottomEdge
831+ // Note: cannot use contentUrl and preload until pad.lv/1604509
832+ contentComponent: locationsPage
833+ height: parent.height
834+ preloadContent: true
835+ hint {
836+ // Once pad.lv/1536669 is fixed, the status will be auto set to
837+ // locked when a mouse is detected, in that case we'll show text
838+ // otherwise we hide the text as this causes strange animations
839+ text: bottomEdge.hint.status == BottomEdgeHint.Locked ? i18n.tr("Locations") : ""
840+ }
841+
842+ Component {
843+ id: locationsPage
844+ LocationsPage {
845+ height: bottomEdge.height
846+ width: bottomEdge.width
847+
848+ onPop: bottomEdge.collapse()
849+ }
850+ }
851+ }
852
853 property bool hourlyVisible : false
854
855@@ -106,8 +125,10 @@
856 ListView {
857 id: locationPages
858 objectName: "locationPages"
859- anchors.fill: parent
860- contentHeight: parent.height
861+ anchors {
862+ fill: parent
863+ }
864+ contentHeight: parent.height - bottomEdge.hint.height
865 currentIndex: settings.current
866 delegate: LocationPane {
867 objectName: "locationPane" + index
868
869=== modified file 'app/ui/LocationsPage.qml'
870--- app/ui/LocationsPage.qml 2016-03-26 16:38:54 +0000
871+++ app/ui/LocationsPage.qml 2017-04-13 10:51:15 +0000
872@@ -20,33 +20,17 @@
873 import Ubuntu.Components 1.3
874 import Ubuntu.Components.ListItems 0.1 as ListItem
875 import "../components"
876+import "../components/HeadState"
877 import "../components/ListItemActions"
878
879
880 Page {
881 id: locationsPage
882 objectName: "locationsPage"
883- title: i18n.tr("Locations")
884-
885 state: locationsListView.state === "multiselectable" ? "selection" : "default"
886 states: [
887- PageHeadState {
888- id: defaultState
889- head: locationsPage.head
890- name: "default"
891- actions: [
892- Action {
893- iconName: "add"
894- objectName: "addLocation"
895- onTriggered: mainPageStack.push(Qt.resolvedUrl("AddLocationPage.qml"))
896- }
897- ]
898- backAction: Action {
899- iconName: "down"
900- onTriggered: {
901- pageStack.pop()
902- }
903- }
904+ LocationsHeadState {
905+ thisPage: locationsPage
906 },
907 MultiSelectHeadState {
908 listview: locationsListView
909@@ -57,6 +41,9 @@
910 }
911 ]
912
913+ // This is used by the header state (LocationsHeadState) to go back
914+ signal pop()
915+
916 ListModel {
917 id: currentLocationModel
918 }
919@@ -64,9 +51,10 @@
920 MultiSelectListView {
921 id: locationsListView
922 anchors {
923- fill: parent
924- // TODO: Fix this offset
925- topMargin: -units.gu(6.125) // FIXME: 6.125 is the header.height
926+ bottom: parent.bottom
927+ left: parent.left
928+ right: parent.right
929+ top: locationsPage.header.bottom
930 }
931 model: ListModel {
932 id: locationsModel
933
934=== modified file 'app/ui/SettingsPage.qml'
935--- app/ui/SettingsPage.qml 2016-02-28 22:12:41 +0000
936+++ app/ui/SettingsPage.qml 2017-04-13 10:51:15 +0000
937@@ -40,6 +40,8 @@
938 }
939
940 ListItem {
941+ objectName: "units"
942+
943 ListItemLayout {
944 title.text: i18n.tr("Units")
945 ProgressionSlot{}
946
947=== modified file 'debian/changelog'
948--- debian/changelog 2017-04-12 10:28:01 +0000
949+++ debian/changelog 2017-04-13 10:51:15 +0000
950@@ -3,6 +3,8 @@
951 [ Andrew Hayzen ]
952 * Release 3.4 and bump version to 3.5
953 * Add support for showing updated X minutes ago (LP: #1583169)
954+ * Migrate to use new uc1.3 page headers - also fixes topMargin on bottom edge page
955+ * Migrate to use sdk bottom edge
956
957 -- Andrew Hayzen <ahayzen@gmail.com> Wed, 17 Aug 2016 21:10:10 +0100
958
959
960=== modified file 'po/com.ubuntu.weather.pot'
961--- po/com.ubuntu.weather.pot 2017-04-12 09:55:14 +0000
962+++ po/com.ubuntu.weather.pot 2017-04-13 10:51:15 +0000
963@@ -8,7 +8,7 @@
964 msgstr ""
965 "Project-Id-Version: ubuntu-weather-app\n"
966 "Report-Msgid-Bugs-To: \n"
967-"POT-Creation-Date: 2017-04-12 10:54+0100\n"
968+"POT-Creation-Date: 2017-04-12 12:07+0100\n"
969 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
970 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
971 "Language-Team: LANGUAGE <LL@li.org>\n"
972@@ -46,6 +46,24 @@
973 msgid "Sunset"
974 msgstr ""
975
976+#: ../app/components/HeadState/LocationsHeadState.qml:36
977+#: ../app/components/HeadState/MultiSelectHeadState.qml:41
978+#: ../app/ui/HomePage.qml:41
979+msgid "Locations"
980+msgstr ""
981+
982+#: ../app/components/HeadState/MultiSelectHeadState.qml:32
983+msgid "Cancel selection"
984+msgstr ""
985+
986+#: ../app/components/HeadState/MultiSelectHeadState.qml:46
987+msgid "Select All"
988+msgstr ""
989+
990+#: ../app/components/HeadState/MultiSelectHeadState.qml:58
991+msgid "Delete"
992+msgstr ""
993+
994 #: ../app/components/HomePageEmptyStateComponent.qml:51
995 msgid "Searching for current location..."
996 msgstr ""
997@@ -95,18 +113,6 @@
998 msgid "No locations found. Tap the plus icon to search for one."
999 msgstr ""
1000
1001-#: ../app/components/MultiSelectHeadState.qml:27
1002-msgid "Select All"
1003-msgstr ""
1004-
1005-#: ../app/components/MultiSelectHeadState.qml:39
1006-msgid "Delete"
1007-msgstr ""
1008-
1009-#: ../app/components/MultiSelectHeadState.qml:51
1010-msgid "Cancel selection"
1011-msgstr ""
1012-
1013 #: ../app/components/NetworkErrorStateComponent.qml:48
1014 msgid "Network Error"
1015 msgstr ""
1016@@ -167,11 +173,7 @@
1017 msgid "OK"
1018 msgstr ""
1019
1020-#: ../app/ui/HomePage.qml:32 ../app/ui/LocationsPage.qml:29
1021-msgid "Locations"
1022-msgstr ""
1023-
1024-#: ../app/ui/LocationsPage.qml:109
1025+#: ../app/ui/LocationsPage.qml:99
1026 msgid "Current Location"
1027 msgstr ""
1028
1029
1030=== modified file 'tests/autopilot/ubuntu_weather_app/__init__.py'
1031--- tests/autopilot/ubuntu_weather_app/__init__.py 2016-01-20 17:12:45 +0000
1032+++ tests/autopilot/ubuntu_weather_app/__init__.py 2017-04-13 10:51:15 +0000
1033@@ -67,40 +67,12 @@
1034 self.main_view = self.get_root_instance().select_single(
1035 objectName="weather")
1036
1037+ @click_object
1038 def click_back(self):
1039- return self.main_view.get_header().click_back_button()
1040-
1041-
1042-class PageWithBottomEdge(Page):
1043- """
1044- An emulator class that makes it easy to interact with the bottom edge
1045- swipe page
1046- """
1047- def __init__(self, *args, **kwargs):
1048- super(PageWithBottomEdge, self).__init__(*args, **kwargs)
1049-
1050- def reveal_bottom_edge_page(self):
1051- """Bring the bottom edge page to the screen"""
1052- self.bottomEdgePageLoaded.wait_for(True)
1053-
1054- try:
1055- action_item = self.wait_select_single("UCUbuntuShape",
1056- objectName='bottomEdgeTip')
1057- action_item.visible.wait_for(True)
1058-
1059- # Pick the middle horizontally and vertically of the bottomEdgeTip
1060- start_x = (action_item.globalRect.x +
1061- (action_item.globalRect.width * 0.5))
1062- start_y = (action_item.globalRect.y +
1063- (action_item.globalRect.height * 0.5))
1064- stop_y = start_y - (self.height * 0.7)
1065-
1066- self.pointing_device.drag(start_x, start_y,
1067- start_x, stop_y, rate=2)
1068- self.isReady.wait_for(True)
1069- except dbus.StateNotFoundError:
1070- logger.error('BottomEdge element not found.')
1071- raise
1072+ return self.wait_select_single(
1073+ "UCAbstractButton", objectName="pagestack_back_action_button",
1074+ visible=True,
1075+ )
1076
1077
1078 #
1079@@ -113,8 +85,12 @@
1080 def __init__(self, *args, **kwargs):
1081 super(AddLocationPage, self).__init__(*args, **kwargs)
1082
1083+ @click_object
1084 def click_back(self):
1085- self.main_view.get_header().click_custom_back_button()
1086+ return self.wait_select_single(
1087+ "UCAbstractButton", objectName="pagestack_back_action_button",
1088+ visible=True,
1089+ )
1090
1091 @click_object
1092 def click_location(self, index):
1093@@ -122,16 +98,17 @@
1094 objectName="addLocation" + str(index))
1095
1096 def click_search_action(self):
1097- self.main_view.get_header().click_action_button("search")
1098+ return self.wait_select_single(
1099+ "ActionBar", objectName="addLocationTrailingActionBar",
1100+ visible=True,
1101+ ).click_action_button("search")
1102
1103 def get_results_count(self):
1104 return self.wait_select_single(
1105 "QQuickListView", objectName="locationList").count
1106
1107 def get_search_field(self):
1108- header = self.main_view.get_header()
1109-
1110- return header.select_single("TextField", objectName="searchField")
1111+ return self.select_single("TextField", objectName="searchField")
1112
1113 def is_empty_label_visible(self):
1114 return self.select_single("UCLabel", objectName="noCity").visible
1115@@ -178,7 +155,7 @@
1116 objectName="windForecast").value
1117
1118
1119-class HomePage(PageWithBottomEdge):
1120+class HomePage(Page):
1121 """Autopilot helper for HomePage."""
1122 def __init__(self, *args, **kwargs):
1123 super(HomePage, self).__init__(*args, **kwargs)
1124@@ -200,6 +177,25 @@
1125 def get_selected_location_pane(self):
1126 return self.get_location_pane(self.get_selected_location_index())
1127
1128+ def reveal_bottom_edge_page(self):
1129+ try:
1130+ bottom_edge_hint = self.wait_select_single(
1131+ "UCBottomEdgeHint", visible=True)
1132+ bottom_edge_hint.visible.wait_for(True)
1133+ start_x = (bottom_edge_hint.globalRect.x +
1134+ (bottom_edge_hint.globalRect.width * 0.5))
1135+ start_y = (bottom_edge_hint.globalRect.y +
1136+ (bottom_edge_hint.height * 0.5))
1137+ stop_y = start_y - (self.height * 0.7)
1138+ self.pointing_device.drag(start_x, start_y,
1139+ start_x, stop_y, rate=2)
1140+ bottom_edge = self.wait_select_single(
1141+ "LocationsPage", objectName="locationsPage")
1142+ bottom_edge.visible.wait_for(True)
1143+ except dbus.StateNotFoundError:
1144+ logger.error('BottomEdge element not found.')
1145+ raise
1146+
1147 def swipe_left(self):
1148
1149 # Define the start and stop locations of the left swipe
1150@@ -256,10 +252,14 @@
1151 super(LocationsPage, self).__init__(*args, **kwargs)
1152
1153 def click_add_location_action(self):
1154- self.main_view.get_header().click_action_button("addLocation")
1155+ return self.wait_select_single(
1156+ "ActionBar", objectName="locationsTrailingActionBar", visible=True,
1157+ ).click_action_button("addLocation")
1158
1159 def click_back(self):
1160- return self.main_view.get_header().click_custom_back_button()
1161+ return self.wait_select_single(
1162+ "ActionBar", objectName="locationsLeadingActionBar", visible=True,
1163+ ).click_action_button("back")
1164
1165 @click_object
1166 def click_location(self, index):
1167@@ -282,8 +282,8 @@
1168 class SettingsPage(Page):
1169 """Autopilot helper for SettingsPage."""
1170 @click_object
1171- def click_settings_page_listitem(self, listitem_title):
1172- return self.select_single("StandardListItem", title=listitem_title)
1173+ def click_settings_page_listitem(self, objectName):
1174+ return self.select_single("UCListItem", objectName=objectName)
1175
1176 def get_units_page(self):
1177 return self.main_view.wait_select_single(UnitsPage, visible=True)
1178@@ -298,14 +298,16 @@
1179 self.expand_units_listitem(unit_name)
1180
1181 # Get the currently selected value
1182- previous_unit = self.get_expanded_listitem(unit_name, "True").title
1183+ previous_unit = self.get_expanded_listitem(
1184+ unit_name, "True"
1185+ ).titleValue
1186
1187 # Click the non-selected value
1188 self.click_not_selected_listitem(unit_name)
1189
1190 # Return True/False if the selection has changed
1191 return self.get_expanded_listitem(
1192- unit_name, "True").title != previous_unit
1193+ unit_name, "True").titleValue != previous_unit
1194
1195 @click_object
1196 def click_not_selected_listitem(self, unit_name):
1197@@ -317,14 +319,14 @@
1198
1199 def expand_units_listitem(self, listitem):
1200 item = self.click_units_listitem(listitem)
1201- item.expanded.wait_for(True)
1202+ item.height.wait_for(item.expansionHeight)
1203 return item
1204
1205 def get_expanded_listitem(self, listitem, showIcon):
1206 listitemSetting = self.select_single(
1207 "ExpandableListItem", objectName=listitem)
1208 return listitemSetting.select_single(
1209- "StandardListItem", showIcon=showIcon)
1210+ "StandardListItem", iconVisible=showIcon)
1211
1212
1213 class WeatherListItem(UbuntuUIToolkitCustomProxyObjectBase):
1214
1215=== modified file 'tests/autopilot/ubuntu_weather_app/tests/__init__.py'
1216--- tests/autopilot/ubuntu_weather_app/tests/__init__.py 2015-08-18 23:48:51 +0000
1217+++ tests/autopilot/ubuntu_weather_app/tests/__init__.py 2017-04-13 10:51:15 +0000
1218@@ -73,7 +73,6 @@
1219 return self.launch_test_application(
1220 base.get_qmlscene_launch_command(),
1221 self.local_location,
1222- "debug",
1223 app_type='qt',
1224 emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase)
1225
1226@@ -82,7 +81,6 @@
1227 return self.launch_test_application(
1228 base.get_qmlscene_launch_command(),
1229 self.installed_location,
1230- "debug",
1231 app_type='qt',
1232 emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase)
1233
1234@@ -122,16 +120,23 @@
1235 temp_dir = os.environ.get('HOME')
1236
1237 # before each test, remove the app's databases
1238- local_dir = os.path.join(temp_dir,
1239- '.local/share/com.ubuntu.weather')
1240-
1241- if (os.path.exists(local_dir)):
1242- shutil.rmtree(local_dir)
1243-
1244- local_dir = os.path.join(temp_dir, '.config/com.ubuntu.weather')
1245-
1246- if (os.path.exists(local_dir)):
1247- shutil.rmtree(local_dir)
1248+ # NOTE: path seems to be .local/share/QtProject/com.ubuntu.weather
1249+ # now not .local/share/com.ubuntu.weather
1250+ local_dir = os.path.join(
1251+ temp_dir, '.local/share/QtProject/com.ubuntu.weather'
1252+ )
1253+
1254+ if (os.path.exists(local_dir)):
1255+ shutil.rmtree(local_dir)
1256+
1257+ # NOTE: path seems to be .config/QtProject/com.ubuntu.weather.conf
1258+ # now not .config/com.ubuntu.weather/com.ubuntu.weather.conf
1259+ local_path = os.path.join(
1260+ temp_dir, '.config/QtProject/com.ubuntu.weather.conf'
1261+ )
1262+
1263+ if (os.path.exists(local_path)):
1264+ os.remove(local_path)
1265 else:
1266 temp_dir_fixture = fixtures.TempDir()
1267 self.useFixture(temp_dir_fixture)
1268@@ -221,9 +226,11 @@
1269 return result
1270
1271 def load_database_vars(self):
1272+ # NOTE: path seems to be .local/share/QtProject/com.ubuntu.weather
1273+ # now not .local/share/com.ubuntu.weather
1274 self.app_dir = os.path.join(
1275 os.environ.get('HOME'),
1276- ".local/share/com.ubuntu.weather")
1277+ ".local/share/QtProject/com.ubuntu.weather")
1278 self.database_tmpl_dir = os.path.join(
1279 os.path.dirname(ubuntu_weather_app.__file__),
1280 'databases')
1281@@ -237,9 +244,11 @@
1282
1283 class LegacyDatabaseMixin(DatabaseMixin):
1284 def load_database_vars(self):
1285+ # NOTE: path seems to be .local/share/QtProject/com.ubuntu.weather
1286+ # now not .local/share/com.ubuntu.weather
1287 self.app_dir = os.path.join(
1288 os.environ.get('HOME'),
1289- ".local/share/com.ubuntu.weather")
1290+ ".local/share/QtProject/com.ubuntu.weather")
1291 self.database_tmpl_dir = os.path.join(
1292 os.path.dirname(ubuntu_weather_app.__file__),
1293 'databases', 'legacy')
1294@@ -280,9 +289,11 @@
1295 def load_settings_vars(self):
1296 self.db_dir = os.path.abspath(
1297 os.path.join(os.path.dirname(__file__), '..', 'databases'))
1298+ # NOTE: path seems to be .config/QtProject/com.ubuntu.weather.conf
1299+ # now not .config/com.ubuntu.weather/com.ubuntu.weather.conf
1300 self.settings_dir = os.path.join(
1301 os.environ.get('HOME'),
1302- ".config/com.ubuntu.weather")
1303+ ".config/QtProject")
1304 self.settings_filepath = os.path.join(self.settings_dir,
1305 'com.ubuntu.weather.conf')
1306 self.settings_location_added = os.path.join(self.db_dir,
1307
1308=== modified file 'tests/autopilot/ubuntu_weather_app/tests/test_settings_page.py'
1309--- tests/autopilot/ubuntu_weather_app/tests/test_settings_page.py 2015-09-14 18:23:35 +0000
1310+++ tests/autopilot/ubuntu_weather_app/tests/test_settings_page.py 2017-04-13 10:51:15 +0000
1311@@ -41,7 +41,7 @@
1312 self.settings_page = self.app.get_settings_page()
1313
1314 # Click the units page
1315- self.settings_page.click_settings_page_listitem("Units")
1316+ self.settings_page.click_settings_page_listitem("units")
1317
1318 # Get the units page
1319 self.units_page = self.settings_page.get_units_page()

Subscribers

People subscribed via source and target branches

to all changes: