[vlc-devel] [PATCH 12/15] qml: Update the drag and drop implementation

Benjamin Arnaud benjamin.arnaud at videolabs.io
Thu Mar 11 09:16:56 UTC 2021


qml/DragItem: Add the 'getSelectedInputItem' function
---
 modules/gui/qt/Makefile.am                    |   1 -
 .../gui/qt/medialibrary/qml/MusicAlbums.qml   |   4 +-
 .../gui/qt/medialibrary/qml/MusicArtist.qml   |   8 +-
 .../medialibrary/qml/MusicArtistsDisplay.qml  |   4 +-
 .../gui/qt/medialibrary/qml/MusicGenres.qml   |   4 +-
 .../medialibrary/qml/MusicTracksDisplay.qml   |   4 +-
 .../medialibrary/qml/PlaylistMediaDisplay.qml |   9 +-
 .../qt/medialibrary/qml/PlaylistMediaList.qml |   8 +-
 modules/gui/qt/medialibrary/qml/VideoAll.qml  |   5 +-
 .../qt/network/qml/NetworkBrowseDisplay.qml   |   4 +-
 .../gui/qt/playlist/qml/PlaylistDroppable.qml |  31 ------
 .../gui/qt/playlist/qml/PlaylistListView.qml  |  48 ++++-----
 modules/gui/qt/vlc.qrc                        |   1 -
 modules/gui/qt/widgets/qml/DragItem.qml       | 102 +++++++++++++-----
 14 files changed, 122 insertions(+), 111 deletions(-)
 delete mode 100644 modules/gui/qt/playlist/qml/PlaylistDroppable.qml

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index f762e5035c..7857c8390a 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -715,7 +715,6 @@ libqt_plugin_la_QML = \
 	gui/qt/player/qml/VolumeWidget.qml \
 	gui/qt/player/qml/ButtonsLayout.qml \
 	gui/qt/playlist/qml/PlaylistDelegate.qml \
-	gui/qt/playlist/qml/PlaylistDroppable.qml \
 	gui/qt/playlist/qml/PlaylistListView.qml \
 	gui/qt/playlist/qml/PlaylistOverlayMenu.qml \
 	gui/qt/playlist/qml/PlaylistToolbar.qml \
diff --git a/modules/gui/qt/medialibrary/qml/MusicAlbums.qml b/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
index ff950c33cd..9fb277ff77 100644
--- a/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicAlbums.qml
@@ -113,8 +113,8 @@ Widgets.NavigableFocusScope {
           }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index, albumModelId.getIdsForIndexes(selectionModel.selectedIndexes))
+        function getSelectedInputItem() {
+            return albumModelId.getItemsForIndexes(selectionModel.selectedIndexes);
         }
     }
 
diff --git a/modules/gui/qt/medialibrary/qml/MusicArtist.qml b/modules/gui/qt/medialibrary/qml/MusicArtist.qml
index 48d11dddf2..d880e0391a 100644
--- a/modules/gui/qt/medialibrary/qml/MusicArtist.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicArtist.qml
@@ -230,8 +230,8 @@ Widgets.NavigableFocusScope {
           }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index, albumModel.getIdsForIndexes(albumSelectionModel.selectedIndexes))
+        function getSelectedInputItem() {
+            return albumModel.getItemsForIndexes(albumSelectionModel.selectedIndexes);
         }
     }
 
@@ -382,8 +382,8 @@ Widgets.NavigableFocusScope {
                   }
                 }
 
-                function insertIntoPlaylist(index) {
-                    medialib.insertIntoPlaylist(index, trackModel.getIdsForIndexes(trackSelectionModel.selectedIndexes))
+                function getSelectedInputItem() {
+                    return trackModel.getItemsForIndexes(trackSelectionModel.selectedIndexes);
                 }
             }
 
diff --git a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
index 798c168d03..7a1b7c9516 100644
--- a/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicArtistsDisplay.qml
@@ -123,8 +123,8 @@ Widgets.PageLoader {
                   }
                 }
 
-                function insertIntoPlaylist(index) {
-                    medialib.insertIntoPlaylist(index, artistModel.getIdsForIndexes(selectionModel.selectedIndexes))
+                function getSelectedInputItem() {
+                    return artistModel.getItemsForIndexes(selectionModel.selectedIndexes);
                 }
             }
 
diff --git a/modules/gui/qt/medialibrary/qml/MusicGenres.qml b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
index 6b6bbab9a3..d12230a5c2 100644
--- a/modules/gui/qt/medialibrary/qml/MusicGenres.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
@@ -114,8 +114,8 @@ Widgets.NavigableFocusScope {
           }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index, genreModel.getIdsForIndexes(selectionModel.selectedIndexes))
+        function getSelectedInputItem() {
+            return genreModel.getItemsForIndexes(selectionModel.selectedIndexes);
         }
     }
 
diff --git a/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml b/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
index a98621ac73..be92b6bac3 100644
--- a/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicTracksDisplay.qml
@@ -46,8 +46,8 @@ Widgets.NavigableFocusScope {
           }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index, model.getIdsForIndexes(selectionModel.selectedIndexes))
+        function getSelectedInputItem() {
+            return model.getItemsForIndexes(selectionModel.selectedIndexes);
         }
     }
 
diff --git a/modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml b/modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml
index d982c633f6..20a0277184 100644
--- a/modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml
+++ b/modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml
@@ -173,9 +173,8 @@ Widgets.NavigableFocusScope {
             }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index,
-                                        model.getIdsForIndexes(modelSelect.selectedIndexes));
+        function getSelectedInputItem() {
+            return model.getItemsForIndexes(modelSelect.selectedIndexes);
         }
     }
 
@@ -195,7 +194,7 @@ Widgets.NavigableFocusScope {
     {
         id: view
 
-        //-------------------------------------------------------------------------------------
+        //-----------------------------------------------------------------------------------------
         // Settings
 
         anchors.left  : parent.left
@@ -222,7 +221,7 @@ Widgets.NavigableFocusScope {
         navigationParent: root
         navigationUpItem: (headerItem) ? headerItem.focus : undefined
 
-        //-------------------------------------------------------------------------------------
+        //-----------------------------------------------------------------------------------------
         // Events
 
         onContextMenuButtonClicked: contextMenu.popup(modelSelect.selectedIndexes,
diff --git a/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml b/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
index 0cd637e76d..1bbdec00e4 100644
--- a/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
+++ b/modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
@@ -174,6 +174,9 @@ Widgets.NavigableFocusScope {
     Widgets.DragItem {
         id: dragItemPlaylist
 
+        //---------------------------------------------------------------------------------------------
+        // DragItem implementation
+
         function updateComponents(maxCovers) {
             var items = modelSelect.selectedIndexes.slice(0, maxCovers).map(function (x){
                 return model.getDataAt(x.row);
@@ -194,9 +197,8 @@ Widgets.NavigableFocusScope {
             };
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index,
-                                        model.getIdsForIndexes(modelSelect.selectedIndexes));
+        function getSelectedInputItem() {
+            return model.getItemsForIndexes(modelSelect.selectedIndexes);
         }
     }
 
diff --git a/modules/gui/qt/medialibrary/qml/VideoAll.qml b/modules/gui/qt/medialibrary/qml/VideoAll.qml
index 0287a61907..52245bb9a3 100644
--- a/modules/gui/qt/medialibrary/qml/VideoAll.qml
+++ b/modules/gui/qt/medialibrary/qml/VideoAll.qml
@@ -179,9 +179,8 @@ Widgets.NavigableFocusScope {
             }
         }
 
-        function insertIntoPlaylist(index) {
-            medialib.insertIntoPlaylist(index,
-                                        model.getIdsForIndexes(modelSelect.selectedIndexes));
+        function getSelectedInputItem() {
+            return model.getItemsForIndexes(modelSelect.selectedIndexes);
         }
     }
 
diff --git a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
index b7e8bfc291..025083037b 100644
--- a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
+++ b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
@@ -86,8 +86,8 @@ Widgets.NavigableFocusScope {
           }
         }
 
-        function insertIntoPlaylist(index) {
-            providerModel.insertIntoPlaylist(filterModel.mapIndexesToSource(selectionModel.selectedIndexes), index)
+        function getSelectedInputItem() {
+            return providerModel.getItemsForIndexes(selectionModel.selectedIndexes);
         }
 
         Component {
diff --git a/modules/gui/qt/playlist/qml/PlaylistDroppable.qml b/modules/gui/qt/playlist/qml/PlaylistDroppable.qml
deleted file mode 100644
index 671990fb9f..0000000000
--- a/modules/gui/qt/playlist/qml/PlaylistDroppable.qml
+++ /dev/null
@@ -1,31 +0,0 @@
-/*****************************************************************************
- * 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 2.11
-
-Item {
-    id: root
-
-    function insertIntoPlaylist(index /* <int>: index to insert at*/) {
-        console.assert(false, "parent should reimplement this function")
-    }
-
-    function canInsertIntoPlaylist(index) {
-        return true
-    }
-}
-
diff --git a/modules/gui/qt/playlist/qml/PlaylistListView.qml b/modules/gui/qt/playlist/qml/PlaylistListView.qml
index 54c0d7dded..9b1840422e 100644
--- a/modules/gui/qt/playlist/qml/PlaylistListView.qml
+++ b/modules/gui/qt/playlist/qml/PlaylistListView.qml
@@ -54,26 +54,34 @@ Widgets.NavigableFocusScope {
 
     function isDropAcceptable(drop, index) {
         return drop.hasUrls || // external drop (i.e. from filesystem)
-                (isValidInstanceOf(drop.source, Widgets.DragItem) && drop.source.canInsertIntoPlaylist(index)) // internal drop (inter-view or intra-playlist)
+                (isValidInstanceOf(drop.source, Widgets.DragItem)) // internal drop (inter-view or intra-playlist)
     }
 
     function acceptDrop(index, drop) {
-        if (isValidInstanceOf(drop.source, Widgets.DragItem)) {
-            // dropping Medialib view content into playlist or intra-playlist dragging:
-            drop.source.insertIntoPlaylist(index)
+        var item = drop.source;
+
+        // NOTE: Move implementation.
+        if (dragItem == item) {
+            model.moveItemsPre(model.getSelection(), index);
+
+        // NOTE: Dropping medialibrary content into the queue.
+        } else if (isValidInstanceOf(item, Widgets.DragItem)) {
+            mainPlaylistController.insert(index, item.getSelectedInputItem());
+
+        // NOTE: Dropping an external item (i.e. filesystem) into the queue.
         } else if (drop.hasUrls) {
-            // dropping an external item (i.e. filesystem drag) into playlist:
-            // force conversion to an actual list
-            var urlList = []
-            for ( var url in drop.urls)
-                urlList.push(drop.urls[url])
-            mainPlaylistController.insert(index, urlList, false)
-
-            // This is required otherwise backend may handle the drop as well yielding double addition
-            drop.accept(Qt.IgnoreAction)
+            var urlList = [];
+
+            for (var url in drop.urls)
+                urlList.push(drop.urls[url]);
+
+            mainPlaylistController.insert(index, urlList, false);
+
+            // NOTE This is required otherwise backend may handle the drop as well yielding double addition.
+            drop.accept(Qt.IgnoreAction);
         }
 
-        listView.forceActiveFocus()
+        listView.forceActiveFocus();
     }
 
     PlaylistOverlayMenu {
@@ -118,16 +126,8 @@ Widgets.NavigableFocusScope {
                 return ({covers: covers, title: title, count: root.model.selectedCount})
             }
 
-            function insertIntoPlaylist(index) {
-                root.model.moveItemsPre(root.model.getSelection(), index)
-            }
-
-            function canInsertIntoPlaylist(index) {
-                var diff = dragItem.index - index
-                if (diff === 0 || diff === -1)
-                    return false
-                else
-                    return true
+            function getSelectedInputItem(index) {
+                return model.getItemsForIndexes(model.getSelection())
             }
 
             property point _pos: null
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 4576eb4545..3cda8faf6c 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -304,7 +304,6 @@
     </qresource>
     <qresource prefix="/playlist">
         <file alias="PlaylistDelegate.qml">playlist/qml/PlaylistDelegate.qml</file>
-        <file alias="PlaylistDroppable.qml">playlist/qml/PlaylistDroppable.qml</file>
         <file alias="PlaylistListView.qml">playlist/qml/PlaylistListView.qml</file>
         <file alias="PlaylistOverlayMenu.qml">playlist/qml/PlaylistOverlayMenu.qml</file>
         <file alias="PlaylistToolbar.qml">playlist/qml/PlaylistToolbar.qml</file>
diff --git a/modules/gui/qt/widgets/qml/DragItem.qml b/modules/gui/qt/widgets/qml/DragItem.qml
index 723ed2ec28..746c0fa008 100644
--- a/modules/gui/qt/widgets/qml/DragItem.qml
+++ b/modules/gui/qt/widgets/qml/DragItem.qml
@@ -15,60 +15,91 @@
  * 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          2.11
 import QtQuick.Controls 2.4
-import QtQml.Models 2.2
-import "qrc:///style/"
-import "qrc:///playlist/" as Playlist
+import QtQml.Models     2.2
 
 import QtGraphicalEffects 1.0
 
-Playlist.PlaylistDroppable {
+import "qrc:///style/"
+import "qrc:///playlist/" as Playlist
+
+Item {
     id: dragItem
 
-    property VLCColors colors: VLCStyle.colors
+    //---------------------------------------------------------------------------------------------
+    // Properties
+    //---------------------------------------------------------------------------------------------
 
     readonly property int coverSize: VLCStyle.icon_normal
+
+    property VLCColors colors: VLCStyle.colors
+
+    //---------------------------------------------------------------------------------------------
+    // Private
+
+    property var _model: {"covers": [], "title": "", "count": 0}
+
     readonly property int _maxCovers: 3
+
     readonly property int _displayedCoversCount: Math.min(_model.count, _maxCovers + 1)
 
-    property var _model: {"covers": [], "title": "", "count": 0}
+    //---------------------------------------------------------------------------------------------
+    // Settings
+    //---------------------------------------------------------------------------------------------
 
-    // return {covers: [{artwork: <string> or cover: <component>},..maxCovers]
-    //         , title: <string>, *subtitle: <string>, count: <int> /*all selected*/}
-    // * - optional
-    function updateComponents(maxCovers) {
-        console.assert(false, "parent should reimplement this function")
-    }
+    parent: g_mainDisplay
+
+    width: VLCStyle.colWidth(2)
+
+    height: coverSize + VLCStyle.margin_small * 2
+
+    opacity: visible ? 0.90 : 0
+
+    visible: Drag.active
+
+    //---------------------------------------------------------------------------------------------
+    // Events
+    //---------------------------------------------------------------------------------------------
 
     Drag.onActiveChanged: {
         if (Drag.active) {
-            _model = updateComponents(_maxCovers)
-            mainInterface.setCursor(Qt.DragMoveCursor)
+            _model = updateComponents(_maxCovers);
+            mainInterface.setCursor(Qt.DragMoveCursor);
         } else {
-            mainInterface.restoreCursor()
+            mainInterface.restoreCursor();
         }
     }
 
+    //---------------------------------------------------------------------------------------------
+    // Functions
+    //---------------------------------------------------------------------------------------------
+
     function coversXPos(index) {
-        return VLCStyle.margin_small + (coverSize / 3) * index
+        return VLCStyle.margin_small + (coverSize / 3) * index;
     }
 
-    parent: g_mainDisplay
-    width: VLCStyle.colWidth(2)
-    height: coverSize + VLCStyle.margin_small * 2
-    opacity: visible ? 0.90 : 0
-    visible: Drag.active
+    //---------------------------------------------------------------------------------------------
+    // Pure virtual
 
-    Rectangle {
-        /* background */
-        anchors.fill: parent
-        color: colors.button
-        border.color: colors.buttonBorder
-        border.width: VLCStyle.dp(1, VLCStyle.scale)
-        radius: VLCStyle.dp(6, VLCStyle.scale)
+    // return {covers: [{artwork: <string> or cover: <component>},..maxCovers]
+    //         , title: <string>, *subtitle: <string>, count: <int> /*all selected*/}
+    // * - optional
+    function updateComponents(maxCovers) {
+        console.assert(false, "updateComponents is not implemented.");
+    }
+
+    function getSelectedInputItem() {
+        console.assert(false, "getSelectedInputItem is not implemented.");
+
+        return undefined;
     }
 
+    //---------------------------------------------------------------------------------------------
+    // Animations
+    //---------------------------------------------------------------------------------------------
+
     Behavior on opacity {
         NumberAnimation {
             easing.type: Easing.InOutSine
@@ -76,6 +107,19 @@ Playlist.PlaylistDroppable {
         }
     }
 
+    //---------------------------------------------------------------------------------------------
+    // Childs
+    //---------------------------------------------------------------------------------------------
+
+    Rectangle {
+        /* background */
+        anchors.fill: parent
+        color: colors.button
+        border.color: colors.buttonBorder
+        border.width: VLCStyle.dp(1, VLCStyle.scale)
+        radius: VLCStyle.dp(6, VLCStyle.scale)
+    }
+
     RectangularGlow {
         anchors.fill: parent
         glowRadius: VLCStyle.dp(8, VLCStyle.scale)
-- 
2.25.1



More information about the vlc-devel mailing list