[vlc-devel] [PATCH 05/16] qml: generalize Playlist drop functionality using new interface PlaylistDroppable

Prince Gupta guptaprince8832 at gmail.com
Fri Dec 4 12:19:02 CET 2020


---
 modules/gui/qt/Makefile.am                    |  1 +
 modules/gui/qt/playlist/qml/PLItem.qml        | 77 ++++---------------
 .../gui/qt/playlist/qml/PlaylistDroppable.qml | 31 ++++++++
 .../gui/qt/playlist/qml/PlaylistListView.qml  | 59 ++++++++------
 modules/gui/qt/vlc.qrc                        |  1 +
 modules/gui/qt/widgets/qml/DNDLabel.qml       | 16 +++-
 6 files changed, 95 insertions(+), 90 deletions(-)
 create mode 100644 modules/gui/qt/playlist/qml/PlaylistDroppable.qml

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 3ff0e265df..8920fe6f8c 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -675,6 +675,7 @@ libqt_plugin_la_QML = \
 	gui/qt/player/qml/TrackInfo.qml \
 	gui/qt/player/qml/VolumeWidget.qml \
 	gui/qt/playlist/qml/PLItem.qml \
+	gui/qt/playlist/qml/PlaylistDroppable.qml \
 	gui/qt/playlist/qml/PlaylistListView.qml \
 	gui/qt/playlist/qml/PlaylistMenu.qml \
 	gui/qt/playlist/qml/PlaylistToolbar.qml \
diff --git a/modules/gui/qt/playlist/qml/PLItem.qml b/modules/gui/qt/playlist/qml/PLItem.qml
index 8b76bacf2b..1c944f5d48 100644
--- a/modules/gui/qt/playlist/qml/PLItem.qml
+++ b/modules/gui/qt/playlist/qml/PLItem.qml
@@ -69,6 +69,10 @@ Rectangle {
 
     }
 
+    function isDropAcceptable(drop, index) {
+        console.assert(false, "parent should reimplement this function")
+    }
+
     onHoveredChanged: {
         if(hovered)
             showTooltip(false)
@@ -285,26 +289,13 @@ Rectangle {
                 Layout.preferredHeight: parent.height / 2
 
                 onEntered: {
-                    var delta = 1
-
-                    if(!drag.hasUrls)
-                        delta = drag.source.model.index - model.index
-
-                    if(delta === 0 || delta === -1)
-                        return
-
-                    dropVisible = true
+                    dropVisible = isDropAcceptable(drag, model.index)
                 }
                 onExited: {
                     dropVisible = false
                 }
                 onDropped: {
-                    var delta = 1
-
-                    if(!drop.hasUrls)
-                        delta = drag.source.model.index - model.index
-
-                    if(delta === 0 || delta === -1)
+                    if (!isDropAcceptable(drop, model.index))
                         return
 
                     plitem.dropedMovedAt(model.index, drop)
@@ -317,64 +308,24 @@ Rectangle {
                 Layout.fillWidth: true
                 Layout.fillHeight: true
 
-                property bool _isLastItem : model.index === plitem.plmodel.count - 1
+                readonly property bool _isLastItem: model.index === plitem.plmodel.count - 1
+                readonly property int _targetIndex: _isLastItem ? model.index + 1 : model.index
 
                 onEntered: {
-                    var delta = -1
-
-                    if(!drag.hasUrls)
-                        delta = drag.source.model.index - model.index
-
-                    if(delta === 0 || delta === 1)
+                    if (!isDropAcceptable(drag, _targetIndex))
                         return
 
-                    if (_isLastItem)
-                    {
-                        root.setItemDropIndicatorVisible(model.index, true, false);
-                    }
-                    else
-                    {
-                        root.setItemDropIndicatorVisible(model.index + 1, true, true);
-                    }
+                    root.setItemDropIndicatorVisible(_targetIndex, true, !_isLastItem)
                 }
                 onExited: {
-                    if (_isLastItem)
-                    {
-                        root.setItemDropIndicatorVisible(model.index, false, false);
-                    }
-                    else
-                    {
-                        root.setItemDropIndicatorVisible(model.index + 1, false, true);
-                    }
+                    root.setItemDropIndicatorVisible(_targetIndex, false, !_isLastItem)
                 }
                 onDropped: {
-                    var delta = -1
-
-                    if(!drop.hasUrls)
-                        delta = drag.source.model.index - model.index
-
-                    if(delta === 0 || delta === 1)
+                    if(!isDropAcceptable(drop, _targetIndex))
                         return
 
-                    if (_isLastItem)
-                    {
-                        if (drop.hasUrls) {
-                            //force conversion to an actual list
-                            var urlList = []
-                            for ( var url in drop.urls)
-                                urlList.push(drop.urls[url])
-                            mainPlaylistController.insert(root.plmodel.count, urlList, false)
-                        } else {
-                            root.plmodel.moveItemsPost(root.plmodel.getSelection(), root.plmodel.count - 1)
-                        }
-                        root.setItemDropIndicatorVisible(model.index, false, false);
-                        drop.accept(Qt.IgnoreAction)
-                    }
-                    else
-                    {
-                        plitem.dropedMovedAt(model.index + 1, drop)
-                        root.setItemDropIndicatorVisible(model.index + 1, false, true);
-                    }
+                    plitem.dropedMovedAt(_targetIndex, drop)
+                    root.setItemDropIndicatorVisible(_targetIndex, false, !_isLastItem)
                 }
             }
         }
diff --git a/modules/gui/qt/playlist/qml/PlaylistDroppable.qml b/modules/gui/qt/playlist/qml/PlaylistDroppable.qml
new file mode 100644
index 0000000000..671990fb9f
--- /dev/null
+++ b/modules/gui/qt/playlist/qml/PlaylistDroppable.qml
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * 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 a0219e6271..4c3f313732 100644
--- a/modules/gui/qt/playlist/qml/PlaylistListView.qml
+++ b/modules/gui/qt/playlist/qml/PlaylistListView.qml
@@ -43,6 +43,25 @@ Widgets.NavigableFocusScope {
 
     signal setItemDropIndicatorVisible(int index, bool isVisible, bool top)
 
+    function isDropAcceptable(drop, index) {
+        return drop.hasUrls
+                || ((!!drop.source && (drop.source instanceof PlaylistDroppable))
+                     && drop.source.canInsertIntoPlaylist(index))
+    }
+
+    function acceptDrop(index, drop) {
+        if (!!drop.source && (drop.source instanceof PlaylistDroppable)) {
+            drop.source.insertIntoPlaylist(index)
+        } else if (drop.hasUrls) {
+            //force conversion to an actual list
+            var urlList = []
+            for ( var url in drop.urls)
+                urlList.push(drop.urls[url])
+            mainPlaylistController.insert(index, urlList, false)
+        }
+        drop.accept(Qt.IgnoreAction)
+    }
+
     VLCColors {id: vlcNightColors; state: "night"}
 
     function sortPL(key) {
@@ -71,6 +90,15 @@ Widgets.NavigableFocusScope {
 
             property int _scrollingDirection: 0
 
+            function insertIntoPlaylist(index) {
+                root.plmodel.moveItemsPre(root.plmodel.getSelection(), index)
+            }
+
+            function canInsertIntoPlaylist(index) {
+                var delta = model.index - index
+                return delta !== 0 && delta !== -1 && index !== model.index
+            }
+
             on_PosChanged: {
                 var dragItemY = root.mapToGlobal(dragItem._pos.x, dragItem._pos.y).y
                 var viewY     = root.mapToGlobal(view.x, view.y).y
@@ -421,7 +449,7 @@ Widgets.NavigableFocusScope {
                     DropArea {
                         anchors.fill: parent
                         onEntered: {
-                            if(!drag.hasUrls && drag.source.model.index === root.plmodel.count - 1)
+                            if(!root.isDropAcceptable(drag, root.plmodel.count))
                                 return
 
                             root.setItemDropIndicatorVisible(view.modelCount - 1, true, false);
@@ -432,20 +460,10 @@ Widgets.NavigableFocusScope {
                             root.setItemDropIndicatorVisible(view.modelCount - 1, false, false);
                         }
                         onDropped: {
-                            if(!drop.hasUrls && drop.source.model.index === root.plmodel.count - 1)
+                            if(!root.isDropAcceptable(drop, root.plmodel.count))
                                 return
-
-                            if (drop.hasUrls) {
-                                //force conversion to an actual list
-                                var urlList = []
-                                for ( var url in drop.urls)
-                                    urlList.push(drop.urls[url])
-                                mainPlaylistController.insert(root.plmodel.count, urlList, false)
-                            } else {
-                                root.plmodel.moveItemsPost(root.plmodel.getSelection(), root.plmodel.count - 1)
-                            }
+                            root.acceptDrop(root.plmodel.count, drop)
                             root.setItemDropIndicatorVisible(view.modelCount - 1, false, false);
-                            drop.accept()
                         }
                     }
                 }
@@ -516,17 +534,12 @@ Widgets.NavigableFocusScope {
                             }
                         }
 
+                        function isDropAcceptable(drop, index) {
+                            return root.isDropAcceptable(drop, index)
+                        }
+
                         onDropedMovedAt: {
-                            if (drop.hasUrls) {
-                                //force conversion to an actual list
-                                var urlList = []
-                                for ( var url in drop.urls)
-                                    urlList.push(drop.urls[url])
-                                mainPlaylistController.insert(target, urlList, false)
-                                drop.accept(Qt.IgnoreAction)
-                            } else {
-                                root.plmodel.moveItemsPre(root.plmodel.getSelection(), target)
-                            }
+                            root.acceptDrop(target, drop)
                         }
 
                         onHoveredChanged: {
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 88e183cce0..bb885ff60e 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -284,6 +284,7 @@
     </qresource>
     <qresource prefix="/playlist">
         <file alias="PLItem.qml">playlist/qml/PLItem.qml</file>
+        <file alias="PlaylistDroppable.qml">playlist/qml/PlaylistDroppable.qml</file>
         <file alias="PlaylistListView.qml">playlist/qml/PlaylistListView.qml</file>
         <file alias="PlaylistMenu.qml">playlist/qml/PlaylistMenu.qml</file>
         <file alias="PlaylistToolbar.qml">playlist/qml/PlaylistToolbar.qml</file>
diff --git a/modules/gui/qt/widgets/qml/DNDLabel.qml b/modules/gui/qt/widgets/qml/DNDLabel.qml
index d6e209245a..dfc0e0b8c7 100644
--- a/modules/gui/qt/widgets/qml/DNDLabel.qml
+++ b/modules/gui/qt/widgets/qml/DNDLabel.qml
@@ -22,22 +22,30 @@ import QtGraphicalEffects 1.0
 import org.videolan.vlc 0.1
 
 import "qrc:///widgets/" as Widgets
+import "qrc:///playlist/" as Playlist
 import "qrc:///style/"
 
-Rectangle {
+Playlist.PlaylistDroppable {
     property alias text: label.text
     property alias model: plitem.model
+    property alias color: bg.color
     property VLCColors _colors: VLCStyle.colors
 
     z: 1
     width:  plitem.visible ? plitem.width : label.width
     height: plitem.visible ? plitem.height : label.height
-    color: _colors.button
-    border.color : _colors.buttonBorder
-    radius: 6
     opacity: 0.75
     visible: false
 
+    Rectangle {
+        id: bg
+
+        anchors.fill: parent
+        color: _colors.button
+        border.color : _colors.buttonBorder
+        radius: 6
+    }
+
     Drag.active: visible
 
     property var count: 0
-- 
2.25.1



More information about the vlc-devel mailing list