[vlc-commits] [Git][videolan/vlc][master] 3 commits: qml: fix broken extent calculations in page change functions in `ListViewExt`

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Dec 18 13:25:20 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
2e6ed7b4 by Fatih Uzunoglu at 2025-12-18T12:47:16+00:00
qml: fix broken extent calculations in page change functions in `ListViewExt`

As noted in e45e98fe, the extents are not calculated correctly here.
It is tricky to calculate the extents properly directly in QML, but
based on evidence the following seems to be a good estimation:

MinimumY: (originY - topMargin)
MinimumX: (originX - leftMargin)
MaximumX: (originX + contentWidth - width + rightMargin)
MaximumY: (originY + contentHeight - height + bottomMargin)

This applies to flickable based views, too. However, these are only
estimates and not the absolute extents. The ideal approach would be
calling the virtual extent methods in `QQuickFlickable`:

```cpp
protected:
    virtual qreal minXExtent() const;
    virtual qreal minYExtent() const;
    virtual qreal maxXExtent() const;
    virtual qreal maxYExtent() const;
```

However, they are protected and not invokable, so it does not seem
possible to call them, at least directly in QML side.

- - - - -
3c36e6e2 by Fatih Uzunoglu at 2025-12-18T12:47:16+00:00
qml: introduce flickable extents estimation functions in `Helpers`

- - - - -
c473a205 by Fatih Uzunoglu at 2025-12-18T12:47:16+00:00
qml: use flickable content extent helpers

- - - - -


3 changed files:

- modules/gui/qt/medialibrary/qml/MusicArtist.qml
- modules/gui/qt/util/qml/Helpers.qml
- modules/gui/qt/widgets/qml/ListViewExt.qml


Changes:

=====================================
modules/gui/qt/medialibrary/qml/MusicArtist.qml
=====================================
@@ -73,6 +73,9 @@ FocusScope {
     })
 
     function navigationShowHeader(y, height) {
+        if (!(_currentView instanceof Flickable))
+            return
+
         const newContentY = Helpers.flickablePositionContaining(_currentView, y, height, 0, 0)
 
         if (newContentY !== _currentView.contentY)


=====================================
modules/gui/qt/util/qml/Helpers.qml
=====================================
@@ -121,9 +121,7 @@ QtObject {
         else
             newContentY = flickable.contentY
 
-        return clamp(newContentY,
-                     flickable.originY - flickable.topMargin,
-                     flickable.originY + flickable.contentHeight - flickable.height + flickable.bottomMargin)
+        return getFlickableBoundedContentY(flickable, newContentY)
     }
 
     function isArray(obj) {
@@ -152,8 +150,50 @@ QtObject {
         const mappedRect = flickable.mapFromItem(item.parent, Qt.rect(item.x, item.y, item.width, item.height))
         // Flickable does not fully contain the item:
         if ((mappedRect.y < 0) || ((mappedRect.y + mappedRect.height) > flickable.height))
-            flickable.contentY = Math.min(Math.max(flickable.originY - flickable.topMargin,
-                                                   flickable.contentItem.mapFromItem(item.parent, item.x, item.y).y - Math.max(0, ((flickable.height - item.height) / 2))),
-                                          flickable.originY + flickable.contentHeight - flickable.height + flickable.bottomMargin)
+            flickable.contentY = getFlickableBoundedContentY(flickable,
+                                                             flickable.contentItem.mapFromItem(item.parent, item.x, item.y).y -
+                                                             Math.max(0, ((flickable.height - item.height) / 2)))
     }
+
+    function getFlickableBoundedContentX(flickable: Flickable, contentX: real) : real {
+        console.assert(flickable)
+        return clamp(contentX,
+                     estimateFlickableMinXExtent(flickable),
+                     estimateFlickableMaxXExtent(flickable))
+    }
+
+    function getFlickableBoundedContentY(flickable: Flickable, contentY: real) : real {
+        console.assert(flickable)
+        return clamp(contentY,
+                     estimateFlickableMinYExtent(flickable),
+                     estimateFlickableMaxYExtent(flickable))
+    }
+
+    /// <flickable-extents>
+
+    // FIXME: Get rid of this in favor of `QQuickFlickable::minXExtent()`:
+    function estimateFlickableMinXExtent(flickable: Flickable) : real {
+        console.assert(flickable)
+        return (flickable.originX - flickable.leftMargin)
+    }
+
+    // FIXME: Get rid of this in favor of `QQuickFlickable::minYExtent()`:
+    function estimateFlickableMinYExtent(flickable: Flickable) : real {
+        console.assert(flickable)
+        return (flickable.originY - flickable.topMargin)
+    }
+
+    // FIXME: Get rid of this in favor of `QQuickFlickable::maxXExtent()`:
+    function estimateFlickableMaxXExtent(flickable: Flickable) : real {
+        console.assert(flickable)
+        return (flickable.originX + flickable.contentWidth - flickable.width + flickable.rightMargin)
+    }
+
+    // FIXME: Get rid of this in favor of `QQuickFlickable::maxYExtent()`:
+    function estimateFlickableMaxYExtent(flickable: Flickable) : real {
+        console.assert(flickable)
+        return (flickable.originY + flickable.contentHeight - flickable.height + flickable.bottomMargin)
+    }
+
+    /// </flickable-extents>
 }


=====================================
modules/gui/qt/widgets/qml/ListViewExt.qml
=====================================
@@ -466,11 +466,11 @@ ListView {
     }
 
     function nextPage() {
-        root.contentX += (Math.min(root.width, (root.contentWidth - root.width - root.contentX)))
+        root.contentX = Helpers.getFlickableBoundedContentX(root, root.contentX + root.width)
     }
 
     function prevPage() {
-        root.contentX -= Math.min(root.width,root.contentX - root.originX)
+        root.contentX = Helpers.getFlickableBoundedContentX(root, root.contentX - root.width)
     }
 
     // Add an indirection here because additional control



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/d9e29546dcd1b738946e58d899bb5aed7c283d0d...c473a20573dec0005f1e9032ad8ecf81faaac02e

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