[vlc-devel] [PATCH 28/29] qml: add new page to artist view with only artists
Prince Gupta
guptaprince8832 at gmail.com
Tue Aug 4 20:06:22 CEST 2020
---
modules/gui/qt/Makefile.am | 1 +
.../medialibrary/qml/MusicArtistsAlbums.qml | 205 +++++++++++
.../medialibrary/qml/MusicArtistsDisplay.qml | 340 +++++++++++-------
.../gui/qt/medialibrary/qml/MusicGenres.qml | 8 -
modules/gui/qt/vlc.qrc | 1 +
5 files changed, 415 insertions(+), 140 deletions(-)
create mode 100644 modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 4ecf090159..6ce02865c6 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -599,6 +599,7 @@ libqt_plugin_la_QML = \
gui/qt/medialibrary/qml/MusicAlbumsDisplay.qml \
gui/qt/medialibrary/qml/MusicAlbumsGridExpandDelegate.qml \
gui/qt/medialibrary/qml/MusicArtist.qml \
+ gui/qt/medialibrary/qml/MusicArtistsAlbums.qml \
gui/qt/medialibrary/qml/MusicArtistsDisplay.qml \
gui/qt/medialibrary/qml/MusicDisplay.qml \
gui/qt/medialibrary/qml/MusicGenres.qml \
diff --git a/modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml b/modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml
new file mode 100644
index 0000000000..56922c7f74
--- /dev/null
+++ b/modules/gui/qt/medialibrary/qml/MusicArtistsAlbums.qml
@@ -0,0 +1,205 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+import QtQuick.Controls 2.4
+import QtQuick 2.11
+import QtQml.Models 2.2
+import QtQuick.Layouts 1.3
+
+import org.videolan.medialib 0.1
+
+import "qrc:///util/" as Util
+import "qrc:///widgets/" as Widgets
+import "qrc:///style/"
+
+Widgets.NavigableFocusScope {
+ id: root
+ property alias model: artistModel
+ property var sortModel: [
+ { text: i18n.qtr("Alphabetic"), criteria: "title" }
+ ]
+
+ property var artistId
+
+ property alias currentIndex: artistList.currentIndex
+ property alias currentAlbumIndex: albumSubView.currentIndex
+ property int initialIndex: 0
+ property int initialAlbumIndex: 0
+
+ onInitialAlbumIndexChanged: resetFocus()
+ onInitialIndexChanged: resetFocus()
+
+ function resetFocus() {
+ if (artistModel.count === 0) {
+ return
+ }
+ var initialIndex = root.initialIndex
+ if (initialIndex >= artistModel.count)
+ initialIndex = 0
+ if (initialIndex !== artistList.currentIndex) {
+ selectionModel.select(artistModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
+ artistList.currentIndex = initialIndex
+ artistList.positionViewAtIndex(initialIndex, ItemView.Contain)
+ }
+ }
+
+ function _actionAtIndex(index) {
+ albumSubView.forceActiveFocus()
+ }
+
+ MLArtistModel {
+ id: artistModel
+ ml: medialib
+
+ onCountChanged: {
+ if (artistModel.count > 0 && !selectionModel.hasSelection) {
+ var initialIndex = root.initialIndex
+ if (initialIndex >= artistModel.count)
+ initialIndex = 0
+ artistList.currentIndex = initialIndex
+ }
+ }
+ }
+
+ Util.SelectableDelegateModel {
+ id: selectionModel
+ model: artistModel
+ }
+
+ FocusScope {
+ visible: artistModel.count > 0
+ focus: visible
+ anchors.fill: parent
+
+ Row {
+ anchors.fill: parent
+
+ Widgets.KeyNavigableListView {
+ id: artistList
+
+ width: parent.width * 0.25
+ height: parent.height
+
+ spacing: 4
+ model: artistModel
+ currentIndex: -1
+
+ focus: true
+
+ onCurrentIndexChanged: {
+ if (artistList.currentIndex < artistModel.count) {
+ root.artistId = artistModel.getIdForIndex(artistList.currentIndex)
+ } else {
+ root.artistId = undefined
+ }
+ }
+
+ navigationParent: root
+ navigationRightItem: albumSubView
+ navigationCancel: function() {
+ if (artistList.currentIndex <= 0)
+ defaultNavigationCancel()
+ else
+ artistList.currentIndex = 0;
+ }
+
+ header: Widgets.SubtitleLabel {
+ text: i18n.qtr("Artists")
+ leftPadding: VLCStyle.margin_normal
+ bottomPadding: VLCStyle.margin_normal
+ topPadding: VLCStyle.margin_normal
+ }
+
+ delegate: Widgets.ListItem {
+ height: VLCStyle.play_cover_small + (VLCStyle.margin_xsmall * 2)
+ width: artistList.width
+
+ property bool selected: artistList.currentIndex === index
+ property bool _highlighted: selected || this.hovered || this.activeFocus
+
+ color: VLCStyle.colors.getBgColor(selected, this.hovered, this.activeFocus)
+
+ cover: Item {
+
+ width: VLCStyle.play_cover_small
+ height: VLCStyle.play_cover_small
+
+ Widgets.RoundImage {
+ source: model.cover || VLCStyle.noArtArtistSmall
+ height: VLCStyle.play_cover_small
+ width: VLCStyle.play_cover_small
+ radius: VLCStyle.play_cover_small
+ mipmap: true
+ }
+
+ Rectangle {
+ height: VLCStyle.play_cover_small
+ width: VLCStyle.play_cover_small
+ radius: VLCStyle.play_cover_small
+ color: 'transparent'
+ border.width: VLCStyle.dp(1, scale)
+ border.color: !_highlighted ? VLCStyle.colors.roundPlayCoverBorder : VLCStyle.colors.accent
+ }
+ }
+
+ line1: model.name || i18n.qtr("Unknown artist")
+
+ actionButtons: []
+
+ onItemClicked: {
+ artistId = model.id
+ selectionModel.updateSelection( modifier , artistList.currentIndex, index)
+ artistList.currentIndex = index
+ artistList.forceActiveFocus()
+ }
+
+ onItemDoubleClicked: {
+ if (keys === Qt.RightButton)
+ medialib.addAndPlay( model.id )
+ else
+ albumSubView.forceActiveFocus()
+ }
+ }
+
+ }
+
+ MusicArtist {
+ id: albumSubView
+
+ height: parent.height
+ width: parent.width * .75
+ focus: true
+ parentId: root.artistId
+ initialIndex: root.initialAlbumIndex
+ navigationParent: root
+ navigationLeftItem: artistList
+ artist: (artistList.currentIndex >= 0)
+ ? artistModel.getDataAt(artistList.currentIndex)
+ : ({})
+ }
+
+ }
+ }
+
+ EmptyLabel {
+ anchors.fill: parent
+ visible: artistModel.count === 0
+ focus: visible
+ text: i18n.qtr("No artists found\nPlease try adding sources, by going to the Network tab")
+ navigationParent: root
+ }
+}
diff --git a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
index ca385f3e87..208addaf1f 100644
--- a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
@@ -26,187 +26,263 @@ import "qrc:///util/" as Util
import "qrc:///widgets/" as Widgets
import "qrc:///style/"
+
Widgets.NavigableFocusScope {
id: root
- property alias model: artistModel
- property var sortModel: [
- { text: i18n.qtr("Alphabetic"), criteria: "title" }
- ]
-
- property var artistId
-
- property alias currentIndex: artistList.currentIndex
- property int initialIndex: 0
- property int initialAlbumIndex: 0
-
- onInitialAlbumIndexChanged: resetFocus()
- onInitialIndexChanged: resetFocus()
- onCurrentIndexChanged: {
- history.update([ "mc", "music", "artists", {"initialIndex": currentIndex}])
+ //name and properties of the tab to be initially loaded
+ property string view: "all"
+ property var viewProperties: ({})
+ property var model
+
+ readonly property var pageModel: [{
+ name: "all",
+ component: artistGridComponent
+ }, {
+ name: "albums",
+ component: artistAlbumsComponent
+ }]
+
+ Component.onCompleted: loadView()
+ onViewChanged: {
+ viewProperties = {}
+ loadView()
}
+ onViewPropertiesChanged: loadView()
- function resetFocus() {
- if (artistModel.count === 0) {
- return
- }
- var initialIndex = root.initialIndex
- if (initialIndex >= artistModel.count)
- initialIndex = 0
- if (initialIndex !== artistList.currentIndex) {
- selectionModel.select(artistModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
- artistList.currentIndex = initialIndex
- artistList.positionViewAtIndex(initialIndex, ItemView.Contain)
- }
+ function loadDefaultView() {
+ root.view = "all"
+ root.viewProperties= ({})
}
- function _actionAtIndex(index) {
- albumSubView.forceActiveFocus()
+ function loadView() {
+ var found = stackView.loadView(root.pageModel, view, viewProperties)
+ if (!found)
+ stackView.replace(root.pageModel[0].component)
+ stackView.currentItem.navigationParent = root
+ model = stackView.currentItem.model
}
- MLArtistModel {
- id: artistModel
- ml: medialib
-
- onCountChanged: {
- if (artistModel.count > 0 && !selectionModel.hasSelection) {
- var initialIndex = root.initialIndex
- if (initialIndex >= artistModel.count)
- initialIndex = 0
- artistList.currentIndex = initialIndex
- }
- }
+ function _updateArtistsAllHistory(currentIndex) {
+ history.update(["mc", "music", "artists", "all", { "initialIndex": currentIndex }])
}
- Util.SelectableDelegateModel {
- id: selectionModel
- model: artistModel
+ function _updateArtistsAlbumsHistory(currentIndex, initialAlbumIndex) {
+ history.update(["mc","music", "artists", "albums", {
+ "initialIndex": currentIndex,
+ "initialAlbumIndex": initialAlbumIndex,
+ }])
}
- FocusScope {
- visible: artistModel.count > 0
- focus: visible
- anchors.fill: parent
+ Component {
+ id: artistGridComponent
- Row {
- anchors.fill: parent
+ Widgets.NavigableFocusScope {
+ id: artistAllView
- Widgets.KeyNavigableListView {
- id: artistList
+ readonly property int currentIndex: view.currentItem.currentIndex
+ property int initialIndex: 0
+ property alias model: artistModel
- width: parent.width * 0.25
- height: parent.height
+ onCurrentIndexChanged: {
+ _updateArtistsAllHistory(currentIndex)
+ }
- spacing: 4
- model: artistModel
- currentIndex: -1
+ onInitialIndexChanged: resetFocus()
- focus: true
+ function showAlbumView() {
+ history.push([ "mc", "music", "artists", "albums", { initialIndex: artistAllView.currentIndex } ])
+ }
- onCurrentIndexChanged: {
- if (artistList.currentIndex < artistModel.count) {
- root.artistId = artistModel.getIdForIndex(artistList.currentIndex)
- } else {
- root.artistId = undefined
+ function resetFocus() {
+ if (artistModel.count === 0) {
+ return
}
+ var initialIndex = artistAllView.initialIndex
+ if (initialIndex >= artistModel.count)
+ initialIndex = 0
+ selectionModel.select(artistModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
+ view.currentItem.currentIndex = initialIndex
+ view.currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
}
- navigationParent: root
- navigationRightItem: albumSubView
- navigationCancel: function() {
- if (artistList.currentIndex <= 0)
- defaultNavigationCancel()
- else
- artistList.currentIndex = 0;
- }
+ MLArtistModel {
+ id: artistModel
+ ml: medialib
- header: Widgets.SubtitleLabel {
- text: i18n.qtr("Artists")
- leftPadding: VLCStyle.margin_normal
- bottomPadding: VLCStyle.margin_normal
- topPadding: VLCStyle.margin_normal
+ onCountChanged: {
+ if (artistModel.count > 0 && !selectionModel.hasSelection) {
+ artistAllView.resetFocus()
+ }
+ }
}
- delegate: Widgets.ListItem {
- height: VLCStyle.play_cover_small + (VLCStyle.margin_xsmall * 2)
- width: artistList.width
+ Util.SelectableDelegateModel {
+ id: selectionModel
+ model: artistModel
+ }
- property bool selected: artistList.currentIndex === index
- property bool _highlighted: selected || this.hovered || this.activeFocus
+ Widgets.MenuExt {
+ id: contextMenu
+ property var model: ({})
+ closePolicy: Popup.CloseOnReleaseOutside | Popup.CloseOnEscape
+
+ Widgets.MenuItemExt {
+ id: playMenuItem
+ text: i18n.qtr("Play")
+ onTriggered: {
+ medialib.addAndPlay( contextMenu.model.id )
+ history.push(["player"])
+ }
+ }
- color: VLCStyle.colors.getBgColor(selected, this.hovered, this.activeFocus)
+ Widgets.MenuItemExt {
+ text: "Enqueue"
+ onTriggered: medialib.addToPlaylist( contextMenu.model.id )
+ }
- cover: Item {
+ onClosed: contextMenu.parent.forceActiveFocus()
- width: VLCStyle.play_cover_small
- height: VLCStyle.play_cover_small
+ }
- Widgets.RoundImage {
- source: model.cover || VLCStyle.noArtArtistSmall
- height: VLCStyle.play_cover_small
- width: VLCStyle.play_cover_small
- radius: VLCStyle.play_cover_small
- mipmap: true
+ Component {
+ id: gridComponent
+
+ Widgets.ExpandGridView {
+ id: artistGrid
+
+ anchors.fill: parent
+ topMargin: VLCStyle.margin_large
+ delegateModel: selectionModel
+ model: artistModel
+ focus: true
+ cellWidth: VLCStyle.colWidth(1)
+ cellHeight: VLCStyle.gridItem_music_height
+ onSelectAll: selectionModel.selectAll()
+ onSelectionUpdated: selectionModel.updateSelection( keyModifiers, oldIndex, newIndex )
+ navigationParent: root
+
+ onActionAtIndex: {
+ if (selectionModel.selectedIndexes.length > 1) {
+ medialib.addAndPlay( artistModel.getIdsForIndexes( selectionModel.selectedIndexes ) )
+ } else {
+ view.currentItem.currentIndex = index
+ showAlbumView()
+ medialib.addAndPlay( artistModel.getIdForIndex(index) )
+ }
}
- Rectangle {
- height: VLCStyle.play_cover_small
- width: VLCStyle.play_cover_small
- radius: VLCStyle.play_cover_small
- color: 'transparent'
- border.width: VLCStyle.dp(1, scale)
- border.color: !_highlighted ? VLCStyle.colors.roundPlayCoverBorder : VLCStyle.colors.accent
+ delegate: AudioGridItem {
+ id: gridItem
+
+ title: model.name
+ subtitle: model.nb_tracks > 1 ? i18n.qtr("%1 songs").arg(model.nb_tracks) : i18n.qtr("%1 song").arg(model.nb_tracks)
+ pictureRadius: VLCStyle.artistGridCover_radius
+ pictureHeight: VLCStyle.artistGridCover_radius
+ pictureWidth: VLCStyle.artistGridCover_radius
+ playCoverBorder.width: VLCStyle.dp(3, VLCStyle.scale)
+ titleMargin: VLCStyle.margin_xlarge
+ playIconSize: VLCStyle.play_cover_small
+ textHorizontalAlignment: Text.AlignHCenter
+ width: VLCStyle.colWidth(1)
+
+ onItemClicked: {
+ selectionModel.updateSelection( modifier , view.currentItem.currentIndex, index )
+ view.currentItem.currentIndex = index
+ view.currentItem.forceActiveFocus()
+ }
+
+ onItemDoubleClicked: artistAllView.showAlbumView(model)
}
}
+ }
- line1: model.name || i18n.qtr("Unknown artist")
- actionButtons: []
- onItemClicked: {
- artistId = model.id
- selectionModel.updateSelection( modifier , artistList.currentIndex, index)
- artistList.currentIndex = index
- artistList.forceActiveFocus()
- }
+ Component {
+ id: tableComponent
+
+ Widgets.KeyNavigableTableView {
+ id: artistTable
+
+ readonly property int _nbCols: VLCStyle.gridColumnsForWidth(artistTable.availableRowWidth)
+
+ anchors.fill: parent
+ model: artistModel
+ focus: true
+ headerColor: VLCStyle.colors.bg
+ navigationParent: root
- onItemDoubleClicked: {
- if (keys === Qt.RightButton)
- medialib.addAndPlay( model.id )
- else
- albumSubView.forceActiveFocus()
+ onActionForSelection: {
+ if (selection.length > 1) {
+ medialib.addAndPlay( artistModel.getIdsForIndexes( selection ) )
+ } else {
+ showAlbumView()
+ medialib.addAndPlay( artistModel.getIdForIndex(index) )
+ }
+ }
+
+ sortModel: [
+ { isPrimary: true, criteria: "name", width: VLCStyle.colWidth(Math.max(artistTable._nbCols - 1, 1)), text: i18n.qtr("Name"), headerDelegate: tableColumns.titleHeaderDelegate, colDelegate: tableColumns.titleDelegate },
+ { criteria: "nb_tracks", width: VLCStyle.colWidth(1), text: i18n.qtr("Tracks") }
+ ]
+
+ onItemDoubleClicked: {
+ artistAllView.showAlbumView(model)
+ }
+
+ onContextMenuButtonClicked: {
+ contextMenu.model = menuModel
+ contextMenu.popup(menuParent)
+ }
+
+ Widgets.TableColumns {
+ id: tableColumns
+ }
}
}
- }
+ Widgets.StackViewExt {
+ id: view
- MusicArtist {
- id: albumSubView
+ anchors.fill: parent
+ focus: true
+ initialItem: medialib.gridView ? gridComponent : tableComponent
+ }
- height: parent.height
- width: parent.width * .75
- focus: true
- parentId: root.artistId
- initialIndex: root.initialAlbumIndex
- navigationParent: root
- navigationLeftItem: artistList
- artist: (artistList.currentIndex >= 0)
- ? artistModel.getDataAt(artistList.currentIndex)
- : ({})
+ Connections {
+ target: medialib
+ onGridViewChanged: {
+ if (medialib.gridView) {
+ view.replace(gridComponent)
+ } else {
+ view.replace(tableComponent)
+ }
+ }
+ }
- onCurrentIndexChanged: {
- history.update(["mc", "music", "artists", {"initialIndex" : root.currentIndex, "initialAlbumIndex": albumSubView.currentIndex }])
+ EmptyLabel {
+ anchors.fill: parent
+ visible: artistModel.count === 0
+ text: i18n.qtr("No artists found\nPlease try adding sources, by going to the Network tab")
+ navigationParent: root
}
}
-
}
+
+ Component {
+ id: artistAlbumsComponent
+ /* List View */
+ MusicArtistsAlbums {
+ onCurrentIndexChanged: _updateArtistsAlbumsHistory(currentIndex, currentAlbumIndex)
+ onCurrentAlbumIndexChanged: _updateArtistsAlbumsHistory(currentIndex, currentAlbumIndex)
+ }
}
- EmptyLabel {
+ Widgets.StackViewExt {
+ id: stackView
+
anchors.fill: parent
- visible: artistModel.count === 0
- focus: visible
- text: i18n.qtr("No artists found\nPlease try adding sources, by going to the Network tab")
- navigationParent: root
+ focus: true
}
}
diff --git a/modules/gui/qt/medialibrary/qml/MusicGenres.qml b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
index 78c74a09d6..c06eef1104 100644
--- a/modules/gui/qt/medialibrary/qml/MusicGenres.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
@@ -227,12 +227,4 @@ Widgets.NavigableFocusScope {
anchors.fill: parent
focus: genreModel.count !== 0
}
-
- EmptyLabel {
- anchors.fill: parent
- visible: genreModel.count === 0
- focus: visible
- text: i18n.qtr("No genres found\nPlease try adding sources, by going to the Network tab")
- navigationParent: root
- }
}
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 51f3a61701..c6eaa47bf9 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -243,6 +243,7 @@
<file alias="MusicAlbumsDisplay.qml">medialibrary/qml/MusicAlbumsDisplay.qml</file>
<file alias="MusicAlbumsGridExpandDelegate.qml">medialibrary/qml/MusicAlbumsGridExpandDelegate.qml</file>
<file alias="MusicArtist.qml">medialibrary/qml/MusicArtist.qml</file>
+ <file alias="MusicArtistsAlbums.qml">medialibrary/qml/MusicArtistsAlbums.qml</file>
<file alias="MusicArtistsDisplay.qml">medialibrary/qml/MusicArtistsDisplay.qml</file>
<file alias="MusicGenresDisplay.qml">medialibrary/qml/MusicGenresDisplay.qml</file>
<file alias="MusicTracksDisplay.qml">medialibrary/qml/MusicTracksDisplay.qml</file>
--
2.25.1
More information about the vlc-devel
mailing list