1 /*****************************************************************************
2 * Copyright (C) 2019 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 *****************************************************************************/
18 import QtQuick.Controls 2.4
20 import QtQml.Models 2.2
21 import QtQuick.Layouts 1.3
23 import org.videolan.medialib 0.1
25 import "qrc:///util/" as Util
26 import "qrc:///widgets/" as Widgets
27 import "qrc:///main/" as MainInterface
28 import "qrc:///style/"
39 component: artistGridComponent
42 component: artistAlbumsComponent
45 onCurrentItemChanged: {
46 model = currentItem.model
49 function _updateArtistsAllHistory(currentIndex) {
50 history.update(["mc", "music", "artists", "all", { "initialIndex": currentIndex }])
53 function _updateArtistsAlbumsHistory(currentIndex, initialAlbumIndex) {
54 history.update(["mc","music", "artists", "albums", {
55 "initialIndex": currentIndex,
56 "initialAlbumIndex": initialAlbumIndex,
61 id: artistGridComponent
63 Widgets.NavigableFocusScope {
66 readonly property int currentIndex: view.currentItem.currentIndex
67 property int initialIndex: 0
68 property alias model: artistModel
70 onCurrentIndexChanged: {
71 _updateArtistsAllHistory(currentIndex)
74 onInitialIndexChanged: resetFocus()
76 function showAlbumView() {
77 history.push([ "mc", "music", "artists", "albums", { initialIndex: artistAllView.currentIndex } ])
80 function resetFocus() {
81 if (artistModel.count === 0) {
84 var initialIndex = artistAllView.initialIndex
85 if (initialIndex >= artistModel.count)
87 selectionModel.select(artistModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
88 if (view.currentItem) {
89 view.currentItem.currentIndex = initialIndex
90 view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
99 if (artistModel.count > 0 && !selectionModel.hasSelection) {
100 artistAllView.resetFocus()
105 Util.SelectableDelegateModel {
113 function updateComponents(maxCovers) {
114 var items = selectionModel.selectedIndexes.slice(0, maxCovers).map(function (x){
115 return artistModel.getDataAt(x.row)
117 var title = items.map(function (item){ return item.name}).join(", ")
118 var covers = items.map(function (item) { return {artwork: item.cover || VLCStyle.noArtArtistSmall}})
122 count: selectionModel.selectedIndexes.length
126 function getSelectedInputItem() {
127 return artistModel.getItemsForIndexes(selectionModel.selectedIndexes);
139 MainInterface.MainGridView {
143 topMargin: VLCStyle.margin_large
144 delegateModel: selectionModel
147 cellWidth: VLCStyle.colWidth(1)
148 cellHeight: VLCStyle.gridItem_music_height
149 onSelectAll: selectionModel.selectAll()
150 onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
151 navigationParent: root
154 if (selectionModel.selectedIndexes.length > 1) {
155 medialib.addAndPlay( artistModel.getIdsForIndexes( selectionModel.selectedIndexes ) )
157 view.currentItem.currentIndex = index
159 medialib.addAndPlay( artistModel.getIdForIndex(index) )
163 Widgets.GridShadows {
166 leftPadding: (VLCStyle.colWidth(1) - shadows.coverWidth) / 2 // GridItem's rect is horizontally centered
167 coverWidth: VLCStyle.artistGridCover_radius
168 coverHeight: VLCStyle.artistGridCover_radius
169 coverRadius: VLCStyle.artistGridCover_radius
172 delegate: AudioGridItem {
175 title: model.name || i18n.qtr("Unknown artist")
176 subtitle: model.nb_tracks > 1 ? i18n.qtr("%1 songs").arg(model.nb_tracks) : i18n.qtr("%1 song").arg(model.nb_tracks)
177 pictureRadius: VLCStyle.artistGridCover_radius
178 pictureHeight: VLCStyle.artistGridCover_radius
179 pictureWidth: VLCStyle.artistGridCover_radius
180 playCoverBorder.width: VLCStyle.dp(3, VLCStyle.scale)
181 titleMargin: VLCStyle.margin_xlarge
182 playIconSize: VLCStyle.play_cover_small
183 textHorizontalAlignment: Text.AlignHCenter
184 width: VLCStyle.colWidth(1)
185 dragItem: artistsDragItem
186 unselectedUnderlay: shadows.unselected
187 selectedUnderlay: shadows.selected
190 onItemClicked: artistGrid.leftClickOnItem(modifier, index)
192 onItemDoubleClicked: artistAllView.showAlbumView(model)
194 onContextMenuButtonClicked: {
195 artistGrid.rightClickOnItem(index)
196 contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
207 MainInterface.MainTableView {
210 readonly property int _nbCols: VLCStyle.gridColumnsForWidth(artistTable.availableRowWidth)
213 selectionDelegateModel: selectionModel
216 headerColor: VLCStyle.colors.bg
217 navigationParent: root
218 dragItem: artistsDragItem
219 rowHeight: VLCStyle.tableCoverRow_height
220 headerTopPadding: VLCStyle.margin_normal
222 onActionForSelection: {
223 if (selection.length > 1) {
224 medialib.addAndPlay( artistModel.getIdsForIndexes( selection ) )
227 medialib.addAndPlay( artistModel.getIdForIndex(index) )
232 { isPrimary: true, criteria: "name", width: VLCStyle.colWidth(Math.max(artistTable._nbCols - 1, 1)), text: i18n.qtr("Name"), headerDelegate: tableColumns.titleHeaderDelegate, colDelegate: tableColumns.titleDelegate },
233 { criteria: "nb_tracks", width: VLCStyle.colWidth(1), text: i18n.qtr("Tracks") }
236 onItemDoubleClicked: {
237 artistAllView.showAlbumView(model)
239 onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes, menuParent.mapToGlobal(0,0))
240 onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
242 Widgets.TableColumns {
248 Widgets.StackViewExt {
252 visible: artistModel.count > 0
253 focus: artistModel.count > 0
254 initialItem: mainInterface.gridView ? gridComponent : tableComponent
258 target: mainInterface
260 if (mainInterface.gridView) {
261 view.replace(gridComponent)
263 view.replace(tableComponent)
270 visible: artistModel.count === 0
271 focus: artistModel.count === 0
272 text: i18n.qtr("No artists found\nPlease try adding sources, by going to the Network tab")
273 navigationParent: root
274 cover: VLCStyle.noArtArtistCover
280 id: artistAlbumsComponent
283 onCurrentIndexChanged: _updateArtistsAlbumsHistory(currentIndex, currentAlbumIndex)
284 onCurrentAlbumIndexChanged: _updateArtistsAlbumsHistory(currentIndex, currentAlbumIndex)