[vlc-commits] [Git][videolan/vlc][master] 11 commits: qml: fix drag to undocked playlist

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Mon Oct 9 10:44:22 UTC 2023



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
62ae1982 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: fix drag to undocked playlist

use native drag

- - - - -
8d3a9349 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: remove glow and animation from dragitem

- - - - -
9446929a by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: remove manual position handling of dragItem

- - - - -
639900eb by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: remove drag scroll handler from listview

it's only used with Playlist

- - - - -
1b83eb24 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: allow drag item like object in DragAutoScrollHandler

- - - - -
29fc5b8b by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: expose drag position in PlaylistDelegate

- - - - -
06b3b367 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: use native dragging in PlayListlistView

this allows autscrolling with native drops

- - - - -
35a52b97 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: add icon_dragItem in VLCStyle

- - - - -
fc0e0fd7 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: improve dragitem visual

- - - - -
d113684c by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: remove title related properties from dragitem

- - - - -
2c29efb2 by Prince Gupta at 2023-10-09T10:25:12+00:00
qml: add fallback cover in drag item

- - - - -


14 changed files:

- modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
- modules/gui/qt/medialibrary/qml/MusicArtist.qml
- modules/gui/qt/medialibrary/qml/MusicArtistDelegate.qml
- modules/gui/qt/medialibrary/qml/MusicGenres.qml
- modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
- modules/gui/qt/network/qml/BrowseTreeDisplay.qml
- modules/gui/qt/playlist/qml/PlaylistDelegate.qml
- modules/gui/qt/playlist/qml/PlaylistListView.qml
- modules/gui/qt/style/VLCStyle.qml
- modules/gui/qt/util/qml/ViewDragAutoScrollHandler.qml
- modules/gui/qt/widgets/qml/DragItem.qml
- modules/gui/qt/widgets/qml/GridItem.qml
- modules/gui/qt/widgets/qml/KeyNavigableListView.qml
- modules/gui/qt/widgets/qml/TableViewDelegate.qml


Changes:

=====================================
modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
=====================================
@@ -61,7 +61,7 @@ MainInterface.MainViewLoader {
 
         mlModel: artistModel
         indexes: selectionModel.selectedIndexes
-        titleRole: "name"
+
         defaultCover: VLCStyle.noArtArtistSmall
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicArtist.qml
=====================================
@@ -494,8 +494,6 @@ FocusScope {
 
                 indexes: trackSelectionModel.selectedIndexes
 
-                titleRole: "name"
-
                 defaultCover: VLCStyle.noArtArtistCover
             }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicArtistDelegate.qml
=====================================
@@ -83,8 +83,6 @@ T.ItemDelegate {
         drag.target: Widgets.DragItem {
             indexes: [index]
 
-            titleRole: "name"
-
             onRequestData: {
                 console.assert(indexes[0] === index)
                 resolve([model])
@@ -105,13 +103,6 @@ T.ItemDelegate {
             dragItem.Drag.active = drag.active;
         }
 
-        onPressed: {
-            const pos = mapToItem(drag.target.parent, mouseX, mouseY);
-
-            drag.target.x = pos.x + VLCStyle.dragDelta;
-            drag.target.y = pos.y + VLCStyle.dragDelta;
-        }
-
         onClicked: itemClicked(mouse)
 
         onDoubleClicked: itemDoubleClicked(mouse)


=====================================
modules/gui/qt/medialibrary/qml/MusicGenres.qml
=====================================
@@ -80,8 +80,6 @@ MainInterface.MainViewLoader {
         mlModel: genreModel
 
         indexes: selectionModel.selectedIndexes
-
-        titleRole: "name"
     }
 
     /*


=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
=====================================
@@ -141,8 +141,6 @@ MainInterface.MainViewLoader {
         coverRole: "thumbnail"
 
         defaultCover: root._placeHolder
-
-        titleRole: "name"
     }
 
     PlaylistListContextMenu {


=====================================
modules/gui/qt/network/qml/BrowseTreeDisplay.qml
=====================================
@@ -95,8 +95,6 @@ MainInterface.MainViewLoader {
 
         indexes: selectionModel.selectedIndexes
 
-        titleRole: "name"
-
         defaultText:  I18n.qtr("Unknown Share")
 
         coverProvider: function(index, data) {


=====================================
modules/gui/qt/playlist/qml/PlaylistDelegate.qml
=====================================
@@ -44,6 +44,18 @@ T.ItemDelegate {
 
     readonly property bool containsDrag: (topContainsDrag || bottomContainsDrag)
 
+    // drag -> point
+    // current drag pos inside the item
+    readonly property point drag: {
+        if (!containsDrag)
+            return Qt.point(0, 0)
+
+        const d = topContainsDrag ? higherDropArea : lowerDropArea
+        const p = d.drag
+        return mapFromItem(d, p.x, p.y)
+    }
+
+
     // Optional
     property var contextMenu
 
@@ -288,14 +300,6 @@ T.ItemDelegate {
                 MainPlaylistController.goTo(index, true)
         }
 
-        onPressed: {
-            if (dragItem) {
-                const pos = mapToItem(dragItem.parent, mouseX, mouseY)
-                dragItem.x = pos.x + VLCStyle.dragDelta
-                dragItem.y = pos.y + VLCStyle.dragDelta
-            }
-        }
-
         drag.target: dragItem
 
         drag.smoothed: false


=====================================
modules/gui/qt/playlist/qml/PlaylistListView.qml
=====================================
@@ -25,6 +25,7 @@ import org.videolan.vlc 0.1
 import org.videolan.compat 0.1
 
 import "qrc:///widgets/" as Widgets
+import "qrc:///util" as Util
 import "qrc:///util/Helpers.js" as Helpers
 import "qrc:///style/"
 
@@ -284,11 +285,15 @@ T.Pane {
 
             model: root.model
 
-            dragAutoScrollDragItem: dragItem
 
             // NOTE: We want a gentle fade at the beginning / end of the playqueue.
             enableFade: true
 
+            enableBeginningFade: (autoScroller.scrollingDirection !== Util.ViewDragAutoScrollHandler.Direction.Backward)
+
+            enableEndFade: (autoScroller.scrollingDirection !== Util.ViewDragAutoScrollHandler.Direction.Forward)
+
+
             backgroundColor: root.background.usingAcrylic ? "transparent"
                                                           : listView.colorContext.bg.primary
 
@@ -319,6 +324,18 @@ T.Pane {
                 }
             }
 
+            Util.ViewDragAutoScrollHandler {
+                id: autoScroller
+
+                view: listView
+                dragging: !!listView.itemContainsDrag && listView.itemContainsDrag !== listView.footerItem
+                dragPosProvider: function () {
+                    const source = listView.itemContainsDrag
+                    const point = source.drag
+                    return listView.mapFromItem(source, point.x, point.y)
+                }
+            }
+
             footer: Item {
                 implicitWidth: parent.width
 
@@ -331,6 +348,8 @@ T.Pane {
 
                 readonly property bool containsDrag: dropArea.containsDrag
 
+                readonly property point drag: Qt.point(dropArea.drag.x, dropArea.drag.y)
+
                 onContainsDragChanged: {
                     if (root.model.count > 0) {
                         listView.updateItemContainsDrag(this, containsDrag)


=====================================
modules/gui/qt/style/VLCStyle.qml
=====================================
@@ -99,6 +99,7 @@ QtObject {
     readonly property int icon_large: dp(64, scale);
     readonly property int icon_xlarge: dp(128, scale);
 
+    readonly property int icon_dragItem: dp(32, scale);
     readonly property int icon_topbar: icon_normal
     readonly property int icon_toolbar: icon_normal
     readonly property int icon_audioPlayerButton: dp(32, scale)


=====================================
modules/gui/qt/util/qml/ViewDragAutoScrollHandler.qml
=====================================
@@ -24,8 +24,18 @@ QtObject {
     id: root
 
     property Flickable view: null
+
+    // if 'dragItem' is null, user must override property 'dragging' and 'dragPosProvider'
     property Item dragItem: null
 
+    property bool dragging: !!dragItem && dragItem.visible
+
+    property var dragPosProvider: function () {
+        return root.view.mapFromItem(root.dragItem.parent,
+                                     root.dragItem.x,
+                                     root.dragItem.y)
+    }
+
     property int orientation: (view && view.orientation !== undefined) ? view.orientation
                                                                        : Qt.Vertical
     property real margin: VLCStyle.dp(20)
@@ -61,15 +71,10 @@ QtObject {
                                                             : null
 
         readonly property int direction: {
-            if (!root.dragItem || !root.view)
-                return ViewDragAutoScrollHandler.Direction.None
-
-            if (!root.dragItem.visible || !root.view.visible)
+            if (!root.view || !root.view.visible || !root.dragging)
                 return ViewDragAutoScrollHandler.Direction.None
 
-            const pos = root.view.mapFromItem(root.dragItem.parent,
-                                            root.dragItem.x,
-                                            root.dragItem.y)
+            const pos = root.dragPosProvider()
 
             let size, mark, atBeginning, atEnd
             if (root.orientation === Qt.Vertical) {


=====================================
modules/gui/qt/widgets/qml/DragItem.qml
=====================================
@@ -25,6 +25,7 @@ import QtQml.Models 2.12
 import QtGraphicalEffects 1.12
 
 import org.videolan.vlc 0.1
+import org.videolan.controls 0.1
 
 import "qrc:///style/"
 import "qrc:///playlist/" as Playlist
@@ -38,7 +39,7 @@ Item {
     // Properties
     //---------------------------------------------------------------------------------------------
 
-    readonly property int coverSize: VLCStyle.icon_normal
+    readonly property int coverSize: VLCStyle.icon_dragItem
 
     property var indexes: []
 
@@ -52,11 +53,7 @@ Item {
     // string => role
     property string coverRole: "cover"
 
-    // function(index, data) - returns title text for the index in the model i.e <string> title
-    property var titleProvider: null
-
-    // string => role
-    property string titleRole: "title"
+    property real padding: VLCStyle.margin_xsmall
 
     readonly property ColorContext colorContext: ColorContext {
         id: theme
@@ -67,7 +64,7 @@ Item {
     signal requestInputItems(var indexes, var data, var resolve, var reject)
 
     function coversXPos(index) {
-        return VLCStyle.margin_small + (coverSize / 3) * index;
+        return VLCStyle.margin_small + (coverSize / 1.5) * index;
     }
 
     /**
@@ -89,7 +86,7 @@ Item {
     //---------------------------------------------------------------------------------------------
     // Private
 
-    readonly property int _maxCovers: 3
+    readonly property int _maxCovers: 10
 
     readonly property int _indexesSize: !!indexes ? indexes.length : 0
 
@@ -101,10 +98,12 @@ Item {
 
     property var _covers: []
 
-    property string _title: ""
-
     property int _currentRequest: 0
 
+    property int _grabImageRequest: 0
+
+    property bool _pendingNativeDragStart: false
+
     property var _dropPromise: null
     property var _dropCallback: null
     property var _dropFailedCallback: null
@@ -113,45 +112,52 @@ Item {
     // Implementation
     //---------------------------------------------------------------------------------------------
 
-    parent: g_mainDisplay
+    // always keep drag item out of view
+    z: -1
+
+    x: parent.width + VLCStyle.margin_large
 
-    width: VLCStyle.colWidth(2)
+    y: parent.height + VLCStyle.margin_large
 
-    height: coverSize + VLCStyle.margin_small * 2
+    visible: false
 
-    opacity: visible ? 0.90 : 0
+    Drag.dragType: Drag.None
 
-    visible: Drag.active
-    enabled: visible
+    Drag.hotSpot.x: - VLCStyle.dragDelta
+
+    Drag.hotSpot.y: - VLCStyle.dragDelta
+
+    parent: g_mainDisplay
+
+    width: padding * 2
+           + coversXPos(_displayedCoversCount - 1) + coverSize + VLCStyle.margin_small
+           + subtitleLabel.width
+
+    height: coverSize + padding * 2
+
+    enabled: false
 
     function _setData(data) {
         console.assert(data.length === indexes.length)
         _data = data
 
         const covers = []
-        const titleList = []
 
         for (let i in indexes) {
             if (covers.length === _maxCovers)
                 break
 
             const cover = _getCover(indexes[i], data[i])
-            const itemTitle = _getTitle(indexes[i], data[i])
-            if (!cover || !itemTitle)
+            if (!cover)
                 continue
 
             covers.push(cover)
-            titleList.push(itemTitle)
         }
 
         if (covers.length === 0)
             covers.push({artwork: dragItem.defaultCover})
 
-        if (titleList.length === 0)
-            titleList.push(defaultText)
-
         _covers = covers
-        _title = titleList.join(",") + (indexes.length > _maxCovers ? "..." : "")
     }
 
     function _setInputItems(inputItems) {
@@ -172,12 +178,34 @@ Item {
             return {artwork: data[dragItem.coverRole] || dragItem.defaultCover}
     }
 
-    function _getTitle(index, data) {
-        console.assert(dragItem.titleRole)
-        if (!!dragItem.titleProvider)
-            return dragItem.titleProvider(index, data)
-        else
-            return data[dragItem.titleRole] || dragItem.defaultText
+    function _startNativeDrag() {
+        if (!_pendingNativeDragStart)
+            return
+
+        _pendingNativeDragStart = false
+
+        const requestId = ++dragItem._grabImageRequest
+
+        visible = true
+
+        const s = dragItem.grabToImage(function (result) {
+            visible = false
+
+            if (requestId !== dragItem._grabImageRequest
+                    || fsmDragInactive.active)
+                return
+
+            dragItem.Drag.imageSource = result.url
+            dragItem.Drag.startDrag()
+        })
+
+        if (!s) {
+            // reject all pending requests
+            ++dragItem._grabImageRequest
+
+            dragItem.Drag.imageSource = ""
+            dragItem.Drag.startDrag()
+        }
     }
 
     //NoRole because I'm not sure we need this to be accessible
@@ -187,16 +215,24 @@ Item {
 
     Drag.onActiveChanged: {
         if (Drag.active) {
+            // reject all pending requests
+            ++dragItem._grabImageRequest
+            _pendingNativeDragStart = true
+
             fsm.startDrag()
         } else {
             fsm.stopDrag()
         }
     }
 
-    Behavior on opacity {
-        NumberAnimation {
-            easing.type: Easing.InOutSine
-            duration: VLCStyle.duration_short
+    Timer {
+        // used to start the drag if it's taking too much time to load data
+        id: nativeDragStarter
+
+        interval: 50
+        running: _pendingNativeDragStart
+        onTriggered: {
+            dragItem._startNativeDrag()
         }
     }
 
@@ -225,7 +261,8 @@ Item {
             id: fsmDragInactive
 
             function enter() {
-                _title = ""
+                _pendingNativeDragStart = false
+
                 _covers = []
                 _data = []
             }
@@ -246,6 +283,9 @@ Item {
 
             function exit() {
                 MainCtx.restoreCursor()
+
+                _pendingNativeDragStart = false
+
                 if (dragItem._dropFailedCallback) {
                     dragItem._dropFailedCallback()
                 }
@@ -308,6 +348,8 @@ Item {
                 id: fsmLoadingDone
 
                 function enter() {
+                    dragItem._startNativeDrag()
+
                     if (dragItem._dropCallback) {
                         dragItem._dropCallback(dragItem._inputItems)
                     }
@@ -320,6 +362,8 @@ Item {
             Util.FSMState {
                 id: fsmLoadingFailed
                 function enter() {
+                    _pendingNativeDragStart = false
+
                     if (dragItem._dropFailedCallback) {
                         dragItem._dropFailedCallback()
                     }
@@ -340,14 +384,6 @@ Item {
         radius: VLCStyle.dp(6, VLCStyle.scale)
     }
 
-    RectangularGlow {
-        anchors.fill: parent
-        glowRadius: VLCStyle.dp(8, VLCStyle.scale)
-        color: theme.shadow
-        spread: 0.2
-        z: -1
-    }
-
     Repeater {
         id: coverRepeater
 
@@ -355,7 +391,7 @@ Item {
 
         Item {
             x: dragItem.coversXPos(index)
-            y: (dragItem.height - height) / 2
+            anchors.verticalCenter: parent.verticalCenter
             width: dragItem.coverSize
             height: dragItem.coverSize
 
@@ -384,12 +420,28 @@ Item {
                 }
             }
 
+            RoundImage {
+                id: fallbackCover
+
+                anchors.centerIn: parent
+                width: coverSize
+                height: coverSize
+                radius: bg.radius
+                source: dragItem.defaultCover
+                visible: !loader.visible
+            }
 
             Loader {
+                id: loader
+
                 // parent may provide extra data with covers
                 property var model: modelData
 
                 anchors.centerIn: parent
+
+                visible: (status === Loader.Ready)
+                         && (!("status" in item) || (item.status === Image.Ready))
+
                 sourceComponent: (!modelData.artwork || modelData.artwork.toString() === "") ? modelData.cover : artworkLoader
                 layer.enabled: true
                 layer.effect: OpacityMask {
@@ -422,7 +474,7 @@ Item {
         id: extraCovers
 
         x: dragItem.coversXPos(_maxCovers)
-        y: (dragItem.height - height) / 2
+        anchors.verticalCenter: parent.verticalCenter
         width: dragItem.coverSize
         height: dragItem.coverSize
         radius: dragItem.coverSize
@@ -432,8 +484,14 @@ Item {
         border.color: theme.border
 
         MenuLabel {
-            anchors.centerIn: parent
+            anchors.fill: parent
+
+            verticalAlignment: Text.AlignVCenter
+            horizontalAlignment: Text.AlignHCenter
+            font.pixelSize: VLCStyle.fontSize_small
+
             color: theme.accent
+
             text: "+" + (dragItem._indexesSize - dragItem._maxCovers)
         }
 
@@ -454,41 +512,15 @@ Item {
     }
 
 
-    Column {
-        id: labelColumn
+    MenuCaption {
+        id: subtitleLabel
 
         anchors.verticalCenter: parent.verticalCenter
         x: dragItem.coversXPos(_displayedCoversCount - 1) + dragItem.coverSize + VLCStyle.margin_small
-        width: parent.width - x - VLCStyle.margin_small
-        spacing: VLCStyle.margin_xxxsmall
-
-        ScrollingText {
-            label: titleLabel
-            height: VLCStyle.fontHeight_large
-            width: parent.width
 
-            clip: scrolling
-            forceScroll: dragItem.visible
-            hoverScroll: false
-
-            T.Label {
-                id: titleLabel
-
-                text: dragItem._title
-                visible: text && text !== ""
-                font.pixelSize: VLCStyle.fontSize_large
-                color: theme.fg.primary
-            }
-        }
-
-        MenuCaption {
-            id: subtitleLabel
-
-            visible: text && text !== ""
-            width: parent.width
-            text: I18n.qtr("%1 selected").arg(dragItem._indexesSize)
-            color: theme.fg.secondary
-        }
+        visible: text && text !== ""
+        text: I18n.qtr("%1 selected").arg(dragItem._indexesSize)
+        color: theme.fg.secondary
     }
 
     Component {
@@ -498,7 +530,6 @@ Item {
             fillMode: Image.PreserveAspectCrop
             width: coverSize
             height: coverSize
-            asynchronous: true
             cache: false
         }
     }


=====================================
modules/gui/qt/widgets/qml/GridItem.qml
=====================================
@@ -205,13 +205,6 @@ T.ItemDelegate {
 
         onPressed: {
             _modifiersOnLastPress = mouse.modifiers
-
-            if (!drag.target)
-                return
-
-            const pos = mapToItem(drag.target.parent, mouseX, mouseY)
-            drag.target.x = pos.x + VLCStyle.dragDelta
-            drag.target.y = pos.y + VLCStyle.dragDelta
         }
 
         drag.onActiveChanged: {


=====================================
modules/gui/qt/widgets/qml/KeyNavigableListView.qml
=====================================
@@ -53,10 +53,6 @@ FadingEdgeListView {
     property alias buttonLeft: buttonLeft
     property alias buttonRight: buttonRight
 
-    property alias dragAutoScrollDragItem: dragAutoScrollHandler.dragItem
-    property alias dragAutoScrollMargin: dragAutoScrollHandler.margin
-    property alias dragAutoScrolling: dragAutoScrollHandler.scrolling
-
     // Signals
 
     signal selectionUpdated(int keyModifiers, int oldIndex, int newIndex)
@@ -96,14 +92,6 @@ FadingEdgeListView {
     section.criteria: ViewSection.FullString
     section.delegate: sectionHeading
 
-    enableBeginningFade: (enableFade && dragAutoScrollHandler.scrollingDirection
-                                        !==
-                                        Util.ViewDragAutoScrollHandler.Backward)
-
-    enableEndFade: (enableFade && dragAutoScrollHandler.scrollingDirection
-                                  !==
-                                  Util.ViewDragAutoScrollHandler.Forward)
-
     Accessible.role: Accessible.List
 
     // Events
@@ -290,12 +278,6 @@ FadingEdgeListView {
         }
     }
 
-    Util.ViewDragAutoScrollHandler {
-        id: dragAutoScrollHandler
-
-        view: root
-    }
-
     Util.FlickableScrollHandler { }
 
     // FIXME: This is probably not useful anymore.


=====================================
modules/gui/qt/widgets/qml/TableViewDelegate.qml
=====================================
@@ -131,14 +131,6 @@ T.Control {
 
             onPressed: {
                 _modifiersOnLastPress = mouse.modifiers
-
-                if (!drag.target)
-                    return
-
-                const pos = mapToItem(drag.target.parent, mouseX, mouseY);
-
-                drag.target.x = pos.x + VLCStyle.dragDelta;
-                drag.target.y = pos.y + VLCStyle.dragDelta;
             }
 
             onClicked: {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e380c2a8261d1c368c963a6cc41827dcde25f6ac...2c29efb24f75527eadf39447899a041c7fbeeb85

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e380c2a8261d1c368c963a6cc41827dcde25f6ac...2c29efb24f75527eadf39447899a041c7fbeeb85
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list