[vlc-commits] [Git][videolan/vlc][master] 4 commits: qml: forward the delegate root to `TableRowDelegate`

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Jun 6 08:13:40 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
55176353 by Fatih Uzunoglu at 2025-06-06T07:59:52+00:00
qml: forward the delegate root to `TableRowDelegate`

- - - - -
8d93e1e6 by Fatih Uzunoglu at 2025-06-06T07:59:52+00:00
qml: signal `ItemView::reused()` and `::pooled()` in `ExpandGridView`

- - - - -
b55f09fe by Fatih Uzunoglu at 2025-06-06T07:59:52+00:00
qml: handle item reusing properly in `MediaCover`

The documentation advises to free resources when the item is
pooled. In this case, we do not know if the pooled item is
going to be reused with the same image, so I release the
image. I do not set the texts to empty, as any potential
resource consumption there is considered negligible, at
least for now.

The documentation also mandates to reset the delegate state
when the item is reused. In this case, there is not much to
reset because of declarative bindings. However, there is
`_loadTimeout` that needs to be reset, in addition to the
restoration of the broken bindings used to free the resources.

- - - - -
f71719de by Fatih Uzunoglu at 2025-06-06T07:59:52+00:00
qml: handle item reusing properly in `PlaylistDelegate`

The documentation advises to free resources when the item is
pooled. In this case, we do not know if the pooled item is
going to be reused with the same image, so I release the
image. I do not set the texts to empty, as any potential
resource consumption there is considered negligible, at
least for now.

The documentation also mandates to reset the delegate state
when the item is reused. In this case, there is not much to
reset because of declarative bindings. However, there is
`artwork.source` that needs to be reset, where the binding
may be broken due to the previous source could not be loaded
or to free resources when the item is pooled.

- - - - -


7 changed files:

- modules/gui/qt/playlist/qml/PlaylistDelegate.qml
- modules/gui/qt/widgets/qml/ExpandGridView.qml
- modules/gui/qt/widgets/qml/GridItem.qml
- modules/gui/qt/widgets/qml/MediaCover.qml
- modules/gui/qt/widgets/qml/TableColumns.qml
- modules/gui/qt/widgets/qml/TableRowDelegate.qml
- modules/gui/qt/widgets/qml/TableViewDelegateExt.qml


Changes:

=====================================
modules/gui/qt/playlist/qml/PlaylistDelegate.qml
=====================================
@@ -172,19 +172,37 @@ T.Control {
 
                 anchors.fill: parent
                 fillMode: Image.PreserveAspectFit
-                source: delegate.preparsed ? targetSource : ""
+                source: defaultSource
                 visible: !statusIcon.visible
                 asynchronous: true
 
                 readonly property url targetSource: (delegate?.artwork.toString()) ? VLCAccessImage.uri(delegate.artwork) : VLCStyle.noArtAlbumCover
+                readonly property url defaultSource: delegate.preparsed ? targetSource : ""
 
                 onStatusChanged: {
                     if (source !== VLCStyle.noArtAlbumCover && status === Image.Error)
                         source = VLCStyle.noArtAlbumCover
                 }
 
+                function resetSource() {
+                    artwork.source = Qt.binding(() => { return artwork.defaultSource })
+                    artworkTimer.running = Qt.binding(() => { return artworkTimer.defaultRunning })
+                }
+
+                function removeSource() {
+                    artworkTimer.running = false
+                    artwork.source = ""
+                }
+
+                Component.onCompleted: {
+                    delegate.ListView.reused.connect(artwork.resetSource)
+                    delegate.ListView.pooled.connect(artwork.removeSource)
+                }
+
                 Timer {
-                    running: (artwork.status === Image.Null)
+                    id: artworkTimer
+                    running: defaultRunning
+                    readonly property bool defaultRunning: (artwork.status === Image.Null)
                     interval: VLCStyle.duration_long
                     onTriggered: {
                         // Remove the preparse guard, enough time has passed:


=====================================
modules/gui/qt/widgets/qml/ExpandGridView.qml
=====================================
@@ -653,6 +653,8 @@ FocusScope {
         item.z = _indexToZ(id)
         item.visible = true
 
+        item.GridView.reused()
+
         _setItem(id, item)
 
         return item
@@ -972,6 +974,7 @@ FocusScope {
                     if (_shouldDelayRemove(item)) {
                         _delayRemove(i, item)
                     } else if (root.reuseItems) {
+                        item.GridView.pooled()
                         item.visible = false
                         root._unusedItemList.push(item)
                     } else {


=====================================
modules/gui/qt/widgets/qml/GridItem.qml
=====================================
@@ -294,6 +294,11 @@ T.ItemDelegate {
                 root.playClicked()
             }
 
+            Component.onCompleted: {
+                root.GridView.reused.connect(picture.reinitialize)
+                root.GridView.pooled.connect(picture.releaseResources)
+            }
+
             DefaultShadow {
                 id: unselectedShadow
 


=====================================
modules/gui/qt/widgets/qml/MediaCover.qml
=====================================
@@ -46,7 +46,7 @@ Item {
 
     property alias color: image.backgroundColor
 
-    property alias source: image.source
+    property url source
 
     property alias cacheImage: image.cache
 
@@ -81,6 +81,20 @@ Item {
     Accessible.role: Accessible.Graphic
     Accessible.name: qsTr("Media cover")
 
+    // If this type is used within a reusable delegate, connect `ItemView::reused()` to this function.
+    function reinitialize() {
+        _loadTimeout = false
+        fallbackImage.source = Qt.binding(() => { return fallbackImage.defaultSource })
+        image.source = Qt.binding(() => { return image.defaultSource })
+    }
+
+    // If this type is used within a reusable delegate, connect `ItemView::pooled()` to this function.
+    // NOTE: This does not override `QQuickItem::releaseResources()`.
+    function releaseResources() {
+        fallbackImage.source = ""
+        image.source = ""
+    }
+
     // Children
 
     //delay placeholder showing up
@@ -96,9 +110,12 @@ Item {
 
         anchors.fill: parent
 
+        source: defaultSource
         sourceSize: Qt.size(root.pictureWidth * root.eDPR,
                             root.pictureHeight * root.eDPR)
 
+        readonly property url defaultSource: root.source
+
         onStatusChanged: {
             if (status === Image.Loading) {
                 root._loadTimeout = false
@@ -126,7 +143,9 @@ Item {
 
         // we only keep this image till there is no main image
         // try to release the resources otherwise
-        source: visible ? root.fallbackImageSource : ""
+        source: defaultSource
+
+        readonly property url defaultSource: visible ? root.fallbackImageSource : ""
 
         sourceSize: Qt.size(root.pictureWidth * root.eDPR,
                             root.pictureHeight * root.eDPR)


=====================================
modules/gui/qt/widgets/qml/TableColumns.qml
=====================================
@@ -117,6 +117,12 @@ Item {
                 radius: root.titleCover_radius
                 color: titleDel.colorContext.bg.secondary
 
+                Component.onCompleted: {
+                    console.assert(titleDel.delegate)
+                    titleDel.delegate.ListView.reused.connect(cover.reinitialize)
+                    titleDel.delegate.ListView.pooled.connect(cover.releaseResources)
+                }
+
                 imageOverlay: Item {
                     width: cover.width
                     height: cover.height


=====================================
modules/gui/qt/widgets/qml/TableRowDelegate.qml
=====================================
@@ -29,4 +29,6 @@ Item {
     // so don't mark 'ColorContext' type here
     // see https://bugreports.qt.io/browse/QTBUG-125095
     required property var colorContext
+
+    required property Item delegate
 }


=====================================
modules/gui/qt/widgets/qml/TableViewDelegateExt.qml
=====================================
@@ -249,6 +249,7 @@ T.Control {
                             selected: Qt.binding(() => delegate.selected),
                             containsMouse: Qt.binding(() => delegate.hovered),
                             colorContext: Qt.binding(() => theme),
+                            delegate: delegate
                         }
                     )
                 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9a17271e123df1500f7dbc4e0e08b2eae7d8257a...f71719de8b279affe628036f58ebe69b025aeffd

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9a17271e123df1500f7dbc4e0e08b2eae7d8257a...f71719de8b279affe628036f58ebe69b025aeffd
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