[vlc-commits] qml: Create PlaylistMediaList
Benjamin Arnaud
git at videolan.org
Tue Feb 23 08:54:17 UTC 2021
vlc | branch: master | Benjamin Arnaud <benjamin.arnaud at videolabs.io> | Fri Feb 19 11:25:35 2021 +0100| [987e982084c48e39d4c07cae36c765e85c94b1ad] | committer: Pierre Lamot
qml: Create PlaylistMediaList
Signed-off-by: Pierre Lamot <pierre at videolabs.io>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=987e982084c48e39d4c07cae36c765e85c94b1ad
---
modules/gui/qt/Makefile.am | 1 +
.../gui/qt/medialibrary/qml/PlaylistMediaList.qml | 422 +++++++++++++++++++++
modules/gui/qt/vlc.qrc | 1 +
po/POTFILES.in | 1 +
4 files changed, 425 insertions(+)
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 6df4b7c71b..9a313611a7 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -666,6 +666,7 @@ libqt_plugin_la_QML = \
gui/qt/medialibrary/qml/VideoDisplay.qml \
gui/qt/medialibrary/qml/VideoAll.qml \
gui/qt/medialibrary/qml/VideoAllDisplay.qml \
+ gui/qt/medialibrary/qml/PlaylistMediaList.qml \
gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml \
gui/qt/medialibrary/qml/VideoGridItem.qml \
gui/qt/medialibrary/qml/VideoInfoExpandPanel.qml \
diff --git a/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml b/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
new file mode 100644
index 0000000000..0cd637e76d
--- /dev/null
+++ b/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
@@ -0,0 +1,422 @@
+/*****************************************************************************
+ * Copyright (C) 2021 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 2.11
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtQml.Models 2.2
+
+import org.videolan.medialib 0.1
+
+import "qrc:///widgets/" as Widgets
+import "qrc:///main/" as MainInterface
+import "qrc:///util/" as Util
+import "qrc:///style/"
+
+Widgets.NavigableFocusScope {
+ id: root
+
+ //---------------------------------------------------------------------------------------------
+ // Properties
+ //---------------------------------------------------------------------------------------------
+
+ readonly property int currentIndex: currentItem.currentIndex
+
+ property int initialIndex: 0
+
+ property var sortModel: [{ text: i18n.qtr("Alphabetic"), criteria: "title" }]
+
+ //---------------------------------------------------------------------------------------------
+ // Private
+
+ property int _width: VLCStyle.colWidth(2)
+
+ property int _height: Math.round(_width / 2)
+
+ property int _widthColumn:
+ Math.max(VLCStyle.gridColumnsForWidth(tableView.availableRowWidth
+ - VLCStyle.listAlbumCover_width
+ - VLCStyle.column_margin_width) - 1, 1)
+
+ //---------------------------------------------------------------------------------------------
+ // Alias
+ //---------------------------------------------------------------------------------------------
+
+ property alias model: model
+
+ property alias currentItem: view.currentItem
+
+ //---------------------------------------------------------------------------------------------
+ // Signals
+ //---------------------------------------------------------------------------------------------
+
+ signal showList(variant model)
+
+ //---------------------------------------------------------------------------------------------
+ // Settings
+ //---------------------------------------------------------------------------------------------
+
+ navigationCancel: function() {
+ if (currentItem.currentIndex > 0) {
+ currentItem.currentIndex = 0;
+ } else {
+ defaultNavigationCancel();
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Events
+ //---------------------------------------------------------------------------------------------
+
+ // NOTE: Define the initial position and selection. This is done on activeFocus rather than
+ // Component.onCompleted because modelSelect.selectedGroup update itself after this
+ // event.
+ onActiveFocusChanged: {
+ if (activeFocus == false || model.count === 0 || modelSelect.hasSelection) return;
+
+ var initialIndex = 0;
+
+ if (currentItem.currentIndex !== -1) {
+ initialIndex = currentItem.currentIndex;
+ }
+
+ modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
+
+ currentItem.currentIndex = initialIndex;
+ }
+
+ onInitialIndexChanged: resetFocus()
+
+ //---------------------------------------------------------------------------------------------
+ // Connections
+ //---------------------------------------------------------------------------------------------
+
+ Connections {
+ target: mainInterface
+
+ onGridViewChanged: {
+ if (mainInterface.gridView) view.replace(grid);
+ else view.replace(table);
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Functions
+ //---------------------------------------------------------------------------------------------
+
+ function resetFocus() {
+ if (model.count === 0) return;
+
+ var initialIndex = root.initialIndex;
+
+ if (initialIndex >= model.count)
+ initialIndex = 0;
+
+ modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
+
+ if (currentItem)
+ currentItem.positionViewAtIndex(initialIndex, ItemView.Contain);
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Private
+
+ function _actionAtIndex(index) {
+ if (modelSelect.selectedIndexes.length > 1) {
+ medialib.addAndPlay(model.getIdsForIndexes(modelSelect.selectedIndexes));
+ } else if (modelSelect.selectedIndexes.length === 1) {
+ var indexes = modelSelect.selectedIndexes[0];
+ showList(model.getDataAt(indexes));
+ }
+ }
+
+ //---------------------------------------------------------------------------------------------
+ // Childs
+ //---------------------------------------------------------------------------------------------
+
+ MLPlaylistListModel {
+ id: model
+
+ ml: medialib
+
+ onCountChanged: {
+ if (count === 0 || modelSelect.hasSelection) return;
+
+ resetFocus();
+ }
+ }
+
+ Widgets.StackViewExt {
+ id: view
+
+ anchors.fill: parent
+
+ initialItem: (mainInterface.gridView) ? grid : table
+
+ focus: (model.count !== 0)
+ }
+
+ Widgets.DragItem {
+ id: dragItemPlaylist
+
+ function updateComponents(maxCovers) {
+ var items = modelSelect.selectedIndexes.slice(0, maxCovers).map(function (x){
+ return model.getDataAt(x.row);
+ })
+
+ var covers = items.map(function (item) {
+ return { artwork: item.cover || VLCStyle.noArtCover };
+ })
+
+ var title = items.map(function (item) {
+ return item.name
+ }).join(", ");
+
+ return {
+ covers: covers,
+ title: title,
+ count: modelSelect.selectedIndexes.length
+ };
+ }
+
+ function insertIntoPlaylist(index) {
+ medialib.insertIntoPlaylist(index,
+ model.getIdsForIndexes(modelSelect.selectedIndexes));
+ }
+ }
+
+ Util.SelectableDelegateModel {
+ id: modelSelect
+
+ model: root.model
+ }
+
+ PlaylistListContextMenu {
+ id: contextMenu
+
+ model: root.model
+ }
+
+ // TBD: Refactor this with MusicGenres ?
+ Component {
+ id: grid
+
+ MainInterface.MainGridView {
+ id: gridView
+
+ //-------------------------------------------------------------------------------------
+ // Settings
+
+ cellWidth : _width
+ cellHeight: _height
+
+ topMargin: VLCStyle.margin_large
+
+ model: root.model
+
+ delegateModel: modelSelect
+
+ navigationParent: root
+
+ focus: true
+
+ //-------------------------------------------------------------------------------------
+ // Events
+
+ onSelectAll: modelSelect.selectAll()
+
+ onSelectionUpdated: modelSelect.updateSelection(keyModifiers, oldIndex, newIndex)
+
+ onActionAtIndex: _actionAtIndex(index)
+
+ //-------------------------------------------------------------------------------------
+ // Childs
+
+ delegate: Widgets.GridItem {
+ id: item
+
+ //---------------------------------------------------------------------------------
+ // Properties
+
+ property var model: ({})
+
+ property int index: -1
+
+ //---------------------------------------------------------------------------------
+ // Settings
+
+ width : _width
+ height: _height
+
+ pictureWidth : width
+ pictureHeight: height
+
+ image: VLCStyle.noArtAlbum
+
+ dragItem: dragItemPlaylist
+
+ pictureOverlay: Item {
+ Column {
+ anchors.centerIn: parent
+
+ Label {
+ width: item.width
+
+ horizontalAlignment: Text.AlignHCenter
+
+ text: model.name
+
+ elide: Text.ElideRight
+
+ color: "white"
+
+ font.pixelSize: VLCStyle.fontSize_large
+ font.weight : Font.DemiBold
+ }
+
+ Widgets.CaptionLabel {
+ width: item.width
+
+ horizontalAlignment: Text.AlignHCenter
+
+ opacity: 0.7
+
+ text: (model.count > 1) ? i18n.qtr("%1 Tracks").arg(model.count)
+ : i18n.qtr("%1 Track") .arg(model.count)
+
+ color: "white"
+ }
+ }
+ }
+
+ playCoverBorder.width: VLCStyle.dp(3, VLCStyle.scale)
+
+ //---------------------------------------------------------------------------------
+ // Events
+
+ onItemDoubleClicked: showList(model)
+
+ onItemClicked: gridView.leftClickOnItem(modifier, index)
+
+ onPlayClicked: if (model.id) medialib.addAndPlay(model.id)
+
+ onContextMenuButtonClicked: {
+ gridView.rightClickOnItem(index);
+
+ contextMenu.popup(modelSelect.selectedIndexes, globalMousePos);
+ }
+ }
+ }
+ }
+
+ Component {
+ id: table
+
+ MainInterface.MainTableView {
+ id: tableView
+
+ //-------------------------------------------------------------------------------------
+ // Properties
+
+ property int _widthName:
+ Math.max(VLCStyle.gridColumnsForWidth(tableView.availableRowWidth
+ - VLCStyle.listAlbumCover_width
+ - VLCStyle.column_margin_width) - 1, 1)
+
+ //-------------------------------------------------------------------------------------
+ // Settings
+
+ rowHeight: VLCStyle.tableCoverRow_height
+
+ headerTopPadding: VLCStyle.margin_normal
+
+ model: root.model
+
+ selectionDelegateModel: modelSelect
+
+ navigationParent: root
+
+ dragItem: dragItemPlaylist
+
+ focus: true
+
+ headerColor: VLCStyle.colors.bg
+
+ sortModel: [{
+ isPrimary: true,
+ criteria: "cover",
+
+ width: VLCStyle.listAlbumCover_width,
+
+ headerDelegate: columns.titleHeaderDelegate,
+ colDelegate : columns.titleDelegate
+ }, {
+ criteria: "name",
+
+ width: VLCStyle.colWidth(_widthName),
+
+ text: i18n.qtr("Name")
+ }, {
+ criteria: "count",
+
+ width: VLCStyle.colWidth(1),
+
+ text: i18n.qtr("Tracks")
+ }]
+
+ //-------------------------------------------------------------------------------------
+ // Events
+
+ onActionForSelection: _actionAtIndex(selection)
+
+ onItemDoubleClicked: showList(model)
+
+ onContextMenuButtonClicked: contextMenu.popup(modelSelect.selectedIndexes,
+ menuParent.mapToGlobal(0,0))
+
+ onRightClick: contextMenu.popup(modelSelect.selectedIndexes, globalMousePos)
+
+ //-------------------------------------------------------------------------------------
+ // Childs
+
+ Widgets.TableColumns {
+ id: columns
+
+ showTitleText: false
+
+ titleCover_width : VLCStyle.listAlbumCover_width
+ titleCover_height: VLCStyle.listAlbumCover_height
+ titleCover_radius: VLCStyle.listAlbumCover_radius
+ }
+ }
+ }
+
+ EmptyLabel {
+ anchors.fill: parent
+
+ visible: (model.count === 0)
+
+ focus: visible
+
+ text: i18n.qtr("No playlists found")
+
+ cover: VLCStyle.noArtAlbumCover
+
+ navigationParent: root
+ }
+}
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 59504dfd18..e211c8e3da 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -272,6 +272,7 @@
<file alias="VideoDisplay.qml">medialibrary/qml/VideoDisplay.qml</file>
<file alias="VideoAll.qml">medialibrary/qml/VideoAll.qml</file>
<file alias="VideoAllDisplay.qml">medialibrary/qml/VideoAllDisplay.qml</file>
+ <file alias="PlaylistMediaList.qml">medialibrary/qml/PlaylistMediaList.qml</file>
<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>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f0a7a984b6..4c15ca20e1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -828,6 +828,7 @@ modules/gui/qt/medialibrary/qml/VideoInfoExpandPanel.qml
modules/gui/qt/medialibrary/qml/VideoListDisplay.qml
modules/gui/qt/medialibrary/qml/VideoAll.qml
modules/gui/qt/medialibrary/qml/VideoAllDisplay.qml
+modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
modules/gui/qt/menus/qml/Menubar.qml
modules/gui/qt/network/qml/DiscoverDisplay.qml
modules/gui/qt/network/qml/DiscoverUrlDisplay.qml
More information about the vlc-commits
mailing list