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 *****************************************************************************/
19 import QtQuick.Controls 2.4
20 import QtQml.Models 2.2
21 import org.videolan.vlc 0.1
22 import org.videolan.medialib 0.1
24 import "qrc:///util/" as Util
25 import "qrc:///widgets/" as Widgets
26 import "qrc:///style/"
28 Widgets.NavigableFocusScope {
30 property alias model: delegateModelId.model
31 property var sortModel: [
32 { text: i18n.qtr("Alphabetic"), criteria: "title" }
35 readonly property var currentIndex: view.currentItem.currentIndex
36 //the index to "go to" when the view is loaded
37 property var initialIndex: 0
39 onInitialIndexChanged: resetFocus()
41 navigationCancel: function() {
42 if (view.currentItem.currentIndex <= 0)
43 defaultNavigationCancel()
45 view.currentItem.currentIndex = 0;
48 Component.onCompleted: loadView()
51 if (medialib.gridView) {
52 view.replace(gridComponent)
54 view.replace(listComponent)
58 function showAlbumView( parent, name ) {
59 history.push([ "mc", "music", "genres", "albums", { parentId: parent, genreName: name } ])
62 function resetFocus() {
63 if (delegateModelId.items.count === 0) {
66 var initialIndex = root.initialIndex
67 if (initialIndex >= delegateModelId.items.count)
69 delegateModelId.selectNone()
70 delegateModelId.items.get(initialIndex).inSelected = true
71 view.currentItem.currentIndex = initialIndex
72 view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
77 onGridViewChanged: loadView()
82 Widgets.LabelSeparator {
83 text: i18n.qtr("Genres")
88 Util.SelectableDelegateModel {
100 height: VLCStyle.icon_normal + VLCStyle.margin_small
104 fillMode: Image.PreserveAspectFit
105 source: model.cover || VLCStyle.noArtAlbum
106 sourceSize: Qt.size(width, height)
109 line1: (model.name || "Unknown genre")+" - "+model.nb_tracks+" tracks"
112 delegateModelId.updateSelection( modifier, view.currentItem.currentIndex, index )
113 view.currentItem.currentIndex = index
114 this.forceActiveFocus()
117 medialib.addAndPlay( model.id )
119 onItemDoubleClicked: {
120 root.showAlbumView(model.id, model.name)
122 onAddToPlaylistClicked: {
123 medialib.addToPlaylist( model.id );
129 if (delegateModelId.items.count > 0 && delegateModelId.selectedGroup.count === 0) {
134 function actionAtIndex(index) {
135 if (delegateModelId.selectedGroup.count > 1) {
137 for (var i = 0; i < delegateModelId.selectedGroup.count; i++)
138 list.push(delegateModelId.selectedGroup.get(i).model.id)
139 medialib.addAndPlay( list )
140 } else if (delegateModelId.selectedGroup.count === 1) {
141 showAlbumView(delegateModelId.selectedGroup.get(0).model.id, delegateModelId.selectedGroup.get(0).model.name)
147 *define the intial position/selection
148 * This is done on activeFocus rather than Component.onCompleted because delegateModelId.
149 * selectedGroup update itself after this event
151 onActiveFocusChanged: {
152 if (activeFocus && delegateModelId.items.count > 0 && delegateModelId.selectedGroup.count === 0) {
154 if (view.currentItem.currentIndex !== -1)
155 initialIndex = view.currentItem.currentIndex
156 delegateModelId.items.get(initialIndex).inSelected = true
157 view.currentItem.currentIndex = initialIndex
164 Widgets.ExpandGridView {
167 delegateModel: delegateModelId
169 headerDelegate: headerComponent
171 delegate: AudioGridItem {
174 image: model.cover || VLCStyle.noArtAlbum
175 title: model.name || "Unknown genre"
177 //selected: element.delegateModelId.inSelected
180 delegateModelId.updateSelection( modifier , view.currentItem.currentIndex, index)
181 view.currentItem.currentIndex = index
182 view.currentItem.forceActiveFocus()
185 onItemDoubleClicked: root.showAlbumView(model.id, model.name)
190 cellWidth: VLCStyle.gridItem_music_width
191 cellHeight: VLCStyle.gridItem_music_height
193 onSelectAll: delegateModelId.selectAll()
194 onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
196 delegateModelId.actionAtIndex(index)
199 navigationParent: root
206 Widgets.KeyNavigableListView {
209 model: delegateModelId.parts.list
211 header: headerComponent
214 spacing: VLCStyle.margin_xxxsmall
216 onSelectAll: delegateModelId.selectAll()
217 onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
218 onActionAtIndex: delegateModelId.actionAtIndex(index)
220 navigationParent: root
224 Widgets.StackViewExt {
227 initialItem: medialib.gridView ? gridComponent : listComponent
230 focus: delegateModelId.items.count !== 0
235 visible: delegateModelId.items.count === 0
237 text: i18n.qtr("No genres found\nPlease try adding sources, by going to the Network tab")
238 navigationParent: root