[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