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