[vlc-devel] [PATCH 07/16] qml: handle drag&drop without using PLItemFooter

Fatih Uzunoglu fuzun54 at outlook.com
Wed Jul 29 23:04:30 CEST 2020


this patch also indirectly fixes drop indicator visible glitch that happens on the bottom of the last item
---
 modules/gui/qt/playlist/qml/PLItem.qml        | 84 ++++++++++++++-----
 .../gui/qt/playlist/qml/PlaylistListView.qml  | 39 +++++++--
 2 files changed, 98 insertions(+), 25 deletions(-)

diff --git a/modules/gui/qt/playlist/qml/PLItem.qml b/modules/gui/qt/playlist/qml/PLItem.qml
index 348babada2..805d24ec8d 100644
--- a/modules/gui/qt/playlist/qml/PLItem.qml
+++ b/modules/gui/qt/playlist/qml/PLItem.qml
@@ -62,11 +62,21 @@ Rectangle {
         onSetItemDropIndicatorVisible: {
             if (index === model.index)
             {
-                dropVisible = isVisible
+                if (top)
+                {
+                    // show top drop indicator bar
+                    dropVisible = isVisible
+                }
+                else
+                {
+                    // show bottom drop indicator bar
+                    bottomDropIndicator.visible = isVisible
+                }
             }
         }
     }
 
+    // top drop indicator bar
     Rectangle {
         z: 2
         width: parent.width
@@ -77,6 +87,24 @@ Rectangle {
         color: _colors.accent
     }
 
+    // bottom drop indicator bar
+    // only active when the item is the last item in the list
+    Loader {
+        id: bottomDropIndicator
+        active: model.index === root.plmodel.count - 1
+        visible: false
+
+        z: 2
+        width: parent.width
+        height: 1
+        anchors.top: parent.bottom
+        antialiasing: true
+
+        sourceComponent: Rectangle {
+            color: _colors.accent
+        }
+    }
+
     MouseArea {
         id: mouse
         anchors.fill: parent
@@ -258,45 +286,63 @@ Rectangle {
                 Layout.fillWidth: true
                 Layout.fillHeight: true
 
-                // not visible on the last item since PLItemFooter handles it
-                visible: model.index !== plitem.plmodel.count - 1
+                property bool _isLastItem : model.index === plitem.plmodel.count - 1
 
                 onEntered: {
                     var delta = drag.source.model.index - model.index
                     if(delta === 0 || delta === 1)
                         return
 
-
-                    root.setItemDropIndicatorVisible(model.index + 1, true, true);
+                    if (_isLastItem)
+                    {
+                        root.setItemDropIndicatorVisible(model.index, true, false);
+                    }
+                    else
+                    {
+                        root.setItemDropIndicatorVisible(model.index + 1, true, true);
+                    }
                 }
                 onExited: {
                     var delta = drag.source.model.index - model.index
                     if(delta === 0 || delta === 1)
                         return
 
-                    root.setItemDropIndicatorVisible(model.index + 1, false, true);
+                    if (_isLastItem)
+                    {
+                        root.setItemDropIndicatorVisible(model.index, false, false);
+                    }
+                    else
+                    {
+                        root.setItemDropIndicatorVisible(model.index + 1, false, true);
+                    }
                 }
                 onDropped: {
                     var delta = drag.source.model.index - model.index
                     if(delta === 0 || delta === 1)
                         return
 
-                    plitem.dropedMovedAt(model.index + 1, drop)
-                    root.setItemDropIndicatorVisible(model.index + 1, false, true);
+                    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)
+                        } else {
+                            root.plmodel.moveItemsPost(root.plmodel.getSelection(), root.plmodel.count - 1)
+                        }
+                        root.setItemDropIndicatorVisible(model.index, false, false);
+                        drop.accept()
+                    }
+                    else
+                    {
+                        plitem.dropedMovedAt(model.index + 1, drop)
+                        root.setItemDropIndicatorVisible(model.index + 1, false, true);
+                    }
                 }
             }
 
-            PLItemFooter {
-               Layout.fillWidth: true
-               Layout.fillHeight: true
-
-               visible: !lowerDropArea.visible
-
-               dropIndicatorBottom: true
-               onDropURLAtEnd: mainPlaylistController.insert(plitem.plmodel.count, urlList)
-               onMoveAtEnd: plitem.plmodel.moveItemsPost(plitem.plmodel.getSelection(), plitem.plmodel.count - 1)
-               listCount: plitem.plmodel.count
-            }
         }
     }
 }
diff --git a/modules/gui/qt/playlist/qml/PlaylistListView.qml b/modules/gui/qt/playlist/qml/PlaylistListView.qml
index 78e482b440..18458fd173 100644
--- a/modules/gui/qt/playlist/qml/PlaylistListView.qml
+++ b/modules/gui/qt/playlist/qml/PlaylistListView.qml
@@ -42,7 +42,7 @@ Widgets.NavigableFocusScope {
     property bool forceDark: false
     property VLCColors _colors: forceDark ? vlcNightColors : VLCStyle.colors
 
-    signal setItemDropIndicatorVisible(int index, bool isVisible)
+    signal setItemDropIndicatorVisible(int index, bool isVisible, bool top)
 
     VLCColors {id: vlcNightColors; state: "night"}
 
@@ -286,11 +286,38 @@ Widgets.NavigableFocusScope {
                     }
                 }
 
-                footer: PLItemFooter {
-                    z: 2
-                    onDropURLAtEnd: mainPlaylistController.insert(root.plmodel.count, urlList)
-                    onMoveAtEnd: root.plmodel.moveItemsPost(root.plmodel.getSelection(), root.plmodel.count - 1)
-                    listCount: view.modelCount
+                footer: DropArea {
+                    width: parent.width
+                    height: Math.max(VLCStyle.icon_normal, view.height - y)
+
+                    onEntered: {
+                        if(drag.source.model.index === root.plmodel.count - 1)
+                            return
+
+                        root.setItemDropIndicatorVisible(view.modelCount - 1, true, false);
+                    }
+                    onExited: {
+                        if(drag.source.model.index === root.plmodel.count - 1)
+                            return
+
+                        root.setItemDropIndicatorVisible(view.modelCount - 1, false, false);
+                    }
+                    onDropped: {
+                        if(drag.source.model.index === root.plmodel.count - 1)
+                            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)
+                        } else {
+                            root.plmodel.moveItemsPost(root.plmodel.getSelection(), root.plmodel.count - 1)
+                        }
+                        root.setItemDropIndicatorVisible(view.modelCount - 1, false, false);
+                        drop.accept()
+                    }
                 }
 
                 delegate: Column {
-- 
2.25.1



More information about the vlc-devel mailing list