vlc | branch: master | Prince Gupta <guptaprince8...@gmail.com> | Tue Aug 4 23:54:22 2020 +0530| [479b188c1efff8bd866e8cedf1ebac496c6a3caa] | committer: Pierre Lamot
qml: add new page to artist view with only artists > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=479b188c1efff8bd866e8cedf1ebac496c6a3caa --- modules/gui/qt/Makefile.am | 1 + .../gui/qt/medialibrary/qml/MusicArtistsAlbums.qml | 205 +++++++++++++ .../qt/medialibrary/qml/MusicArtistsDisplay.qml | 340 +++++++++++++-------- modules/gui/qt/medialibrary/qml/MusicGenres.qml | 8 - modules/gui/qt/vlc.qrc | 1 + 5 files changed, 415 insertions(+), 140 deletions(-) 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> _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits