François Cartegnie pushed to branch master at VideoLAN / VLC


Commits:
0505bad7 by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/ComboBoxExt: Fix the Popup 'z' value

- - - - -
980aeb4e by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/ComboBoxExt: Fix the null context warning

- - - - -
00db9fa8 by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/Helpers: Add the 'compareFloat' function

- - - - -
4f2aaf3b by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/PlaybackSpeed: Revamp implementation

- - - - -
47b83ada by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/PlaybackSpeed: Remove slower/faster buttons

- - - - -
b295b3a5 by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/TracksPageSpeed: Ensure the speed component is aligned on top

- - - - -
0d201c35 by Benjamin Arnaud at 2022-06-02T09:36:35+00:00
qml/PlaybackSpeedButton: Increase Popup width

- - - - -


5 changed files:

- modules/gui/qt/player/qml/PlaybackSpeed.qml
- modules/gui/qt/player/qml/TracksPageSpeed.qml
- modules/gui/qt/player/qml/controlbarcontrols/PlaybackSpeedButton.qml
- modules/gui/qt/util/qml/Helpers.js
- modules/gui/qt/widgets/qml/ComboBoxExt.qml


Changes:

=====================================
modules/gui/qt/player/qml/PlaybackSpeed.qml
=====================================
@@ -18,159 +18,347 @@
 
 import QtQuick 2.11
 import QtQuick.Controls 2.4
-import QtQuick.Templates 2.4 as T
 import QtQuick.Layouts 1.11
+import QtQuick.Templates 2.4 as T
 
 import org.videolan.vlc 0.1
 
 import "qrc:///style/"
 import "qrc:///widgets/" as Widgets
+import "qrc:///util/Helpers.js" as Helpers
 
-// FIXME: We should refactor this item with a list of presets.
 ColumnLayout {
     id: root
 
+    // Properties
+
     property VLCColors colors: VLCStyle.nightColors
 
-    Widgets.ListLabel {
+    // Private
+
+    property var _model: [{ "value": 0.25 },
+                          { "value": 0.5 },
+                          { "value": 0.75 },
+                          { "value": 1, "title": I18n.qtr("Normal") },
+                          { "value": 1.25 },
+                          { "value": 1.5 },
+                          { "value": 1.75 },
+                          { "value": 2 }]
+
+    // NOTE: 0.96 and 1.04 are useful for video enthusiasts.
+    property var _values: [ 0.25, 0.5, 0.75, 0.96, 1.0, 1.04, 1.25, 1.5, 1.75, 
2 ]
+
+    property bool _update: true
+
+    // FIXME: Currently we are not updating the ShiftModifier status while 
dragging. This could be
+    //        fixed with a custom Slider based on a MouseArea.
+    property bool _shiftPressed: false
+
+    property real _value: 1.0
+
+    property real _minimum: 0.25
+    property real _maximum: 4.0
+
+    property real _threshold: 0.03
+
+    property color _color: (slider.visualFocus || slider.pressed) ? 
colors.accent
+                                                                  : colors.text
+
+    // Settings
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    // Events
+
+    Component.onCompleted: _updateValue(Player.rate)
+
+    // Function
+
+    function _updateComboBox(value) {
+        // NOTE: We want a rounded 1.xx value.
+        value = Math.round(value * 100) / 100
+
+        for (var i = 0; i < _model.length; i++) {
+            if (Helpers.compareFloat(_model[i].value, value) === false)
+                continue
+
+            comboBox.currentIndex = i
+
+            _value = value
+
+            return;
+        }
+
+        comboBox.currentIndex = -1
+
+        _value = value
+    }
+
+    function _updateValue(value) {
+        _update = false
+
+        _applySlider(value)
+
+        _updateComboBox(value)
+
+        _update = true
+    }
+
+    function _applySlider(value) {
+        value = 17 * Math.log(value) / Math.log(2)
+
+        if (value <= 1.0)
+            slider.value = Math.max(slider.from, value)
+        else
+            slider.value = Math.min(value, slider.to)
+    }
+
+    function _applyPlayer(value) {
+        if (_update === false)
+            return
+
+        value = Math.pow(2, value / 17)
+
+        if (_shiftPressed === false) {
+            for (var i = 0; i < _values.length; i++) {
+                var clamp = _values[i]
+
+                if (_testClamp(value, clamp)) {
+                    value = clamp
+
+                    break
+                }
+            }
+        }
+
+        _update = false
+
+        Player.rate = value
+
+        _updateComboBox(value)
+
+        _update = true
+    }
+
+    function _testClamp(value, target) {
+        return (Math.abs(value - target) < _threshold)
+    }
+
+    // Connections
+
+    Connections {
+        target: Player
+
+        onRateChanged: _updateValue(Player.rate)
+    }
+
+    // Children
+
+    Widgets.SubtitleLabel {
+        id: label
+
+        Layout.fillWidth: true
+
+        Layout.alignment: Qt.AlignTop
+
         text: I18n.qtr("Playback Speed")
+
         color: root.colors.text
-        font.pixelSize: VLCStyle.fontSize_large
+    }
+
+    Item {
+        id: rowA
 
         Layout.fillWidth: true
-        Layout.bottomMargin: VLCStyle.margin_xsmall
+        Layout.topMargin: VLCStyle.margin_xsmall
 
         Layout.alignment: Qt.AlignTop
+
+        implicitHeight: buttonReset.height
+
+        Navigation.parentItem: root
+        Navigation.downItem: slider
+
+        Widgets.CaptionLabel {
+            anchors.verticalCenter: parent.verticalCenter
+
+            text: I18n.qtr("0.25")
+
+            color: label.color
+
+            font.pixelSize: VLCStyle.fontSize_normal
+        }
+
+        Widgets.IconControlButton {
+            id: buttonReset
+
+            // NOTE: This needs to be wider to fully encapsulate the label.
+            width: VLCStyle.dp(64, VLCStyle.scale)
+
+            anchors.centerIn: parent
+
+            colors: root.colors
+
+            focus: true
+
+            Navigation.parentItem: rowB
+            Navigation.downItem: slider
+
+            onClicked: slider.value = 0
+
+            Widgets.CaptionLabel {
+                anchors.centerIn: parent
+
+                text: I18n.qtr("1.00x")
+
+                color: buttonReset.background.foregroundColor
+
+                font.pixelSize: VLCStyle.fontSize_xlarge
+            }
+        }
+
+        Widgets.CaptionLabel {
+            anchors.right: parent.right
+
+            anchors.verticalCenter: parent.verticalCenter
+
+            text: I18n.qtr("4.00")
+
+            color: label.color
+
+            font.pixelSize: VLCStyle.fontSize_normal
+        }
     }
 
-    Slider {
-        id: speedSlider
+    T.Slider {
+        id: slider
 
-        // '_inhibitPlayerUpdate' is used to guard against double update
-        // initialize with true so that we don't update the Player till
-        // we initialize `value` property
-        property bool _inhibitPlayerUpdate: true
+        Layout.fillWidth: true
 
-        from: 0.25
-        to: 4
-        clip: true
         implicitHeight: VLCStyle.heightBar_small
 
+        // NOTE: These values come from the VLC 3.x implementation.
+        from: -34
+        to: 34
+
+        stepSize: 1
+
+        wheelEnabled: true
+
         Navigation.parentItem: root
-        Navigation.downItem: resetButton
+        Navigation.upItem: buttonReset
+        Navigation.downItem: comboBox
+
         Keys.priority: Keys.AfterItem
         Keys.onPressed: Navigation.defaultKeyAction(event)
 
+        onValueChanged: root._applyPlayer(value)
+
         background: Rectangle {
-            x: speedSlider.leftPadding
-            y: speedSlider.topPadding + speedSlider.availableHeight / 2 - 
height / 2
-            implicitWidth: 200
-            implicitHeight: 4
-            width: speedSlider.availableWidth
+            width: slider.availableWidth
             height: implicitHeight
-            radius: 2
+
+            implicitWidth: VLCStyle.dp(256, VLCStyle.scale)
+            implicitHeight: VLCStyle.dp(4, VLCStyle.scale)
+
+            x: slider.leftPadding
+            y: slider.topPadding + slider.availableHeight / 2 - height / 2
+
+            radius: VLCStyle.dp(2, VLCStyle.scale)
+
             color: root.colors.bgAlt
 
             Rectangle {
-                width: speedSlider.visualPosition * parent.width
+                width: slider.visualPosition * parent.width
                 height: parent.height
-                radius: 2
-                color: (speedSlider.visualFocus || speedSlider.pressed)
-                       ? root.colors.accent
-                       : root.colors.text
+
+                radius: parent.radius
+
+                color: root._color
             }
         }
 
         handle: Rectangle {
-            x: speedSlider.leftPadding + speedSlider.visualPosition * 
(speedSlider.availableWidth - width)
-            y: speedSlider.topPadding + speedSlider.availableHeight / 2 - 
height / 2
-            width: speedSlider.implicitHeight
-            height: speedSlider.implicitHeight
-            radius: speedSlider.implicitHeight
-            color: (speedSlider.visualFocus || speedSlider.pressed) ? 
root.colors.accent : root.colors.text
-        }
+            width: slider.implicitHeight
+            height: slider.implicitHeight
 
-        onValueChanged:  {
-            if (_inhibitPlayerUpdate)
-                return
-            Player.rate = value
-        }
+            x: slider.leftPadding + slider.visualPosition * 
(slider.availableWidth - width)
+            y: slider.topPadding + slider.availableHeight / 2 - height / 2
 
-        function _updateFromPlayer() {
-            _inhibitPlayerUpdate = true
-            value = Player.rate
-            _inhibitPlayerUpdate = false
-        }
+            radius: slider.implicitHeight
 
-        Connections {
-            target: Player
-            onRateChanged: speedSlider._updateFromPlayer()
+            color: root._color
         }
 
-        Layout.fillWidth: true
+        MouseArea {
+            anchors.fill: parent
 
-        Component.onCompleted: speedSlider._updateFromPlayer()
-    }
+            acceptedButtons: Qt.LeftButton
 
-    RowLayout {
-        id: buttonLayout
+            onPressed: {
+                mouse.accepted = false
 
-        spacing: 0
+                root._shiftPressed = (mouse.modifiers === Qt.ShiftModifier)
+            }
+        }
+    }
 
-        Navigation.parentItem: root
-        Navigation.upItem: speedSlider
+    Item {
+        id: rowB
 
-        Widgets.IconControlButton {
-            id: slowerButton
+        Layout.fillWidth: true
+        Layout.topMargin: VLCStyle.margin_xsmall
 
-            iconText: VLCIcons.slower
-            colors: root.colors
+        implicitHeight: comboBox.height
 
-            Navigation.parentItem: buttonLayout
-            Navigation.rightItem: resetButton
+        Navigation.parentItem: root
+        Navigation.upItem: slider
 
-            onClicked: speedSlider.decrease()
-        }
+        Widgets.ComboBoxExt {
+            id: comboBox
 
-        Item {
-            Layout.fillWidth: true
-        }
+            anchors.centerIn: parent
 
-        Widgets.IconControlButton {
-            id: resetButton
+            width: VLCStyle.combobox_width_normal
+            height: VLCStyle.combobox_height_normal
 
-            colors: root.colors
+            model: ListModel {}
 
-            Navigation.parentItem: buttonLayout
-            Navigation.leftItem: slowerButton
-            Navigation.rightItem: fasterButton
+            // NOTE: We display the 'Normal' string when the Slider is 
centered.
+            displayText: (currentIndex === 3) ? currentText
+                                              : root._value
 
-            onClicked: speedSlider.value = 1.0
+            color: root.colors.buttonText
+            bgColor: root.colors.button
+            borderColor: root.colors.buttonBorder
 
-            focus: true
+            // NOTE: Applying the right theme to the ComboBox.
+            Navigation.parentItem: rowB
 
-            T.Label {
-                anchors.centerIn: parent
-                font.pixelSize: VLCStyle.fontSize_normal
-                text: I18n.qtr("1x")
-                color: resetButton.background.foregroundColor // 
IconToolButton.background is a AnimatedBackground
-            }
-        }
+            // NOTE: This makes the navigation convenient since 'up' is 
changing the comboBox value.
+            Navigation.leftItem: slider
+            Navigation.rightItem: slider
 
-        Item {
-            Layout.fillWidth: true
-        }
+            Component.onCompleted: {
+                for (var i = 0; i < _model.length; i++) {
+                    var item = _model[i]
 
-        Widgets.IconControlButton {
-            id: fasterButton
+                    var title = item.title
 
-            iconText: VLCIcons.faster
-            colors: root.colors
+                    if (title)
+                        model.append({ "title": title })
+                    else
+                        model.append({ "title": String(item.value) })
+                }
+            }
 
-            Navigation.parentItem: buttonLayout
-            Navigation.leftItem: resetButton
+            onCurrentIndexChanged: {
+                if (root._update === false || currentIndex === -1)
+                    return
 
-            onClicked: speedSlider.increase()
+                root._applySlider(_model[currentIndex].value)
+            }
         }
     }
 }


=====================================
modules/gui/qt/player/qml/TracksPageSpeed.qml
=====================================
@@ -28,7 +28,8 @@ TracksPage {
     // Children
 
     PlaybackSpeed {
-        anchors.fill: parent
+        anchors.left: parent.left
+        anchors.right: parent.right
 
         Navigation.parentItem: root
     }


=====================================
modules/gui/qt/player/qml/controlbarcontrols/PlaybackSpeedButton.qml
=====================================
@@ -47,7 +47,7 @@ Widgets.IconControlButton {
                 ? root // button is not part of main display 
(ToolbarEditorDialog)
                 : root._isCurrentViewPlayer ? rootPlayer : g_root
 
-        width: implicitWidth
+        width: VLCStyle.dp(256, VLCStyle.scale)
         height: implicitHeight
 
         padding: VLCStyle.margin_small


=====================================
modules/gui/qt/util/qml/Helpers.js
=====================================
@@ -76,3 +76,7 @@ function contains(rect, pos) {
 function isInteger(data) {
     return (typeof data === 'number' && (data % 1) === 0)
 }
+
+function compareFloat(a, b) {
+    return (Math.abs(a - b) < Number.EPSILON)
+}


=====================================
modules/gui/qt/widgets/qml/ComboBoxExt.qml
=====================================
@@ -63,6 +63,9 @@ ComboBox {
         }
 
         onPaint: {
+            if (context === null)
+                return
+
             context.reset();
             context.moveTo(0, 0);
             context.lineTo(width, 0);
@@ -95,6 +98,10 @@ ComboBox {
 
     popup: Popup {
         y: control.height - 1
+
+        // NOTE: This Popup should be on top of other Popup(s) most of the 
time.
+        z: 100
+
         width: control.width
         implicitHeight: contentItem.implicitHeight
         padding: 1



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/2398a5f469ad083794bfecf142e480871a8040f6...0d201c35492e44cd162874cfcb5c10fb78f99f5c

-- 
View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/2398a5f469ad083794bfecf142e480871a8040f6...0d201c35492e44cd162874cfcb5c10fb78f99f5c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to