From 30a9a3a4fdd740b8214cfdf0f3814fc8e0201e08 Mon Sep 17 00:00:00 2001 From: Fatih Uzunoglu Date: Tue, 7 Sep 2021 18:20:38 +0300 Subject: [PATCH] qml: make PlaylistListView a Control --- .../gui/qt/maininterface/qml/MainDisplay.qml | 2 +- .../gui/qt/playlist/qml/PlaylistListView.qml | 845 +++++++++--------- 2 files changed, 417 insertions(+), 430 deletions(-) diff --git a/modules/gui/qt/maininterface/qml/MainDisplay.qml b/modules/gui/qt/maininterface/qml/MainDisplay.qml index 7f6c41c6de..0a6967688d 100644 --- a/modules/gui/qt/maininterface/qml/MainDisplay.qml +++ b/modules/gui/qt/maininterface/qml/MainDisplay.qml @@ -327,7 +327,7 @@ FocusScope { focus: true rightPadding: VLCStyle.applicationHorizontalMargin - bottomPadding: Math.max(VLCStyle.applicationVerticalMargin - miniPlayer.height, 0) + bottomPadding: topPadding + Math.max(VLCStyle.applicationVerticalMargin - miniPlayer.height, 0) Navigation.parentItem: medialibId Navigation.leftItem: stackView diff --git a/modules/gui/qt/playlist/qml/PlaylistListView.qml b/modules/gui/qt/playlist/qml/PlaylistListView.qml index 9c684db56c..4b1a508b44 100644 --- a/modules/gui/qt/playlist/qml/PlaylistListView.qml +++ b/modules/gui/qt/playlist/qml/PlaylistListView.qml @@ -27,7 +27,7 @@ import "qrc:///widgets/" as Widgets import "qrc:///util/Helpers.js" as Helpers import "qrc:///style/" -FocusScope { +Control { id: root property alias model: listView.model @@ -39,9 +39,10 @@ FocusScope { rightPadding + 2 * (VLCStyle.margin_xsmall) - property real leftPadding - property real rightPadding - property real bottomPadding + topPadding: VLCStyle.margin_normal + bottomPadding: VLCStyle.margin_normal + + onActiveFocusChanged: if (activeFocus) listView.forceActiveFocus(focusReason) property VLCColors colors: VLCStyle.colors @@ -101,569 +102,555 @@ FocusScope { colors: root.colors itemParent: listView - backgroundItem: parentRect + backgroundItem: contentItem } } - Widgets.AcrylicBackground { - id: acrylicBackground + Widgets.DragItem { + id: dragItem - anchors.fill: parent - alternativeColor: colors.bgAlt - } + parent: (typeof g_mainDisplay !== 'undefined') ? g_mainDisplay : root - Item { - id: parentRect - anchors.fill: parent + property int index: -1 - Widgets.DragItem { - id: dragItem + colors: root.colors - parent: (typeof g_mainDisplay !== 'undefined') ? g_mainDisplay : root - - property int index: -1 - - colors: root.colors - - function updateComponents(maxCovers) { - var count = root.model.selectedCount - var selection = root.model.getSelection() + function updateComponents(maxCovers) { + var count = root.model.selectedCount + var selection = root.model.getSelection() - var title = selection.map(function (index){ - return root.model.itemAt(index).title - }).join(", ") + var title = selection.map(function (index){ + return root.model.itemAt(index).title + }).join(", ") - var covers = selection.map(function (index) { - var artwork = root.model.itemAt(index).artwork - return {artwork: (artwork && artwork.toString()) ? artwork : VLCStyle.noArtCover} - }) + var covers = selection.map(function (index) { + var artwork = root.model.itemAt(index).artwork + return {artwork: (artwork && artwork.toString()) ? artwork : VLCStyle.noArtCover} + }) - return ({covers: covers, title: title, count: root.model.selectedCount}) - } - - function getSelectedInputItem(index) { - return model.getItemsForIndexes(model.getSelection()) - } - - property point _pos - property int _scrollingDirection: 0 + return ({covers: covers, title: title, count: root.model.selectedCount}) + } - function updatePos(pos) { - dragItem.x = pos.x + VLCStyle.dp(15) - dragItem.y = pos.y // y should be same otherwise dropIndicator will not be shown correctly (DropArea cares about itemY not mouseY) + function getSelectedInputItem(index) { + return model.getItemsForIndexes(model.getSelection()) + } - // since we override position update during dragging with updatePos(), - // we have to track the final position: - _pos = pos - } + property point _pos + property int _scrollingDirection: 0 - on_PosChanged: { - var dragItemY = dragItem._pos.y - var viewY = root.mapFromItem(listView, listView.x, listView.y).y + function updatePos(pos) { + dragItem.x = pos.x + VLCStyle.dp(15) + dragItem.y = pos.y // y should be same otherwise dropIndicator will not be shown correctly (DropArea cares about itemY not mouseY) - var topDiff = (viewY + VLCStyle.dp(20, VLCStyle.scale)) - dragItemY - var bottomDiff = dragItemY - (viewY + listView.height - toolbar.height - VLCStyle.dp(20, VLCStyle.scale)) + // since we override position update during dragging with updatePos(), + // we have to track the final position: + _pos = pos + } - if(!listView.listView.atYBeginning && topDiff > 0) { - _scrollingDirection = -1 + on_PosChanged: { + var dragItemY = dragItem._pos.y + var viewY = root.mapFromItem(listView, listView.x, listView.y).y - listView.fadeRectTopHovered = true - } - else if( !listView.listView.atYEnd && bottomDiff > 0) { - _scrollingDirection = 1 + var topDiff = (viewY + VLCStyle.dp(20, VLCStyle.scale)) - dragItemY + var bottomDiff = dragItemY - (viewY + listView.height - toolbar.height - VLCStyle.dp(20, VLCStyle.scale)) - listView.fadeRectBottomHovered = true - } - else { - _scrollingDirection = 0 + if(!listView.listView.atYBeginning && topDiff > 0) { + _scrollingDirection = -1 - listView.fadeRectTopHovered = false - listView.fadeRectBottomHovered = false - } + listView.fadeRectTopHovered = true } + else if( !listView.listView.atYEnd && bottomDiff > 0) { + _scrollingDirection = 1 - // FIXME: Drag animation for listView sometimes messes up dragging (dragged item sticking to the cursor). - SmoothedAnimation { - id: upAnimation - target: listView.listView - property: "contentY" - to: 0 - running: dragItem._scrollingDirection === -1 && dragItem.visible + listView.fadeRectBottomHovered = true + } + else { + _scrollingDirection = 0 - velocity: VLCStyle.dp(225, VLCStyle.scale) + listView.fadeRectTopHovered = false + listView.fadeRectBottomHovered = false } + } - SmoothedAnimation { - id: downAnimation - target: listView.listView - property: "contentY" - to: listView.listView.contentHeight - listView.height - running: dragItem._scrollingDirection === 1 && dragItem.visible + // FIXME: Drag animation for listView sometimes messes up dragging (dragged item sticking to the cursor). + SmoothedAnimation { + id: upAnimation + target: listView.listView + property: "contentY" + to: 0 + running: dragItem._scrollingDirection === -1 && dragItem.visible - velocity: VLCStyle.dp(225, VLCStyle.scale) - } + velocity: VLCStyle.dp(225, VLCStyle.scale) } - PlaylistContextMenu { - id: contextMenu - model: root.model - controler: mainPlaylistController + SmoothedAnimation { + id: downAnimation + target: listView.listView + property: "contentY" + to: listView.listView.contentHeight - listView.height + running: dragItem._scrollingDirection === 1 && dragItem.visible + + velocity: VLCStyle.dp(225, VLCStyle.scale) } + } - ColumnLayout { - anchors.fill: parent - anchors.topMargin: VLCStyle.margin_normal - anchors.bottomMargin: VLCStyle.margin_normal + PlaylistContextMenu { + id: contextMenu + model: root.model + controler: mainPlaylistController + } - anchors.leftMargin: root.leftPadding - anchors.rightMargin: root.rightPadding + background: Widgets.AcrylicBackground { + id: acrylicBackground - spacing: 0 + alternativeColor: colors.bgAlt + } - ColumnLayout { - id: headerTextLayout + contentItem: ColumnLayout { + spacing: 0 - Layout.fillWidth: true - Layout.leftMargin: VLCStyle.margin_normal + ColumnLayout { + id: headerTextLayout - spacing: VLCStyle.margin_xxxsmall + Layout.fillWidth: true + Layout.leftMargin: VLCStyle.margin_normal - Widgets.SubtitleLabel { - text: i18n.qtr("Playqueue") - color: colors.text - font.weight: Font.Bold - font.pixelSize: VLCStyle.dp(24, VLCStyle.scale) - } + spacing: VLCStyle.margin_xxxsmall - Widgets.CaptionLabel { - color: (listView.mode === PlaylistListView.Mode.Select || listView.mode === PlaylistListView.Mode.Move) - ? colors.accent : colors.caption - visible: model.count !== 0 - text: { - switch (listView.mode) { - case PlaylistListView.Mode.Select: - return i18n.qtr("Selected tracks: %1").arg(model.selectedCount) - case PlaylistListView.Mode.Move: - return i18n.qtr("Moving tracks: %1").arg(model.selectedCount) - case PlaylistListView.Mode.Normal: - default: - return i18n.qtr("%1 elements, %2").arg(model.count).arg(getHoursMinutesText(model.duration)) - } - } + Widgets.SubtitleLabel { + text: i18n.qtr("Playqueue") + color: colors.text + font.weight: Font.Bold + font.pixelSize: VLCStyle.dp(24, VLCStyle.scale) + } - function getHoursMinutesText(duration) { - var hours = duration.toHours() - var minutes = duration.toMinutes() - var text - if (hours >= 1) { - minutes = minutes % 60 - text = i18n.qtr("%1h %2 min").arg(hours).arg(minutes) - } - else if (minutes > 0) { - text = i18n.qtr("%1 min").arg(minutes) - } - else { - text = i18n.qtr("%1 sec").arg(duration.toSeconds()) - } + Widgets.CaptionLabel { + color: (listView.mode === PlaylistListView.Mode.Select || listView.mode === PlaylistListView.Mode.Move) + ? colors.accent : colors.caption + visible: model.count !== 0 + text: { + switch (listView.mode) { + case PlaylistListView.Mode.Select: + return i18n.qtr("Selected tracks: %1").arg(model.selectedCount) + case PlaylistListView.Mode.Move: + return i18n.qtr("Moving tracks: %1").arg(model.selectedCount) + case PlaylistListView.Mode.Normal: + default: + return i18n.qtr("%1 elements, %2").arg(model.count).arg(getHoursMinutesText(model.duration)) + } + } - return text + function getHoursMinutesText(duration) { + var hours = duration.toHours() + var minutes = duration.toMinutes() + var text + if (hours >= 1) { + minutes = minutes % 60 + text = i18n.qtr("%1h %2 min").arg(hours).arg(minutes) + } + else if (minutes > 0) { + text = i18n.qtr("%1 min").arg(minutes) } + else { + text = i18n.qtr("%1 sec").arg(duration.toSeconds()) + } + + return text } } + } - RowLayout { - visible: model.count !== 0 + RowLayout { + visible: model.count !== 0 - Layout.topMargin: VLCStyle.margin_normal - Layout.leftMargin: VLCStyle.margin_normal - Layout.rightMargin: listView.scrollBarWidth + Layout.topMargin: VLCStyle.margin_normal + Layout.leftMargin: VLCStyle.margin_normal + Layout.rightMargin: listView.scrollBarWidth - spacing: 0 + spacing: 0 - Widgets.IconLabel { - Layout.preferredWidth: VLCStyle.icon_normal + Widgets.IconLabel { + Layout.preferredWidth: VLCStyle.icon_normal - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: VLCIcons.album_cover - color: colors.caption - } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: VLCIcons.album_cover + color: colors.caption + } - Widgets.CaptionLabel { - Layout.fillWidth: true - Layout.leftMargin: VLCStyle.margin_large + Widgets.CaptionLabel { + Layout.fillWidth: true + Layout.leftMargin: VLCStyle.margin_large - verticalAlignment: Text.AlignVCenter - text: i18n.qtr("Title") - color: colors.caption - } + verticalAlignment: Text.AlignVCenter + text: i18n.qtr("Title") + color: colors.caption + } - Widgets.IconLabel { - Layout.rightMargin: VLCStyle.margin_xsmall - Layout.preferredWidth: durationMetric.width + Widgets.IconLabel { + Layout.rightMargin: VLCStyle.margin_xsmall + Layout.preferredWidth: durationMetric.width - text: VLCIcons.time - color: colors.caption - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + text: VLCIcons.time + color: colors.caption + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter - TextMetrics { - id: durationMetric - font.pixelSize: VLCStyle.fontSize_normal - text: "-00:00-" - } + TextMetrics { + id: durationMetric + font.pixelSize: VLCStyle.fontSize_normal + text: "-00:00-" } } + } - Widgets.KeyNavigableListView { - id: listView + Widgets.KeyNavigableListView { + id: listView - Layout.fillWidth: true - Layout.fillHeight: true + Layout.fillWidth: true + Layout.fillHeight: true - focus: true + focus: true - clip: true // else out of view items will overlap with surronding items + clip: true // else out of view items will overlap with surronding items - model: PlaylistListModel { - playlistId: mainctx.playlist - } + model: PlaylistListModel { + playlistId: mainctx.playlist + } - fadeColor: parentRect.color + fadeColor: background.color - property int shiftIndex: -1 - property int mode: PlaylistListView.Mode.Normal + property int shiftIndex: -1 + property int mode: PlaylistListView.Mode.Normal - signal setItemDropIndicatorVisible(int index, bool visible) + signal setItemDropIndicatorVisible(int index, bool visible) - Connections { - target: listView.model + Connections { + target: listView.model - onRowsInserted: { - if (listView.currentIndex === -1) - listView.currentIndex = 0 - } + onRowsInserted: { + if (listView.currentIndex === -1) + listView.currentIndex = 0 + } - onModelReset: { - if (listView.currentIndex === -1 && root.model.count > 0) - listView.currentIndex = 0 - } + onModelReset: { + if (listView.currentIndex === -1 && root.model.count > 0) + listView.currentIndex = 0 + } - onSelectedCountChanged: { - var selectedIndexes = listView.model.getSelection() + onSelectedCountChanged: { + var selectedIndexes = listView.model.getSelection() - if (listView.modelCount === 0 || selectedIndexes.length === 0) - return + if (listView.modelCount === 0 || selectedIndexes.length === 0) + return - var bottomItemIndex = listView.listView.indexAt(listView.width / 2, (listView.listView.contentY + listView.height) + 1) - var topItemIndex = listView.listView.indexAt(listView.width / 2, listView.listView.contentY - 1) + var bottomItemIndex = listView.listView.indexAt(listView.width / 2, (listView.listView.contentY + listView.height) + 1) + var topItemIndex = listView.listView.indexAt(listView.width / 2, listView.listView.contentY - 1) - if (listView.model.isSelected(topItemIndex) || (listView.model.isSelected(topItemIndex + 1))) - listView.fadeRectTopHovered = true - else - listView.fadeRectTopHovered = false + if (listView.model.isSelected(topItemIndex) || (listView.model.isSelected(topItemIndex + 1))) + listView.fadeRectTopHovered = true + else + listView.fadeRectTopHovered = false - if (listView.model.isSelected(bottomItemIndex) || (bottomItemIndex !== -1 && listView.model.isSelected(bottomItemIndex - 1))) - listView.fadeRectBottomHovered = true - else - listView.fadeRectBottomHovered = false - } + if (listView.model.isSelected(bottomItemIndex) || (bottomItemIndex !== -1 && listView.model.isSelected(bottomItemIndex - 1))) + listView.fadeRectBottomHovered = true + else + listView.fadeRectBottomHovered = false } + } - footer: Item { - width: parent.width - height: Math.max(VLCStyle.icon_normal, listView.height - y) + footer: Item { + width: parent.width + height: Math.max(VLCStyle.icon_normal, listView.height - y) - property alias firstItemIndicatorVisible: firstItemIndicator.visible + property alias firstItemIndicatorVisible: firstItemIndicator.visible - function setDropIndicatorVisible(visible) { - dropIndicator.visible = Qt.binding(function() { return (visible || dropArea.containsDragItem); }) - } + function setDropIndicatorVisible(visible) { + dropIndicator.visible = Qt.binding(function() { return (visible || dropArea.containsDragItem); }) + } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton | Qt.LeftButton + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton | Qt.LeftButton - onClicked: { - listView.forceActiveFocus() + onClicked: { + listView.forceActiveFocus() - if ( mouse.button === Qt.LeftButton || mouse.button === Qt.RightButton ) { - root.model.deselectAll() - } + if ( mouse.button === Qt.LeftButton || mouse.button === Qt.RightButton ) { + root.model.deselectAll() + } - if ( mouse.button === Qt.RightButton ) { - contextMenu.popup(-1, this.mapToGlobal(mouse.x, mouse.y)) - } + if ( mouse.button === Qt.RightButton ) { + contextMenu.popup(-1, this.mapToGlobal(mouse.x, mouse.y)) } } + } - Rectangle { - id: dropIndicator + Rectangle { + id: dropIndicator - anchors.left: parent.left - anchors.right: parent.right - height: VLCStyle.dp(1) - anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: VLCStyle.dp(1) + anchors.top: parent.top - visible: dropArea.containsDragItem - color: colors.accent - } + visible: dropArea.containsDragItem + color: colors.accent + } - Rectangle { - id: firstItemIndicator + Rectangle { + id: firstItemIndicator - anchors.fill: parent - anchors.margins: VLCStyle.margin_small + anchors.fill: parent + anchors.margins: VLCStyle.margin_small - border.width: VLCStyle.dp(2) - border.color: colors.accent + border.width: VLCStyle.dp(2) + border.color: colors.accent - color: "transparent" + color: "transparent" - visible: false + visible: false - opacity: 0.8 + opacity: 0.8 - Label { - anchors.centerIn: parent + Label { + anchors.centerIn: parent - text: VLCIcons.add + text: VLCIcons.add - font.pointSize: VLCStyle.fontHeight_xxxlarge + font.pointSize: VLCStyle.fontHeight_xxxlarge - font.family: VLCIcons.fontFamily - color: colors.accent - } + font.family: VLCIcons.fontFamily + color: colors.accent } + } - DropArea { - id: dropArea + DropArea { + id: dropArea - anchors.fill: parent + anchors.fill: parent - property bool containsDragItem: false + property bool containsDragItem: false - onEntered: { - if(!root.isDropAcceptable(drag, root.model.count)) - return + onEntered: { + if(!root.isDropAcceptable(drag, root.model.count)) + return - if (root.model.count === 0) - firstItemIndicator.visible = true - else - containsDragItem = true - } - onExited: { - if (root.model.count === 0) - firstItemIndicator.visible = false - else - containsDragItem = false - } - onDropped: { - if(!root.isDropAcceptable(drop, root.model.count)) - return + if (root.model.count === 0) + firstItemIndicator.visible = true + else + containsDragItem = true + } + onExited: { + if (root.model.count === 0) + firstItemIndicator.visible = false + else + containsDragItem = false + } + onDropped: { + if(!root.isDropAcceptable(drop, root.model.count)) + return - root.acceptDrop(root.model.count, drop) + root.acceptDrop(root.model.count, drop) - if (root.model.count === 0) - firstItemIndicator.visible = false - else - containsDragItem = false - } + if (root.model.count === 0) + firstItemIndicator.visible = false + else + containsDragItem = false } } + } - ToolTip { - id: plInfoTooltip - delay: 750 - } + ToolTip { + id: plInfoTooltip + delay: 750 + } - delegate: PlaylistDelegate { - id: delegate + delegate: PlaylistDelegate { + id: delegate - // Instead of property forwarding, PlaylistDelegate is tightly coupled with PlaylistlistView - // since PlaylistDelegate is expected to be used only within PlaylistlistView + // Instead of property forwarding, PlaylistDelegate is tightly coupled with PlaylistlistView + // since PlaylistDelegate is expected to be used only within PlaylistlistView - width: parent.width - } + width: parent.width + } - add: Transition { - NumberAnimation { - property: "opacity"; from: 0; to: 1.0 + add: Transition { + NumberAnimation { + property: "opacity"; from: 0; to: 1.0 - duration: VLCStyle.duration_normal - } + duration: VLCStyle.duration_normal } + } - displaced: Transition { - NumberAnimation { - properties: "x,y" - - duration: VLCStyle.duration_normal; easing.type: Easing.OutSine - } + displaced: Transition { + NumberAnimation { + properties: "x,y" - NumberAnimation { property: "opacity"; to: 1.0 } + duration: VLCStyle.duration_normal; easing.type: Easing.OutSine } - onSelectAll: root.model.selectAll() - onSelectionUpdated: { - if (listView.mode === PlaylistListView.Mode.Select) { - console.log("update selection select") - } else if (listView.mode === PlaylistListView.Mode.Move) { - var selectedIndexes = root.model.getSelection() - if (selectedIndexes.length === 0) - return - /* always move relative to the first item of the selection */ - var target = selectedIndexes[0]; - if (newIndex > oldIndex) { - /* move down */ - target++ - } else if (newIndex < oldIndex && target > 0) { - /* move up */ - target-- - } + NumberAnimation { property: "opacity"; to: 1.0 } + } - listView.currentIndex = selectedIndexes[0] - /* the target is the position _after_ the move is applied */ - root.model.moveItemsPost(selectedIndexes, target) - } else { // normal - updateSelection(keyModifiers, oldIndex, newIndex); + onSelectAll: root.model.selectAll() + onSelectionUpdated: { + if (listView.mode === PlaylistListView.Mode.Select) { + console.log("update selection select") + } else if (listView.mode === PlaylistListView.Mode.Move) { + var selectedIndexes = root.model.getSelection() + if (selectedIndexes.length === 0) + return + /* always move relative to the first item of the selection */ + var target = selectedIndexes[0]; + if (newIndex > oldIndex) { + /* move down */ + target++ + } else if (newIndex < oldIndex && target > 0) { + /* move up */ + target-- } + + listView.currentIndex = selectedIndexes[0] + /* the target is the position _after_ the move is applied */ + root.model.moveItemsPost(selectedIndexes, target) + } else { // normal + updateSelection(keyModifiers, oldIndex, newIndex); } + } - Keys.onDeletePressed: onDelete() - Keys.onMenuPressed: overlayMenu.open() + Keys.onDeletePressed: onDelete() + Keys.onMenuPressed: overlayMenu.open() - Navigation.parentItem: root - Navigation.rightAction: function() { - overlayMenu.open() - } - Navigation.leftAction: function() { - if (mode === PlaylistListView.Mode.Normal) { - root.Navigation.defaultNavigationLeft() - } else { - mode = PlaylistListView.Mode.Normal - } + Navigation.parentItem: root + Navigation.rightAction: function() { + overlayMenu.open() + } + Navigation.leftAction: function() { + if (mode === PlaylistListView.Mode.Normal) { + root.Navigation.defaultNavigationLeft() + } else { + mode = PlaylistListView.Mode.Normal } - Navigation.cancelAction: function() { - if (mode === PlaylistListView.Mode.Normal) { - root.Navigation.defaultNavigationCancel() - } else { - mode = PlaylistListView.Mode.Normal - } + } + Navigation.cancelAction: function() { + if (mode === PlaylistListView.Mode.Normal) { + root.Navigation.defaultNavigationCancel() + } else { + mode = PlaylistListView.Mode.Normal } + } - Navigation.upAction: function() { - if (mode === PlaylistListView.Mode.Normal) - root.Navigation.defaultNavigationUp() - } + Navigation.upAction: function() { + if (mode === PlaylistListView.Mode.Normal) + root.Navigation.defaultNavigationUp() + } - Navigation.downAction: function() { - if (mode === PlaylistListView.Mode.Normal) - root.Navigation.defaultNavigationDown() - } + Navigation.downAction: function() { + if (mode === PlaylistListView.Mode.Normal) + root.Navigation.defaultNavigationDown() + } - onActionAtIndex: { - if (index < 0) - return + onActionAtIndex: { + if (index < 0) + return - if (mode === PlaylistListView.Mode.Select) - root.model.toggleSelected(index) - else if (mode === PlaylistListView.Mode.Normal) - mainPlaylistController.goTo(index, true) - } + if (mode === PlaylistListView.Mode.Select) + root.model.toggleSelected(index) + else if (mode === PlaylistListView.Mode.Normal) + mainPlaylistController.goTo(index, true) + } - function onDelete() { - var selection = root.model.getSelection() - if (selection.length === 0) - return - root.model.removeItems(selection) - } + function onDelete() { + var selection = root.model.getSelection() + if (selection.length === 0) + return + root.model.removeItems(selection) + } - function _addRange(from, to) { - root.model.setRangeSelected(from, to - from + 1, true) - } + function _addRange(from, to) { + root.model.setRangeSelected(from, to - from + 1, true) + } - function _delRange(from, to) { - root.model.setRangeSelected(from, to - from + 1, false) - } + function _delRange(from, to) { + root.model.setRangeSelected(from, to - from + 1, false) + } - // copied from SelectableDelegateModel, which is intended to be removed - function updateSelection( keymodifiers, oldIndex, newIndex ) { - if ((keymodifiers & Qt.ShiftModifier)) { - if ( shiftIndex === oldIndex) { - if ( newIndex > shiftIndex ) - _addRange(shiftIndex, newIndex) - else - _addRange(newIndex, shiftIndex) - } else if (shiftIndex <= newIndex && newIndex < oldIndex) { - _delRange(newIndex + 1, oldIndex ) - } else if ( shiftIndex < oldIndex && oldIndex < newIndex ) { - _addRange(oldIndex, newIndex) - } else if ( newIndex < shiftIndex && shiftIndex < oldIndex ) { - _delRange(shiftIndex, oldIndex) - _addRange(newIndex, shiftIndex) - } else if ( newIndex < oldIndex && oldIndex < shiftIndex ) { - _addRange(newIndex, oldIndex) - } else if ( oldIndex <= shiftIndex && shiftIndex < newIndex ) { - _delRange(oldIndex, shiftIndex) + // copied from SelectableDelegateModel, which is intended to be removed + function updateSelection( keymodifiers, oldIndex, newIndex ) { + if ((keymodifiers & Qt.ShiftModifier)) { + if ( shiftIndex === oldIndex) { + if ( newIndex > shiftIndex ) _addRange(shiftIndex, newIndex) - } else if ( oldIndex < newIndex && newIndex <= shiftIndex ) { - _delRange(oldIndex, newIndex - 1) - } + else + _addRange(newIndex, shiftIndex) + } else if (shiftIndex <= newIndex && newIndex < oldIndex) { + _delRange(newIndex + 1, oldIndex ) + } else if ( shiftIndex < oldIndex && oldIndex < newIndex ) { + _addRange(oldIndex, newIndex) + } else if ( newIndex < shiftIndex && shiftIndex < oldIndex ) { + _delRange(shiftIndex, oldIndex) + _addRange(newIndex, shiftIndex) + } else if ( newIndex < oldIndex && oldIndex < shiftIndex ) { + _addRange(newIndex, oldIndex) + } else if ( oldIndex <= shiftIndex && shiftIndex < newIndex ) { + _delRange(oldIndex, shiftIndex) + _addRange(shiftIndex, newIndex) + } else if ( oldIndex < newIndex && newIndex <= shiftIndex ) { + _delRange(oldIndex, newIndex - 1) + } + } else { + shiftIndex = newIndex + if (keymodifiers & Qt.ControlModifier) { + root.model.toggleSelected(newIndex) } else { - shiftIndex = newIndex - if (keymodifiers & Qt.ControlModifier) { - root.model.toggleSelected(newIndex) - } else { - root.model.setSelection([newIndex]) - } + root.model.setSelection([newIndex]) } } + } - Column { - id: noContentInfoColumn - anchors.centerIn: parent - visible: model.count === 0 && !listView.footerItem.firstItemIndicatorVisible - - Widgets.IconLabel { - font.pixelSize: VLCStyle.dp(48, VLCStyle.scale) - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: VLCIcons.playlist - color: (listView.activeFocus) ? colors.accent : colors.text - opacity: 0.3 - } + Column { + id: noContentInfoColumn + anchors.centerIn: parent + visible: model.count === 0 && !listView.footerItem.firstItemIndicatorVisible - Label { - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: VLCStyle.margin_xlarge - text: i18n.qtr("No content yet") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: VLCStyle.fontSize_xxlarge - color: (listView.activeFocus) ? colors.accent : colors.text - opacity: 0.4 - } + Widgets.IconLabel { + font.pixelSize: VLCStyle.dp(48, VLCStyle.scale) + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: VLCIcons.playlist + color: (listView.activeFocus) ? colors.accent : colors.text + opacity: 0.3 + } - Label { - anchors.topMargin: VLCStyle.margin_normal - text: i18n.qtr("Drag & Drop some content here!") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: VLCStyle.fontSize_large - color: (listView.activeFocus) ? colors.accent : colors.text - opacity: 0.4 - } + Label { + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: VLCStyle.margin_xlarge + text: i18n.qtr("No content yet") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: VLCStyle.fontSize_xxlarge + color: (listView.activeFocus) ? colors.accent : colors.text + opacity: 0.4 + } + + Label { + anchors.topMargin: VLCStyle.margin_normal + text: i18n.qtr("Drag & Drop some content here!") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: VLCStyle.fontSize_large + color: (listView.activeFocus) ? colors.accent : colors.text + opacity: 0.4 } } + } - PlaylistToolbar { - id: toolbar + PlaylistToolbar { + id: toolbar - Layout.fillWidth: true - Layout.bottomMargin: bottomPadding - } + Layout.fillWidth: true } }