diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index 286d01d6..095febf7 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -325,7 +325,9 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Nächster Treffer bei: %1" AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren" AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren" AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="Auf{{scenes}}{{sources}}passt zur Transformation" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="Auf{{scenes}}{{sources}}{{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="entspricht Transformation" +AdvSceneSwitcher.condition.sceneTransform.entry.type.changed="hat sich geändert" AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.transition="Übergang" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 42c2fdae..f4abbf69 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -407,7 +407,9 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1" AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}On repeat update selected date to repeat date" AdvSceneSwitcher.condition.sceneTransform="Scene item transform" AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="On{{scenes}}{{sources}}matches transform" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="On{{scenes}}{{sources}}{{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="matches transform" +AdvSceneSwitcher.condition.sceneTransform.entry.type.changed="has changed" AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}}{{getSettings}}" AdvSceneSwitcher.condition.transition="Transition" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index ce7eaf75..dbff47f5 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -275,7 +275,9 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima coincidencia en: % AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha" AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena" AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="En{{scenes}}{{sources}}coincide con la transformación" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="En{{scenes}}{{sources}}{{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="coincide con la transformación" +; AdvSceneSwitcher.condition.sceneTransform.entry.type.changed= AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.transition="Transición" diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini index 2d3ae40d..8f14cafa 100644 --- a/data/locale/fr-FR.ini +++ b/data/locale/fr-FR.ini @@ -386,7 +386,9 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Prochaine correspondance à AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition" AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène" AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="Sur{{scenes}}{{sources}}correspond à la transformation" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="Sur{{scenes}}{{sources}}{{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="correspond à la transformation" +; AdvSceneSwitcher.condition.sceneTransform.entry.type.changed= AdvSceneSwitcher.condition.transition="Transition" AdvSceneSwitcher.condition.transition.type.current="Le type de transition actuel est" AdvSceneSwitcher.condition.transition.type.duration="La durée de la transition actuelle est" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 409a07e0..564bab78 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -231,7 +231,9 @@ AdvSceneSwitcher.condition.date.state.before="Önce" AdvSceneSwitcher.condition.date.state.between="Arasında" AdvSceneSwitcher.condition.sceneTransform="Sahne öğesi dönüşümü" AdvSceneSwitcher.condition.sceneTransform.getTransform="Dönüşümü al" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="Açık{{scenes}}{{sources}} dönüşümle eşleşir" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="Açık{{scenes}}{{sources}}{{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="dönüşümle eşleşir" +; AdvSceneSwitcher.condition.sceneTransform.entry.type.changed= AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.transition="Geçiş" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 497462b2..f5a408c9 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -371,7 +371,9 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1" AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期" AdvSceneSwitcher.condition.sceneTransform="场景项目被改变" AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} 匹配变换" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} {{types}}" +AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="匹配变换" +; AdvSceneSwitcher.condition.sceneTransform.entry.type.changed= AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.transition="转场" diff --git a/src/macro-core/macro-condition-scene-transform.cpp b/src/macro-core/macro-condition-scene-transform.cpp index 0874418f..e2c834ca 100644 --- a/src/macro-core/macro-condition-scene-transform.cpp +++ b/src/macro-core/macro-condition-scene-transform.cpp @@ -12,19 +12,79 @@ bool MacroConditionSceneTransform::_registered = MacroConditionSceneTransformEdit::Create, "AdvSceneSwitcher.condition.sceneTransform"}); -bool MacroConditionSceneTransform::CheckCondition() +const static std::map + conditionTypes = { + {MacroConditionSceneTransform::CondType::MATCHES, + "AdvSceneSwitcher.condition.sceneTransform.entry.type.matches"}, + {MacroConditionSceneTransform::CondType::CHANGED, + "AdvSceneSwitcher.condition.sceneTransform.entry.type.changed"}, +}; + +static bool doesTransformOfAnySceneItemMatch( + const std::vector &items, const std::string &jsonCompare, + const RegexConfig ®ex, std::string &newVariable) { bool ret = false; - auto items = _source.GetSceneItems(_scene); - std::string json; for (const auto &item : items) { json = GetSceneItemTransform(item); - if (MatchJson(json, _settings, _regex)) { + if (MatchJson(json, jsonCompare, regex)) { ret = true; } } - SetVariableValue(json); + newVariable = json; + return ret; +} + +static bool +didTransformOfAnySceneItemChange(const std::vector &items, + std::vector &previousTransform, + std::string &newVariable) +{ + bool ret = false; + std::string json; + RegexConfig regex; + int n_items = items.size(); + if (previousTransform.size() < n_items) { + ret = true; + previousTransform.resize(n_items); + } + for (int idx = 0; idx < n_items; ++idx) { + auto const &item = items[idx]; + json = GetSceneItemTransform(item); + if (!MatchJson(json, previousTransform[idx], regex)) { + ret = true; + previousTransform[idx] = json; + } + } + newVariable = json; + return ret; +} + +bool MacroConditionSceneTransform::CheckCondition() +{ + auto items = _source.GetSceneItems(_scene); + if (items.empty()) { + return false; + } + + std::string newVariable = ""; + bool ret = false; + switch (_type) { + case CondType::MATCHES: + ret = doesTransformOfAnySceneItemMatch(items, _settings, _regex, + newVariable); + break; + case CondType::CHANGED: + ret = didTransformOfAnySceneItemChange( + items, _previousTransform, newVariable); + break; + + default: + return false; + } + + SetVariableValue(newVariable); return ret; } @@ -35,6 +95,7 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj) const _source.Save(obj); _settings.Save(obj, "settings"); _regex.Save(obj); + obs_data_set_int(obj, "type", static_cast(_type)); return true; } @@ -52,6 +113,7 @@ bool MacroConditionSceneTransform::Load(obs_data_t *obj) _source.Load(obj); _settings.Load(obj, "settings"); _regex.Load(obj); + _type = static_cast(obs_data_get_int(obj, "type")); // TOOD: remove in future version if (obs_data_has_user_value(obj, "regex")) { _regex.CreateBackwardsCompatibleRegex( @@ -69,6 +131,13 @@ std::string MacroConditionSceneTransform::GetShortDesc() const return _scene.ToString() + " - " + _source.ToString(); } +static inline void populateTypesSelection(QComboBox *list) +{ + for (const auto &entry : conditionTypes) { + list->addItem(obs_module_text(entry.second.c_str())); + } +} + MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( QWidget *parent, std::shared_ptr entryData) @@ -76,11 +145,14 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( _scenes(new SceneSelectionWidget(window(), true, false, false, true)), _sources(new SceneItemSelectionWidget( parent, true, SceneItemSelectionWidget::Placeholder::ANY)), + _types(new QComboBox()), _getSettings(new QPushButton(obs_module_text( "AdvSceneSwitcher.condition.sceneTransform.getTransform"))), _settings(new VariableTextEdit(this)), _regex(new RegexConfigWidget(parent)) { + populateTypesSelection(_types); + QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), @@ -88,6 +160,8 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( QWidget::connect(_sources, SIGNAL(SceneItemChanged(const SceneItemSelection &)), this, SLOT(SourceChanged(const SceneItemSelection &))); + QWidget::connect(_types, SIGNAL(currentIndexChanged(int)), this, + SLOT(TypeChanged(int))); QWidget::connect(_getSettings, SIGNAL(clicked()), this, SLOT(GetSettingsClicked())); QWidget::connect(_settings, SIGNAL(textChanged()), this, @@ -96,8 +170,11 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( SLOT(RegexChanged(RegexConfig))); std::unordered_map widgetPlaceholders = { - {"{{scenes}}", _scenes}, {"{{sources}}", _sources}, - {"{{settings}}", _settings}, {"{{getSettings}}", _getSettings}, + {"{{scenes}}", _scenes}, + {"{{sources}}", _sources}, + {"{{types}}", _types}, + {"{{settings}}", _settings}, + {"{{getSettings}}", _getSettings}, {"{{regex}}", _regex}, }; @@ -136,11 +213,10 @@ void MacroConditionSceneTransformEdit::UpdateEntryData() _scenes->SetScene(_entryData->_scene); _sources->SetSceneItem(_entryData->_source); + _types->setCurrentIndex(static_cast(_entryData->_type)); _regex->SetRegexConfig(_entryData->_regex); _settings->setPlainText(_entryData->_settings); - - adjustSize(); - updateGeometry(); + SetWidgetVisibility(); } void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s) @@ -168,6 +244,18 @@ void MacroConditionSceneTransformEdit::SourceChanged( updateGeometry(); } +void MacroConditionSceneTransformEdit::TypeChanged(int index) +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_type = + static_cast(index); + SetWidgetVisibility(); +} + void MacroConditionSceneTransformEdit::GetSettingsClicked() { @@ -213,4 +301,16 @@ void MacroConditionSceneTransformEdit::RegexChanged(RegexConfig conf) updateGeometry(); } +void MacroConditionSceneTransformEdit::SetWidgetVisibility() +{ + const bool showSettingsAndRegex = + _entryData->_type == + MacroConditionSceneTransform::CondType::MATCHES; + _settings->setVisible(showSettingsAndRegex); + _getSettings->setVisible(showSettingsAndRegex); + _regex->setVisible(showSettingsAndRegex); + adjustSize(); + updateGeometry(); +} + } // namespace advss diff --git a/src/macro-core/macro-condition-scene-transform.hpp b/src/macro-core/macro-condition-scene-transform.hpp index 945b1802..bfaf5e4c 100644 --- a/src/macro-core/macro-condition-scene-transform.hpp +++ b/src/macro-core/macro-condition-scene-transform.hpp @@ -23,12 +23,20 @@ public: return std::make_shared(m); } + enum class CondType { + MATCHES, + CHANGED, + }; + SceneSelection _scene; SceneItemSelection _source; + CondType _type = CondType::MATCHES; RegexConfig _regex; StringVariable _settings = ""; private: + std::vector _previousTransform; + static bool _registered; static const std::string id; }; @@ -54,6 +62,7 @@ public: private slots: void SceneChanged(const SceneSelection &); void SourceChanged(const SceneItemSelection &); + void TypeChanged(int type); void GetSettingsClicked(); void SettingsChanged(); void RegexChanged(RegexConfig); @@ -63,6 +72,7 @@ signals: protected: SceneSelectionWidget *_scenes; SceneItemSelectionWidget *_sources; + QComboBox *_types; QPushButton *_getSettings; VariableTextEdit *_settings; RegexConfigWidget *_regex; @@ -70,6 +80,7 @@ protected: std::shared_ptr _entryData; private: + void SetWidgetVisibility(); bool _loading = true; };