[vlc-commits] [Git][videolan/vlc][master] qml: fix player seekbar position is not updated when hidden
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Sat May 27 15:03:11 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
8b79382d by Pierre Lamot at 2023-05-27T14:47:50+00:00
qml: fix player seekbar position is not updated when hidden
Using `Item` for the FSM implementation had the drawback that when the seekbar
was hidden, the FSM was disabled (enabled became false) by propagation
- - - - -
1 changed file:
- modules/gui/qt/player/qml/SliderBar.qml
Changes:
=====================================
modules/gui/qt/player/qml/SliderBar.qml
=====================================
@@ -86,20 +86,91 @@ Slider {
pos: Qt.point(sliderRectMouseArea.mouseX, 0)
}
- Item {
+ QtObject {
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
+ //each signal is associated to a key, when a signal is received,
+ //transitions of active state for the given key are evaluated
+ property var signalMap: ({
+ playerUpdatePosition: fsm.playerUpdatePosition,
+ pressControl: fsm.pressControl,
+ releaseControl: fsm.releaseControl,
+ moveControl: fsm.moveControl
+ })
+
+ property var initialState: fsmReleased
+ property var _state: null
+
+ function _evaluateTransition(state, event, t, ...args) {
+ if ("guard" in t) {
+ if (!(t.guard instanceof Function)) {
+ console.error(`guard property of ${state}::${event} is not a function`)
+ }
+ if (!t.guard(...args))
+ return false
+ }
+
+ if ("action" in t) {
+ if (!(t.action instanceof Function))
+ console.error(`action property of ${state}::${event} is not a function`)
+ t.action(...args)
+ }
+
+ if ("target" in t)
+ changeState(t.target)
+
+ return true
+ }
+
+ function handleSignal(event, state, ...args) {
+ if (!state)
+ return
+
+ if (!(event in _state.transitions))
+ return
+
+ const transitions = state.transitions[event]
+ if (Array.isArray(transitions)) {
+ for (const t of transitions) {
+ //stop at the first accepted transition
+ if (_evaluateTransition(state, event, t, ...args))
+ return
+ }
+ } else {
+ _evaluateTransition(state, event, transitions, ...args)
+ }
+ }
+
+ function changeState(state) {
+ if (_state) {
+ if (_state.exit instanceof Function)
+ _state.exit()
+ }
- function _changeState(state) {
- _state.enabled = false
_state = state
- _state.enabled = true
+
+ if (_state) {
+ if (_state.enter instanceof Function)
+ _state.enter()
+ }
+ }
+
+ Component.onCompleted: {
+ for (const signalName of Object.keys(signalMap)) {
+ signalMap[signalName].connect((...args) => {
+ //use callLater to ensure transitions are ordered.
+ //signal are not queued by default, this is an issue
+ //if an action/enter/exit function raise another signal
+ Qt.callLater(() => {
+ handleSignal(signalName, fsm._state, ...args)
+ })
+ })
+ }
+ changeState(initialState)
}
function _seekToPosition(position, threshold, forcePrecise) {
@@ -115,37 +186,38 @@ Slider {
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)
+ property list<QtObject> subStates: [
+ QtObject {
+ id: fsmReleased
+ property var transitions: ({
+ playerUpdatePosition: {
+ action: (position) => {
+ control.value = position
+ }
+ },
+ pressControl: {
+ action: (position, forcePrecise) => {
+ control.forceActiveFocus()
+ fsm._seekToPosition(position, VLCStyle.dp(4) / control.width, forcePrecise)
+ },
+ target: fsmHeld
+ }
+ })
+ },
+ QtObject {
+ id: fsmHeld
+ property var transitions: ({
+ moveControl: {
+ action: (position, forcePrecise) => {
+ fsm._seekToPosition(position, VLCStyle.dp(2) / control.width, forcePrecise)
+ }
+ },
+ releaseControl: {
+ target: fsmReleased
+ }
+ })
}
- }
+ ]
}
Connections {
@@ -283,7 +355,7 @@ Slider {
}
]
- state: (seekpointsRect._hovered || (seekpointsRect._currentChapter === 0 && fsm._state == fsmHeld))
+ state: (seekpointsRect._hovered || (seekpointsRect._currentChapter === 0 && fsm._state == fsm.fsmHeld))
? "visibleLarge"
: "visible"
}
@@ -433,7 +505,7 @@ Slider {
]
state: (control.hovered || control.activeFocus)
- ? ((control._currentChapterHovered || (Player.hasChapters && fsm._state == fsmHeld)) ? "visibleLarge" : "visible")
+ ? ((control._currentChapterHovered || (Player.hasChapters && fsm._state == fsm.fsmHeld)) ? "visibleLarge" : "visible")
: "hidden"
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/8b79382d32b06c9ba6047757d11a8208f4e8f583
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/8b79382d32b06c9ba6047757d11a8208f4e8f583
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