Add variable support to media condition

This commit is contained in:
WarmUpTill 2022-12-27 21:57:32 +01:00 committed by WarmUpTill
parent 30294842f2
commit a2906a534b
6 changed files with 88 additions and 76 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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="不匹配"

View File

@ -48,7 +48,8 @@ static std::map<MacroConditionMedia::State, std::string> 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<int>(_sourceType));
obs_data_set_int(obj, "state", static_cast<int>(_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<Type>(obs_data_get_int(obj, "sourceType"));
_state = static_cast<MacroConditionMedia::State>(
@ -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<int>(MacroConditionMedia::Type::SOURCE));
list->addItem(
obs_module_text("AdvSceneSwitcher.condition.media.anyOnScene"),
static_cast<int>(MacroConditionMedia::Type::ANY));
list->addItem(
obs_module_text("AdvSceneSwitcher.condition.media.allOnScene"),
static_cast<int>(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<std::string, QWidget *> 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<std::mutex> lock(switcher->m);
_entryData->_sourceType = static_cast<MacroConditionMedia::Type>(
_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<std::mutex> 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<int>(_entryData->_sourceType)));
_sources->SetSource(_entryData->_source);
_scenes->SetScene(_entryData->_scene);
_states->setCurrentIndex(getIdxFromMediaState(_entryData->_state));
_timeRestrictions->setCurrentIndex(

View File

@ -1,13 +1,14 @@
#pragma once
#include "macro.hpp"
#include "duration-control.hpp"
#include "scene-selection.hpp"
#include "source-selection.hpp"
#include <limits>
#include <QWidget>
#include <QComboBox>
#include <QCheckBox>
#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<MacroConditionMedia> _sources;
SourceSelection _source;
OBSWeakSource _rawSource = nullptr;
std::vector<MacroConditionMedia> _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;