[vlc-commits] [Git][videolan/vlc][master] 8 commits: qml/ControlLayout: Add the 'contentWidth' property

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Apr 7 12:26:03 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
9bea3945 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ControlLayout: Add the 'contentWidth' property

- - - - -
a421045f by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ControlLayout: Add the 'alignment' property

- - - - -
96e3f573 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ControlLayout: Add the 'count' alias

- - - - -
44bc4d84 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ControlLayout: Update the 'implicitWidth' property

- - - - -
3efc5ce6 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ControlLayout: Add the 'preferredWidth' support

- - - - -
aec938f0 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/ArtworkInfoWidget: Add the 'preferredWidth' property

Co-authored-by: Fatih Uzunoglu <fuzun54 at outlook.com>

- - - - -
a1f2bda7 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/PlayerControlLayout: Update resize and collpasing behavior

This patch adds dynamic scaling for the loaders based on their internal content. It's
notably useful to gain space when one of them is empty. We have that scenario for the
classic controls layout.

- - - - -
72c34ac1 by Benjamin Arnaud at 2023-04-07T12:11:27+00:00
qml/PlayerControlLayout: Update the 'layoutSpacing' property

The spacing between controls feels more optimal with the 'margin_xlarge' value.

- - - - -


3 changed files:

- modules/gui/qt/player/qml/ControlLayout.qml
- modules/gui/qt/player/qml/PlayerControlLayout.qml
- modules/gui/qt/player/qml/controlbarcontrols/ArtworkInfoWidget.qml


Changes:

=====================================
modules/gui/qt/player/qml/ControlLayout.qml
=====================================
@@ -32,27 +32,9 @@ FocusScope {
 
     // Properties
 
-    readonly property real minimumWidth: {
-        var count = repeater.count
+    property int contentWidth: 0
 
-        if (count === 0)
-            return 0
-
-        var size = 0
-
-        for (var i = 0; i < count; ++i) {
-            var item = repeater.itemAt(i)
-
-            if (item.minimumWidth === undefined)
-                size += item.implicitWidth
-            else
-                size += item.minimumWidth
-        }
-
-        return size + ((count - 1) * playerControlLayout.spacing)
-    }
-
-    property bool rightAligned: false
+    property int alignment: 0
 
     property var altFocusAction: Navigation.defaultNavigationUp
 
@@ -63,6 +45,8 @@ FocusScope {
 
     // Aliases
 
+    property alias count: repeater.count
+
     property alias model: repeater.model
 
     // Signals
@@ -71,7 +55,23 @@ FocusScope {
 
     // Settings
 
-    implicitWidth: minimumWidth
+    implicitWidth: {
+        if (count === 0)
+            return 0
+
+        var size = 0
+
+        for (var i = 0; i < count; ++i) {
+            size += repeater.itemAt(i).preferredWidth
+        }
+
+        if (alignment)
+            // NOTE: We provision the spacing induced by the alignment item.
+            return size + count * rowLayout.spacing
+        else
+            return size + (count - 1) * rowLayout.spacing
+    }
+
     implicitHeight: rowLayout.implicitHeight
 
     Navigation.navigable: {
@@ -102,6 +102,28 @@ FocusScope {
             altFocusAction()
     }
 
+    function _updateContentWidth() {
+        var size = 0
+
+        for (var i = 0; i < count; i++) {
+
+            var item = repeater.itemAt(i)
+
+            if (item === null || item.isActive === false)
+                continue
+
+            var width = item.width
+
+            if (width)
+                size += width + spacing
+        }
+
+        if (size)
+            contentWidth = size - spacing
+        else
+            contentWidth = size
+    }
+
     // Children
 
     RowLayout {
@@ -112,20 +134,26 @@ FocusScope {
         spacing: playerControlLayout.spacing
 
         Item {
-            Layout.fillWidth: rightAligned
+            Layout.fillWidth: (controlLayout.alignment === Qt.AlignRight)
         }
 
         Repeater {
             id: repeater
 
             // NOTE: We apply the 'navigation chain' after adding the item.
-            onItemAdded: item.applyNavigation()
+            onItemAdded: {
+                item.applyNavigation()
+
+                controlLayout._updateContentWidth()
+            }
 
             onItemRemoved: {
                 // NOTE: We update the 'navigation chain' after removing the item.
                 item.removeNavigation()
 
                 item.recoverFocus(index)
+
+                controlLayout._updateContentWidth()
             }
 
             delegate: Loader {
@@ -133,6 +161,9 @@ FocusScope {
 
                 // Properties
 
+                // NOTE: This is required for contentWidth because the visible property is delayed.
+                property bool isActive: (x + minimumWidth <= rowLayout.width)
+
                 property int minimumWidth: {
                     if (expandable)
                         return item.minimumWidth
@@ -142,6 +173,9 @@ FocusScope {
                         return 0
                 }
 
+                property int preferredWidth: (item && item.preferredWidth) ? item.preferredWidth
+                                                                           : minimumWidth
+
                 readonly property bool expandable: (item && item.minimumWidth !== undefined)
 
                 // Settings
@@ -154,22 +188,27 @@ FocusScope {
 
                 Layout.minimumWidth: minimumWidth
 
-                // NOTE: -1 resets to the implicit maximum width.
-                Layout.maximumWidth: (item) ? item.implicitWidth : -1
+                Layout.preferredWidth: preferredWidth
+
+                Layout.maximumWidth: preferredWidth
 
-                Layout.alignment: Qt.AlignVCenter | (rightAligned ? Qt.AlignRight : Qt.AlignLeft)
+                Layout.alignment: (Qt.AlignVCenter | controlLayout.alignment)
 
                 BindingCompat {
                     delayed: true // this is important
                     target: loader
                     property: "visible"
-                    value: (loader.x + minimumWidth <= rowLayout.width)
+                    value: isActive
                 }
 
                 // Events
 
                 Component.onCompleted: repeater.countChanged.connect(controlLayout._handleFocus)
 
+                onIsActiveChanged: controlLayout._updateContentWidth()
+
+                onWidthChanged: controlLayout._updateContentWidth()
+
                 onActiveFocusChanged: {
                     if (activeFocus && (!!item && !item.focus)) {
                         recoverFocus()
@@ -328,7 +367,7 @@ FocusScope {
         }
 
         Item {
-            Layout.fillWidth: !rightAligned
+            Layout.fillWidth: (controlLayout.alignment === Qt.AlignLeft)
         }
     }
 }


=====================================
modules/gui/qt/player/qml/PlayerControlLayout.qml
=====================================
@@ -32,7 +32,7 @@ FocusScope {
 
     property real spacing: VLCStyle.margin_normal // spacing between controls
 
-    property real layoutSpacing: VLCStyle.margin_xxlarge // spacing between layouts (left, center, and right)
+    property real layoutSpacing: VLCStyle.margin_xlarge // spacing between layouts (left, center, and right)
 
     property int identifier: -1
 
@@ -48,35 +48,96 @@ FocusScope {
         colorSet: ColorContext.Window
     }
 
+    // Private
+
+    property int _minimumSpacing: layoutSpacing - spacing
+
     // Signals
 
     signal requestLockUnlockAutoHide(bool lock)
 
     // Settings
 
-    implicitWidth: loaderLeft.implicitWidth + loaderCenter.implicitWidth
-                   + loaderRight.implicitWidth + 2 * layoutSpacing
-
     implicitHeight: VLCStyle.maxControlbarControlHeight
 
     // Events
 
-    Component.onCompleted: console.assert(identifier >= 0)
+    Component.onCompleted: {
+        console.assert(identifier >= 0)
+
+        _updateLayout()
+    }
+
+    onWidthChanged: _updateLayout()
+
+    // Functions
+
+    function _updateLayout() {
+        var item = loaderCenter.item
+
+        // NOTE: Sometimes this gets called before the item is loaded.
+        if (item === null)
+            return
+
+        if (item.count) {
+
+            loaderCenter.width = Math.min(loaderCenter.implicitWidth, width)
+
+            loaderLeft.width = loaderCenter.x - _minimumSpacing
+
+            loaderRight.width = width - loaderCenter.x - loaderCenter.width - _minimumSpacing
+
+        } else if (loaderRight.item.count) {
+
+            var implicitLeft = loaderLeft.implicitWidth
+            var implicitRight = loaderRight.implicitWidth
+
+            var total = implicitLeft + implicitRight
+
+            var size = total + _minimumSpacing
+
+            if (size > width) {
+                size = width - _minimumSpacing
+
+                // NOTE: When both sizes are equals we expand on the left.
+                if (implicitLeft >= implicitRight) {
+
+                    loaderRight.width = Math.round(size * (implicitRight / total))
+
+                    var contentWidth = loaderRight.item.contentWidth
+
+                    // NOTE: We assign the remaining width based on the contentWidth.
+                    if (contentWidth)
+                        loaderLeft.width = width - contentWidth - _minimumSpacing
+                    else
+                        loaderLeft.width = width
+                } else {
+                    loaderLeft.width = Math.round(size * (implicitLeft / total))
+
+                    var contentWidth = loaderLeft.item.contentWidth
+
+                    // NOTE: We assign the remaining width based on the contentWidth.
+                    if (contentWidth)
+                        loaderRight.width = width - contentWidth - _minimumSpacing
+                    else
+                        loaderRight.width = width
+                }
+            } else {
+                loaderLeft.width = implicitLeft
+                loaderRight.width = implicitRight
+            }
+        } else
+            loaderLeft.width = width
+    }
 
     // Children
 
     Loader {
         id: loaderLeft
 
-        anchors {
-            right: loaderCenter.left
-            left: parent.left
-            top: parent.top
-            bottom: parent.bottom
-
-            // Spacing for the filler item acts as padding
-            rightMargin: layoutSpacing - spacing
-        }
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
 
         active: !!playerControlLayout.model && !!playerControlLayout.model.left
 
@@ -90,6 +151,8 @@ FocusScope {
                 ctx: MainCtx
             }
 
+            alignment: Qt.AlignLeft
+
             focus: true
 
             altFocusAction: Navigation.defaultNavigationRight
@@ -97,6 +160,10 @@ FocusScope {
             Navigation.parentItem: playerControlLayout
             Navigation.rightItem: loaderCenter.item
 
+            onImplicitWidthChanged: playerControlLayout._updateLayout()
+
+            onCountChanged: playerControlLayout._updateLayout()
+
             onRequestLockUnlockAutoHide: playerControlLayout.requestLockUnlockAutoHide(lock)
         }
     }
@@ -104,16 +171,12 @@ FocusScope {
     Loader {
         id: loaderCenter
 
-        anchors {
-            horizontalCenter: parent.horizontalCenter
-            top: parent.top
-            bottom: parent.bottom
-        }
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
 
-        active: !!playerControlLayout.model && !!playerControlLayout.model.center
+        anchors.horizontalCenter: parent.horizontalCenter
 
-        width: (parent.width < implicitWidth) ? parent.width
-                                              : implicitWidth
+        active: !!playerControlLayout.model && !!playerControlLayout.model.center
 
         sourceComponent: ControlLayout {
             model: ControlListFilter {
@@ -131,6 +194,10 @@ FocusScope {
             Navigation.leftItem: loaderLeft.item
             Navigation.rightItem: loaderRight.item
 
+            onImplicitWidthChanged: playerControlLayout._updateLayout()
+
+            onCountChanged: playerControlLayout._updateLayout()
+
             onRequestLockUnlockAutoHide: playerControlLayout.requestLockUnlockAutoHide(lock)
         }
     }
@@ -138,15 +205,9 @@ FocusScope {
     Loader {
         id: loaderRight
 
-        anchors {
-            left: loaderCenter.right
-            right: parent.right
-            top: parent.top
-            bottom: parent.bottom
-
-            // Spacing for the filler item acts as padding
-            leftMargin: layoutSpacing - spacing
-        }
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
 
         active: !!playerControlLayout.model && !!playerControlLayout.model.right
 
@@ -158,7 +219,7 @@ FocusScope {
                 ctx: MainCtx
             }
 
-            rightAligned: true
+            alignment: Qt.AlignRight
 
             focus: true
 
@@ -167,6 +228,10 @@ FocusScope {
             Navigation.parentItem: playerControlLayout
             Navigation.leftItem: loaderCenter.item
 
+            onImplicitWidthChanged: playerControlLayout._updateLayout()
+
+            onCountChanged: playerControlLayout._updateLayout()
+
             onRequestLockUnlockAutoHide: playerControlLayout.requestLockUnlockAutoHide(lock)
         }
     }


=====================================
modules/gui/qt/player/qml/controlbarcontrols/ArtworkInfoWidget.qml
=====================================
@@ -33,6 +33,12 @@ AbstractButton {
     readonly property real minimumWidth: coverRect.implicitWidth +
                                          + (leftPadding + rightPadding)
 
+    readonly property int preferredWidth: minimumWidth + contentItem.spacing * 2
+                                          +
+                                          Math.max(titleLabel.implicitWidth,
+                                                   artistLabel.implicitWidth,
+                                                   progressIndicator.implicitWidth)
+
     property bool _keyPressed: false
 
     text: I18n.qtr("Open player")



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/34e98057dd9dc50b5e33209072441cdc44d20e81...72c34ac178d835a549920ece08a0e4edefe12351

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/34e98057dd9dc50b5e33209072441cdc44d20e81...72c34ac178d835a549920ece08a0e4edefe12351
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