diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 5bb9c3c0..99abfbdc 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -127,9 +127,11 @@ AdvSceneSwitcher.condition.scene.type.current="Current scene is" AdvSceneSwitcher.condition.scene.type.previous="Previous scene is" AdvSceneSwitcher.condition.scene.type.changed="Scene changed" AdvSceneSwitcher.condition.scene.type.notChanged="Scene has not changed" +AdvSceneSwitcher.condition.scene.type.currentPattern="Current scene matches" +AdvSceneSwitcher.condition.scene.type.previousPattern="Previous scene matches" AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="During transition check for transition target scene" AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="During transition check for transition source scene" -AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}} {{scenes}}" +AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}" AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}" AdvSceneSwitcher.condition.window="Window" AdvSceneSwitcher.condition.window.entry.line1="{{windows}} exist and ..." diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index 05474012..e3131894 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -121,7 +121,7 @@ AdvSceneSwitcher.condition.scene.type.changed="Escena cambiada" AdvSceneSwitcher.condition.scene.type.notChanged="La escena no ha cambiado" AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Durante la transición, verifique la escena de destino de la transición" AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la transición, verifique la escena de origen de la transición" -AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}} {{scenes}}" +AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}" AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}" AdvSceneSwitcher.condition.window="Ventana" AdvSceneSwitcher.condition.window.entry.line1="{{windows}} existen y ..." diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 2501a8c3..bec83986 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -109,7 +109,7 @@ AdvSceneSwitcher.condition.scene.type.previous="Önceki Sahne" AdvSceneSwitcher.condition.scene.type.changed="Sahne değişti" AdvSceneSwitcher.condition.scene.type.notChanged="Sahne değişmedi" AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Geçiş hedefi sahnesi için geçiş kontrolü sırasında" -AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}} {{scenes}}" +AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}" AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}" AdvSceneSwitcher.condition.window="Pencere" AdvSceneSwitcher.condition.window.entry.line1="{{windows}} Varolan ve ..." diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 6efe5982..1fd77531 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -113,7 +113,7 @@ AdvSceneSwitcher.condition.scene.type.current="当前场景是" AdvSceneSwitcher.condition.scene.type.previous="上一个场景是" AdvSceneSwitcher.condition.scene.type.changed="场景改变了" AdvSceneSwitcher.condition.scene.type.notChanged="场景没有改变" -AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}} {{scenes}}" +AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}" AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}" AdvSceneSwitcher.condition.window="窗口" AdvSceneSwitcher.condition.window.entry.line1="{{windows}} 存在..." diff --git a/src/macro-core/macro-condition-scene.cpp b/src/macro-core/macro-condition-scene.cpp index 27f98ad6..9d57841a 100644 --- a/src/macro-core/macro-condition-scene.cpp +++ b/src/macro-core/macro-condition-scene.cpp @@ -10,14 +10,35 @@ bool MacroConditionScene::_registered = MacroConditionFactory::Register( {MacroConditionScene::Create, MacroConditionSceneEdit::Create, "AdvSceneSwitcher.condition.scene"}); -static std::map sceneTypes = { - {SceneType::CURRENT, "AdvSceneSwitcher.condition.scene.type.current"}, - {SceneType::PREVIOUS, "AdvSceneSwitcher.condition.scene.type.previous"}, - {SceneType::CHANGED, "AdvSceneSwitcher.condition.scene.type.changed"}, - {SceneType::NOTCHANGED, +static std::map sceneTypes = { + {MacroConditionScene::Type::CURRENT, + "AdvSceneSwitcher.condition.scene.type.current"}, + {MacroConditionScene::Type::PREVIOUS, + "AdvSceneSwitcher.condition.scene.type.previous"}, + {MacroConditionScene::Type::CHANGED, + "AdvSceneSwitcher.condition.scene.type.changed"}, + {MacroConditionScene::Type::NOT_CHANGED, "AdvSceneSwitcher.condition.scene.type.notChanged"}, + {MacroConditionScene::Type::CURRENT_PATTERN, + "AdvSceneSwitcher.condition.scene.type.currentPattern"}, + {MacroConditionScene::Type::PREVIOUS_PATTERN, + "AdvSceneSwitcher.condition.scene.type.previousPattern"}, }; +static bool sceneNameMatchesRegex(const OBSWeakSource &scene, + const std::string &pattern) +{ + auto regex = QRegularExpression(QRegularExpression::anchoredPattern( + QString::fromStdString(pattern))); + if (!regex.isValid()) { + return false; + } + + auto match = + regex.match(QString::fromStdString(GetWeakSourceName(scene))); + return match.hasMatch(); +} + bool MacroConditionScene::CheckCondition() { bool sceneChanged = _lastSceneChangeTime != @@ -27,7 +48,7 @@ bool MacroConditionScene::CheckCondition() } switch (_type) { - case SceneType::CURRENT: + case Type::CURRENT: if (_useTransitionTargetScene) { auto current = obs_frontend_get_current_scene(); auto weak = obs_source_get_weak_source(current); @@ -37,18 +58,20 @@ bool MacroConditionScene::CheckCondition() return match; } return switcher->currentScene == _scene.GetScene(false); - case SceneType::PREVIOUS: + case Type::PREVIOUS: if (switcher->anySceneTransitionStarted() && _useTransitionTargetScene) { return switcher->currentScene == _scene.GetScene(false); } return switcher->previousScene == _scene.GetScene(false); - case SceneType::CHANGED: + case Type::CHANGED: return sceneChanged; - case SceneType::NOTCHANGED: + case Type::NOT_CHANGED: return !sceneChanged; - default: - break; + case Type::CURRENT_PATTERN: + return sceneNameMatchesRegex(switcher->currentScene, _pattern); + case Type::PREVIOUS_PATTERN: + return sceneNameMatchesRegex(switcher->previousScene, _pattern); } return false; @@ -59,6 +82,7 @@ bool MacroConditionScene::Save(obs_data_t *obj) MacroCondition::Save(obj); _scene.Save(obj); obs_data_set_int(obj, "type", static_cast(_type)); + obs_data_set_string(obj, "pattern", _pattern.c_str()); obs_data_set_bool(obj, "useTransitionTargetScene", _useTransitionTargetScene); return true; @@ -68,7 +92,8 @@ bool MacroConditionScene::Load(obs_data_t *obj) { MacroCondition::Load(obj); _scene.Load(obj); - _type = static_cast(obs_data_get_int(obj, "type")); + _type = static_cast(obs_data_get_int(obj, "type")); + _pattern = obs_data_get_string(obj, "pattern"); if (obs_data_has_user_value(obj, "waitForTransition")) { _useTransitionTargetScene = !obs_data_get_bool(obj, "waitForTransition"); @@ -81,7 +106,10 @@ bool MacroConditionScene::Load(obs_data_t *obj) std::string MacroConditionScene::GetShortDesc() { - return _scene.ToString(); + if (_type == Type::CURRENT || _type == Type::PREVIOUS) { + return _scene.ToString(); + } + return ""; } static inline void populateTypeSelection(QComboBox *list) @@ -93,17 +121,20 @@ static inline void populateTypeSelection(QComboBox *list) MacroConditionSceneEdit::MacroConditionSceneEdit( QWidget *parent, std::shared_ptr entryData) - : QWidget(parent) + : QWidget(parent), + _scenes(new SceneSelectionWidget(window(), true, false, false, + false)), + _sceneType(new QComboBox()), + _pattern(new QLineEdit()), + _useTransitionTargetScene(new QCheckBox(obs_module_text( + "AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour"))) { - _scenes = new SceneSelectionWidget(window(), true, false, false, false); - _sceneType = new QComboBox(); - _useTransitionTargetScene = new QCheckBox(obs_module_text( - "AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour")); - QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_sceneType, SIGNAL(currentIndexChanged(int)), this, SLOT(TypeChanged(int))); + QWidget::connect(_pattern, SIGNAL(editingFinished()), this, + SLOT(PatternChanged())); QWidget::connect(_useTransitionTargetScene, SIGNAL(stateChanged(int)), this, SLOT(UseTransitionTargetSceneChanged(int))); @@ -112,6 +143,7 @@ MacroConditionSceneEdit::MacroConditionSceneEdit( std::unordered_map widgetPlaceholders = { {"{{scenes}}", _scenes}, {"{{sceneType}}", _sceneType}, + {"{{pattern}}", _pattern}, {"{{useTransitionTargetScene}}", _useTransitionTargetScene}, }; QHBoxLayout *line1Layout = new QHBoxLayout; @@ -151,10 +183,20 @@ void MacroConditionSceneEdit::TypeChanged(int value) } std::lock_guard lock(switcher->m); - _entryData->_type = static_cast(value); + _entryData->_type = static_cast(value); SetWidgetVisibility(); } +void MacroConditionSceneEdit::PatternChanged() +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_pattern = _pattern->text().toStdString(); +} + void MacroConditionSceneEdit::UseTransitionTargetSceneChanged(int state) { if (_loading || !_entryData) { @@ -167,17 +209,23 @@ void MacroConditionSceneEdit::UseTransitionTargetSceneChanged(int state) void MacroConditionSceneEdit::SetWidgetVisibility() { - _scenes->setVisible(_entryData->_type == SceneType::CURRENT || - _entryData->_type == SceneType::PREVIOUS); + _scenes->setVisible( + _entryData->_type == MacroConditionScene::Type::CURRENT || + _entryData->_type == MacroConditionScene::Type::PREVIOUS); _useTransitionTargetScene->setVisible( - _entryData->_type == SceneType::CURRENT || - _entryData->_type == SceneType::PREVIOUS); + _entryData->_type == MacroConditionScene::Type::CURRENT || + _entryData->_type == MacroConditionScene::Type::PREVIOUS); + _pattern->setVisible( + _entryData->_type == + MacroConditionScene::Type::CURRENT_PATTERN || + _entryData->_type == + MacroConditionScene::Type::PREVIOUS_PATTERN); - if (_entryData->_type == SceneType::PREVIOUS) { + if (_entryData->_type == MacroConditionScene::Type::PREVIOUS) { _useTransitionTargetScene->setText(obs_module_text( "AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour")); } - if (_entryData->_type == SceneType::CURRENT) { + if (_entryData->_type == MacroConditionScene::Type::CURRENT) { _useTransitionTargetScene->setText(obs_module_text( "AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour")); } @@ -192,6 +240,7 @@ void MacroConditionSceneEdit::UpdateEntryData() _scenes->SetScene(_entryData->_scene); _sceneType->setCurrentIndex(static_cast(_entryData->_type)); + _pattern->setText(QString::fromStdString(_entryData->_pattern)); _useTransitionTargetScene->setChecked( _entryData->_useTransitionTargetScene); SetWidgetVisibility(); diff --git a/src/macro-core/macro-condition-scene.hpp b/src/macro-core/macro-condition-scene.hpp index be367ed7..97b0a04c 100644 --- a/src/macro-core/macro-condition-scene.hpp +++ b/src/macro-core/macro-condition-scene.hpp @@ -5,13 +5,7 @@ #include #include #include - -enum class SceneType { - CURRENT, - PREVIOUS, - CHANGED, - NOTCHANGED, -}; +#include class MacroConditionScene : public MacroCondition { public: @@ -26,8 +20,18 @@ public: return std::make_shared(m); } + enum class Type { + CURRENT, + PREVIOUS, + CHANGED, + NOT_CHANGED, + CURRENT_PATTERN, + PREVIOUS_PATTERN, + }; + SceneSelection _scene; - SceneType _type = SceneType::CURRENT; + Type _type = Type::CURRENT; + std::string _pattern = ".*Scene.*"; // During a transition "current" scene could either stand for the scene // being transitioned to or the scene still being transitioned away // from. @@ -58,6 +62,7 @@ public: private slots: void SceneChanged(const SceneSelection &); void TypeChanged(int value); + void PatternChanged(); void UseTransitionTargetSceneChanged(int state); signals: void HeaderInfoChanged(const QString &); @@ -65,6 +70,7 @@ signals: protected: SceneSelectionWidget *_scenes; QComboBox *_sceneType; + QLineEdit *_pattern; QCheckBox *_useTransitionTargetScene; std::shared_ptr _entryData;