diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index fd9c83eb..c49b378a 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -387,7 +387,8 @@ AdvSceneSwitcher.action.media.type.stop="Stop" AdvSceneSwitcher.action.media.type.restart="Restart" AdvSceneSwitcher.action.media.type.next="Next" AdvSceneSwitcher.action.media.type.previous="Previous" -AdvSceneSwitcher.action.media.entry="{{actions}} {{mediaSources}}" +AdvSceneSwitcher.action.media.type.seek="Seek to" +AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}" AdvSceneSwitcher.action.macro="Macro" AdvSceneSwitcher.action.macro.type.pause="Pause" AdvSceneSwitcher.action.macro.type.unpause="Unpause" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index a90b6303..b5842627 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -321,7 +321,7 @@ AdvSceneSwitcher.action.media.type.stop="Dur" AdvSceneSwitcher.action.media.type.restart="Yeniden Başlat" AdvSceneSwitcher.action.media.type.next="Sonraki" AdvSceneSwitcher.action.media.type.previous="Önceki" -AdvSceneSwitcher.action.media.entry="{{actions}} {{mediaSources}}" +AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}" AdvSceneSwitcher.action.macro="Makro" AdvSceneSwitcher.action.macro.type.pause="Duraklat" AdvSceneSwitcher.action.macro.type.unpause="Duraklatma" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index e59c896e..6083ee9d 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -364,7 +364,7 @@ AdvSceneSwitcher.action.media.type.stop="停止" AdvSceneSwitcher.action.media.type.restart="重新启动" AdvSceneSwitcher.action.media.type.next="下一个" AdvSceneSwitcher.action.media.type.previous="上一个" -AdvSceneSwitcher.action.media.entry="{{actions}} {{mediaSources}}" +AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}" AdvSceneSwitcher.action.macro="宏" AdvSceneSwitcher.action.macro.type.pause="暂停" AdvSceneSwitcher.action.macro.type.unpause="取消暂停" diff --git a/src/headers/macro-action-media.hpp b/src/headers/macro-action-media.hpp index c6622faf..dc7cdc03 100644 --- a/src/headers/macro-action-media.hpp +++ b/src/headers/macro-action-media.hpp @@ -1,5 +1,6 @@ #pragma once #include "macro-action-edit.hpp" +#include "duration-control.hpp" #include #include @@ -11,6 +12,7 @@ enum class MediaAction { RESTART, NEXT, PREVIOUS, + SEEK, }; class MacroActionMedia : public MacroAction { @@ -29,6 +31,7 @@ public: OBSWeakSource _mediaSource; MediaAction _action = MediaAction::PLAY; + Duration _seek; private: static bool _registered; @@ -54,15 +57,20 @@ public: private slots: void SourceChanged(const QString &text); void ActionChanged(int value); + void DurationChanged(double value); + void DurationUnitChanged(DurationUnit unit); signals: void HeaderInfoChanged(const QString &); protected: QComboBox *_mediaSources; QComboBox *_actions; + DurationSelection *_seek; std::shared_ptr _entryData; private: + void SetWidgetVisibility(); + QHBoxLayout *_mainLayout; bool _loading = true; }; diff --git a/src/macro-action-media.cpp b/src/macro-action-media.cpp index eb072d18..af0392d6 100644 --- a/src/macro-action-media.cpp +++ b/src/macro-action-media.cpp @@ -16,6 +16,7 @@ const static std::map actionTypes = { {MediaAction::RESTART, "AdvSceneSwitcher.action.media.type.restart"}, {MediaAction::NEXT, "AdvSceneSwitcher.action.media.type.next"}, {MediaAction::PREVIOUS, "AdvSceneSwitcher.action.media.type.previous"}, + {MediaAction::SEEK, "AdvSceneSwitcher.action.media.type.seek"}, }; bool MacroActionMedia::PerformAction() @@ -46,6 +47,9 @@ bool MacroActionMedia::PerformAction() case MediaAction::PREVIOUS: obs_source_media_previous(source); break; + case MediaAction::SEEK: + obs_source_media_set_time(source, _seek.seconds * 1000); + break; default: break; } @@ -72,6 +76,7 @@ bool MacroActionMedia::Save(obs_data_t *obj) obs_data_set_string(obj, "mediaSource", GetWeakSourceName(_mediaSource).c_str()); obs_data_set_int(obj, "action", static_cast(_action)); + _seek.Save(obj); return true; } @@ -81,6 +86,7 @@ bool MacroActionMedia::Load(obs_data_t *obj) const char *MediaSourceName = obs_data_get_string(obj, "mediaSource"); _mediaSource = GetWeakSourceByName(MediaSourceName); _action = static_cast(obs_data_get_int(obj, "action")); + _seek.Load(obj); return true; } @@ -101,11 +107,11 @@ static inline void populateActionSelection(QComboBox *list) MacroActionMediaEdit::MacroActionMediaEdit( QWidget *parent, std::shared_ptr entryData) - : QWidget(parent) + : QWidget(parent), + _mediaSources(new QComboBox()), + _actions(new QComboBox()), + _seek(new DurationSelection()) { - _mediaSources = new QComboBox(); - _actions = new QComboBox(); - populateActionSelection(_actions); populateMediaSelection(_mediaSources); @@ -114,11 +120,16 @@ MacroActionMediaEdit::MacroActionMediaEdit( QWidget::connect(_mediaSources, SIGNAL(currentTextChanged(const QString &)), this, SLOT(SourceChanged(const QString &))); + QWidget::connect(_seek, SIGNAL(DurationChanged(double)), this, + SLOT(DurationChanged(double))); + QWidget::connect(_seek, SIGNAL(UnitChanged(DurationUnit)), this, + SLOT(DurationUnitChanged(DurationUnit))); QHBoxLayout *mainLayout = new QHBoxLayout; std::unordered_map widgetPlaceholders = { {"{{mediaSources}}", _mediaSources}, {"{{actions}}", _actions}, + {"{{duration}}", _seek}, }; placeWidgets(obs_module_text("AdvSceneSwitcher.action.media.entry"), mainLayout, widgetPlaceholders); @@ -138,6 +149,8 @@ void MacroActionMediaEdit::UpdateEntryData() _mediaSources->setCurrentText( GetWeakSourceName(_entryData->_mediaSource).c_str()); _actions->setCurrentIndex(static_cast(_entryData->_action)); + _seek->SetDuration(_entryData->_seek); + SetWidgetVisibility(); } void MacroActionMediaEdit::SourceChanged(const QString &text) @@ -160,4 +173,34 @@ void MacroActionMediaEdit::ActionChanged(int value) std::lock_guard lock(switcher->m); _entryData->_action = static_cast(value); + SetWidgetVisibility(); +} + +void MacroActionMediaEdit::DurationChanged(double seconds) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_seek.seconds = seconds; +} + +void MacroActionMediaEdit::DurationUnitChanged(DurationUnit unit) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_seek.displayUnit = unit; +} + +void MacroActionMediaEdit::SetWidgetVisibility() +{ + if (!_entryData) { + return; + } + _seek->setVisible(_entryData->_action == MediaAction::SEEK); + adjustSize(); }