ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #05311
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
Andrew Hayzen has proposed merging lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app with lp:~vthompson/music-app/music-uc1.3 as a prerequisite.
Commit message:
* Switch to using the new listitems within the SDK
Requested reviews:
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot): continuous-integration
Andrew Hayzen (ahayzen)
Related bugs:
Bug #1400551 in Ubuntu Music App: "[Music] When reordering, an item can be made to temporarily disappear"
https://bugs.launchpad.net/music-app/+bug/1400551
Bug #1472080 in Ubuntu Music App: "Select boxes display a little lag when quick swipe up/down in playlist"
https://bugs.launchpad.net/music-app/+bug/1472080
For more details, see:
https://code.launchpad.net/~ahayzen/music-app/refactor-use-sdk-listitems/+merge/274829
* Switch to using the new listitems within the SDK
Note: this includes lp:~ahayzen/music-app/fix-child-page-freezes to ease testing otherwise you'll likely be able to freeze some views
--
Your team Music App Developers is subscribed to branch lp:music-app.
=== modified file 'app/components/BlurredHeader.qml'
--- app/components/BlurredHeader.qml 2015-10-18 18:16:18 +0000
+++ app/components/BlurredHeader.qml 2015-10-18 18:16:18 +0000
@@ -18,9 +18,8 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.0 as ListItem
-ListItem.Standard {
+ListItem {
width: parent.width
property alias bottomColumn: bottomColumnLoader.sourceComponent
=== added file 'app/components/Delegates/ActionDelegate.qml'
--- app/components/Delegates/ActionDelegate.qml 1970-01-01 00:00:00 +0000
+++ app/components/Delegates/ActionDelegate.qml 2015-10-18 18:16:18 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015
+ * Andrew Hayzen <ahayzen@xxxxxxxxx>
+ * Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * 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.2
+
+Rectangle {
+ color: currentColor
+ width: height
+
+ Icon {
+ anchors {
+ centerIn: parent
+ }
+ objectName: action.objectName
+ color: pressed ? UbuntuColors.blue : styleMusic.common.white
+ name: action.iconName
+ height: units.gu(3)
+ width: units.gu(3)
+ }
+
+ Rectangle { // FIXME: pad.lv/1507339 Workaround for gap between end of listitem and first action
+ anchors {
+ bottom: parent.bottom
+ right: parent.left
+ top: parent.top
+ }
+ color: currentColor
+ width: units.gu(0.5)
+ }
+}
=== removed file 'app/components/Delegates/ListItemWithActions.qml'
--- app/components/Delegates/ListItemWithActions.qml 2015-10-18 18:16:18 +0000
+++ app/components/Delegates/ListItemWithActions.qml 1970-01-01 00:00:00 +0000
@@ -1,507 +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: styleMusic.mainView.backgroundColor
- property color selectedColor: "#3d3d45" // "#E6E6E6" // CUSTOM
- 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) // CUSTOM 5?
- 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
-
- Rectangle { // CUSTOM
- anchors {
- bottom: parent.bottom
- left: parent.left
- top: parent.top
- }
- color: styleMusic.common.black
- opacity: 0.7
- width: parent.width + actionThreshold
- }
-
- 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.blue : styleMusic.common.white // 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/Delegates/MusicListItem.qml'
--- app/components/Delegates/MusicListItem.qml 2015-10-18 18:16:18 +0000
+++ app/components/Delegates/MusicListItem.qml 2015-10-18 18:16:18 +0000
@@ -21,131 +21,66 @@
import Ubuntu.Components 1.3
import "../"
+ListItem {
+ color: styleMusic.mainView.backgroundColor
+ highlightColor: Qt.lighter(color, 1.2)
-ListItemWithActions {
- id: root
+ // Store the currentColor so that actions can bind to it
+ property var currentColor: highlighted ? highlightColor : color
property alias column: musicRow.column
property alias imageSource: musicRow.imageSource
- property int listItemIndex: index
property bool multiselectable: false
- property int previousListItemIndex: -1
property bool reorderable: false
- signal reorder(int from, int to)
-
- onItemPressAndHold: {
+ signal itemClicked()
+
+ onClicked: {
+ if (selectMode) {
+ selected = !selected;
+ } else {
+ itemClicked()
+ }
+ }
+
+ onPressAndHold: {
+ // FIXME: pad.lv/1468100 drag a listitem with no leadingActions to right, then press and hold causes no signal
+
+ if (reorderable) {
+ ListView.view.ViewItems.dragMode = !ListView.view.ViewItems.dragMode
+ }
+
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 ? styleMusic.common.white : "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: mainView
- 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"
- }
- }
-
+ ListView.view.ViewItems.selectMode = !ListView.view.ViewItems.selectMode
+ }
+ }
+
+ divider {
+ visible: false
+ }
MusicRow {
id: musicRow
anchors {
- verticalCenter: parent.verticalCenter
- }
- height: parent.height
- }
-
- Component.onCompleted: { // reload settings as delegates are destroyed
- if (parent.parent.selectedItems.indexOf(index) !== -1) {
- selected = true
- }
-
- selectionMode = root.parent.parent.state === "multiselectable"
+ fill: parent
+ // When not in selectMode we want a margin between the Image and the left edge
+ // when in selectMode the checkbox has its own margin so we don't want a double margin
+ leftMargin: selectMode ? 0 : units.gu(2)
+ rightMargin: selectMode ? 0 : units.gu(2)
+ }
+
+ // Animate margin changes so it isn't noticible
+ Behavior on anchors.leftMargin {
+ NumberAnimation {
+
+ }
+ }
+
+ Behavior on anchors.rightMargin {
+ NumberAnimation {
+
+ }
+ }
}
}
=== modified file 'app/components/Flickables/MultiSelectListView.qml'
--- app/components/Flickables/MultiSelectListView.qml 2015-10-18 18:16:18 +0000
+++ app/components/Flickables/MultiSelectListView.qml 2015-10-18 18:16:18 +0000
@@ -21,31 +21,50 @@
import Ubuntu.Components 1.3
MusicListView {
- 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" : "normal"
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/HeadState/MultiSelectHeadState.qml'
--- app/components/HeadState/MultiSelectHeadState.qml 2015-10-18 18:16:18 +0000
+++ app/components/HeadState/MultiSelectHeadState.qml 2015-10-18 18:16:18 +0000
@@ -18,6 +18,7 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
+import "../Flickables"
PageHeadState {
id: selectionState
@@ -26,7 +27,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()
@@ -34,14 +35,15 @@
}
},
Action {
- enabled: listview !== null ? listview.selectedItems.length > 0 : false
+ enabled: listview !== null ? listview.getSelectedIndices().length > 0 : false
iconName: "add-to-playlist"
text: i18n.tr("Add to playlist")
onTriggered: {
var items = []
+ var indicies = listview.getSelectedIndices();
- for (var i=0; i < listview.selectedItems.length; i++) {
- items.push(makeDict(listview.model.get(listview.selectedItems[i], listview.model.RoleModelData)));
+ for (var i=0; i < indicies.length; i++) {
+ items.push(makeDict(listview.model.get(indicies[i], listview.model.RoleModelData)));
}
mainPageStack.push(Qt.resolvedUrl("../../ui/AddToPlaylist.qml"),
@@ -51,16 +53,17 @@
}
},
Action {
- enabled: listview !== null ? listview.selectedItems.length > 0 : false
+ enabled: listview !== null ? listview.getSelectedIndices().length > 0 : false
iconName: "add"
text: i18n.tr("Add to queue")
visible: addToQueue
onTriggered: {
var items = []
+ var indicies = listview.getSelectedIndices();
- for (var i=0; i < listview.selectedItems.length; i++) {
- items.push(listview.model.get(listview.selectedItems[i], listview.model.RoleModelData));
+ for (var i=0; i < indicies.length; i++) {
+ items.push(listview.model.get(indicies[i], listview.model.RoleModelData));
}
trackQueue.appendList(items)
@@ -69,13 +72,13 @@
}
},
Action {
- enabled: listview !== null ? listview.selectedItems.length > 0 : false
+ enabled: listview !== null ? listview.getSelectedIndices().length > 0 : false
iconName: "delete"
text: i18n.tr("Delete")
visible: removable
onTriggered: {
- removed(listview.selectedItems)
+ removed(listview.getSelectedIndices())
listview.closeSelection()
}
@@ -85,10 +88,7 @@
backAction: Action {
text: i18n.tr("Cancel selection")
iconName: "back"
- onTriggered: {
- listview.clearSelection()
- listview.state = "normal"
- }
+ onTriggered: listview.closeSelection()
}
head: thisPage.head
name: "selection"
@@ -100,9 +100,9 @@
}
property bool addToQueue: true
- property ListView listview
+ property MultiSelectListView listview
property bool removable: false
property Page thisPage
- signal removed(var selectedItems)
+ signal removed(var selectedIndices)
}
=== added file 'app/components/ListItemActions/AddToQueueAndPlaylist.qml'
--- app/components/ListItemActions/AddToQueueAndPlaylist.qml 1970-01-01 00:00:00 +0000
+++ app/components/ListItemActions/AddToQueueAndPlaylist.qml 2015-10-18 18:16:18 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015
+ * Andrew Hayzen <ahayzen@xxxxxxxxx>
+ * Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * 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.2
+import "../Delegates"
+
+ListItemActions {
+ actions: [
+ AddToQueue {
+
+ },
+ AddToPlaylist {
+ }
+ ]
+ delegate: ActionDelegate {
+
+ }
+}
=== removed file 'app/components/ListItemActions/CheckBox.qml'
--- app/components/ListItemActions/CheckBox.qml 2015-10-18 18:16:18 +0000
+++ app/components/ListItemActions/CheckBox.qml 1970-01-01 00:00:00 +0000
@@ -1,25 +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
-
-CheckBox {
- checked: root.selected
- width: implicitWidth
- // disable item mouse area to avoid conflicts with parent mouse area
- __mouseArea.enabled: false
-}
=== modified file 'app/components/MusicRow.qml'
--- app/components/MusicRow.qml 2015-10-18 18:16:18 +0000
+++ app/components/MusicRow.qml 2015-10-18 18:16:18 +0000
@@ -22,12 +22,6 @@
Row {
- anchors {
- left: parent.left
- leftMargin: units.gu(2)
- right: parent.right
- rightMargin: units.gu(2)
- }
height: units.gu(7)
property alias column: columnComponent.sourceComponent
=== modified file 'app/components/Queue.qml'
--- app/components/Queue.qml 2015-10-18 18:16:18 +0000
+++ app/components/Queue.qml 2015-10-18 18:16:18 +0000
@@ -37,9 +37,6 @@
model: trackQueue.model
objectName: "nowPlayingqueueList"
- property int normalHeight: units.gu(6)
- property int transitionDuration: 250 // transition length of animations
-
onCountChanged: customdebug("Queue: Now has: " + queueList.count + " tracks")
delegate: MusicListItem {
@@ -62,41 +59,44 @@
text: model.author
}
}
- height: queueList.normalHeight
+ leadingActions: ListItemActions {
+ actions: [
+ Remove {
+ onTriggered: trackQueue.removeQueueList([index])
+ }
+ ]
+ }
+ multiselectable: true
objectName: "nowPlayingListItem" + index
- state: ""
- leftSideAction: Remove {
- onTriggered: trackQueue.removeQueueList([index])
- }
- multiselectable: true
reorderable: true
- rightSideActions: [
- AddToPlaylist{
+ trailingActions: ListItemActions {
+ actions: [
+ AddToPlaylist {
+ }
+ ]
+ delegate: ActionDelegate {
+
}
- ]
+ }
onItemClicked: {
customdebug("File: " + model.filename) // debugger
trackQueueClick(index); // toggle track state
}
- onReorder: {
- console.debug("Move: ", from, to);
-
- trackQueue.model.move(from, to, 1);
- Library.moveQueueItem(from, to);
-
- // Maintain currentIndex with current song
- if (from === player.currentIndex) {
- player.currentIndex = to;
- }
- else if (from < player.currentIndex && to >= player.currentIndex) {
- player.currentIndex -= 1;
- }
- else if (from > player.currentIndex && to <= player.currentIndex) {
- player.currentIndex += 1;
- }
-
- queueIndex = player.currentIndex
+ }
+
+ onReorder: {
+ Library.moveQueueItem(from, to);
+
+ // Maintain currentIndex with current song
+ if (from === player.currentIndex) {
+ player.currentIndex = to;
+ } else if (from < player.currentIndex && to >= player.currentIndex) {
+ player.currentIndex -= 1;
+ } else if (from > player.currentIndex && to <= player.currentIndex) {
+ player.currentIndex += 1;
}
+
+ queueIndex = player.currentIndex
}
}
=== modified file 'app/components/Walkthrough/Walkthrough.qml'
--- app/components/Walkthrough/Walkthrough.qml 2015-10-18 18:16:18 +0000
+++ app/components/Walkthrough/Walkthrough.qml 2015-10-18 18:16:18 +0000
@@ -22,7 +22,6 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.0 as ListItem
Page {
id: walkthrough
=== modified file 'app/ui/AddToPlaylist.qml'
--- app/ui/AddToPlaylist.qml 2015-10-18 18:16:18 +0000
+++ app/ui/AddToPlaylist.qml 2015-10-18 18:16:18 +0000
@@ -20,7 +20,6 @@
import QtMultimedia 5.0
import QtQuick 2.4
import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.Components.Popups 1.0
import QtQuick.LocalStorage 2.0
import "../logic/meta-database.js" as Library
=== modified file 'app/ui/ArtistView.qml'
--- app/ui/ArtistView.qml 2015-10-18 18:16:18 +0000
+++ app/ui/ArtistView.qml 2015-10-18 18:16:18 +0000
@@ -20,7 +20,6 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Components.Popups 1.0
-import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.MediaScanner 0.1
import Ubuntu.Thumbnailer 0.1
import QtQuick.LocalStorage 2.0
=== modified file 'app/ui/Artists.qml'
--- app/ui/Artists.qml 2015-10-18 18:16:18 +0000
+++ app/ui/Artists.qml 2015-10-18 18:16:18 +0000
@@ -20,7 +20,6 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Components.Popups 1.0
-import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.MediaScanner 0.1
import Ubuntu.Thumbnailer 0.1
import QtQuick.LocalStorage 2.0
=== modified file 'app/ui/NowPlaying.qml'
--- app/ui/NowPlaying.qml 2015-10-18 18:16:18 +0000
+++ app/ui/NowPlaying.qml 2015-10-18 18:16:18 +0000
@@ -128,7 +128,7 @@
// Remove the tracks from the queue
// Use slice() to copy the list
// so that the indexes don't change as they are removed
- trackQueue.removeQueueList(selectedItems.slice())
+ trackQueue.removeQueueList(selectedIndices.slice())
}
}
]
=== modified file 'app/ui/Recent.qml'
--- app/ui/Recent.qml 2015-10-18 18:16:18 +0000
+++ app/ui/Recent.qml 2015-10-18 18:16:18 +0000
@@ -20,7 +20,6 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Components.Popups 1.0
-import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.MediaScanner 0.1
import Ubuntu.Thumbnailer 0.1
import QtMultimedia 5.0
=== modified file 'app/ui/Songs.qml'
--- app/ui/Songs.qml 2015-10-18 18:16:18 +0000
+++ app/ui/Songs.qml 2015-10-18 18:16:18 +0000
@@ -65,7 +65,6 @@
fill: parent
topMargin: units.gu(2)
}
- highlightFollowsCurrentItem: false
objectName: "trackstab-listview"
model: SortFilterModel {
id: songsModelFilter
@@ -113,12 +112,8 @@
height: units.gu(7)
imageSource: {"art": model.art}
multiselectable: true
- rightSideActions: [
- AddToQueue {
- },
- AddToPlaylist {
- }
- ]
+ trailingActions: AddToQueueAndPlaylist {
+ }
onItemClicked: {
if (songsPage.state === "search") { // only play single track when searching
=== modified file 'app/ui/SongsView.qml'
--- app/ui/SongsView.qml 2015-10-18 18:16:18 +0000
+++ app/ui/SongsView.qml 2015-10-18 18:16:18 +0000
@@ -19,7 +19,6 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
-import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.Components.Popups 1.0
import Ubuntu.MediaScanner 0.1
import Ubuntu.Thumbnailer 0.1
@@ -155,7 +154,7 @@
thisPage: songStackPage
onRemoved: {
- Playlists.removeFromPlaylist(songStackPage.line2, selectedItems)
+ Playlists.removeFromPlaylist(songStackPage.line2, selectedIndices)
playlistChangedHelper() // update recent/playlist models
@@ -315,18 +314,12 @@
}
}
height: units.gu(6)
-
- leftSideAction: songStackPage.line1 === i18n.tr("Playlist")
+ leadingActions: songStackPage.line1 === i18n.tr("Playlist")
? playlistRemoveAction.item : null
multiselectable: true
reorderable: songStackPage.line1 === i18n.tr("Playlist")
- rightSideActions: [
- AddToQueue {
-
- },
- AddToPlaylist {
- }
- ]
+ trailingActions: AddToQueueAndPlaylist {
+ }
onItemClicked: {
trackClicked(albumtrackslist.model, index) // play track
@@ -341,24 +334,21 @@
recentChangedHelper();
}
- onReorder: {
- console.debug("Move: ", from, to);
-
- Playlists.move(songStackPage.line2, from, to)
-
- albumTracksModel.filterPlaylistTracks(songStackPage.line2)
- }
Loader {
id: playlistRemoveAction
- sourceComponent: Remove {
- onTriggered: {
- Playlists.removeFromPlaylist(songStackPage.line2, [model.i])
-
- playlistChangedHelper() // update recent/playlist models
-
- albumTracksModel.filterPlaylistTracks(songStackPage.line2)
- }
+ sourceComponent: ListItemActions {
+ actions: [
+ Remove {
+ onTriggered: {
+ Playlists.removeFromPlaylist(songStackPage.line2, [model.i])
+
+ playlistChangedHelper() // update recent/playlist models
+
+ albumTracksModel.filterPlaylistTracks(songStackPage.line2)
+ }
+ }
+ ]
}
}
@@ -370,6 +360,14 @@
}
}
}
+
+ onReorder: {
+ console.debug("Move: ", from, to);
+
+ Playlists.move(songStackPage.line2, from, to)
+
+ albumTracksModel.filterPlaylistTracks(songStackPage.line2)
+ }
}
Component.onCompleted: loaded = true
=== modified file 'debian/changelog'
--- debian/changelog 2015-10-18 18:16:18 +0000
+++ debian/changelog 2015-10-18 18:16:18 +0000
@@ -6,6 +6,9 @@
[ Victor Thompson ]
* Remove some deprecated code for the UbuntuShape image property.
+ [ Andrew Hayzen ]
+ * Switch to using the new listitems within the SDK
+
-- Bartosz Kosiorek <gang65@xxxxxxxxxxxxxx> Tue, 08 Sep 2015 10:08:49 +0200
music-app (2.2ubuntu1) vivid; urgency=medium
=== modified file 'tests/autopilot/music_app/__init__.py'
--- tests/autopilot/music_app/__init__.py 2015-05-04 14:07:05 +0000
+++ tests/autopilot/music_app/__init__.py 2015-10-18 18:16:18 +0000
@@ -6,7 +6,9 @@
# by the Free Software Foundation.
"""music-app tests and emulators - top level package."""
-from ubuntuuitoolkit import MainView, UbuntuUIToolkitCustomProxyObjectBase
+from ubuntuuitoolkit import (
+ MainView, UbuntuUIToolkitCustomProxyObjectBase, UCListItem
+)
class MusicAppException(Exception):
@@ -383,42 +385,20 @@
now_playing_page.visible.wait_for(True)
-class MusicListItem(UbuntuUIToolkitCustomProxyObjectBase):
- @click_object
+class MusicListItem(UCListItem):
def click_add_to_playlist_action(self):
- return self.wait_select_single(objectName="addToPlaylistAction")
+ return self.trigger_trailing_action("addToPlaylistAction")
- @click_object
def click_add_to_queue_action(self):
- return self.wait_select_single(objectName="addToQueueAction")
+ return self.trigger_trailing_action("addToQueueAction")
- @click_object
- def confirm_removal(self):
- return self.wait_select_single(objectName="swipeDeleteAction")
+ def click_remove_action(self):
+ return self.trigger_leading_action("swipeDeleteAction",
+ self.wait_until_destroyed)
def get_label_text(self, name):
return self.wait_select_single(objectName=name).text
- def swipe_reveal_actions(self):
- x, y, width, height = self.globalRect
- start_x = x + (width * 0.8)
- stop_x = x + (width * 0.2)
- start_y = stop_y = y + (height // 2)
-
- self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
-
- self.swipping.wait_for(False)
-
- def swipe_to_delete(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.swipping.wait_for(False)
-
class Dialog(UbuntuUIToolkitCustomProxyObjectBase):
@click_object
=== modified file 'tests/autopilot/music_app/tests/test_music.py'
--- tests/autopilot/music_app/tests/test_music.py 2015-04-29 00:55:02 +0000
+++ tests/autopilot/music_app/tests/test_music.py 2015-10-18 18:16:18 +0000
@@ -79,7 +79,6 @@
# get track item to swipe and queue
track = self.app.get_songs_view().get_track(0)
- track.swipe_reveal_actions()
# add track to the queue
track.click_add_to_queue_action()
@@ -206,8 +205,6 @@
# get track row and swipe to reveal actions
track = tracks_page.get_track(i)
- track.swipe_reveal_actions()
-
track.click_add_to_queue_action() # add track to queue
# wait for the player index to change
@@ -344,8 +341,6 @@
songs_page = self.app.get_songs_view()
track = songs_page.get_track(0)
- track.swipe_reveal_actions()
-
track.click_add_to_queue_action() # add track to the queue
# verify track queue has added one to initial value
@@ -417,8 +412,6 @@
# get track row and swipe to reveal actions
track = tracks_page.get_track(0)
- track.swipe_reveal_actions()
-
track.click_add_to_queue_action() # add track to queue
# verify track queue has added all songs to initial value
@@ -452,8 +445,6 @@
# get track row and swipe to reveal actions
track = tracks_page.get_track(0)
- track.swipe_reveal_actions()
-
track.click_add_to_playlist_action() # add track to queue
add_to_playlist_page = self.app.get_add_to_playlist_page()
@@ -601,9 +592,7 @@
# get track row and swipe to reveal swipe to delete
track = now_playing_page.get_track(0)
- track.swipe_to_delete()
-
- track.confirm_removal() # confirm delete
+ track.click_remove_action()
# verify song has been deleted
self.assertThat(self.app.get_queue_count(),
Follow ups
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: noreply, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
[Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Andrew Hayzen, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-11-02
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-11-01
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-30
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-10-28
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-28
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-10-25
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Victor Thompson, 2015-10-25
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-21
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-21
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-18
-
Re: [Merge] lp:~ahayzen/music-app/refactor-use-sdk-listitems into lp:music-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-10-18