[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: allow to retrieve the nearest chapter in ChapterModel

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu May 19 08:50:08 UTC 2022



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
5edae385 by Pierre Lamot at 2022-05-19T08:33:57+00:00
qt: allow to retrieve the nearest chapter in ChapterModel

- - - - -
7e06c87a by Pierre Lamot at 2022-05-19T08:33:57+00:00
qml: seek precisely to chapters when clicking near the chapter time

it remains possible to bypass the "magnetic" effect by holding the shift
modifier when pressing the mouse

- - - - -


4 changed files:

- modules/gui/qt/player/input_models.cpp
- modules/gui/qt/player/input_models.hpp
- modules/gui/qt/player/qml/ControlBar.qml
- modules/gui/qt/player/qml/SliderBar.qml


Changes:

=====================================
modules/gui/qt/player/input_models.cpp
=====================================
@@ -383,6 +383,16 @@ void ChapterListModel::resetTitle(const vlc_player_title *newTitle)
     emit countChanged();
 }
 
+void ChapterListModel::selectChapter(int index)
+{
+    if (!m_title || index < 0 || static_cast<size_t>(index) >= m_title->chapter_count)
+        return;
+    {
+        vlc_player_locker lock{ m_player };
+        vlc_player_SelectChapter(m_player, m_title, index);
+    }
+}
+
 QString ChapterListModel::getNameAtPosition(float pos) const
 {
     if(m_title != nullptr){
@@ -406,6 +416,42 @@ QString ChapterListModel::getNameAtPosition(float pos) const
     return QString();
 }
 
+int ChapterListModel::getClosestChapterFromPos(float pos, float threshold) const
+{
+    if(m_title == nullptr)
+        return -1;
+
+    vlc_tick_t posTime = pos * m_title->length;
+    vlc_tick_t closestTime = VLC_TICK_INVALID;
+    int chapterIndex = -1;
+
+    for(size_t i=0; i<m_title->chapter_count; i++){
+
+        vlc_tick_t currentChapterTime = m_title->chapters[i].time;
+        if (currentChapterTime == VLC_TICK_INVALID)
+            continue;
+        if (closestTime == VLC_TICK_INVALID
+            || qAbs(currentChapterTime - posTime) < qAbs(closestTime - posTime))
+        {
+            closestTime = currentChapterTime;
+            chapterIndex = i;
+        }
+    }
+
+    if (closestTime == VLC_TICK_INVALID)
+        return -1;
+    else
+    {
+        float chapterPos = closestTime / (float)m_title->length;
+
+        if (qAbs(chapterPos - pos) < threshold)
+            return chapterIndex;
+        return -1;
+    }
+
+}
+
+
 //***************************
 //  ProgramListModel
 //***************************


=====================================
modules/gui/qt/player/input_models.hpp
=====================================
@@ -186,6 +186,10 @@ public:
 
     inline int getCount() const { return (m_title == nullptr) ?  0 : m_title->chapter_count; }
 
+    Q_INVOKABLE void selectChapter(int index);
+
+    Q_INVOKABLE int getClosestChapterFromPos(float pos, float threshold) const;
+
 signals:
     void countChanged();
 


=====================================
modules/gui/qt/player/qml/ControlBar.qml
=====================================
@@ -178,7 +178,7 @@ Control {
         visible: false
         backgroundColor: Qt.lighter(colors.playerBg, 1.6180)
         barHeight: VLCStyle.heightBar_xxsmall
-        enabled: Player.playingState == Player.PLAYING_STATE_PLAYING || Player.playingState == Player.PLAYING_STATE_PAUSED
+        enabled: Player.playingState === Player.PLAYING_STATE_PLAYING || Player.playingState === Player.PLAYING_STATE_PAUSED
         colors: root.colors
 
         Navigation.parentItem: root


=====================================
modules/gui/qt/player/qml/SliderBar.qml
=====================================
@@ -24,12 +24,12 @@ import org.videolan.vlc 0.1
 
 import "qrc:///widgets/" as Widgets
 import "qrc:///style/"
+import "qrc:///util/Helpers.js" as Helpers
 
 Slider {
     id: control
 
     property int barHeight: VLCStyle.dp(5, VLCStyle.scale)
-    property bool _isHold: false
     property bool _isSeekPointsShown: true
     property real _tooltipPosition: timeTooltip.pos.x / sliderRectMouseArea.width
 
@@ -67,13 +67,71 @@ Slider {
         colors: control.colors
     }
 
-    Connections {    
-        /* only update the control position when the player position actually change, this avoid the slider
-         * to jump around when clicking
-         */
+    Item {
+        id: fsm
+
+        signal playerUpdatePosition(real position)
+        signal pressControl(real position, bool forcePrecise)
+        signal releaseControl(real position, bool forcePrecise)
+        signal moveControl(real position, bool forcePrecise)
+
+        property var _state: fsmReleased
+
+        function _changeState(state) {
+            _state.enabled = false
+            _state = state
+            _state.enabled = true
+        }
+
+        function _seekToPosition(position, threshold, forcePrecise) {
+            position = Helpers.clamp(position, 0., 1.)
+            control.value = position
+            if (!forcePrecise) {
+                var chapter = Player.chapters.getClosestChapterFromPos(position, threshold)
+                if (chapter !== -1) {
+                    Player.chapters.selectChapter(chapter)
+                    return
+                }
+            }
+            Player.position = position
+        }
+
+        Item {
+            id: fsmReleased
+            enabled: true
+
+            Connections {
+                enabled: fsmReleased.enabled
+                target: fsm
+
+                onPlayerUpdatePosition: control.value = position
+
+                onPressControl: {
+                    control.forceActiveFocus()
+                    fsm._seekToPosition(position, VLCStyle.dp(4) / control.width, forcePrecise)
+                    fsm._changeState(fsmHeld)
+                }
+            }
+        }
+
+        Item {
+            id: fsmHeld
+            enabled: false
+
+            Connections {
+                enabled: fsmHeld.enabled
+                target: fsm
+
+                onMoveControl: fsm._seekToPosition(position, VLCStyle.dp(2) / control.width, forcePrecise)
+
+                onReleaseControl: fsm._changeState(fsmReleased)
+            }
+        }
+    }
+
+    Connections {
         target: Player
-        enabled: !_isHold
-        onPositionChanged: control.value = Player.position
+        onPositionChanged: fsm.playerUpdatePosition(Player.position)
     }
 
     height: control.barHeight
@@ -96,27 +154,17 @@ Slider {
 
         MouseArea {
             id: sliderRectMouseArea
-            property bool isEntered: false
 
             anchors.fill: parent
+
             hoverEnabled: true
 
-            onPressed: function (event) {
-                control.forceActiveFocus()
-                control._isHold = true
-                control.value = event.x / control.width
-                Player.position = control.value
-            }
-            onReleased: control._isHold = false
-            onPositionChanged: function (event) {
-                if (pressed) {
-                    if (event.x < 0) event.x = 0;
-                    else if (event.x > control.width) event.x = control.width;
-
-                    control.value = event.x / control.width
-                    Player.position = control.value
-                }
-            }
+            onPressed: fsm.pressControl(mouse.x / control.width, mouse.modifiers === Qt.ShiftModifier)
+
+            onReleased: fsm.releaseControl(mouse.x / control.width, mouse.modifiers === Qt.ShiftModifier)
+
+            onPositionChanged: fsm.moveControl(mouse.x / control.width, mouse.modifiers === Qt.ShiftModifier)
+
             onEntered: {
                 if(Player.hasChapters)
                     control._isSeekPointsShown = true



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5a236388dea5f9e95f95204829050e89318e1d9c...7e06c87ad9290e559f3a33e7e0d90f2e016ef050

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