diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 5a1bacbd..fa324726 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -159,11 +159,12 @@ AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{condition AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}" AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}" AdvSceneSwitcher.condition.media="Media" +AdvSceneSwitcher.condition.media.source="Source" AdvSceneSwitcher.condition.media.anyOnScene="Any media source on" AdvSceneSwitcher.condition.media.allOnScene="All media sources on" AdvSceneSwitcher.condition.media.matchOnChange="Only match on change (Note: This option will be removed in a future version - please use duration modifiers instead)" AdvSceneSwitcher.condition.media.inconsistencyInfo="Unfortunately not all media source types behave the same (e.g. Media Source vs. VLC Video Source \"Stopped\" state).\nSo please experiment what works for your setup!" -AdvSceneSwitcher.condition.media.entry="{{mediaSources}}{{scenes}} state is {{states}} and {{timeRestrictions}} {{time}}" +AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}state is{{states}}and{{timeRestrictions}}{{time}}" AdvSceneSwitcher.condition.video="Video" AdvSceneSwitcher.condition.video.condition.match="exactly matches" AdvSceneSwitcher.condition.video.condition.differ="does not match" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index ca2e52ce..cd099503 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -133,7 +133,7 @@ AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activad AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas" AdvSceneSwitcher.condition.media.matchOnChange="Solo coincidir con el cambio (Nota: esta opción se eliminará en una versión futura; use modificadores de duración en su lugar)" AdvSceneSwitcher.condition.media.inconsistencyInfo="Desafortunadamente, no todos los tipos de fuentes de medios se comportan de la misma manera (p. ej., fuente de medios frente a estado \"Detenido\" de fuente de video VLC).\n¡Así que experimente lo que funciona para su configuración!" -AdvSceneSwitcher.condition.media.entry="El estado de {{mediaSources}}{{scenes}} es {{states}} y {{timeRestrictions}} {{time}}" +AdvSceneSwitcher.condition.media.entry="El estado de{{sourceTypes}}{{mediaSources}}{{scenes}}es{{states}}y{{timeRestrictions}}{{time}}" AdvSceneSwitcher.condition.video="Video" AdvSceneSwitcher.condition.video.condition.match="coincide exactamente" AdvSceneSwitcher.condition.video.condition.differ="no coincide" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 1e78e292..eef54791 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -122,7 +122,7 @@ AdvSceneSwitcher.condition.media="Medya" AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı" AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları " AdvSceneSwitcher.condition.media.matchOnChange="Yalnızca değişiklikle eşleştirin (Not: Bu seçenek gelecekteki bir sürümde kaldırılacaktır - lütfen bunun yerine zaman kısıtlamalarını kullanın)" -AdvSceneSwitcher.condition.media.entry="{{mediaSources}}{{scenes}} durumu {{states}} ve {{timeRestrictions}} {{time}}" +AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}durumu{{states}}ve{{timeRestrictions}}{{time}}" AdvSceneSwitcher.condition.video="Video" AdvSceneSwitcher.condition.video.condition.match="Tam olarak eşleşir" AdvSceneSwitcher.condition.video.condition.differ="Eşleştirme" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 99f3469b..5842d364 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -145,7 +145,7 @@ AdvSceneSwitcher.condition.media.anyOnScene="任何媒体来源" AdvSceneSwitcher.condition.media.allOnScene="所有媒体来源" AdvSceneSwitcher.condition.media.matchOnChange="仅在更改时匹配(注意:此选项将在未来版本中删除-请改用时间限制)" AdvSceneSwitcher.condition.media.inconsistencyInfo="不幸的是,并非所有媒体源类型的行为都相同(例如,媒体源与VLC视频源“停止”状态)。\n所以,请尝试适合您的设置!" -AdvSceneSwitcher.condition.media.entry="{{mediaSources}}{{scenes}} 的状态是 {{states}} 和 {{timeRestrictions}} {{time}}" +AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}的状态是{{states}}和{{timeRestrictions}}{{time}}" AdvSceneSwitcher.condition.video="视频" AdvSceneSwitcher.condition.video.condition.match="完全匹配" AdvSceneSwitcher.condition.video.condition.differ="不匹配" diff --git a/src/macro-core/macro-condition-media.cpp b/src/macro-core/macro-condition-media.cpp index 213f96a3..4612cb58 100644 --- a/src/macro-core/macro-condition-media.cpp +++ b/src/macro-core/macro-condition-media.cpp @@ -48,7 +48,8 @@ static std::map mediaStates = { MacroConditionMedia::~MacroConditionMedia() { - obs_source_t *mediasource = obs_weak_source_get_source(_source); + obs_source_t *mediasource = + obs_weak_source_get_source(_source.GetSource()); signal_handler_t *sh = obs_source_get_signal_handler(mediasource); signal_handler_disconnect(sh, "media_stopped", MediaStopped, this); signal_handler_disconnect(sh, "media_ended", MediaEnded, this); @@ -58,7 +59,7 @@ MacroConditionMedia::~MacroConditionMedia() bool MacroConditionMedia::CheckTime() { - obs_source_t *s = obs_weak_source_get_source(_source); + obs_source_t *s = obs_weak_source_get_source(_source.GetSource()); auto duration = obs_source_media_get_duration(s); auto currentTime = obs_source_media_get_time(s); obs_source_release(s); @@ -92,7 +93,7 @@ bool MacroConditionMedia::CheckTime() bool MacroConditionMedia::CheckState() { - obs_source_t *s = obs_weak_source_get_source(_source); + obs_source_t *s = obs_weak_source_get_source(_source.GetSource()); obs_media_state currentState = obs_source_media_get_state(s); obs_source_release(s); @@ -143,7 +144,7 @@ bool MacroConditionMedia::CheckPlaylistEnd(const obs_media_state currentState) bool MacroConditionMedia::CheckMediaMatch() { - if (!_source) { + if (!_source.GetSource()) { return false; } bool match = false; @@ -173,13 +174,13 @@ bool MacroConditionMedia::CheckCondition() bool match = false; switch (_sourceType) { case Type::ANY: - for (auto &source : _sources) { + for (auto &source : _sourceGroup) { match = match || source.CheckCondition(); } break; case Type::ALL: { bool res = true; - for (auto &source : _sources) { + for (auto &source : _sourceGroup) { res = res && source.CheckCondition(); } match = res; @@ -202,7 +203,7 @@ bool MacroConditionMedia::CheckCondition() bool MacroConditionMedia::Save(obs_data_t *obj) const { MacroCondition::Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); + _source.Save(obj); _scene.Save(obj); obs_data_set_int(obj, "sourceType", static_cast(_sourceType)); obs_data_set_int(obj, "state", static_cast(_state)); @@ -236,7 +237,7 @@ static bool enumSceneItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr) void MacroConditionMedia::UpdateMediaSourcesOfSceneList() { - _sources.clear(); + _sourceGroup.clear(); if (!_scene.GetScene(false)) { return; } @@ -245,21 +246,20 @@ void MacroConditionMedia::UpdateMediaSourcesOfSceneList() auto scene = obs_scene_from_source(s); obs_scene_enum_items(scene, enumSceneItem, &mediaSources); obs_source_release(s); - _sources.reserve(mediaSources.size()); + _sourceGroup.reserve(mediaSources.size()); for (auto &source : mediaSources) { MacroConditionMedia cond(*this); cond._sourceType = Type::SOURCE; - cond._source = source; - _sources.push_back(cond); + cond._source.SetSource(source); + _sourceGroup.push_back(cond); } } bool MacroConditionMedia::Load(obs_data_t *obj) { MacroCondition::Load(obj); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); + _source.Load(obj); _scene.Load(obj); _sourceType = static_cast(obs_data_get_int(obj, "sourceType")); _state = static_cast( @@ -270,7 +270,8 @@ bool MacroConditionMedia::Load(obs_data_t *obj) _onlyMatchOnChagne = obs_data_get_bool(obj, "matchOnChagne"); if (_sourceType == Type::SOURCE) { - obs_source_t *mediasource = obs_weak_source_get_source(_source); + obs_source_t *mediasource = + obs_weak_source_get_source(_source.GetSource()); signal_handler_t *sh = obs_source_get_signal_handler(mediasource); signal_handler_connect(sh, "media_stopped", MediaStopped, this); @@ -293,10 +294,7 @@ std::string MacroConditionMedia::GetShortDesc() const { switch (_sourceType) { case Type::SOURCE: - if (_source) { - return GetWeakSourceName(_source); - } - break; + return _source.ToString(); case Type::ANY: if (_scene.GetScene(false)) { return obs_module_text( @@ -319,7 +317,8 @@ std::string MacroConditionMedia::GetShortDesc() const void MacroConditionMedia::ClearSignalHandler() { - obs_source_t *mediasource = obs_weak_source_get_source(_source); + obs_source_t *mediasource = + obs_weak_source_get_source(_source.GetSource()); signal_handler_t *sh = obs_source_get_signal_handler(mediasource); signal_handler_disconnect(sh, "media_stopped", MediaStopped, this); signal_handler_disconnect(sh, "media_ended", MediaEnded, this); @@ -329,7 +328,8 @@ void MacroConditionMedia::ClearSignalHandler() void MacroConditionMedia::ResetSignalHandler() { - obs_source_t *mediasource = obs_weak_source_get_source(_source); + obs_source_t *mediasource = + obs_weak_source_get_source(_source.GetSource()); signal_handler_t *sh = obs_source_get_signal_handler(mediasource); signal_handler_disconnect(sh, "media_stopped", MediaStopped, this); signal_handler_disconnect(sh, "media_ended", MediaEnded, this); @@ -384,14 +384,18 @@ static void populateMediaStates(QComboBox *list) } } -static void addAnyAndAllStates(QComboBox *list) +static void populateSourceTypes(QComboBox *list) { - list->insertItem( - 1, - obs_module_text("AdvSceneSwitcher.condition.media.anyOnScene")); - list->insertItem( - 1, - obs_module_text("AdvSceneSwitcher.condition.media.allOnScene")); + list->clear(); + list->addItem( + obs_module_text("AdvSceneSwitcher.condition.media.source"), + static_cast(MacroConditionMedia::Type::SOURCE)); + list->addItem( + obs_module_text("AdvSceneSwitcher.condition.media.anyOnScene"), + static_cast(MacroConditionMedia::Type::ANY)); + list->addItem( + obs_module_text("AdvSceneSwitcher.condition.media.allOnScene"), + static_cast(MacroConditionMedia::Type::ALL)); } MacroConditionMediaEdit::MacroConditionMediaEdit( @@ -399,20 +403,26 @@ MacroConditionMediaEdit::MacroConditionMediaEdit( : QWidget(parent), _scenes(new SceneSelectionWidget(window(), true, true, true, true, true)), - _mediaSources(new QComboBox()), + _sourceTypes(new QComboBox()), + _sources(new SourceSelectionWidget(this, QStringList(), true)), _states(new QComboBox()), _timeRestrictions(new QComboBox()), _time(new DurationSelection()), _onChange(new QCheckBox(obs_module_text( "AdvSceneSwitcher.condition.media.matchOnChange"))) - { _states->setToolTip(obs_module_text( "AdvSceneSwitcher.condition.media.inconsistencyInfo")); - QWidget::connect(_mediaSources, - SIGNAL(currentTextChanged(const QString &)), this, - SLOT(SourceChanged(const QString &))); + auto sources = GetMediaSourceNames(); + sources.sort(); + _sources->SetSourceNameList(sources); + + QWidget::connect(_sourceTypes, SIGNAL(currentIndexChanged(int)), this, + SLOT(SourceTypeChanged(int))); + QWidget::connect(_sources, + SIGNAL(SourceChanged(const SourceSelection &)), this, + SLOT(SourceChanged(const SourceSelection &))); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_states, SIGNAL(currentIndexChanged(int)), this, @@ -426,14 +436,14 @@ MacroConditionMediaEdit::MacroConditionMediaEdit( QWidget::connect(_onChange, SIGNAL(stateChanged(int)), this, SLOT(OnChangeChanged(int))); - populateMediaSelection(_mediaSources); - addAnyAndAllStates(_mediaSources); + populateSourceTypes(_sourceTypes); populateMediaStates(_states); populateMediaTimes(_timeRestrictions); QHBoxLayout *entryLayout = new QHBoxLayout; std::unordered_map widgetPlaceholders = { - {"{{mediaSources}}", _mediaSources}, + {"{{sourceTypes}}", _sourceTypes}, + {"{{mediaSources}}", _sources}, {"{{scenes}}", _scenes}, {"{{states}}", _states}, {"{{timeRestrictions}}", _timeRestrictions}, @@ -451,28 +461,20 @@ MacroConditionMediaEdit::MacroConditionMediaEdit( _loading = false; } -void MacroConditionMediaEdit::SourceChanged(const QString &text) +void MacroConditionMediaEdit::SourceTypeChanged(int idx) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); + _entryData->_sourceType = static_cast( + _sourceTypes->itemData(idx).toInt()); - if (text == - obs_module_text("AdvSceneSwitcher.condition.media.anyOnScene")) { - _entryData->_sourceType = MacroConditionMedia::Type::ANY; - } else if (text == - obs_module_text( - "AdvSceneSwitcher.condition.media.allOnScene")) { - _entryData->_sourceType = MacroConditionMedia::Type::ALL; - } else { - _entryData->_sources.clear(); - _entryData->_sourceType = MacroConditionMedia::Type::SOURCE; + if (_entryData->_sourceType == MacroConditionMedia::Type::SOURCE) { + _entryData->_sourceGroup.clear(); } - _entryData->ClearSignalHandler(); - _entryData->_source = GetWeakSourceByQString(text); _entryData->ResetSignalHandler(); emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); @@ -480,6 +482,23 @@ void MacroConditionMediaEdit::SourceChanged(const QString &text) SetWidgetVisibility(); } +void MacroConditionMediaEdit::SourceChanged(const SourceSelection &source) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_sourceGroup.clear(); + _entryData->_sourceType = MacroConditionMedia::Type::SOURCE; + _entryData->ClearSignalHandler(); + _entryData->_source = source; + _entryData->ResetSignalHandler(); + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); + SetWidgetVisibility(); +} + void MacroConditionMediaEdit::SceneChanged(const SceneSelection &s) { if (_loading || !_entryData) { @@ -582,6 +601,8 @@ void MacroConditionMediaEdit::OnChangeChanged(int value) void MacroConditionMediaEdit::SetWidgetVisibility() { + _sources->setVisible(_entryData->_sourceType == + MacroConditionMedia::Type::SOURCE); _scenes->setVisible(_entryData->_sourceType != MacroConditionMedia::Type::SOURCE); if (!_onChange->isChecked()) { @@ -606,23 +627,9 @@ void MacroConditionMediaEdit::UpdateEntryData() return; } - switch (_entryData->_sourceType) { - case MacroConditionMedia::Type::ANY: - _mediaSources->setCurrentText(obs_module_text( - "AdvSceneSwitcher.condition.media.anyOnScene")); - break; - case MacroConditionMedia::Type::ALL: - _mediaSources->setCurrentText(obs_module_text( - "AdvSceneSwitcher.condition.media.allOnScene")); - break; - case MacroConditionMedia::Type::SOURCE: - _mediaSources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); - break; - default: - break; - } - + _sourceTypes->setCurrentIndex(_sourceTypes->findData( + static_cast(_entryData->_sourceType))); + _sources->SetSource(_entryData->_source); _scenes->SetScene(_entryData->_scene); _states->setCurrentIndex(getIdxFromMediaState(_entryData->_state)); _timeRestrictions->setCurrentIndex( diff --git a/src/macro-core/macro-condition-media.hpp b/src/macro-core/macro-condition-media.hpp index f8a56f70..5ce4905c 100644 --- a/src/macro-core/macro-condition-media.hpp +++ b/src/macro-core/macro-condition-media.hpp @@ -1,13 +1,14 @@ #pragma once #include "macro.hpp" +#include "duration-control.hpp" +#include "scene-selection.hpp" +#include "source-selection.hpp" + #include #include #include #include -#include "duration-control.hpp" -#include "scene-selection.hpp" - constexpr auto custom_media_states_offset = 100; class MacroConditionMedia : public MacroCondition { @@ -65,8 +66,9 @@ public: Time _restriction = Time::TIME_RESTRICTION_NONE; SceneSelection _scene; - OBSWeakSource _source = nullptr; - std::vector _sources; + SourceSelection _source; + OBSWeakSource _rawSource = nullptr; + std::vector _sourceGroup; Duration _time; bool _onlyMatchOnChagne = false; @@ -109,7 +111,8 @@ public: } private slots: - void SourceChanged(const QString &text); + void SourceTypeChanged(int); + void SourceChanged(const SourceSelection &); void SceneChanged(const SceneSelection &); void StateChanged(int index); void TimeRestrictionChanged(int index); @@ -120,8 +123,9 @@ signals: void HeaderInfoChanged(const QString &); protected: + QComboBox *_sourceTypes; SceneSelectionWidget *_scenes; - QComboBox *_mediaSources; + SourceSelectionWidget *_sources; QComboBox *_states; QComboBox *_timeRestrictions; DurationSelection *_time;