[vlc-commits] [Git][videolan/vlc][master] 2 commits: qml: introduce FadingEdgeListView

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Sep 4 08:24:32 UTC 2022



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


Commits:
caf27c28 by Fatih Uzunoglu at 2022-09-04T08:07:37+00:00
qml: introduce FadingEdgeListView

- - - - -
5d93b442 by Fatih Uzunoglu at 2022-09-04T08:07:37+00:00
qml: use FadingEdgeListView in KeyNavigableListView

- - - - -


7 changed files:

- modules/gui/qt/Makefile.am
- modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
- modules/gui/qt/playlist/qml/PlaylistListView.qml
- modules/gui/qt/vlc.qrc
- + modules/gui/qt/widgets/qml/FadingEdgeListView.qml
- modules/gui/qt/widgets/qml/KeyNavigableListView.qml
- modules/gui/qt/widgets/qml/KeyNavigableTableView.qml


Changes:

=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -1004,7 +1004,8 @@ libqt_plugin_la_QML = \
 	gui/qt/widgets/qml/OverlayMenu.qml \
 	gui/qt/widgets/qml/ToolTipExt.qml \
 	gui/qt/widgets/qml/DropShadowImage.qml \
-	gui/qt/widgets/qml/DoubleShadow.qml
+	gui/qt/widgets/qml/DoubleShadow.qml \
+	gui/qt/widgets/qml/FadingEdgeListView.qml
 
 lib_qt_plugin_la_QRC = gui/qt/vlc.qrc
 


=====================================
modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
=====================================
@@ -95,8 +95,6 @@ FocusScope {
 
             focus: true
 
-            fadeColor: VLCStyle.colors.bg
-
             Navigation.parentItem: root
 
             visible: listView.count > 0


=====================================
modules/gui/qt/playlist/qml/PlaylistListView.qml
=====================================
@@ -300,9 +300,6 @@ Control {
 
             dragAutoScrollDragItem: dragItem
 
-            fadeColor: background.usingAcrylic ? undefined
-                                               : background.alternativeColor
-
             property int shiftIndex: -1
 
             property Item itemContainsDrag: null


=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -210,6 +210,7 @@
         <file alias="ScaledImage.qml">widgets/qml/ScaledImage.qml</file>
         <file alias="DropShadowImage.qml">widgets/qml/DropShadowImage.qml</file>
         <file alias="DoubleShadow.qml">widgets/qml/DoubleShadow.qml</file>
+        <file alias="FadingEdgeListView.qml">widgets/qml/FadingEdgeListView.qml</file>
     </qresource>
     <qresource prefix="/network">
         <file alias="AddressbarButton.qml">network/qml/AddressbarButton.qml</file>


=====================================
modules/gui/qt/widgets/qml/FadingEdgeListView.qml
=====================================
@@ -0,0 +1,233 @@
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+import QtQuick 2.11
+
+import org.videolan.compat 0.1
+
+import "qrc:///style/"
+import "qrc:///util/Helpers.js" as Helpers
+
+ListView {
+    id: root
+
+    property bool disableBeginningFade: false
+    property bool disableEndFade: false
+
+    property real fadeSize: root.delegateItem
+                           ? (orientation === Qt.Vertical ? root.delegateItem.height
+                                                          : root.delegateItem.width) / 2
+                           : (VLCStyle.margin_large * 2)
+
+    readonly property bool transitionsRunning: ((add ? add.running : false) ||
+                                                (addDisplaced ? addDisplaced.running : false) ||
+                                                (populate ? populate.running : false) ||
+                                                (remove ? remove.running : false) ||
+                                                (removeDisplaced ? removeDisplaced.running : false))
+
+    // TODO: Use itemAtIndex(0) Qt >= 5.13
+    // FIXME: Delegate with variable size
+    readonly property Item delegateItem: root.contentItem.children.length > 0
+                                         ? root.contentItem.children[root.contentItem.children.length - 1]
+                                         : null
+
+    readonly property Item firstVisibleItem: {
+        if (transitionsRunning || !delegateItem)
+            return null
+
+        var margin = 0 // -root.displayMarginBeginning
+        if (orientation === Qt.Vertical) {
+            if (headerItem && headerItem.visible && headerPositioning === ListView.OverlayHeader)
+                margin += headerItem.height
+
+            return itemAt(contentX + (delegateItem.x + delegateItem.width / 2), contentY + margin)
+        } else {
+            if (headerItem && headerItem.visible && headerPositioning === ListView.OverlayHeader)
+                margin += headerItem.width
+
+            return itemAt(contentX + margin, contentY + (delegateItem.y + delegateItem.height / 2))
+        }
+    }
+
+    readonly property Item lastVisibleItem: {
+        if (transitionsRunning || !delegateItem)
+            return null
+
+        var margin = 0 // -root.displayMarginEnd
+        if (orientation === Qt.Vertical) {
+            if (footerItem && footerItem.visible && footerPositioning === ListView.OverlayFooter)
+                margin += footerItem.height
+
+            return itemAt(contentX + (delegateItem.x + delegateItem.width / 2), contentY + height - margin - 1)
+        } else {
+            if (footerItem && footerItem.visible && footerPositioning === ListView.OverlayFooter)
+                margin += footerItem.width
+
+            return itemAt(contentX + width - margin - 1, contentY + (delegateItem.y + delegateItem.height / 2))
+        }
+    }
+
+    readonly property bool _fadeRectEnoughSize: (root.orientation === Qt.Vertical
+                                                 ? root.height
+                                                 : root.width) > (fadeSize * 2 + VLCStyle.dp(25))
+
+    readonly property bool _beginningFade: !disableBeginningFade &&
+                                           _fadeRectEnoughSize &&
+                                           (orientation === ListView.Vertical ? !atYBeginning
+                                                                              : !atXBeginning) &&
+                                           (!firstVisibleItem ||
+                                           (!firstVisibleItem.activeFocus &&
+                                            !Helpers.get(firstVisibleItem, "hovered", false)))
+
+    readonly property bool _endFade:       !disableEndFade &&
+                                           _fadeRectEnoughSize &&
+                                           (orientation === ListView.Vertical ? !atYEnd
+                                                                              : !atXEnd) &&
+                                           (!lastVisibleItem ||
+                                           (!lastVisibleItem.activeFocus &&
+                                            !Helpers.get(lastVisibleItem, "hovered", false)))
+
+    // If Qt < 5.14, have to force clip enable,
+    // because we can not dictate the reused
+    // one to always have a binding assigned
+    // to clip property.
+    Component.onCompleted: {
+        if (!(clipBinding.restoreMode === 3 /* RestoreBindingOrValue */)) {
+            clip = Qt.binding(function() { return true })
+        }
+    }
+
+    // When the effect is active,
+    // it will clip inherently.
+    // So the parent does not need
+    // clipping enabled.
+    BindingCompat on clip {
+        id: clipBinding
+        when: proxyContentItem.visible
+        value: false
+    }
+
+    ShaderEffectSource {
+        id: proxyContentItem
+
+        visible: (root._beginningFade || root._endFade) ||
+                 (layer.effect.beginningFadeSize > 0 || layer.effect.endFadeSize > 0)
+
+        BindingCompat on visible {
+            // Let's see if the effect is compatible...
+            value: false
+            when: proxyContentItem.effectCompatible
+        }
+
+        readonly property bool effectCompatible: !(((GraphicsInfo.shaderType === GraphicsInfo.GLSL)) &&
+                                                  ((GraphicsInfo.shaderSourceType & GraphicsInfo.ShaderSourceString)))
+
+        anchors.fill: parent
+
+        z: root.contentItem.z
+
+        sourceItem: root.contentItem
+
+        sourceRect: Qt.rect(root.contentX,
+                            root.contentY,
+                            root.width,
+                            root.height)
+
+        // Make sure contentItem is not rendered twice:
+        hideSource: visible
+
+        layer.enabled: true
+        layer.effect: ShaderEffect {
+            // It makes sense to use the effect for only in the fading part.
+            // However, it would complicate things in the QML side. As it
+            // would require two additional items, as well as two more texture
+            // allocations.
+            // Given the shading done here is not complex, this is not done.
+            // Applying the texture and the effect is done in one step.
+
+            id: effect
+
+            readonly property bool vertical: (root.orientation === Qt.Vertical)
+            readonly property real normalFadeSize: root.fadeSize / (vertical ? height : width)
+
+            property real beginningFadeSize: root._beginningFade ? normalFadeSize : 0
+            property real endFadeSize: root._endFade ? normalFadeSize : 0
+            readonly property real endFadePos: 1.0 - endFadeSize
+
+            // TODO: Qt >= 5.15 use inline component
+            Behavior on beginningFadeSize {
+                // Qt Bug: UniformAnimator does not work...
+                NumberAnimation {
+                    duration: VLCStyle.duration_veryShort
+                    easing.type: Easing.InOutSine
+                }
+            }
+
+            Behavior on endFadeSize {
+                // Qt Bug: UniformAnimator does not work...
+                NumberAnimation {
+                    duration: VLCStyle.duration_veryShort
+                    easing.type: Easing.InOutSine
+                }
+            }
+
+            // Atlas textures can be supported
+            // but in this use case it is not
+            // necessary as the layer texture
+            // can not be placed in the atlas.
+            supportsAtlasTextures: false
+
+            vertexShader: " uniform highp mat4 qt_Matrix;
+
+                            attribute highp vec4 qt_Vertex;
+                            attribute highp vec2 qt_MultiTexCoord0;
+
+                            varying highp vec2 coord;
+                            varying highp float pos; // x or y component of coord depending on orientation
+
+                            void main() {
+                                coord = qt_MultiTexCoord0;
+
+                                pos = qt_MultiTexCoord0.%1;
+
+                                gl_Position = qt_Matrix * qt_Vertex;
+                            } ".arg(vertical ? "y" : "x")
+
+            fragmentShader: " uniform lowp sampler2D source;
+                              uniform lowp float qt_Opacity;
+
+                              uniform highp float beginningFadeSize;
+                              uniform highp float endFadePos;
+
+                              varying highp vec2 coord;
+                              varying highp float pos;
+
+                              void main() {
+                                  lowp vec4 texel = texture2D(source, coord);
+
+                                  // Note that the whole texel is multiplied instead
+                                  // of only the alpha component because it must be
+                                  // in premultiplied alpha format.
+                                  texel *= (1.0 - smoothstep(endFadePos, 1.0, pos));
+                                  texel *= (smoothstep(0.0, beginningFadeSize, pos));
+
+                                  // We still need to respect the accumulated scene graph opacity:
+                                  gl_FragColor = texel * qt_Opacity;
+                              } "
+        }
+    }
+}


=====================================
modules/gui/qt/widgets/qml/KeyNavigableListView.qml
=====================================
@@ -25,18 +25,11 @@ import "qrc:///style/"
 import "qrc:///util/" as Util
 import "qrc:///util/Helpers.js" as Helpers
 
-ListView {
+FadingEdgeListView {
     id: root
 
     // Properties
 
-    property int fadeSize: root.delegateItem
-                           ? (orientation === Qt.Vertical ? root.delegateItem.height
-                                                          : root.delegateItem.width) / 2
-                           : (VLCStyle.margin_large * 2)
-
-    property var fadeColor: undefined // fading will only work when fade color is defined
-
     // NOTE: We want buttons to be centered vertically but configurable.
     property int buttonMargin: height / 2 - buttonLeft.height / 2
 
@@ -44,54 +37,6 @@ ListView {
 
     property bool keyNavigationWraps : false
 
-    // TODO: Use itemAtIndex(0) Qt >= 5.13
-    // FIXME: Delegate with variable size
-    readonly property Item delegateItem: root.contentItem.children.length > 0
-                                         ? root.contentItem.children[root.contentItem.children.length - 1]
-                                         : null
-
-    readonly property bool transitionsRunning: ((root.add ? root.add.running : false) ||
-                                                (root.addDisplaced ? root.addDisplaced.running : false) ||
-                                                (root.populate ? root.populate.running : false) ||
-                                                (root.remove ? root.remove.running : false) ||
-                                                (root.removeDisplaced ? root.removeDisplaced.running : false))
-
-    readonly property Item firstVisibleItem: {
-        if (transitionsRunning || !delegateItem)
-            return null
-
-        var margin = -root.displayMarginBeginning
-        if (orientation === Qt.Vertical) {
-            if (headerItem && headerItem.visible && headerPositioning === ListView.OverlayHeader)
-                margin += headerItem.height
-
-            return itemAt(contentX + (delegateItem.x + delegateItem.width / 2), contentY + margin)
-        } else {
-            if (headerItem && headerItem.visible && headerPositioning === ListView.OverlayHeader)
-                margin += headerItem.width
-
-            return itemAt(contentX + margin, contentY + (delegateItem.y + delegateItem.height / 2))
-        }
-    }
-
-    readonly property Item lastVisibleItem: {
-        if (transitionsRunning || !delegateItem)
-            return null
-
-        var margin = -root.displayMarginEnd
-        if (orientation === Qt.Vertical) {
-            if (footerItem && footerItem.visible && footerPositioning === ListView.OverlayFooter)
-                margin += footerItem.height
-
-            return itemAt(contentX + (delegateItem.x + delegateItem.width / 2), contentY + height - margin - 1)
-        } else {
-            if (footerItem && footerItem.visible && footerPositioning === ListView.OverlayFooter)
-                margin += footerItem.width
-
-            return itemAt(contentX + width - margin - 1, contentY + (delegateItem.y + delegateItem.height / 2))
-        }
-    }
-
     // Private
 
     property bool _keyPressed: false
@@ -124,9 +69,6 @@ ListView {
 
     property int _currentFocusReason: Qt.OtherFocusReason
 
-    readonly property bool _fadeRectEnoughSize: (root.orientation === Qt.Vertical
-                                                 ? root.height
-                                                 : root.width) > (fadeSize * 2 + VLCStyle.dp(25))
 
     // Settings
 
@@ -192,6 +134,9 @@ ListView {
     // NOTE: We always want a valid 'currentIndex' by default.
     onCountChanged: if (count && currentIndex === -1) currentIndex = 0
 
+    disableBeginningFade: (dragAutoScrollHandler.scrollingDirection === Util.ViewDragAutoScrollHandler.Backward)
+    disableEndFade: (dragAutoScrollHandler.scrollingDirection === Util.ViewDragAutoScrollHandler.Forward)
+
     Keys.onPressed: {
         var newIndex = -1
 
@@ -335,156 +280,6 @@ ListView {
         }
     }
 
-    // TODO: Make fade rectangle inline component when Qt >= 5.15
-    LinearGradient {
-        id: fadeRectStart
-
-        anchors {
-            top: parent.top
-            left: parent.left
-            right: root.orientation === Qt.Vertical ? parent.right : undefined
-            bottom: root.orientation === Qt.Horizontal ? root.bottom : undefined
-            topMargin: root.orientation === Qt.Vertical ? ((root.headerItem &&
-                                                            root.headerItem.visible &&
-                                                            (root.headerPositioning === ListView.OverlayHeader)) ? root.headerItem.height
-                                                                                                                 : 0) - root.displayMarginBeginning
-                                                        : 0
-            leftMargin: root.orientation === Qt.Horizontal ? ((root.headerItem &&
-                                                               root.headerItem.visible &&
-                                                               (root.headerPositioning === ListView.OverlayHeader)) ? root.headerItem.width
-                                                                                                                    : 0) - root.displayMarginBeginning
-                                                           : 0
-        }
-
-        implicitHeight: fadeSize
-        implicitWidth: fadeSize
-
-        visible: (opacity !== 0.0)
-        opacity: 0.0
-
-        readonly property bool requestShow: !root.firstVisibleItem ||
-                                            (!root.firstVisibleItem.activeFocus &&
-                                             // TODO: Qt >5.12 use HoverHandler within the fade:
-                                             !Helpers.get(root.firstVisibleItem, "hovered", false)) &&
-                                            (dragAutoScrollHandler.scrollingDirection !== Util.ViewDragAutoScrollHandler.Backward)
-
-        state: (!!root.fadeColor &&
-                root._fadeRectEnoughSize &&
-                requestShow &&
-                (orientation === ListView.Vertical ? !root.atYBeginning
-                                                   : !root.atXBeginning)) ? "shown"
-                                                                          : ""
-
-        states: State {
-            name: "shown"
-            PropertyChanges {
-                target: fadeRectStart
-                opacity: 1.0
-            }
-        }
-
-        transitions: Transition {
-            from: ""; to: "shown"
-            reversible: true
-
-            NumberAnimation {
-                property: "opacity"
-                duration: VLCStyle.duration_short
-                easing.type: Easing.InOutSine
-            }
-        }
-
-        start: Qt.point(0, 0)
-
-        end: {
-            if (root.orientation === ListView.Vertical) {
-                return Qt.point(0, fadeRectStart.height)
-            } else {
-                return Qt.point(fadeRectStart.width, 0)
-            }
-        }
-
-        gradient: Gradient {
-            GradientStop { position: 0.0; color: !!fadeColor ? fadeColor : "transparent" }
-            GradientStop { position: 1.0; color: "transparent" }
-        }
-    }
-
-    LinearGradient {
-        id: fadeRectEnd
-
-        anchors {
-            top: root.orientation === Qt.Horizontal ? parent.top : undefined
-            left: root.orientation === Qt.Vertical ? parent.left : undefined
-            right: parent.right
-            bottom: parent.bottom
-
-            bottomMargin: root.orientation === Qt.Vertical ? ((root.footerItem &&
-                                                               root.footerItem.visible &&
-                                                               (root.footerPositioning === ListView.OverlayFooter)) ? root.footerItem.height
-                                                                                                                    : 0) - root.displayMarginEnd
-                                                           : 0
-            rightMargin: root.orientation === Qt.Horizontal ? ((root.footerItem &&
-                                                                root.footerItem.visible &&
-                                                                (root.headerPositioning === ListView.OverlayFooter)) ? root.footerItem.width
-                                                                                                                     : 0) - root.displayMarginEnd
-                                                            : 0
-        }
-
-        implicitHeight: fadeSize
-        implicitWidth: fadeSize
-
-        visible: opacity !== 0.0
-        opacity: 0.0
-
-        readonly property bool requestShow: !root.lastVisibleItem ||
-                                            (!root.lastVisibleItem.activeFocus &&
-                                             // TODO: Qt >5.12 use HoverHandler within the fade:
-                                             !Helpers.get(root.lastVisibleItem, "hovered", false)) &&
-                                            (dragAutoScrollHandler.scrollingDirection !== Util.ViewDragAutoScrollHandler.Forward)
-
-        state: (!!root.fadeColor &&
-                root._fadeRectEnoughSize &&
-                requestShow &&
-                (orientation === ListView.Vertical ? !root.atYEnd
-                                                   : !root.atXEnd)) ? "shown"
-                                                                    : ""
-
-        states: State {
-            name: "shown"
-            PropertyChanges {
-                target: fadeRectEnd
-                opacity: 1.0
-            }
-        }
-
-        transitions: Transition {
-            from: ""; to: "shown"
-            reversible: true
-
-            NumberAnimation {
-                property: "opacity"
-                duration: VLCStyle.duration_short
-                easing.type: Easing.InOutSine
-            }
-        }
-
-        start: Qt.point(0, 0)
-
-        end: {
-            if (root.orientation === ListView.Vertical) {
-                return Qt.point(0, fadeRectEnd.height)
-            } else {
-                return Qt.point(fadeRectEnd.width, 0)
-            }
-        }
-
-        gradient: Gradient {
-            GradientStop { position: 0.0; color: "transparent" }
-            GradientStop { position: 1.0; color: !!fadeColor ? fadeColor : "transparent" }
-        }
-    }
-
     // FIXME: We probably need to upgrade these RoundButton(s) eventually. And we probably need
     //        to have some kind of animation when switching pages.
 


=====================================
modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
=====================================
@@ -97,7 +97,6 @@ FocusScope {
     property alias footerItem: view.footerItem
     property alias footer: view.footer
 
-    property alias fadeColor: view.fadeColor
     property alias fadeSize: view.fadeSize
 
     property alias add:       view.add
@@ -212,8 +211,6 @@ FocusScope {
 
         headerPositioning: ListView.OverlayHeader
 
-        fadeColor: VLCStyle.colors.bg
-
         onDeselectAll: {
             if (selectionDelegateModel) {
                 selectionDelegateModel.clear()



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2c76c045d9423f3fc9d5160460e6668c594d3960...5d93b442afacd94ec13e63dfb58b1435ce5d72cd

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2c76c045d9423f3fc9d5160460e6668c594d3960...5d93b442afacd94ec13e63dfb58b1435ce5d72cd
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