[vlc-commits] [Git][videolan/vlc][master] 4 commits: qt: create DelayEstimator class

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Thu Jul 20 11:57:09 UTC 2023



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


Commits:
73829169 by Mohit Marathe at 2023-07-20T11:31:53+00:00
qt: create DelayEstimator class

Signed-off-by: Mohit Marathe <mohitmarathe23 at gmail.com>

- - - - -
e2497b63 by Mohit Marathe at 2023-07-20T11:31:53+00:00
qt: create functions to add delay

Signed-off-by: Mohit Marathe <mohitmarathe23 at gmail.com>

- - - - -
40d39356 by Mohit Marathe at 2023-07-20T11:31:53+00:00
qt: create TrackDelayButton from ButtonExt

Signed-off-by: Mohit Marathe <mohitmarathe23 at gmail.com>

- - - - -
4982441f by Mohit Marathe at 2023-07-20T11:31:53+00:00
qt: redesign TracksPageAudio & TracksPageSubtitle

Signed-off-by: Mohit Marathe <mohitmarathe23 at gmail.com>

- - - - -


12 changed files:

- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/meson.build
- + modules/gui/qt/player/delay_estimator.cpp
- + modules/gui/qt/player/delay_estimator.hpp
- modules/gui/qt/player/player_controller.cpp
- modules/gui/qt/player/player_controller.hpp
- modules/gui/qt/player/qml/TracksPageAudio.qml
- modules/gui/qt/player/qml/TracksPageSubtitle.qml
- modules/gui/qt/vlc.qrc
- modules/gui/qt/widgets/qml/ButtonExt.qml
- + modules/gui/qt/widgets/qml/TrackDelayButton.qml


Changes:

=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -269,6 +269,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/style/defaultthemeproviders.hpp \
 	gui/qt/style/systempalettethemeprovider.cpp \
 	gui/qt/player/input_models.cpp gui/qt/player/input_models.hpp \
+	gui/qt/player/delay_estimator.cpp \
+	gui/qt/player/delay_estimator.hpp \
 	gui/qt/player/player_controller.cpp gui/qt/player/player_controller.hpp gui/qt/player/player_controller_p.hpp \
 	gui/qt/player/player_controlbar_model.cpp gui/qt/player/player_controlbar_model.hpp \
 	gui/qt/player/control_list_model.cpp gui/qt/player/control_list_model.hpp \
@@ -482,6 +484,7 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/network/standardpathmodel.moc.cpp \
 	gui/qt/style/colorcontext.moc.cpp \
 	gui/qt/style/systempalette.moc.cpp \
+	gui/qt/player/delay_estimator.moc.cpp \
 	gui/qt/player/input_models.moc.cpp \
 	gui/qt/player/player_controller.moc.cpp \
 	gui/qt/player/player_controlbar_model.moc.cpp \
@@ -1051,6 +1054,7 @@ libqt_plugin_la_QML = \
 	gui/qt/widgets/qml/TableColumns.qml \
 	gui/qt/widgets/qml/TextFieldExt.qml \
 	gui/qt/widgets/qml/TextToolButton.qml \
+	gui/qt/widgets/qml/TrackDelayButton.qml \
 	gui/qt/widgets/qml/VideoProgressBar.qml \
 	gui/qt/widgets/qml/VideoQualityLabels.qml \
 	gui/qt/widgets/qml/ListSubtitleLabel.qml \


=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -25,6 +25,7 @@
 #include "player/player_controlbar_model.hpp"
 #include "player/control_list_model.hpp"
 #include "player/control_list_filter.hpp"
+#include "player/delay_estimator.hpp"
 
 #include "dialogs/toolbar/controlbar_profile_model.hpp"
 #include "dialogs/toolbar/controlbar_profile.hpp"
@@ -239,6 +240,8 @@ void MainUI::registerQMLTypes()
         qmlRegisterSingletonType<SVGColorImage>(uri, versionMajor, versionMinor, "SVGColorImage", SingletonRegisterHelper<SVGColorImage>::callback);
         qmlRegisterSingletonType<PlaylistController>(uri, versionMajor, versionMinor, "MainPlaylistController", SingletonRegisterHelper<PlaylistController>::callback);
 
+        qmlRegisterType<DelayEstimator>( uri, versionMajor, versionMinor, "DelayEstimator" );
+
         qmlRegisterUncreatableType<QAbstractItemModel>(uri, versionMajor, versionMinor, "QtAbstractItemModel", "");
         qmlRegisterUncreatableType<QWindow>(uri, versionMajor, versionMinor, "QtWindow", "");
         qmlRegisterUncreatableType<QScreen>(uri, versionMajor, versionMinor, "QtScreen", "");


=====================================
modules/gui/qt/meson.build
=====================================
@@ -107,6 +107,7 @@ moc_headers = files(
     'style/systempalette.hpp',
     'style/colorcontext.hpp',
     'player/input_models.hpp',
+    'player/delay_estimator.hpp',
     'player/player_controller.hpp',
     'player/player_controlbar_model.hpp',
     'player/control_list_model.hpp',
@@ -377,6 +378,7 @@ some_sources = files(
     'style/defaultthemeproviders.hpp',
     'style/systempalettethemeprovider.cpp',
     'player/input_models.cpp',
+    'player/delay_estimator.cpp',
     'player/input_models.hpp',
     'player/player_controller.cpp',
     'player/player_controller.hpp',


=====================================
modules/gui/qt/player/delay_estimator.cpp
=====================================
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ * Copyright (C) 2023 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.
+ *****************************************************************************/
+
+#include "util/vlctick.hpp"
+#include "delay_estimator.hpp"
+
+DelayEstimator::DelayEstimator(QObject *parent)
+    : QObject(parent)
+{
+}
+
+DelayEstimator::~DelayEstimator()
+{
+}
+
+bool DelayEstimator::isHeardTimeMarked() {
+    return (m_heardTime != VLC_TICK_INVALID);
+}
+
+bool DelayEstimator::isSpottedTimeMarked() {
+    return (m_spottedTime != VLC_TICK_INVALID);
+}
+
+/*Q_INVOKABLE*/ VLCTick DelayEstimator::getDelay()
+{
+    return m_delay;
+}
+
+/*Q_INVOKABLE*/ void DelayEstimator::markHeardTime()
+{
+    if (isHeardTimeMarked())
+        m_heardTime = VLC_TICK_INVALID;
+    else
+        m_heardTime = vlc_tick_now();
+
+    emit heardTimeChanged();
+
+    if (isSpottedTimeMarked())
+        calculateDelay();
+}
+
+/*Q_INVOKABLE*/ void DelayEstimator::markSpottedTime()
+{
+    if (isSpottedTimeMarked())
+        m_spottedTime = VLC_TICK_INVALID;
+    else
+        m_spottedTime = vlc_tick_now();
+
+    emit spottedTimeChanged();
+
+    if (isHeardTimeMarked())
+        calculateDelay();
+}
+
+void DelayEstimator::calculateDelay()
+{
+    if (m_heardTime != VLC_TICK_INVALID &&
+        m_spottedTime != VLC_TICK_INVALID)
+    {
+        m_delay = m_heardTime - m_spottedTime;
+        emit delayChanged();
+        m_heardTime = VLC_TICK_INVALID;
+        m_spottedTime = VLC_TICK_INVALID;
+        emit spottedTimeChanged();
+        emit heardTimeChanged();
+    }
+}
+
+/*Q_INVOKABLE*/ void DelayEstimator::reset()
+{
+    m_heardTime = VLC_TICK_INVALID;
+    m_spottedTime = VLC_TICK_INVALID;
+    m_delay = VLC_TICK_INVALID;
+    emit delayChanged();
+    emit spottedTimeChanged();
+    emit heardTimeChanged();
+}


=====================================
modules/gui/qt/player/delay_estimator.hpp
=====================================
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * Copyright (C) 2023 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.
+ *****************************************************************************/
+#ifndef DELAYESTIMATOR
+#define DELAYESTIMATOR
+
+#pragma once
+
+#include <QObject>
+#include <QEvent>
+#include "qt.hpp"
+#include "util/vlctick.hpp"
+
+class VLCTick;
+
+class DelayEstimator : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(bool isHeardTimeMarked READ isHeardTimeMarked NOTIFY heardTimeChanged FINAL)
+    Q_PROPERTY(bool isSpottedTimeMarked READ isSpottedTimeMarked NOTIFY spottedTimeChanged FINAL)
+    Q_PROPERTY(VLCTick delay READ getDelay NOTIFY delayChanged FINAL)
+
+public:
+    explicit DelayEstimator(QObject* parent = nullptr);
+    ~DelayEstimator();
+
+    bool isHeardTimeMarked();
+    bool isSpottedTimeMarked();
+    void calculateDelay();
+    VLCTick getDelay();
+
+    Q_INVOKABLE void markHeardTime();
+    Q_INVOKABLE void markSpottedTime();
+    Q_INVOKABLE void reset();
+
+signals:
+    void heardTimeChanged();
+    void spottedTimeChanged();
+    void delayChanged();
+
+private:
+    VLCTick m_heardTime = VLC_TICK_INVALID;
+    VLCTick m_spottedTime = VLC_TICK_INVALID;
+    VLCTick m_delay = VLC_TICK_INVALID;
+};
+
+#endif


=====================================
modules/gui/qt/player/player_controller.cpp
=====================================
@@ -1306,6 +1306,14 @@ void PlayerController::setAudioDelay(VLCTick delay)
     vlc_player_SetAudioDelay( d->m_player, delay, VLC_PLAYER_WHENCE_ABSOLUTE );
 }
 
+/*Q_INVOKABLE*/void PlayerController::addAudioDelay(VLCTick delay)
+{
+    Q_D(PlayerController);
+    vlc_player_locker lock{ d->m_player };
+    vlc_player_SetAudioDelay( d->m_player, delay, VLC_PLAYER_WHENCE_RELATIVE );
+    emit audioDelayChanged(delay);
+}
+
 void PlayerController::setSubtitleDelay(VLCTick delay)
 {
     Q_D(PlayerController);
@@ -1315,6 +1323,14 @@ void PlayerController::setSubtitleDelay(VLCTick delay)
     vlc_player_SetSubtitleDelay( d->m_player, delay, VLC_PLAYER_WHENCE_ABSOLUTE );
 }
 
+/*Q_INVOKABLE*/void PlayerController::addSubtitleDelay(VLCTick delay)
+{
+    Q_D(PlayerController);
+    vlc_player_locker lock{ d->m_player };
+    vlc_player_SetSubtitleDelay( d->m_player, delay, VLC_PLAYER_WHENCE_RELATIVE);
+    emit subtitleDelayChanged(delay);
+}
+
 void PlayerController::setSecondarySubtitleDelay(VLCTick delay)
 {
     Q_D(PlayerController);
@@ -1326,6 +1342,17 @@ void PlayerController::setSecondarySubtitleDelay(VLCTick delay)
                                 delay, VLC_PLAYER_WHENCE_ABSOLUTE);
 }
 
+/*Q_INVOKABLE*/void PlayerController::addSecondarySubtitleDelay(VLCTick delay)
+{
+    Q_D(PlayerController);
+    vlc_player_locker lock{ d->m_player };
+    if (d->m_secondarySpuEsId.get() != NULL) {
+        vlc_player_SetEsIdDelay(d->m_player, d->m_secondarySpuEsId.get(),
+                                delay, VLC_PLAYER_WHENCE_RELATIVE);
+        emit secondarySubtitleDelayChanged(delay);
+    }
+}
+
 int PlayerController::getAudioDelayMS() const
 {
     return MS_FROM_VLC_TICK( getAudioDelay() );


=====================================
modules/gui/qt/player/player_controller.hpp
=====================================
@@ -312,10 +312,13 @@ public slots:
 
     VLCTick getAudioDelay() const;
     void setAudioDelay( VLCTick );
+    Q_INVOKABLE void addAudioDelay( VLCTick );
     VLCTick getSubtitleDelay() const;
     VLCTick getSecondarySubtitleDelay() const;
     void setSubtitleDelay( VLCTick );
+    Q_INVOKABLE void addSubtitleDelay( VLCTick );
     void setSecondarySubtitleDelay( VLCTick );
+    Q_INVOKABLE void addSecondarySubtitleDelay( VLCTick );
     int getAudioDelayMS() const;
     void setAudioDelayMS( int );
     int getSubtitleDelayMS() const;


=====================================
modules/gui/qt/player/qml/TracksPageAudio.qml
=====================================
@@ -64,6 +64,11 @@ TracksPage {
             Accessible.role: Accessible.Grouping
             Accessible.name: I18n.qtr("Audio track delay")
 
+            DelayEstimator {
+                id: delayEstimator
+                onDelayChanged: Player.addAudioDelay(delayEstimator.delay)
+            }
+
             Widgets.MenuCaption {
                 Layout.fillWidth: true
                 Layout.alignment: Qt.AlignHCenter
@@ -121,11 +126,49 @@ TracksPage {
 
                 text: I18n.qtr("Reset")
 
-                onClicked: spinBox.value = 0
+                onClicked: {
+                    Player.audioDelayMS = 0
+                    delayEstimator.reset()
+                }
 
                 Navigation.parentItem: root
                 Navigation.leftItem: spinBox
             }
         }
+
+        RowLayout {
+            Layout.fillWidth: true
+            Layout.alignment: Qt.AlignRight
+
+            spacing: VLCStyle.margin_xsmall
+
+            Widgets.TrackDelayButton {
+                id: soundHeard
+
+                text: I18n.qtr("Sound Heard")
+                iconTxt: VLCIcons.check
+                selected: delayEstimator.isSpottedTimeMarked
+
+                onClicked: {
+                    delayEstimator.markSpottedTime() //method name should be changed
+                    if (!delayEstimator.isHeardTimeMarked && delayEstimator.isSpottedTimeMarked)
+                        soundSpotted.animate()
+                }
+            }
+
+            Widgets.TrackDelayButton {
+                id: soundSpotted
+
+                text: I18n.qtr("Sound Spotted")
+                iconTxt: VLCIcons.check
+                selected: delayEstimator.isHeardTimeMarked
+
+                onClicked: {
+                    delayEstimator.markHeardTime() //method name should be changed
+                    if (!delayEstimator.isSpottedTimeMarked && delayEstimator.isHeardTimeMarked)
+                        soundHeard.animate()
+                }
+            }
+        }
     }
 }


=====================================
modules/gui/qt/player/qml/TracksPageSubtitle.qml
=====================================
@@ -53,7 +53,7 @@ TracksPage {
         anchors.left: parent.left
         anchors.right: parent.right
 
-        spacing: VLCStyle.margin_xxsmall
+        spacing: VLCStyle.margin_xsmall
 
         Widgets.SubtitleLabel {
             Layout.fillWidth: true
@@ -63,153 +63,260 @@ TracksPage {
             color: root.colorContext.fg.primary
         }
 
-        RowLayout {
+        ColumnLayout {
             Layout.fillWidth: true
             Layout.topMargin: VLCStyle.margin_large
 
-            spacing: VLCStyle.margin_xsmall
+            spacing: VLCStyle.margin_xxxsmall
 
             Accessible.role: Accessible.Grouping
             Accessible.name: I18n.qtr("Primary subtitle delay")
 
-            Widgets.MenuCaption {
+            DelayEstimator {
+                id: delayEstimatorPrimary
+
+                onDelayChanged: {
+                    Player.addSubtitleDelay(delayEstimatorPrimary.delay)
+                }
+            }
+
+            RowLayout {
                 Layout.fillWidth: true
-                Layout.alignment: Qt.AlignHCenter
 
-                text: I18n.qtr("Primary subtitle delay")
+                spacing: VLCStyle.margin_xsmall
 
-                color: root.colorContext.fg.primary
-            }
+                Widgets.MenuCaption {
+                    Layout.fillWidth: true
+                    Layout.alignment: Qt.AlignHCenter
 
-            Widgets.SpinBoxExt {
-                id: spinBoxA
+                    text: I18n.qtr("Primary subtitle delay")
 
-                property bool update: false
+                    color: root.colorContext.fg.primary
+                }
 
-                Layout.preferredWidth: VLCStyle.dp(128, VLCStyle.scale)
+                Widgets.SpinBoxExt {
+                    id: spinBoxA
 
-                stepSize: 50
-                from: -10000
-                to: 10000
+                    property bool update: false
 
-                textFromValue: root.textFromValueA
-                valueFromText: root.valueFromTextA
+                    Layout.preferredWidth: VLCStyle.dp(128, VLCStyle.scale)
 
-                Navigation.parentItem: root
-                Navigation.rightItem: resetA
+                    stepSize: 50
+                    from: -10000
+                    to: 10000
 
-                Component.onCompleted: {
-                    value = Player.subtitleDelayMS
+                    textFromValue: root.textFromValueA
+                    valueFromText: root.valueFromTextA
 
-                    update = true
-                }
+                    Navigation.parentItem: root
+                    Navigation.rightItem: resetA
 
-                onValueChanged: {
-                    if (update === false)
-                        return
+                    Component.onCompleted: {
+                        spinBoxA.value = Player.subtitleDelayMS
 
-                    Player.subtitleDelayMS = value
+                        spinBoxA.update = true
+                    }
+
+                    onValueChanged: {
+                        if (update === false)
+                            return
+
+                        Player.subtitleDelayMS = spinBoxA.value
+                    }
+
+                    Connections {
+                        target: Player
+
+                        onSubtitleDelayChanged: {
+                            spinBoxA.update = false
+
+                            spinBoxA.value = Player.subtitleDelayMS
+
+                            spinBoxA.update = true
+                        }
+
+                    }
                 }
 
-                Connections {
-                    target: Player
+                Widgets.TextToolButton {
+                    id: resetA
 
-                    onSubtitleDelayChanged: {
-                        spinBoxA.update = false
+                    text: I18n.qtr("Reset")
 
-                        spinBoxA.value = Player.subtitleDelayMS
+                    focus: true
 
-                        spinBoxA.update = true
+                    Navigation.parentItem: root
+                    Navigation.leftItem: spinBoxA
+                    Navigation.downItem: resetB
+
+                    onClicked: {
+                        Player.subtitleDelayMS = 0
+                        delayEstimatorPrimary.reset()
                     }
                 }
             }
 
-            Widgets.ActionButtonOverlay {
-                id: resetA
+            RowLayout {
+                Layout.fillWidth: true
+
+                Layout.alignment: Qt.AlignRight
 
-                focus: true
+                spacing: VLCStyle.margin_small
 
-                text: I18n.qtr("Reset")
+                Widgets.TrackDelayButton {
+                    id: voiceHeardA
 
-                Navigation.parentItem: root
-                Navigation.leftItem: spinBoxA
-                Navigation.downItem: resetB
+                    iconTxt: VLCIcons.check
+                    text: I18n.qtr("Voice Heard")
+                    selected: delayEstimatorPrimary.isHeardTimeMarked
+
+                    onClicked: {
+                        delayEstimatorPrimary.markHeardTime()
+                        if (!delayEstimatorPrimary.isSpottedTimeMarked && delayEstimatorPrimary.isHeardTimeMarked)
+                            textSeenA.animate()
+                    }
+                }
+
+                Widgets.TrackDelayButton {
+                    id: textSeenA
+
+                    iconTxt: VLCIcons.check
+                    text: I18n.qtr("Text Seen")
+                    selected: delayEstimatorPrimary.isSpottedTimeMarked
 
-                onClicked: spinBoxA.value = 0
+                    onClicked: {
+                        delayEstimatorPrimary.markSpottedTime()
+                        if (!delayEstimatorPrimary.isHeardTimeMarked && delayEstimatorPrimary.isSpottedTimeMarked)
+                            voiceHeardA.animate()
+                    }
+                }
             }
         }
 
-        RowLayout {
+        ColumnLayout {
             Layout.fillWidth: true
 
-            spacing: VLCStyle.margin_xsmall
+            spacing: VLCStyle.margin_xxxsmall
 
             Accessible.role: Accessible.Grouping
             Accessible.name: I18n.qtr("Secondary subtitle delay")
 
-            Widgets.MenuCaption {
+            DelayEstimator {
+                id: delayEstimatorSecondary
+
+                onDelayChanged: {
+                    Player.addSecondarySubtitleDelay(delayEstimatorSecondary.delay)
+                }
+            }
+
+            RowLayout {
                 Layout.fillWidth: true
-                Layout.alignment: Qt.AlignHCenter
 
-                text: I18n.qtr("Secondary subtitle delay")
+                spacing: VLCStyle.margin_xsmall
 
-                color: root.colorContext.fg.primary
-            }
+                Widgets.MenuCaption {
+                    Layout.fillWidth: true
+                    Layout.alignment: Qt.AlignHCenter
 
-            Widgets.SpinBoxExt {
-                id: spinBoxB
+                    text: I18n.qtr("Secondary subtitle delay")
 
-                property bool update: false
+                    color: root.colorContext.fg.primary
+                }
 
-                Layout.preferredWidth: VLCStyle.dp(128, VLCStyle.scale)
+                Widgets.SpinBoxExt {
+                    id: spinBoxB
 
-                stepSize: 50
-                from: -10000
-                to: 10000
+                    property bool update: false
 
-                textFromValue: root.textFromValueA
-                valueFromText: root.valueFromTextA
+                    Layout.preferredWidth: VLCStyle.dp(128, VLCStyle.scale)
 
-                Navigation.parentItem: root
-                Navigation.rightItem: resetB
+                    stepSize: 50
+                    from: -10000
+                    to: 10000
 
-                Component.onCompleted: {
-                    value = Player.secondarySubtitleDelayMS
+                    textFromValue: root.textFromValueA
+                    valueFromText: root.valueFromTextA
 
-                    update = true
-                }
+                    Navigation.parentItem: root
+                    Navigation.rightItem: resetB
 
-                onValueChanged: {
-                    if (update === false)
-                        return
+                    Component.onCompleted: {
+                        value = Player.secondarySubtitleDelayMS
 
-                    Player.secondarySubtitleDelayMS = value
+                        update = true
+                    }
+
+                    onValueChanged: {
+                        if (update === false)
+                            return
+
+                        Player.secondarySubtitleDelayMS = spinBoxB.value
+                    }
+
+                    Connections {
+                        target: Player
+
+                        onSecondarySubtitleDelayChanged: {
+                            spinBoxB.update = false
+
+                            spinBoxB.value = Player.secondarySubtitleDelayMS
+
+                            spinBoxB.update = true
+                        }
+                    }
                 }
 
-                Connections {
-                    target: Player
+                Widgets.TextToolButton {
+                    id: resetB
 
-                    onSecondarySubtitleDelayChanged: {
-                        spinBoxB.update = false
+                    text: I18n.qtr("Reset")
 
-                        spinBoxB.value = Player.secondarySubtitleDelayMS
+                    Navigation.parentItem: root
+                    Navigation.leftItem: spinBoxB
+                    Navigation.upItem: resetA
+                    Navigation.downItem: resetC
 
-                        spinBoxB.update = true
+                    onClicked: {
+                        Player.secondarySubtitleDelayMS = 0
+                        delayEstimatorSecondary.reset()
                     }
                 }
             }
 
-            Widgets.ActionButtonOverlay {
-                id: resetB
+            RowLayout {
+                Layout.fillWidth: true
 
-                text: I18n.qtr("Reset")
+                Layout.alignment: Qt.AlignRight
 
-                Navigation.parentItem: root
-                Navigation.leftItem: spinBoxB
-                Navigation.upItem: resetA
-                Navigation.downItem: resetC
+                spacing: VLCStyle.margin_xsmall
+
+                Widgets.TrackDelayButton {
+                    id: voiceHeardB
 
-                onClicked: spinBoxB.value = 0
+                    text: I18n.qtr("Voice Heard")
+                    iconTxt: VLCIcons.check
+                    selected: delayEstimatorSecondary.isHeardTimeMarked
+
+                    onClicked: {
+                        delayEstimatorSecondary.markHeardTime()
+                        if (!delayEstimatorSecondary.isSpottedTimeMarked && delayEstimatorSecondary.isHeardTimeMarked)
+                            textSeenB.animate()
+                    }
+                }
+
+                Widgets.TrackDelayButton {
+                    id: textSeenB
+
+                    text: I18n.qtr("Text Seen")
+                    iconTxt: VLCIcons.check
+                    selected: delayEstimatorSecondary.isSpottedTimeMarked
+
+                    onClicked: {
+                        delayEstimatorSecondary.markSpottedTime()
+                        if (!delayEstimatorSecondary.isHeardTimeMarked && delayEstimatorSecondary.isSpottedTimeMarked)
+                            voiceHeardB.animate()
+                    }
+                }
             }
         }
 
@@ -273,7 +380,7 @@ TracksPage {
                 }
             }
 
-            Widgets.ActionButtonOverlay {
+            Widgets.TextToolButton {
                 id: resetC
 
                 text: I18n.qtr("Reset")


=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -171,6 +171,7 @@
         <file alias="CSDWindowButtonSet.qml">widgets/qml/CSDWindowButtonSet.qml</file>
         <file alias="CSDTitlebarTapNDrapHandler.qml">widgets/qml/CSDTitlebarTapNDrapHandler.qml</file>
         <file alias="CSDMouseStealer.qml">widgets/qml/CSDMouseStealer.qml</file>
+        <file alias="TrackDelayButton.qml">widgets/qml/TrackDelayButton.qml</file>
         <file alias="CurrentIndicator.qml">widgets/qml/CurrentIndicator.qml</file>
         <file alias="GridItem.qml">widgets/qml/GridItem.qml</file>
         <file alias="LoaderFade.qml">widgets/qml/LoaderFade.qml</file>


=====================================
modules/gui/qt/widgets/qml/ButtonExt.qml
=====================================
@@ -42,6 +42,8 @@ T.Button {
     property color color: theme.fg.primary
     property color colorFocus: theme.visualFocus
 
+    //set to true when user animates the background manually
+    property bool extBackgroundAnimation: false
 
     // Aliases
     property alias iconRotation: icon.rotation
@@ -91,7 +93,7 @@ T.Button {
         width: control.width
 
         active: control.visualFocus
-        animate: theme.initialized
+        animate: theme.initialized && !control.extBackgroundAnimation
 
         backgroundColor: theme.bg.primary
         foregroundColor: control.color


=====================================
modules/gui/qt/widgets/qml/TrackDelayButton.qml
=====================================
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * Copyright (C) 2020 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.12
+import QtQuick.Layouts 1.12
+
+import org.videolan.vlc 0.1
+
+import "qrc:///widgets/" as Widgets
+import "qrc:///style/"
+
+ButtonExt {
+    id: control
+
+    //Signals
+
+    signal animate()
+
+    extBackgroundAnimation: blinkAnimation.running
+
+    onAnimate: blinkAnimation.start()
+
+    property ColorContext colorContext: ColorContext {
+        id: theme
+        colorSet: ColorContext.ButtonStandard
+
+        focused: control.visualFocus
+        hovered: control.hovered
+        enabled: control.enabled
+        pressed: control.down
+    }
+
+    SequentialAnimation {
+        id: blinkAnimation
+        loops: 2
+
+        ColorAnimation {
+            target: control.background
+            property: "backgroundColor"
+            from: theme.bg.primary
+            to: theme.accent
+            duration: VLCStyle.duration_long
+        }
+        ColorAnimation {
+            target: control.background
+            property: "backgroundColor"
+            from: theme.accent
+            to: theme.bg.primary
+            duration: VLCStyle.duration_long
+        }
+    }
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/de40a3a601cb92726b1ee9410490dea8a6c4bdd0...4982441ff0b09b6aae372f3dc0a700995948f019

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/de40a3a601cb92726b1ee9410490dea8a6c4bdd0...4982441ff0b09b6aae372f3dc0a700995948f019
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