#include "macro-condition-scene-visibility.hpp" #include "layout-helpers.hpp" #include "obs-module-helper.hpp" #include namespace advss { const std::string MacroConditionSceneVisibility::id = "scene_visibility"; bool MacroConditionSceneVisibility::_registered = MacroConditionFactory::Register( MacroConditionSceneVisibility::id, {MacroConditionSceneVisibility::Create, MacroConditionSceneVisibilityEdit::Create, "AdvSceneSwitcher.condition.sceneVisibility"}); const static std::map conditionTypes = { {MacroConditionSceneVisibility::Condition::SHOWN, "AdvSceneSwitcher.condition.sceneVisibility.type.shown"}, {MacroConditionSceneVisibility::Condition::HIDDEN, "AdvSceneSwitcher.condition.sceneVisibility.type.hidden"}, {MacroConditionSceneVisibility::Condition::CHANGED, "AdvSceneSwitcher.condition.sceneVisibility.type.changed"}, }; static bool areAllSceneItemsShown(const std::vector &items) { bool ret = true; for (const auto &item : items) { if (!obs_sceneitem_visible(item)) { ret = false; } } return ret; } static bool isAnySceneItemShown(const std::vector &items) { bool ret = false; for (const auto &item : items) { ret |= obs_sceneitem_visible(item); } return ret; } static bool areAllSceneItemsHidden(const std::vector &items) { bool ret = true; for (const auto &item : items) { if (obs_sceneitem_visible(item)) { ret = false; } } return ret; } static bool isAnySceneItemHidden(const std::vector &items) { bool ret = false; for (const auto &item : items) { ret |= (!obs_sceneitem_visible(item)); } return ret; } static bool didVisibilityOfAnySceneItemsChange(const std::vector &items, std::vector &previousVisibility) { std::vector currentVisibility; for (const auto &item : items) { currentVisibility.emplace_back(obs_sceneitem_visible(item)); } bool ret = true; if (previousVisibility.size() != currentVisibility.size()) { ret = false; } else { ret = previousVisibility != currentVisibility; } previousVisibility = currentVisibility; return ret; } static bool didVisibilityOfAllSceneItemsChange(const std::vector &items, std::vector &previousVisibility) { std::vector currentVisibility; for (const auto &item : items) { currentVisibility.emplace_back(obs_sceneitem_visible(item)); } if (previousVisibility.size() != currentVisibility.size()) { previousVisibility = currentVisibility; return false; } for (std::size_t i = 0; i < currentVisibility.size(); i++) { if (currentVisibility[i] == previousVisibility[i]) { previousVisibility = currentVisibility; return false; } } previousVisibility = currentVisibility; return true; } bool MacroConditionSceneVisibility::CheckCondition() { auto items = _source.GetSceneItems(_scene); if (items.empty()) { _previousVisibility.clear(); return false; } const bool checkAny = _source.IsSelectionOfTypeAny(); switch (_condition) { case Condition::SHOWN: return checkAny ? isAnySceneItemShown(items) : areAllSceneItemsShown(items); case Condition::HIDDEN: return checkAny ? isAnySceneItemHidden(items) : areAllSceneItemsHidden(items); case Condition::CHANGED: return checkAny ? didVisibilityOfAnySceneItemsChange( items, _previousVisibility) : didVisibilityOfAllSceneItemsChange( items, _previousVisibility); default: break; } return false; } bool MacroConditionSceneVisibility::Save(obs_data_t *obj) const { MacroCondition::Save(obj); _scene.Save(obj); _source.Save(obj); obs_data_set_int(obj, "condition", static_cast(_condition)); obs_data_set_int(obj, "version", 1); return true; } bool MacroConditionSceneVisibility::Load(obs_data_t *obj) { // Convert old data format // TODO: Remove in future version if (obs_data_has_user_value(obj, "source")) { auto sourceName = obs_data_get_string(obj, "source"); obs_data_set_string(obj, "sceneItem", sourceName); } MacroCondition::Load(obj); _scene.Load(obj); _source.Load(obj); _condition = static_cast(obs_data_get_int(obj, "condition")); if (!obs_data_has_user_value(obj, "version") && _condition == Condition::CHANGED && _source.GetType() == SceneItemSelection::Type::ALL) { _source.SetType(SceneItemSelection::Type::ANY); } return true; } std::string MacroConditionSceneVisibility::GetShortDesc() const { if (_source.ToString().empty()) { return ""; } return _scene.ToString() + " - " + _source.ToString(); } static inline void populateConditionSelection(QComboBox *list) { for (const auto &entry : conditionTypes) { list->addItem(obs_module_text(entry.second.c_str())); } } MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit( QWidget *parent, std::shared_ptr entryData) : QWidget(parent) { _scenes = new SceneSelectionWidget(this, true, false, true, true); _sources = new SceneItemSelectionWidget(parent); _conditions = new QComboBox(); populateConditionSelection(_conditions); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), _sources, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_sources, SIGNAL(SceneItemChanged(const SceneItemSelection &)), this, SLOT(SourceChanged(const SceneItemSelection &))); QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this, SLOT(ConditionChanged(int))); auto layout = new QHBoxLayout; PlaceWidgets( obs_module_text( "AdvSceneSwitcher.condition.sceneVisibility.entry"), layout, {{"{{sources}}", _sources}, {"{{scenes}}", _scenes}, {"{{conditions}}", _conditions}}); setLayout(layout); _entryData = entryData; UpdateEntryData(); _loading = false; } void MacroConditionSceneVisibilityEdit::SourceChanged( const SceneItemSelection &item) { GUARD_LOADING_AND_LOCK(); _entryData->_source = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); adjustSize(); updateGeometry(); } void MacroConditionSceneVisibilityEdit::SceneChanged(const SceneSelection &s) { GUARD_LOADING_AND_LOCK(); _entryData->_scene = s; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } void MacroConditionSceneVisibilityEdit::ConditionChanged(int index) { GUARD_LOADING_AND_LOCK(); _entryData->_condition = static_cast(index); } void MacroConditionSceneVisibilityEdit::UpdateEntryData() { if (!_entryData) { return; } _conditions->setCurrentIndex(static_cast(_entryData->_condition)); _scenes->SetScene(_entryData->_scene); _sources->SetSceneItem(_entryData->_source); } } // namespace advss