Merge lp:~nik90/unav/code-cleanup-part2 into lp:~costales/unav/trunk

Proposed by Nekhelesh Ramananthan
Status: Merged
Merged at revision: 7
Proposed branch: lp:~nik90/unav/code-cleanup-part2
Merge into: lp:~costales/unav/trunk
Prerequisite: lp:~nik90/unav/code-cleanup-part1
Diff against target: 548 lines (+341/-184)
2 files modified
qml/SettingsPage.qml (+254/-184)
qml/components/ExpandableListItem.qml (+87/-0)
To merge this branch: bzr merge lp:~nik90/unav/code-cleanup-part2
Reviewer Review Type Date Requested Status
costales Pending
Review via email: mp+289794@code.launchpad.net

Description of the change

Revamped Settings Page.

To post a comment you must log in.
lp:~nik90/unav/code-cleanup-part2 updated
15. By Nekhelesh Ramananthan

Updated header

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/SettingsPage.qml'
2--- qml/SettingsPage.qml 2016-03-22 14:03:11 +0000
3+++ qml/SettingsPage.qml 2016-03-22 14:03:11 +0000
4@@ -18,7 +18,6 @@
5 import QtQuick 2.4
6 import Ubuntu.Components 1.3
7 import Ubuntu.Components.Popups 1.3
8-import Ubuntu.Components.ListItems 1.3 as ListItems
9 import QtQuick.LocalStorage 2.0
10 import "js/db.js" as UnavDB
11 import "components"
12@@ -26,190 +25,261 @@
13 Page {
14 id: settingsPage
15
16- title: i18n.tr("Settings")
17+ header: PageHeader {
18+ title: i18n.tr("Settings")
19+ flickable: flickable
20+ }
21+
22 signal settingsChanged()
23
24- Flickable {
25- id: flickable
26- anchors.fill: parent
27- contentHeight: settingsColumn.height + units.gu(5)
28-
29- Column {
30- id: settingsColumn
31-
32- anchors {
33- top: parent.top
34- left: parent.left
35- right: parent.right
36- }
37-
38- HeaderListItem {
39- id: mapModeHeader
40- title: i18n.tr("Navigation")
41- }
42-
43- ListItems.ItemSelector {
44- id: modeList
45- text: i18n.tr("Mode:")
46- width: parent.width
47- anchors.horizontalCenter: parent.horizontalCenter
48-
49- objectName: "modeList"
50- model: [i18n.tr("Car"), // index: 0
51- i18n.tr("Walking"), // index: 1
52- i18n.tr("Bicycle") // index: 2
53- ]
54- selectedIndex: navApp.settings.routingMode
55- onSelectedIndexChanged: {
56- if (navApp.settings.routingMode !== selectedIndex) {
57- navApp.settings.routingMode = selectedIndex
58- mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no' && !nav.get_route_status().startsWith('simulate')){nav.set_route_status('waiting4signal')}; settings.set_routing_mode(" + selectedIndex +");")
59- }
60- }
61- }
62-
63- ListItem {
64- height: tollsLayout.height + divider.height
65- ListItemLayout {
66- id: tollsLayout
67- title.text: i18n.tr("Avoid Tolls")
68- Switch {
69- id: tollsSwitch
70- checked: navApp.settings.avoidTolls
71- onClicked: {
72- navApp.settings.avoidTolls = checked;
73- mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_avoid_tolls(" + checked.toString() + ");")
74- }
75- SlotsLayout.position: SlotsLayout.Last
76- }
77- }
78- }
79-
80- ListItem {
81- height: speedCameraLayout.height + divider.height
82- ListItemLayout {
83- id: speedCameraLayout
84- title.text: i18n.tr("Speed Camera Alerts")
85- Switch {
86- id: radarsSwitch
87- checked: navApp.settings.alertRadars
88- onClicked: {
89- navApp.settings.alertRadars = checked;
90- mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_alert_radars(" + checked.toString() + ");");
91- if (navApp.settings.legalRadarShow) {
92- navApp.settings.legalRadarShow = false;
93- PopupUtils.open(confirmEnableRadar);
94- }
95- }
96- SlotsLayout.position: SlotsLayout.Last
97- }
98- }
99- }
100-
101- ListItems.ItemSelector {
102- id: soundsList
103- text: i18n.tr("Indications:")
104- width: parent.width
105- anchors.horizontalCenter: parent.horizontalCenter
106-
107- objectName: "soundsList"
108- model: [i18n.tr("A Voice"), // index: 0
109- i18n.tr("A Notification"), // index: 1
110- i18n.tr("None") // index: 2
111- ]
112- selectedIndex: navApp.settings.soundIndications
113- onSelectedIndexChanged: {
114- navApp.settings.soundIndications = selectedIndex
115- mainPageStack.executeJavaScript("settings.set_sound(" + selectedIndex + ");")
116- }
117- }
118-
119- HeaderListItem {
120- id: mapListHeader
121- title: i18n.tr("Map")
122- }
123-
124- ListItems.ItemSelector {
125- id: unitsList
126- text: i18n.tr("Units:")
127- width: parent.width
128- anchors.horizontalCenter: parent.horizontalCenter
129-
130- objectName: "unitsList"
131- model: [i18n.tr("Kilometers"), // index: 0
132- i18n.tr("Miles") // index: 1
133- ]
134- selectedIndex: navApp.settings.unit
135- onSelectedIndexChanged: {
136- navApp.settings.unit = selectedIndex
137- mainPageStack.executeJavaScript("settings.set_unit(\'" + ( selectedIndex === 0 ? "km" : "mi" ) +"\');")
138- mainPageStack.executeJavaScript("ui.set_scale_unit(\'" + ( navApp.settings.unit === 0 ? "km" : "mi" ) +"\');")
139- }
140- }
141-
142- HeaderListItem {
143- id: privacyListHeader
144- title: i18n.tr("History")
145- }
146-
147- ListItem {
148- height: storeSearchLayout.height + divider.height
149- ListItemLayout {
150- id: storeSearchLayout
151- title.text: i18n.tr("Store new searches")
152- Switch {
153- id: saveHistorySwitch
154- checked: navApp.settings.saveHistory
155- onClicked: navApp.settings.saveHistory = checked
156- SlotsLayout.position: SlotsLayout.Last
157- }
158- }
159- }
160-
161- ListItem {
162- Label {
163- anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: units.gu(2) }
164- text: i18n.tr("Clear History")
165- }
166- onClicked: PopupUtils.open(confirmEraseHistory)
167- }
168- }
169-
170- Component {
171- id: confirmEraseHistory
172- Dialog {
173- id: dialogueErase
174- title: i18n.tr("Clear History")
175- text: i18n.tr("You'll delete the current history")
176- Button {
177- text: i18n.tr("Delete")
178- color: UbuntuColors.red
179- onClicked: {
180- UnavDB.dropHistoryTables();
181- PopupUtils.close(dialogueErase);
182- }
183- }
184- Button {
185- text: i18n.tr("Cancel")
186- onClicked: PopupUtils.close(dialogueErase)
187- }
188- }
189- }
190-
191- Component {
192- id: confirmEnableRadar
193- Dialog {
194- id: dialogueRadars
195- title: i18n.tr("Speed Camera alerts and the law")
196- text: i18n.tr("uNav is only reading the OpenStreetMap database.\nuNav will show a max speed notification and a Speed Camera marker (marker hidden for French users because of law).\n\nIn a few countries Speed Camera alerts are illegal, then enable this option only if it's legal in the country.\n\nRead more about it here:\n%1").arg("http://goo.gl/ulXvG8")
197- Button {
198- text: i18n.tr("OK")
199- color: UbuntuColors.red
200- onClicked: PopupUtils.close(dialogueRadars);
201- }
202- }
203- }
204-
205- }
206+ ListModel {
207+ id: navigationModeModel
208+ Component.onCompleted: initialize()
209+ function initialize() {
210+ navigationModeModel.append({ "mode": i18n.tr("Car"), "index": 0 })
211+ navigationModeModel.append({ "mode": i18n.tr("Walking"), "index": 1 })
212+ navigationModeModel.append({ "mode": i18n.tr("Bicycle"), "index": 2 })
213+
214+ _modeList.subText.text = navigationModeModel.get(navApp.settings.routingMode).mode
215+ }
216+ }
217+
218+ ListModel {
219+ id: soundModel
220+ Component.onCompleted: initialize()
221+ function initialize() {
222+ soundModel.append({ "sound": i18n.tr("A Voice"), "index": 0 })
223+ soundModel.append({ "sound": i18n.tr("A Notification"), "index": 1 })
224+ soundModel.append({ "sound": i18n.tr("None"), "index": 2 })
225+
226+ _soundList.subText.text = soundModel.get(navApp.settings.soundIndications).sound
227+ }
228+ }
229+
230+ ListModel {
231+ id: unitModel
232+ Component.onCompleted: initialize()
233+ function initialize() {
234+ unitModel.append({ "unit": i18n.tr("Kilometres"), "index": 0 })
235+ unitModel.append({ "unit": i18n.tr("Miles"), "index": 1 })
236+
237+ _unitList.subText.text = unitModel.get(navApp.settings.unit).unit
238+ }
239+ }
240+
241+ Flickable {
242+ id: flickable
243+ anchors.fill: parent
244+ contentHeight: settingsColumn.height + units.gu(5)
245+
246+ Column {
247+ id: settingsColumn
248+
249+ anchors {
250+ top: parent.top
251+ left: parent.left
252+ right: parent.right
253+ }
254+
255+ ExpandableListItem {
256+ id: _modeList
257+
258+ listViewHeight: units.gu(21)
259+ titleText.text: i18n.tr("Navigation Mode")
260+
261+ model: navigationModeModel
262+
263+ delegate: ListItem {
264+ ListItemLayout {
265+ title.text: model.mode
266+
267+ Icon {
268+ SlotsLayout.position: SlotsLayout.Trailing
269+ width: units.gu(2)
270+ height: width
271+ name: "tick"
272+ visible: navApp.settings.routingMode === model.index
273+ }
274+ }
275+
276+ onClicked: {
277+ navApp.settings.routingMode = model.index
278+ mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no' && !nav.get_route_status().startsWith('simulate')){nav.set_route_status('waiting4signal')}; settings.set_routing_mode(" + model.index +");")
279+ _modeList.subText.text = navigationModeModel.get(navApp.settings.routingMode).mode
280+ _modeList.toggleExpansion()
281+ }
282+ }
283+ }
284+
285+ ListItem {
286+ visible: navApp.settings.routingMode === 0
287+ height: tollsLayout.height + divider.height
288+ ListItemLayout {
289+ id: tollsLayout
290+ title.text: i18n.tr("Avoid Tolls")
291+ Switch {
292+ id: tollsSwitch
293+ checked: navApp.settings.avoidTolls
294+ onClicked: {
295+ navApp.settings.avoidTolls = checked;
296+ mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_avoid_tolls(" + checked.toString() + ");")
297+ }
298+ SlotsLayout.position: SlotsLayout.Last
299+ }
300+ }
301+ }
302+
303+ ListItem {
304+ visible: navApp.settings.routingMode === 0
305+ height: speedCameraLayout.height + divider.height
306+ ListItemLayout {
307+ id: speedCameraLayout
308+ title.text: i18n.tr("Speed Camera Alerts")
309+ Switch {
310+ id: radarsSwitch
311+ checked: navApp.settings.alertRadars
312+ onClicked: {
313+ navApp.settings.alertRadars = checked;
314+ mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_alert_radars(" + checked.toString() + ");");
315+ if (navApp.settings.legalRadarShow) {
316+ navApp.settings.legalRadarShow = false;
317+ PopupUtils.open(confirmEnableRadar);
318+ }
319+ }
320+ SlotsLayout.position: SlotsLayout.Last
321+ }
322+ }
323+ }
324+
325+ ExpandableListItem {
326+ id: _soundList
327+
328+ listViewHeight: units.gu(21)
329+ titleText.text: i18n.tr("Guidance")
330+
331+ model: soundModel
332+
333+ delegate: ListItem {
334+ ListItemLayout {
335+ title.text: model.sound
336+
337+ Icon {
338+ SlotsLayout.position: SlotsLayout.Trailing
339+ width: units.gu(2)
340+ height: width
341+ name: "tick"
342+ visible: navApp.settings.soundIndications === model.index
343+ }
344+ }
345+
346+ onClicked: {
347+ navApp.settings.soundIndications = model.index
348+ mainPageStack.executeJavaScript("settings.set_sound(" + model.index + ");")
349+ _soundList.subText.text = soundModel.get(navApp.settings.soundIndications).sound
350+ _soundList.toggleExpansion()
351+ }
352+ }
353+ }
354+
355+ HeaderListItem {
356+ id: mapListHeader
357+ title: i18n.tr("Map")
358+ }
359+
360+ ExpandableListItem {
361+ id: _unitList
362+
363+ listViewHeight: units.gu(14)
364+ titleText.text: i18n.tr("Units")
365+
366+ model: unitModel
367+
368+ delegate: ListItem {
369+ ListItemLayout {
370+ title.text: model.unit
371+
372+ Icon {
373+ SlotsLayout.position: SlotsLayout.Trailing
374+ width: units.gu(2)
375+ height: width
376+ name: "tick"
377+ visible: navApp.settings.unit === model.index
378+ }
379+ }
380+
381+ onClicked: {
382+ navApp.settings.unit = model.index
383+ mainPageStack.executeJavaScript("settings.set_unit(\'" + ( model.index === 0 ? "km" : "mi" ) +"\');")
384+ mainPageStack.executeJavaScript("ui.set_scale_unit(\'" + ( navApp.settings.unit === 0 ? "km" : "mi" ) +"\');")
385+ _unitList.subText.text = unitModel.get(navApp.settings.unit).unit
386+ _unitList.toggleExpansion()
387+ }
388+ }
389+ }
390+
391+ HeaderListItem {
392+ id: privacyListHeader
393+ title: i18n.tr("History")
394+ }
395+
396+ ListItem {
397+ height: storeSearchLayout.height + divider.height
398+ ListItemLayout {
399+ id: storeSearchLayout
400+ title.text: i18n.tr("Store new searches")
401+ Switch {
402+ id: saveHistorySwitch
403+ checked: navApp.settings.saveHistory
404+ onClicked: navApp.settings.saveHistory = checked
405+ SlotsLayout.position: SlotsLayout.Last
406+ }
407+ }
408+ }
409+
410+ ListItem {
411+ Label {
412+ anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: units.gu(2) }
413+ text: i18n.tr("Clear History")
414+ }
415+ onClicked: PopupUtils.open(confirmEraseHistory)
416+ }
417+ }
418+
419+ Component {
420+ id: confirmEraseHistory
421+ Dialog {
422+ id: dialogueErase
423+ title: i18n.tr("Clear History")
424+ text: i18n.tr("You'll delete the current history")
425+ Button {
426+ text: i18n.tr("Delete")
427+ color: UbuntuColors.red
428+ onClicked: {
429+ UnavDB.dropHistoryTables();
430+ PopupUtils.close(dialogueErase);
431+ }
432+ }
433+ Button {
434+ text: i18n.tr("Cancel")
435+ onClicked: PopupUtils.close(dialogueErase)
436+ }
437+ }
438+ }
439+
440+ Component {
441+ id: confirmEnableRadar
442+ Dialog {
443+ id: dialogueRadars
444+ title: i18n.tr("Speed Camera alerts and the law")
445+ text: i18n.tr("uNav is only reading the OpenStreetMap database.\nuNav will show a max speed notification and a Speed Camera marker (marker hidden for French users because of law).\n\nIn a few countries Speed Camera alerts are illegal, then enable this option only if it's legal in the country.\n\nRead more about it here:\n%1").arg("http://goo.gl/ulXvG8")
446+ Button {
447+ text: i18n.tr("OK")
448+ color: UbuntuColors.red
449+ onClicked: PopupUtils.close(dialogueRadars);
450+ }
451+ }
452+ }
453+
454+ }
455 }
456
457
458=== added file 'qml/components/ExpandableListItem.qml'
459--- qml/components/ExpandableListItem.qml 1970-01-01 00:00:00 +0000
460+++ qml/components/ExpandableListItem.qml 2016-03-22 14:03:11 +0000
461@@ -0,0 +1,87 @@
462+/*
463+ * uNav http://launchpad.net/unav
464+ * Copyright (C) 2016 Nekhelesh Ramananthan https://launchpad.net/~nik90
465+ *
466+ * uNav is free software: you can redistribute it and/or modify
467+ * it under the terms of the GNU General Public License version 3 as
468+ * published by the Free Software Foundation.
469+ *
470+ * uNav is distributed in the hope that it will be useful,
471+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
472+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
473+ * GNU General Public License for more details.
474+ *
475+ * You should have received a copy of the GNU General Public License
476+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
477+ */
478+
479+import QtQuick 2.4
480+import Ubuntu.Components 1.3
481+
482+/*
483+ Component which extends the SDK Expandable list item and provides a easy
484+ to use component where the title, subtitle and a listview can be displayed. It
485+ matches the design specification provided for clock.
486+*/
487+
488+ListItem {
489+ id: expandableListItem
490+
491+ // Public APIs
492+ property ListModel model
493+ property Component delegate
494+ property alias titleText: expandableHeader.title
495+ property alias subText: expandableHeader.subtitle
496+ property alias listViewHeight: expandableListLoader.height
497+
498+ height: headerListItem.height
499+ expansion.height: headerListItem.height + expandableListLoader.height
500+ onClicked: toggleExpansion()
501+
502+ function toggleExpansion() {
503+ expansion.expanded = !expansion.expanded
504+ }
505+
506+ ListItem {
507+ id: headerListItem
508+ height: expandableHeader.height + divider.height
509+
510+ ListItemLayout {
511+ id: expandableHeader
512+
513+ subtitle.textSize: Label.Medium
514+
515+ Icon {
516+ id: arrow
517+
518+ width: units.gu(2)
519+ height: width
520+ SlotsLayout.position: SlotsLayout.Trailing
521+ name: "go-down"
522+ rotation: expandableListItem.expansion.expanded ? 180 : 0
523+
524+ Behavior on rotation {
525+ UbuntuNumberAnimation {}
526+ }
527+ }
528+ }
529+ }
530+
531+ Loader {
532+ id: expandableListLoader
533+ width: parent.width
534+ asynchronous: true
535+ anchors.top: headerListItem.bottom
536+ sourceComponent: expandableListItem.expansion.expanded ? expandableListComponent : undefined
537+ }
538+
539+ Component {
540+ id: expandableListComponent
541+ ListView {
542+ id: expandableList
543+ interactive: false
544+ model: expandableListItem.model
545+ delegate: expandableListItem.delegate
546+ }
547+ }
548+}

Subscribers

People subscribed via source and target branches