qml: rename ExpandGridView.model to ExpandGridView.delegateModel
[vlc.git] / modules / gui / qt / medialibrary / qml / MusicGenres.qml
blobc67a33892f47d8b587ccb452f8840e9493be2e2d
1 /*****************************************************************************
2  * Copyright (C) 2019 VLC authors and VideoLAN
3  *
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.
8  *
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.
13  *
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 2.11
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 {
29     id: root
30     property alias model: delegateModelId.model
31     property var sortModel: [
32         { text: i18n.qtr("Alphabetic"), criteria: "title" }
33     ]
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()
44         else
45             view.currentItem.currentIndex = 0;
46     }
48     Component.onCompleted: loadView()
50     function loadView() {
51         if (medialib.gridView) {
52             view.replace(gridComponent)
53         } else {
54             view.replace(listComponent)
55         }
56     }
58     function showAlbumView( parent, name ) {
59         history.push([ "mc", "music", "genres", "albums", { parentId: parent, genreName: name } ])
60     }
62     function resetFocus() {
63         if (delegateModelId.items.count === 0) {
64             return
65         }
66         var initialIndex = root.initialIndex
67         if (initialIndex >= delegateModelId.items.count)
68             initialIndex = 0
69         delegateModelId.selectNone()
70         delegateModelId.items.get(initialIndex).inSelected = true
71         view.currentItem.currentIndex = initialIndex
72         view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
73     }
75     Connections {
76         target: medialib
77         onGridViewChanged: loadView()
78     }
80     Component {
81         id: headerComponent
82         Widgets.LabelSeparator {
83             text: i18n.qtr("Genres")
84             width: root.width
85         }
86     }
88     Util.SelectableDelegateModel {
89         id: delegateModelId
90         model: MLGenreModel {
91             id: genreModel
92             ml: medialib
93         }
95         delegate: Package {
96             Widgets.ListItem {
97                 Package.name: "list"
99                 width: root.width
100                 height: VLCStyle.icon_normal + VLCStyle.margin_small
102                 cover: Image {
103                     id: cover_obj
104                     fillMode: Image.PreserveAspectFit
105                     source: model.cover || VLCStyle.noArtAlbum
106                     sourceSize: Qt.size(width, height)
107                 }
109                 line1: (model.name || "Unknown genre")+" - "+model.nb_tracks+" tracks"
111                 onItemClicked: {
112                     delegateModelId.updateSelection( modifier, view.currentItem.currentIndex, index )
113                     view.currentItem.currentIndex = index
114                     this.forceActiveFocus()
115                 }
116                 onPlayClicked: {
117                     medialib.addAndPlay( model.id )
118                 }
119                 onItemDoubleClicked: {
120                     root.showAlbumView(model.id, model.name)
121                 }
122                 onAddToPlaylistClicked: {
123                     medialib.addToPlaylist( model.id );
124                 }
125             }
126         }
128         onCountChanged: {
129             if (delegateModelId.items.count > 0 && delegateModelId.selectedGroup.count === 0) {
130                 root.resetFocus()
131             }
132         }
134         function actionAtIndex(index) {
135             if (delegateModelId.selectedGroup.count > 1) {
136                 var list = []
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)
142             }
143         }
144     }
146     /*
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
150      */
151     onActiveFocusChanged: {
152         if (activeFocus && delegateModelId.items.count > 0 && delegateModelId.selectedGroup.count === 0) {
153             var initialIndex = 0
154             if (view.currentItem.currentIndex !== -1)
155                 initialIndex = view.currentItem.currentIndex
156             delegateModelId.items.get(initialIndex).inSelected = true
157             view.currentItem.currentIndex = initialIndex
158         }
159     }
161     /* Grid View */
162     Component {
163         id: gridComponent
164         Widgets.ExpandGridView {
165             id: gridView_id
167             delegateModel: delegateModelId
169             headerDelegate: headerComponent
171             delegate: AudioGridItem {
172                 id: gridItem
174                 image: model.cover || VLCStyle.noArtAlbum
175                 title: model.name || "Unknown genre"
176                 subtitle: ""
177                 //selected: element.delegateModelId.inSelected
179                 onItemClicked: {
180                     delegateModelId.updateSelection( modifier , view.currentItem.currentIndex, index)
181                     view.currentItem.currentIndex = index
182                     view.currentItem.forceActiveFocus()
183                 }
185                 onItemDoubleClicked: root.showAlbumView(model.id, model.name)
186             }
188             focus: true
190             cellWidth: VLCStyle.gridItem_music_width
191             cellHeight: VLCStyle.gridItem_music_height
193             onSelectAll: delegateModelId.selectAll()
194             onSelectionUpdated:  delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
195             onActionAtIndex: {
196                 delegateModelId.actionAtIndex(index)
197             }
199             navigationParent: root
200         }
201     }
203     Component {
204         id: listComponent
205         /* List View */
206         Widgets.KeyNavigableListView {
207             id: listView_id
209             model: delegateModelId.parts.list
211             header: headerComponent
213             focus: true
214             spacing: VLCStyle.margin_xxxsmall
216             onSelectAll: delegateModelId.selectAll()
217             onSelectionUpdated: delegateModelId.updateSelection( keyModifiers, oldIndex, newIndex )
218             onActionAtIndex: delegateModelId.actionAtIndex(index)
220             navigationParent: root
221         }
222     }
224     Widgets.StackViewExt {
225         id: view
227         initialItem: medialib.gridView ? gridComponent : listComponent
229         anchors.fill: parent
230         focus: delegateModelId.items.count !== 0
231     }
233     EmptyLabel {
234         anchors.fill: parent
235         visible: delegateModelId.items.count === 0
236         focus: visible
237         text: i18n.qtr("No genres found\nPlease try adding sources, by going to the Network tab")
238         navigationParent: root
239     }