Andrew Hayzen has proposed merging lp:~ahayzen/ubuntu-weather-app/uc1.3-listitems into lp:ubuntu-weather-app.
Commit message: * Migrate remaining old style listitems to UC1.3 ListItems Requested reviews: Jenkins Bot (ubuntu-core-apps-jenkins-bot): continuous-integration Ubuntu Weather Developers (ubuntu-weather-dev) For more details, see: https://code.launchpad.net/~ahayzen/ubuntu-weather-app/uc1.3-listitems/+merge/323134 * Migrate remaining old style listitems to UC1.3 ListItems -- Your team Ubuntu Weather Developers is requested to review the proposed merge of lp:~ahayzen/ubuntu-weather-app/uc1.3-listitems into lp:ubuntu-weather-app.
=== modified file 'app/components/HeadState/MultiSelectHeadState.qml' --- app/components/HeadState/MultiSelectHeadState.qml 2016-07-19 16:14:05 +0000 +++ app/components/HeadState/MultiSelectHeadState.qml 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 + * Copyright (C) 2015, 2017 * Andrew Hayzen <ahay...@gmail.com> * Victor Thompson <victor.thomp...@gmail.com> * @@ -31,10 +31,7 @@ Action { text: i18n.tr("Cancel selection") iconName: "back" - onTriggered: { - listview.clearSelection() - listview.state = "normal" - } + onTriggered: listview.closeSelection() } ] } @@ -45,7 +42,7 @@ iconName: "select" text: i18n.tr("Select All") onTriggered: { - if (listview.selectedItems.length === listview.model.count) { + if (listview.getSelectedIndices().length === listview.model.count) { listview.clearSelection() } else { listview.selectAll() @@ -53,13 +50,13 @@ } }, Action { - enabled: listview.selectedItems.length > 0 + enabled: listview.getSelectedIndices().length > 0 iconName: "delete" text: i18n.tr("Delete") visible: removable onTriggered: { - removed(listview.selectedItems) + removed(listview.getSelectedIndices()) listview.closeSelection() } @@ -74,7 +71,7 @@ property bool removable: false property Page thisPage - signal removed(var selectedItems) + signal removed(var selectedIndices) PropertyChanges { target: thisPage === removed file 'app/components/ListItemReorderComponent.qml' --- app/components/ListItemReorderComponent.qml 2015-11-02 21:28:34 +0000 +++ app/components/ListItemReorderComponent.qml 1970-01-01 00:00:00 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2013, 2014, 2015 - * Andrew Hayzen <ahay...@gmail.com> - * Nekhelesh Ramananthan <krnekhel...@gmail.com> - * Victor Thompson <victor.thomp...@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import QtQuick 2.4 -import Ubuntu.Components 1.3 - - -Item { - id: actionReorder - width: units.gu(4) - - Icon { - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - } - name: "navigation-menu" // TODO: use proper image - height: width - width: units.gu(3) - } - - MouseArea { - id: actionReorderMouseArea - anchors { - fill: parent - } - property int startY: 0 - property int startContentY: 0 - - onPressed: { - root.parent.parent.interactive = false; // stop scrolling of listview - startY = root.y; - startContentY = root.parent.parent.contentY; - root.z += 10; // force ontop of other elements - - console.debug("Reorder listitem pressed", root.y) - } - onMouseYChanged: root.y += mouse.y - (root.height / 2); - onReleased: { - console.debug("Reorder diff by position", getDiff()); - - var diff = getDiff(); - - // Remove the height of the actual item if moved down - if (diff > 0) { - diff -= 1; - } - - root.parent.parent.interactive = true; // reenable scrolling - - if (diff === 0) { - // Nothing has changed so reset the item - // z index is restored after animation - resetListItemYAnimation.start(); - } - else { - var newIndex = index + diff; - - if (newIndex < 0) { - newIndex = 0; - } - else if (newIndex > root.parent.parent.count - 1) { - newIndex = root.parent.parent.count - 1; - } - - root.z -= 10; // restore z index - reorder(index, newIndex) - } - } - - function getDiff() { - // Get the amount of items that have been passed over (by centre) - return Math.round((((root.y - startY) + (root.parent.parent.contentY - startContentY)) / root.height) + 0.5); - } - } - - SequentialAnimation { - id: resetListItemYAnimation - UbuntuNumberAnimation { - target: root; - property: "y"; - to: actionReorderMouseArea.startY - } - ScriptAction { - script: { - root.z -= 10; // restore z index - } - } - } -} === removed file 'app/components/ListItemWithActions.qml' --- app/components/ListItemWithActions.qml 2015-11-02 21:28:34 +0000 +++ app/components/ListItemWithActions.qml 1970-01-01 00:00:00 +0000 @@ -1,496 +0,0 @@ -/* - * Copyright (C) 2012-2015 Canonical, Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import QtQuick 2.4 -import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 1.0 as ListItem - - -Item { - id: root - width: parent.width - - property Action leftSideAction: null - property list<Action> rightSideActions - property double defaultHeight: units.gu(8) - property bool locked: false - property Action activeAction: null - property var activeItem: null - property bool triggerActionOnMouseRelease: false - property color color: Theme.palette.normal.background - property color selectedColor: "#E6E6E6" - property bool selected: false - property bool selectionMode: false - property alias internalAnchors: mainContents.anchors - default property alias contents: mainContents.children - - readonly property double actionWidth: units.gu(4) - readonly property double leftActionWidth: units.gu(10) - readonly property double actionThreshold: actionWidth * 0.4 - readonly property double threshold: 0.4 - readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft" - readonly property alias swipping: mainItemMoving.running - readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping - - property alias _main: main // CUSTOM - property alias pressed: mouseArea.pressed // CUSTOM - - /* internal */ - property var _visibleRightSideActions: filterVisibleActions(rightSideActions) - - signal itemClicked(var mouse) - signal itemPressAndHold(var mouse) - - function returnToBoundsRTL(direction) - { - var actionFullWidth = actionWidth + units.gu(2) - - // go back to normal state if swipping reverse - if (direction === "LTR") { - updatePosition(0) - return - } else if (!triggerActionOnMouseRelease) { - updatePosition(-rightActionsView.width + units.gu(2)) - return - } - - var xOffset = Math.abs(main.x) - var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) - var newX = 0 - - if (index === _visibleRightSideActions.length) { - newX = -(rightActionsView.width - units.gu(2)) - } else if (index >= 1) { - newX = -(actionFullWidth * index) - } - - updatePosition(newX) - } - - function returnToBoundsLTR(direction) - { - var finalX = leftActionWidth - if ((direction === "RTL") || (main.x <= (finalX * root.threshold))) - finalX = 0 - updatePosition(finalX) - } - - function returnToBounds(direction) - { - if (main.x < 0) { - returnToBoundsRTL(direction) - } else if (main.x > 0) { - returnToBoundsLTR(direction) - } else { - updatePosition(0) - } - } - - function contains(item, point, marginX) - { - var itemStartX = item.x - marginX - var itemEndX = item.x + item.width + marginX - return (point.x >= itemStartX) && (point.x <= itemEndX) && - (point.y >= item.y) && (point.y <= (item.y + item.height)); - } - - function getActionAt(point) - { - if (leftSideAction && contains(leftActionViewLoader.item, point, 0)) { - return leftSideAction - } else if (contains(rightActionsView, point, 0)) { - var newPoint = root.mapToItem(rightActionsView, point.x, point.y) - for (var i = 0; i < rightActionsRepeater.count; i++) { - var child = rightActionsRepeater.itemAt(i) - if (contains(child, newPoint, units.gu(1))) { - return i - } - } - } - return -1 - } - - function updateActiveAction() - { - if (triggerActionOnMouseRelease && - (main.x <= -(root.actionWidth + units.gu(2))) && - (main.x > -(rightActionsView.width - units.gu(2)))) { - var actionFullWidth = actionWidth + units.gu(2) - var xOffset = Math.abs(main.x) - var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) - index = index - 1 - if (index > -1) { - root.activeItem = rightActionsRepeater.itemAt(index) - root.activeAction = root._visibleRightSideActions[index] - } - } else { - root.activeAction = null - } - } - - function resetSwipe() - { - updatePosition(0) - } - - function filterVisibleActions(actions) - { - var visibleActions = [] - for(var i = 0; i < actions.length; i++) { - var action = actions[i] - if (action.visible) { - visibleActions.push(action) - } - } - return visibleActions - } - - function updatePosition(pos) - { - if (!root.triggerActionOnMouseRelease && (pos !== 0)) { - mouseArea.state = pos > 0 ? "RightToLeft" : "LeftToRight" - } else { - mouseArea.state = "" - } - main.x = pos - } - - // CUSTOM remove animation - SequentialAnimation { - id: removeAnimation - - property var action - - UbuntuNumberAnimation { - target: root - duration: UbuntuAnimation.BriskDuration - property: "height"; - to: 0 - } - ScriptAction { - script: removeAnimation.action.trigger() - } - } - - states: [ - State { - name: "select" - when: selectionMode || selected - PropertyChanges { - target: selectionIcon - source: Qt.resolvedUrl("ListItemActions/CheckBox.qml") - anchors.leftMargin: units.gu(2) - } - PropertyChanges { - target: root - locked: true - } - PropertyChanges { - target: main - x: 0 - } - } - ] - - height: defaultHeight - //clip: height !== defaultHeight // CUSTOM - - Loader { // CUSTOM - id: leftActionViewLoader - anchors { - top: parent.top - bottom: parent.bottom - right: main.left - } - asynchronous: true - sourceComponent: leftSideAction ? leftActionViewComponent : undefined - } - - Component { // CUSTOM - id: leftActionViewComponent - - Rectangle { - id: leftActionView - width: root.leftActionWidth + actionThreshold - color: UbuntuColors.red - - Icon { - id: leftActionIcon - anchors { - centerIn: parent - horizontalCenterOffset: actionThreshold / 2 - } - objectName: "swipeDeleteAction" // CUSTOM - name: leftSideAction && _showActions ? leftSideAction.iconName : "" - color: Theme.palette.selected.field - height: units.gu(3) - width: units.gu(3) - } - } - } - - //Rectangle { - Item { // CUSTOM - id: rightActionsView - - anchors { - top: main.top - left: main.right - bottom: main.bottom - } - visible: _visibleRightSideActions.length > 0 - width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + root.actionThreshold + units.gu(2) : 0 - // color: "white" // CUSTOM - - Row { - anchors{ - top: parent.top - left: parent.left - leftMargin: units.gu(2) - right: parent.right - rightMargin: units.gu(2) - bottom: parent.bottom - } - spacing: units.gu(2) - Repeater { - id: rightActionsRepeater - - model: _showActions ? _visibleRightSideActions : [] - Item { - property alias image: img - - height: rightActionsView.height - width: root.actionWidth - - Icon { - id: img - - anchors.centerIn: parent - objectName: rightSideActions[index].objectName // CUSTOM - width: units.gu(3) - height: units.gu(3) - name: modelData.iconName - color: root.activeAction === modelData ? UbuntuColors.orange : UbuntuColors.coolGrey // CUSTOM - } - } - } - } - } - - Rectangle { - id: main - objectName: "mainItem" - - anchors { - top: parent.top - bottom: parent.bottom - } - - width: parent.width - color: root.selected ? root.selectedColor : root.color - - Loader { - id: selectionIcon - - anchors { - left: main.left - verticalCenter: main.verticalCenter - } - asynchronous: true // CUSTOM - width: (status === Loader.Ready) ? item.implicitWidth : 0 - visible: (status === Loader.Ready) && (item.width === item.implicitWidth) - - Behavior on width { - NumberAnimation { - duration: UbuntuAnimation.SnapDuration - } - } - } - - Item { - id: mainContents - - anchors { - left: selectionIcon.right - //leftMargin: units.gu(2) // CUSTOM - top: parent.top - //topMargin: units.gu(1) // CUSTOM - right: parent.right - //rightMargin: units.gu(2) // CUSTOM - bottom: parent.bottom - //bottomMargin: units.gu(1) // CUSTOM - } - } - - Behavior on x { - UbuntuNumberAnimation { - id: mainItemMoving - - easing.type: Easing.OutElastic - duration: UbuntuAnimation.SlowDuration - } - } - } - - SequentialAnimation { - id: triggerAction - - property var currentItem: root.activeItem ? root.activeItem.image : null - - running: false - ParallelAnimation { - UbuntuNumberAnimation { - target: triggerAction.currentItem - property: "opacity" - from: 1.0 - to: 0.0 - duration: UbuntuAnimation.SlowDuration - easing {type: Easing.InOutBack; } - } - UbuntuNumberAnimation { - target: triggerAction.currentItem - properties: "width, height" - from: units.gu(3) - to: root.actionWidth - duration: UbuntuAnimation.SlowDuration - easing {type: Easing.InOutBack; } - } - } - PropertyAction { - target: triggerAction.currentItem - properties: "width, height" - value: units.gu(3) - } - PropertyAction { - target: triggerAction.currentItem - properties: "opacity" - value: 1.0 - } - ScriptAction { - script: { - root.activeAction.triggered(root) - mouseArea.state = "" - } - } - PauseAnimation { - duration: 500 - } - UbuntuNumberAnimation { - target: main - property: "x" - to: 0 - } - } - - MouseArea { - id: mouseArea - - property bool locked: root.locked || ((root.leftSideAction === null) && (root._visibleRightSideActions.count === 0)) // CUSTOM - property bool manual: false - property string direction: "None" - property real lastX: -1 - - anchors.fill: parent - drag { - target: locked ? null : main - axis: Drag.XAxis - minimumX: rightActionsView.visible ? -(rightActionsView.width) : 0 - maximumX: leftSideAction ? leftActionViewLoader.item.width : 0 - threshold: root.actionThreshold - } - - states: [ - State { - name: "LeftToRight" - PropertyChanges { - target: mouseArea - drag.maximumX: 0 - } - }, - State { - name: "RightToLeft" - PropertyChanges { - target: mouseArea - drag.minimumX: 0 - } - } - ] - - onMouseXChanged: { - var offset = (lastX - mouseX) - if (Math.abs(offset) <= root.actionThreshold) { - return - } - lastX = mouseX - direction = offset > 0 ? "RTL" : "LTR"; - } - - onPressed: { - lastX = mouse.x - } - - onReleased: { - if (root.triggerActionOnMouseRelease && root.activeAction) { - triggerAction.start() - } else { - root.returnToBounds() - root.activeAction = null - } - lastX = -1 - direction = "None" - } - onClicked: { - if (selectionMode) { // CUSTOM - selecting a listitem should toggle selection if in selectionMode - selected = !selected - return - } else if (main.x === 0) { - root.itemClicked(mouse) - } else if (main.x > 0) { - var action = getActionAt(Qt.point(mouse.x, mouse.y)) - if (action && action !== -1) { - //action.triggered(root) - removeAnimation.action = action // CUSTOM - use our animation instead - removeAnimation.start() // CUSTOM - } - } else { - var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y)) - - if (actionIndex !== -1 && actionIndex !== leftSideAction) { // CUSTOM - can be leftAction - root.activeItem = rightActionsRepeater.itemAt(actionIndex) - root.activeAction = root.rightSideActions[actionIndex] - triggerAction.start() - return - } - } - root.resetSwipe() - } - - onPositionChanged: { - if (mouseArea.pressed) { - updateActiveAction() - - listItemSwiping(index) // CUSTOM - tells other listitems to dismiss any swipe - } - } - onPressAndHold: { - if (main.x === 0) { - root.itemPressAndHold(mouse) - } - } - - z: -1 - } -} === modified file 'app/components/MultiSelectListView.qml' --- app/components/MultiSelectListView.qml 2015-11-02 21:28:34 +0000 +++ app/components/MultiSelectListView.qml 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2014, 2015 + * Copyright (C) 2013, 2014, 2015, 2017 * Andrew Hayzen <ahay...@gmail.com> * Daniel Holm <d.hol...@gmail.com> * Victor Thompson <victor.thomp...@gmail.com> @@ -20,33 +20,52 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 - WeatherListView { - property var selectedItems: [] + // Can't access ViewItems externally + // so we need to expose if in multiselect mode for the header states + state: ViewItems.selectMode ? "multiselectable" : "default" signal clearSelection() signal closeSelection() + signal reorder(int from, int to) signal selectAll() - onClearSelection: selectedItems = [] + onClearSelection: ViewItems.selectedIndices = [] onCloseSelection: { clearSelection() - state = "normal" + ViewItems.selectMode = false + ViewItems.dragMode = false } onSelectAll: { - var tmp = selectedItems + var tmp = [] for (var i=0; i < model.count; i++) { - if (tmp.indexOf(i) === -1) { - tmp.push(i) - } + tmp.push(i) } - selectedItems = tmp - } - onVisibleChanged: { - if (!visible) { - closeSelection() + ViewItems.selectedIndices = tmp + } + + // Can't access ViewItems externally + // so for the header actions we need to expose the selectedIndices + function getSelectedIndices() { + var indicies = ViewItems.selectedIndices.slice(); + + indicies.sort(); // ensure indicies are in-order + + return indicies; + } + + ViewItems.selectMode: false + ViewItems.dragMode: false + ViewItems.onDragUpdated: { + // Only update the model when the listitem is dropped, not 'live' + if (event.status == ListItemDrag.Moving) { + event.accept = false + } else if (event.status == ListItemDrag.Dropped) { + model.move(event.from, event.to, 1); + + reorder(event.from, event.to) } } } === modified file 'app/components/WeatherListItem.qml' --- app/components/WeatherListItem.qml 2015-11-02 21:28:34 +0000 +++ app/components/WeatherListItem.qml 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2014, 2015 + * Copyright (C) 2013, 2014, 2015, 2017 * Andrew Hayzen <ahay...@gmail.com> * Nekhelesh Ramananthan <krnekhel...@gmail.com> * Victor Thompson <victor.thomp...@gmail.com> @@ -20,119 +20,39 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 -ListItemWithActions { - id: root +ListItem { color: "transparent" - - property int listItemIndex: index + divider { + visible: true + } + highlightColor: Qt.lighter(color, 1.2) + + // Store the currentColor so that actions can bind to it + property var currentColor: highlighted ? highlightColor : color + property bool multiselectable: false - property int previousListItemIndex: -1 + property bool pressAndHoldEnabled: true property bool reorderable: false - signal reorder(int from, int to) - - onItemPressAndHold: { - if (multiselectable) { - selectionMode = true - } - } - - onListItemIndexChanged: { - var i = parent.parent.selectedItems.lastIndexOf(previousListItemIndex) - - if (i !== -1) { - parent.parent.selectedItems[i] = listItemIndex - } - - previousListItemIndex = listItemIndex - } - - onSelectedChanged: { - if (selectionMode) { - var tmp = parent.parent.selectedItems - - if (selected) { - if (parent.parent.selectedItems.indexOf(listItemIndex) === -1) { - tmp.push(listItemIndex) - parent.parent.selectedItems = tmp - } - } else { - tmp.splice(parent.parent.selectedItems.indexOf(listItemIndex), 1) - parent.parent.selectedItems = tmp - } - } - } - - onSelectionModeChanged: { - if (reorderable && selectionMode) { - resetSwipe() - } - - for (var j=0; j < _main.children.length; j++) { - if (_main.children[j] !== actionReorderLoader) { - _main.children[j].anchors.rightMargin = reorderable && selectionMode ? actionReorderLoader.width + units.gu(2) : 0 - } - } - - parent.parent.state = selectionMode ? "multiselectable" : "normal" - - if (!selectionMode) { - selected = false - } - } - - /* Highlight the listitem on press */ - Rectangle { - id: listItemBrighten - color: root.pressed ? UbuntuColors.coolGrey : "transparent" - opacity: 0.1 - height: root.height - x: root.x - parent.x // -parent.x due to selectionIcon in ListItemWithActions - width: root.width - } - - /* Reorder Component */ - Loader { - id: actionReorderLoader - active: reorderable && selectionMode && root.parent.parent.selectedItems.length === 0 - anchors { - bottom: parent.bottom - right: parent.right - rightMargin: units.gu(1) - top: parent.top - } - asynchronous: true - source: "ListItemReorderComponent.qml" - } - - Item { - Connections { // Only allow one ListItem to be swiping at any time - target: weatherApp - onListItemSwiping: { - if (i !== index) { - root.resetSwipe(); - } - } - } - - Connections { // Connections from signals in the ListView - target: root.parent.parent - onClearSelection: selected = false - onFlickingChanged: { - if (root.parent.parent.flicking) { - root.resetSwipe() - } - } - onSelectAll: selected = true - onStateChanged: selectionMode = root.parent.parent.state === "multiselectable" - } - } - - Component.onCompleted: { // reload settings as delegates are destroyed - if (parent.parent.selectedItems.indexOf(index) !== -1) { - selected = true - } - - selectionMode = root.parent.parent.state === "multiselectable" + signal itemClicked() + + onClicked: { + if (selectMode) { + selected = !selected; + } else { + itemClicked() + } + } + + onPressAndHold: { + if (pressAndHoldEnabled) { + if (reorderable) { + ListView.view.ViewItems.dragMode = !ListView.view.ViewItems.dragMode + } + + if (multiselectable) { + ListView.view.ViewItems.selectMode = !ListView.view.ViewItems.selectMode + } + } } } === modified file 'app/ui/LocationPane.qml' --- app/ui/LocationPane.qml 2017-04-12 09:55:14 +0000 +++ app/ui/LocationPane.qml 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Canonical Ltd + * Copyright (C) 2015, 2017 Canonical Ltd * * This file is part of Ubuntu Weather App * @@ -18,7 +18,6 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 0.1 as ListItem import "../components" import "../data/suncalc.js" as SunCalc @@ -55,79 +54,78 @@ modelData: model } - header: Column { - id: locationTop - - anchors { - left: parent.left - right: parent.right - margins: units.gu(2) - } - spacing: units.gu(1) - - Row { // spacing at top - height: units.gu(1) - width: parent.width - } - - HeaderRow { - id: headerRow - locationName: mainPageWeekdayListView.name - } - - HomeGraphic { - id: homeGraphic - icon: mainPageWeekdayListView.icon - visible: graphicVisible; - MouseArea { - anchors.fill: parent - onClicked: { - graphicVisible = false; - } - } - } - - Loader { - id: homeHourlyLoader - active: !homeGraphic.visible - asynchronous: true - height: units.gu(32) - source: "../components/HomeHourly.qml" - visible: active - width: parent.width - } - - HomeTempInfo { - id: homeTempInfo - modelData: todayData - now: mainPageWeekdayListView.currentTemp - updatedAt: mainPageWeekdayListView.lastFetch - } - - // TODO: Migrate this to using the new SDK list item when possible. - ListItem.ThinDivider { + header: ListItem { + divider { + visible: true + } + height: locationTop.height + + Column { + id: locationTop + anchors { - leftMargin: units.gu(-2); - rightMargin: units.gu(-2) - } - } - - NumberAnimation { - id: scrollToTopAnimation - target: mainPageWeekdayListView; - property: "contentY"; - duration: 200; - easing.type: Easing.InOutQuad - to: -height - } - - Connections { - target: locationPages - onCurrentIndexChanged: { - if (locationPages.currentIndex !== index) { - scrollToTopAnimation.start() - } else { - mainPageWeekdayListView.contentY = -locationTop.height + left: parent.left + right: parent.right + margins: units.gu(2) + } + spacing: units.gu(1) + + Row { // spacing at top + height: units.gu(1) + width: parent.width + } + + HeaderRow { + id: headerRow + locationName: mainPageWeekdayListView.name + } + + HomeGraphic { + id: homeGraphic + icon: mainPageWeekdayListView.icon + visible: graphicVisible; + MouseArea { + anchors.fill: parent + onClicked: { + graphicVisible = false; + } + } + } + + Loader { + id: homeHourlyLoader + active: !homeGraphic.visible + asynchronous: true + height: units.gu(32) + source: "../components/HomeHourly.qml" + visible: active + width: parent.width + } + + HomeTempInfo { + id: homeTempInfo + modelData: todayData + now: mainPageWeekdayListView.currentTemp + updatedAt: mainPageWeekdayListView.lastFetch + } + + NumberAnimation { + id: scrollToTopAnimation + target: mainPageWeekdayListView; + property: "contentY"; + duration: 200; + easing.type: Easing.InOutQuad + to: -height + } + + Connections { + target: locationPages + onCurrentIndexChanged: { + if (locationPages.currentIndex !== index) { + scrollToTopAnimation.start() + } else { + mainPageWeekdayListView.contentY = -locationTop.height + } } } } === modified file 'app/ui/LocationsPage.qml' --- app/ui/LocationsPage.qml 2017-04-18 09:08:08 +0000 +++ app/ui/LocationsPage.qml 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Canonical Ltd + * Copyright (C) 2015, 2017 Canonical Ltd * * This file is part of Ubuntu Weather App * @@ -18,7 +18,6 @@ import QtQuick 2.4 import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 0.1 as ListItem import "../components" import "../components/HeadState" import "../components/ListItemActions" @@ -37,7 +36,7 @@ removable: true thisPage: locationsPage - onRemoved: storage.removeMultiLocations(selectedItems.slice()); + onRemoved: storage.removeMultiLocations(selectedIndices.slice()); } ] @@ -65,93 +64,91 @@ left: parent.left right: parent.right } - height: settings.addedCurrentLocation && settings.detectCurrentLocation ? units.gu(8) : units.gu(0) + height: settings.addedCurrentLocation && settings.detectCurrentLocation ? contentHeight : units.gu(0) interactive: false model: currentLocationModel delegate: WeatherListItem { id: currentLocationListItem + height: currentListItemLayout.height + (divider.visible ? divider.height : 0) + (fakeDivider.visible ? fakeDivider.height : 0) onItemClicked: { settings.current = index; + + // Ensure any selections are closed + locationsListView.closeSelection(); + locationsPage.pop() } - Column { - anchors { - left: parent.left - right: currentWeatherImage.left - rightMargin: units.gu(3) - verticalCenter: parent.verticalCenter + ListItemLayout { + id: currentListItemLayout + subtitle { + elide: Text.ElideRight + fontSize: "small" + text: name + ", " + (adminName1 == name ? countryName : adminName1) } - - Label { - id: currentLocationName - - anchors { - left: parent.left - leftMargin: units.gu(2) - } - + title { elide: Text.ElideRight fontSize: "medium" text: i18n.tr("Current Location") - width: parent.width - } + } + + Icon { + anchors { + verticalCenter: parent.verticalCenter + } + height: parent.height / 2 + name: icon + SlotsLayout.position: SlotsLayout.Trailing + SlotsLayout.overrideVerticalPositioning: true + width: height + } + Label { - id: currentLocationName2 - anchors { - left: parent.left - leftMargin: units.gu(2) + verticalCenter: parent.verticalCenter } - - color: UbuntuColors.graphite + color: UbuntuColors.orange elide: Text.ElideRight - fontSize: "small" - font.weight: Font.Light - text: name + ", " + (adminName1 == name ? countryName : adminName1) - width: parent.width - } - } - - Icon { - id: currentWeatherImage - anchors { - right: parent.right - rightMargin: units.gu(14) - verticalCenter: parent.verticalCenter - } - name: icon - height: units.gu(3) - width: units.gu(3) - } - - Label { - id: currentTemperatureLabel - anchors { - left: currentWeatherImage.right - leftMargin: units.gu(1) - right: parent.right - rightMargin: units.gu(2) - verticalCenter: parent.verticalCenter - } - color: UbuntuColors.orange - elide: Text.ElideRight - font.pixelSize: units.gu(4) - font.weight: Font.Light - horizontalAlignment: Text.AlignRight - text: temp + settings.tempScale + font { + pixelSize: parent.height / 2 + weight: Font.Light + } + horizontalAlignment: Text.AlignRight + SlotsLayout.position: SlotsLayout.Trailing + SlotsLayout.overrideVerticalPositioning: true + text: temp + settings.tempScale + } + } + + // Inject extra divider when we are the last as the SDK hides it + // but we need one as we have another listview directly below + ListItem { + id: fakeDivider + anchors { + bottom: parent.bottom + } + divider { + visible: true + } + height: divider.height + visible: currentLocationModel.count - 1 == index } } } delegate: WeatherListItem { id: locationsListItem + height: listItemLayout.height + (divider.visible ? divider.height : 0) + leadingActions: ListItemActions { + actions: [ + Remove { + onTriggered: storage.removeLocation(index) + } + ] + } + multiselectable: true objectName: "location" + index - leftSideAction: Remove { - onTriggered: storage.removeLocation(index) - } - multiselectable: true reorderable: true onItemClicked: { @@ -163,89 +160,56 @@ locationsPage.pop() } - onReorder: { - console.debug("Move: ", from, to); - - storage.moveLocation(from, to); - } - - ListItem.ThinDivider { - anchors { - top: parent.top - } - visible: index == 0 - } - - Item { - anchors { - fill: parent - leftMargin: units.gu(2) - rightMargin: units.gu(2) - } - - Column { - anchors { - left: parent.left - right: weatherImage.visible ? weatherImage.left : parent.right - rightMargin: units.gu(1) - verticalCenter: parent.verticalCenter - } - - Label { - id: locationName - objectName: "name" - elide: Text.ElideRight - fontSize: "medium" - text: name - width: parent.width - } - Label { - id: locationName2 - color: UbuntuColors.graphite - elide: Text.ElideRight - fontSize: "small" - font.weight: Font.Light - text: adminName1 == name ? countryName : adminName1 - width: parent.width - } + + ListItemLayout { + id: listItemLayout + subtitle { + elide: Text.ElideRight + fontSize: "small" + text: adminName1 == name ? countryName : adminName1 + } + title { + elide: Text.ElideRight + fontSize: "medium" + objectName: "name" + text: name } Icon { - id: weatherImage anchors { - right: parent.right - rightMargin: units.gu(12) verticalCenter: parent.verticalCenter } + height: parent.height / 2 name: icon - height: units.gu(3) - width: units.gu(3) - visible: locationsPage.state === "default" + SlotsLayout.position: SlotsLayout.Trailing + SlotsLayout.overrideVerticalPositioning: true + width: height + visible: locationsListView.state === "default" } Label { - id: temperatureLabel anchors { - left: weatherImage.right - leftMargin: units.gu(1) - right: parent.right verticalCenter: parent.verticalCenter } color: UbuntuColors.orange elide: Text.ElideRight - font.pixelSize: units.gu(4) - font.weight: Font.Light + font { + pixelSize: parent.height / 2 + weight: Font.Light + } horizontalAlignment: Text.AlignRight + SlotsLayout.position: SlotsLayout.Trailing + SlotsLayout.overrideVerticalPositioning: true text: temp + settings.tempScale - visible: locationsPage.state === "default" - } - } - - ListItem.ThinDivider { - anchors { - bottom: parent.bottom - } - } + visible: locationsListView.state === "default" + } + } + } + + onReorder: { + console.debug("Move: ", from, to); + + storage.moveLocation(from, to); } } === modified file 'tests/autopilot/ubuntu_weather_app/__init__.py' --- tests/autopilot/ubuntu_weather_app/__init__.py 2017-04-13 10:38:05 +0000 +++ tests/autopilot/ubuntu_weather_app/__init__.py 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- -# Copyright 2013, 2014, 2015 Canonical +# Copyright 2013, 2014, 2015, 2017 Canonical # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published @@ -8,7 +8,7 @@ """ubuntu-weather-app tests and emulators - top level package.""" from autopilot.introspection import dbus import logging -from ubuntuuitoolkit import (MainView, QQuickListView, +from ubuntuuitoolkit import (MainView, QQuickListView, UCListItem, UbuntuUIToolkitCustomProxyObjectBase) logger = logging.getLogger(__name__) @@ -329,20 +329,10 @@ "StandardListItem", iconVisible=showIcon) -class WeatherListItem(UbuntuUIToolkitCustomProxyObjectBase): +class WeatherListItem(UCListItem): + def click_remove_action(self): + return self.trigger_leading_action("swipeDeleteAction", + self.wait_until_destroyed) + def get_name(self): return self.select_single("UCLabel", objectName="name").text - - @click_object - def select_remove(self): - return self.select_single(objectName="swipeDeleteAction") - - def swipe_and_select_remove(self): - x, y, width, height = self.globalRect - start_x = x + (width * 0.2) - stop_x = x + (width * 0.8) - start_y = stop_y = y + (height // 2) - - self.pointing_device.drag(start_x, start_y, stop_x, stop_y) - - self.select_remove() === modified file 'tests/autopilot/ubuntu_weather_app/tests/test_locations_page.py' --- tests/autopilot/ubuntu_weather_app/tests/test_locations_page.py 2015-08-10 03:13:48 +0000 +++ tests/autopilot/ubuntu_weather_app/tests/test_locations_page.py 2017-04-25 12:59:22 +0000 @@ -1,5 +1,5 @@ # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- -# Copyright 2013, 2014, 2015 Canonical +# Copyright 2013, 2014, 2015, 2017 Canonical # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published @@ -48,7 +48,7 @@ self.assertThat(list_item.get_name(), Equals("London")) # Remove the location via the list item action - list_item.swipe_and_select_remove() + list_item.click_remove_action() # Check that the location was removed self.assertThat(self.home_page.get_location_count,
-- Mailing list: https://launchpad.net/~ubuntu-touch-coreapps-reviewers Post to : ubuntu-touch-coreapps-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~ubuntu-touch-coreapps-reviewers More help : https://help.launchpad.net/ListHelp