1 /*****************************************************************************
2 * Copyright (C) 2021 VLC authors and VideoLAN
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * ( at your option ) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
17 *****************************************************************************/
20 import QtQuick.Controls 2.4
21 import QtQuick.Layouts 1.3
22 import QtQml.Models 2.2
24 import org.videolan.medialib 0.1
26 import "qrc:///widgets/" as Widgets
27 import "qrc:///main/" as MainInterface
28 import "qrc:///util/" as Util
29 import "qrc:///style/"
31 Widgets.NavigableFocusScope {
34 //---------------------------------------------------------------------------------------------
36 //---------------------------------------------------------------------------------------------
38 readonly property bool isViewMultiView: false
40 readonly property int currentIndex: currentItem.currentIndex
42 property int initialIndex: 0
43 property variant initialId
44 property string initialName
46 // NOTE: Specify an optionnal header for the view.
47 property Component header: undefined
49 property Item headerItem: (currentItem) ? currentItem.headerItem : undefined
51 //---------------------------------------------------------------------------------------------
53 //---------------------------------------------------------------------------------------------
55 // NOTE: This is used to determine which media(s) shall be displayed.
56 property alias parentId: model.parentId
58 // NOTE: The name of the playlist.
59 property alias name: label.text
61 property alias model: model
63 property alias currentItem: view
65 //---------------------------------------------------------------------------------------------
67 property alias dragItem: dragItem
69 //---------------------------------------------------------------------------------------------
71 //---------------------------------------------------------------------------------------------
73 navigationCancel: function() {
74 if (currentItem.currentIndex <= 0) {
75 defaultNavigationCancel()
77 currentItem.currentIndex = 0;
79 currentItem.positionViewAtIndex(0, ItemView.Contain);
83 //---------------------------------------------------------------------------------------------
85 //---------------------------------------------------------------------------------------------
87 onModelChanged: resetFocus()
89 onInitialIndexChanged: resetFocus()
91 //---------------------------------------------------------------------------------------------
93 //---------------------------------------------------------------------------------------------
95 function setCurrentItemFocus() { view.currentItem.forceActiveFocus() }
97 function resetFocus() {
98 if (model.count === 0) return
100 var initialIndex = root.initialIndex
102 if (initialIndex >= model.count)
105 modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
108 currentItem.positionViewAtIndex(initialIndex, ItemView.Contain);
111 //---------------------------------------------------------------------------------------------
114 function _actionAtIndex(index) {
115 g_mainDisplay.showPlayer();
117 medialib.addAndPlay(model.getIdsForIndexes(modelSelect.selectedIndexes));
120 //---------------------------------------------------------------------------------------------
122 //---------------------------------------------------------------------------------------------
132 if (count === 0 || modelSelect.hasSelection) return;
138 Widgets.SubtitleLabel {
141 anchors.top: parent.top
143 anchors.topMargin: VLCStyle.margin_normal
147 leftPadding : VLCStyle.margin_xlarge
148 bottomPadding: VLCStyle.margin_xsmall
156 function updateComponents(maxCovers) {
157 var items = modelSelect.selectedIndexes.slice(0, maxCovers).map(function (x){
158 return model.getDataAt(x.row);
161 var covers = items.map(function (item) {
162 return { artwork: item.thumbnail || VLCStyle.noArtCover }
165 var title = items.map(function (item) {
172 count: modelSelect.selectedIndexes.length
176 function insertIntoPlaylist(index) {
177 medialib.insertIntoPlaylist(index,
178 model.getIdsForIndexes(modelSelect.selectedIndexes));
182 Util.SelectableDelegateModel {
188 PlaylistMediaContextMenu {
198 //-------------------------------------------------------------------------------------
201 anchors.left : parent.left
202 anchors.right : parent.right
203 anchors.top : label.bottom
204 anchors.bottom: parent.bottom
208 focus: (model.count !== 0)
212 selectionDelegateModel: modelSelect
214 dragItem: root.dragItem
218 headerTopPadding: VLCStyle.margin_normal
220 headerPositioning: ListView.InlineHeader
222 navigationParent: root
223 navigationUpItem: (headerItem) ? headerItem.focus : undefined
225 //-------------------------------------------------------------------------------------
228 onContextMenuButtonClicked: contextMenu.popup(modelSelect.selectedIndexes,
229 menuParent.mapToGlobal(0,0))
231 onRightClick: contextMenu.popup(modelSelect.selectedIndexes, globalMousePos)
237 visible: (model.count === 0)
241 text: i18n.qtr("No media found")
243 cover: VLCStyle.noArtAlbumCover
245 navigationParent: root