diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9ce5f642..73704bf2 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -214,7 +214,7 @@ AdvSceneSwitcher.condition.sceneOrder.type.above="Is above" AdvSceneSwitcher.condition.sceneOrder.type.below="Is below" AdvSceneSwitcher.condition.sceneOrder.type.position="Is at position" AdvSceneSwitcher.condition.sceneOrder.positionInfo="The position value starts at the bottom with 0 and increases by one for each scene item including the ones in scene groups" -AdvSceneSwitcher.condition.sceneOrder.entry="On {{scenes}} {{sources}} {{conditions}} {{sources2}} {{position}}" +AdvSceneSwitcher.condition.sceneOrder.entry="On{{scenes}}{{sources}}{{conditions}}{{sources2}}{{position}}" AdvSceneSwitcher.condition.hotkey="Hotkey" AdvSceneSwitcher.condition.hotkey.name="Macro trigger hotkey" AdvSceneSwitcher.condition.hotkey.tip="Note: You can configure the keybindings for this hotkey in the OBS settings window" @@ -234,7 +234,7 @@ AdvSceneSwitcher.condition.date.entry.line2="{{repeat}} Repeat every {{duration} AdvSceneSwitcher.condition.sceneTransform="Scene item transform" AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform" AdvSceneSwitcher.condition.sceneTransform.regex="Use regular expressions" -AdvSceneSwitcher.condition.sceneTransform.entry.line1="On {{scenes}} {{sources}} matches transform" +AdvSceneSwitcher.condition.sceneTransform.entry.line1="On{{scenes}}{{sources}}matches transform" AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}" AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.transition="Transition" @@ -249,7 +249,7 @@ AdvSceneSwitcher.condition.transition.entry="{{conditions}}{{transitions}}{{scen AdvSceneSwitcher.condition.sceneVisibility="Scene item visibility" AdvSceneSwitcher.condition.sceneVisibility.type.shown="Shown" AdvSceneSwitcher.condition.sceneVisibility.type.hidden="Hidden" -AdvSceneSwitcher.condition.sceneVisibility.entry="On {{scenes}} {{sources}} is {{conditions}}" +AdvSceneSwitcher.condition.sceneVisibility.entry="On{{scenes}}{{sources}}is{{conditions}}" AdvSceneSwitcher.condition.studioMode="Studio mode" AdvSceneSwitcher.condition.studioMode.state.active="Studio mode is active" AdvSceneSwitcher.condition.studioMode.state.notActive="Studio mode is not active" @@ -298,7 +298,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.show="Show" AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide" AdvSceneSwitcher.action.sceneVisibility.type.source="Source" AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Any" -AdvSceneSwitcher.action.sceneVisibility.entry="On {{scenes}} {{actions}} {{sourceTypes}} {{sources}}" +AdvSceneSwitcher.action.sceneVisibility.entry="On{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}" AdvSceneSwitcher.action.filter="Filter" AdvSceneSwitcher.action.filter.type.enable="Enable" AdvSceneSwitcher.action.filter.type.disable="Disable" @@ -354,10 +354,10 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down" AdvSceneSwitcher.action.sceneOrder.type.moveTop="Move to top" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom" AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position" -AdvSceneSwitcher.action.sceneOrder.entry="On {{scenes}} {{actions}} {{sources}} {{position}}" +AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}" AdvSceneSwitcher.action.sceneTransform="Scene item transform" AdvSceneSwitcher.action.sceneTransform.getTransform="Get transform" -AdvSceneSwitcher.action.sceneTransform.entry="On {{scenes}} transform {{sources}}" +AdvSceneSwitcher.action.sceneTransform.entry="On{{scenes}}transform{{sources}}" AdvSceneSwitcher.action.file="File" AdvSceneSwitcher.action.file.type.write="Write" AdvSceneSwitcher.action.file.type.append="Append" diff --git a/src/headers/macro-action-scene-order.hpp b/src/headers/macro-action-scene-order.hpp index dcd19c27..37be93d8 100644 --- a/src/headers/macro-action-scene-order.hpp +++ b/src/headers/macro-action-scene-order.hpp @@ -1,7 +1,9 @@ #pragma once -#include #include "macro-action-edit.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" + +#include enum class SceneOrderAction { MOVE_UP, @@ -25,7 +27,7 @@ public: } SceneSelection _scene; - OBSWeakSource _source; + SceneItemSelection _source; SceneOrderAction _action = SceneOrderAction::MOVE_UP; int _position = 0; @@ -53,7 +55,7 @@ public: private slots: void SceneChanged(const SceneSelection &); - void SourceChanged(const QString &text); + void SourceChanged(const SceneItemSelection &); void ActionChanged(int value); void PositionChanged(int value); signals: @@ -61,7 +63,7 @@ signals: protected: SceneSelectionWidget *_scenes; - QComboBox *_sources; + SceneItemSelectionWidget *_sources; QComboBox *_actions; QSpinBox *_position; std::shared_ptr _entryData; diff --git a/src/headers/macro-action-scene-transform.hpp b/src/headers/macro-action-scene-transform.hpp index 77c544a5..1468a95b 100644 --- a/src/headers/macro-action-scene-transform.hpp +++ b/src/headers/macro-action-scene-transform.hpp @@ -1,8 +1,10 @@ #pragma once -#include -#include #include "macro-action-edit.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" + +#include +#include class MacroActionSceneTransform : public MacroAction { public: @@ -20,7 +22,7 @@ public: void SetSettings(std::string &); SceneSelection _scene; - OBSWeakSource _source; + SceneItemSelection _source; struct obs_transform_info _info = {}; struct obs_sceneitem_crop _crop = {}; @@ -48,7 +50,7 @@ public: private slots: void SceneChanged(const SceneSelection &); - void SourceChanged(const QString &text); + void SourceChanged(const SceneItemSelection &); void GetSettingsClicked(); void SettingsChanged(); signals: @@ -56,7 +58,7 @@ signals: protected: SceneSelectionWidget *_scenes; - QComboBox *_sources; + SceneItemSelectionWidget *_sources; QPushButton *_getSettings; QPlainTextEdit *_settings; std::shared_ptr _entryData; diff --git a/src/headers/macro-action-scene-visibility.hpp b/src/headers/macro-action-scene-visibility.hpp index 0c31cd21..aa5d0336 100644 --- a/src/headers/macro-action-scene-visibility.hpp +++ b/src/headers/macro-action-scene-visibility.hpp @@ -1,7 +1,9 @@ #pragma once -#include #include "macro-action-edit.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" + +#include enum class SceneVisibilityAction { SHOW, @@ -28,7 +30,7 @@ public: SceneSelection _scene; SceneItemSourceType _sourceType = SceneItemSourceType::SOURCE; - OBSWeakSource _source; + SceneItemSelection _source; std::string _sourceGroup = ""; SceneVisibilityAction _action = SceneVisibilityAction::SHOW; @@ -57,7 +59,8 @@ public: private slots: void SceneChanged(const SceneSelection &); void SourceTypeChanged(int value); - void SourceChanged(const QString &text); + void SourceChanged(const SceneItemSelection &); + void SourceGroupChanged(const QString &text); void ActionChanged(int value); signals: void HeaderInfoChanged(const QString &); @@ -65,11 +68,14 @@ signals: protected: SceneSelectionWidget *_scenes; QComboBox *_sourceTypes; - QComboBox *_sources; + SceneItemSelectionWidget *_sources; + QComboBox *_sourceGroups; QComboBox *_actions; std::shared_ptr _entryData; private: + void SetWidgetVisibility(); + QHBoxLayout *_mainLayout; bool _loading = true; }; diff --git a/src/headers/macro-condition-scene-order.hpp b/src/headers/macro-condition-scene-order.hpp index 0604f9a1..81efa901 100644 --- a/src/headers/macro-condition-scene-order.hpp +++ b/src/headers/macro-condition-scene-order.hpp @@ -1,6 +1,7 @@ #pragma once #include "macro.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" #include #include @@ -24,8 +25,8 @@ public: } SceneSelection _scene; - OBSWeakSource _source; - OBSWeakSource _source2; + SceneItemSelection _source; + SceneItemSelection _source2; int _position = 0; SceneOrderCondition _condition = SceneOrderCondition::ABOVE; @@ -53,8 +54,8 @@ public: private slots: void SceneChanged(const SceneSelection &); - void SourceChanged(const QString &text); - void Source2Changed(const QString &text); + void SourceChanged(const SceneItemSelection &); + void Source2Changed(const SceneItemSelection &); void ConditionChanged(int cond); void PositionChanged(int cond); signals: @@ -63,8 +64,8 @@ signals: protected: SceneSelectionWidget *_scenes; QComboBox *_conditions; - QComboBox *_sources; - QComboBox *_sources2; + SceneItemSelectionWidget *_sources; + SceneItemSelectionWidget *_sources2; QSpinBox *_position; QLabel *_posInfo; diff --git a/src/headers/macro-condition-scene-transform.hpp b/src/headers/macro-condition-scene-transform.hpp index 9e393286..fa0c23ea 100644 --- a/src/headers/macro-condition-scene-transform.hpp +++ b/src/headers/macro-condition-scene-transform.hpp @@ -1,6 +1,7 @@ #pragma once #include "macro.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" #include #include @@ -19,7 +20,7 @@ public: } SceneSelection _scene; - OBSWeakSource _source; + SceneItemSelection _source; bool _regex = false; std::string _settings = ""; @@ -48,7 +49,7 @@ public: private slots: void SceneChanged(const SceneSelection &); - void SourceChanged(const QString &text); + void SourceChanged(const SceneItemSelection &); void GetSettingsClicked(); void SettingsChanged(); void RegexChanged(int); @@ -57,7 +58,7 @@ signals: protected: SceneSelectionWidget *_scenes; - QComboBox *_sources; + SceneItemSelectionWidget *_sources; QPushButton *_getSettings; QPlainTextEdit *_settings; QCheckBox *_regex; diff --git a/src/headers/macro-condition-scene-visibility.hpp b/src/headers/macro-condition-scene-visibility.hpp index 7360fc24..a51ecd2e 100644 --- a/src/headers/macro-condition-scene-visibility.hpp +++ b/src/headers/macro-condition-scene-visibility.hpp @@ -1,6 +1,7 @@ #pragma once #include "macro.hpp" #include "scene-selection.hpp" +#include "scene-item-selection.hpp" #include @@ -22,7 +23,7 @@ public: } SceneSelection _scene; - OBSWeakSource _source; + SceneItemSelection _source; SceneVisibilityCondition _condition = SceneVisibilityCondition::SHOWN; private: @@ -49,14 +50,14 @@ public: private slots: void SceneChanged(const SceneSelection &); - void SourceChanged(const QString &text); + void SourceChanged(const SceneItemSelection &); void ConditionChanged(int cond); signals: void HeaderInfoChanged(const QString &); protected: SceneSelectionWidget *_scenes; - QComboBox *_sources; + SceneItemSelectionWidget *_sources; QComboBox *_conditions; std::shared_ptr _entryData; diff --git a/src/macro-action-scene-order.cpp b/src/macro-action-scene-order.cpp index b622125b..9cff6434 100644 --- a/src/macro-action-scene-order.cpp +++ b/src/macro-action-scene-order.cpp @@ -22,37 +22,77 @@ const static std::map actionTypes = { "AdvSceneSwitcher.action.sceneOrder.type.movePosition"}, }; -bool MacroActionSceneOrder::PerformAction() +void moveSceneItemsUp(std::vector &items) { - auto s = obs_weak_source_get_source(_scene.GetScene()); - auto scene = obs_scene_from_source(s); - auto name = GetWeakSourceName(_source); - auto items = getSceneItemsWithName(scene, name); + // In the case of the same source being in two sequential positions + // moving the sources up will cause the sources to swap positions due to + // the order scene items are being iterated over, which is most likely + // not the desired effect. + // Instead we reverse the order of the scene items so all scene items + // will be moved up. + std::reverse(items.begin(), items.end()); for (auto &i : items) { - switch (_action) { - case SceneOrderAction::MOVE_UP: - obs_sceneitem_set_order(i, OBS_ORDER_MOVE_UP); - break; - case SceneOrderAction::MOVE_DOWN: - obs_sceneitem_set_order(i, OBS_ORDER_MOVE_DOWN); - break; - case SceneOrderAction::MOVE_TOP: - obs_sceneitem_set_order(i, OBS_ORDER_MOVE_TOP); - break; - case SceneOrderAction::MOVE_BOTTOM: - obs_sceneitem_set_order(i, OBS_ORDER_MOVE_BOTTOM); - break; - case SceneOrderAction::POSITION: - obs_sceneitem_set_order_position(i, _position); - break; - default: - break; - } + obs_sceneitem_set_order(i, OBS_ORDER_MOVE_UP); obs_sceneitem_release(i); } +} - obs_source_release(s); +void moveSceneItemsDown(std::vector &items) +{ + for (auto &i : items) { + obs_sceneitem_set_order(i, OBS_ORDER_MOVE_DOWN); + obs_sceneitem_release(i); + } +} + +void moveSceneItemsTop(std::vector &items) +{ + for (auto &i : items) { + obs_sceneitem_set_order(i, OBS_ORDER_MOVE_TOP); + obs_sceneitem_release(i); + } +} + +void moveSceneItemsBottom(std::vector &items) +{ + for (auto &i : items) { + obs_sceneitem_set_order(i, OBS_ORDER_MOVE_BOTTOM); + obs_sceneitem_release(i); + } +} + +void moveSceneItemsPos(std::vector &items, int pos) +{ + for (auto &i : items) { + obs_sceneitem_set_order_position(i, pos); + obs_sceneitem_release(i); + } +} + +bool MacroActionSceneOrder::PerformAction() +{ + auto items = _source.GetSceneItems(_scene); + + switch (_action) { + case SceneOrderAction::MOVE_UP: + moveSceneItemsUp(items); + break; + case SceneOrderAction::MOVE_DOWN: + moveSceneItemsDown(items); + break; + case SceneOrderAction::MOVE_TOP: + moveSceneItemsTop(items); + break; + case SceneOrderAction::MOVE_BOTTOM: + moveSceneItemsBottom(items); + break; + case SceneOrderAction::POSITION: + moveSceneItemsPos(items, _position); + break; + default: + break; + } return true; } @@ -62,7 +102,7 @@ void MacroActionSceneOrder::LogAction() if (it != actionTypes.end()) { vblog(LOG_INFO, "performed order action \"%s\" for source \"%s\" on scene \"%s\"", - it->second.c_str(), GetWeakSourceName(_source).c_str(), + it->second.c_str(), _source.ToString().c_str(), _scene.ToString().c_str()); } else { blog(LOG_WARNING, "ignored unknown scene order action %d", @@ -74,7 +114,7 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj) { MacroAction::Save(obj); _scene.Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); + _source.Save(obj); obs_data_set_int(obj, "action", static_cast(_action)); obs_data_set_int(obj, "position", _position); return true; @@ -82,10 +122,16 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj) bool MacroActionSceneOrder::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); + } + MacroAction::Load(obj); _scene.Load(obj); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); + _source.Load(obj); _action = static_cast(obs_data_get_int(obj, "action")); _position = obs_data_get_int(obj, "position"); @@ -94,10 +140,10 @@ bool MacroActionSceneOrder::Load(obs_data_t *obj) std::string MacroActionSceneOrder::GetShortDesc() { - if (_source) { - return _scene.ToString() + " - " + GetWeakSourceName(_source); + if (_source.ToString().empty()) { + return ""; } - return ""; + return _scene.ToString() + " - " + _source.ToString(); } static inline void populateActionSelection(QComboBox *list) @@ -112,7 +158,7 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit( : QWidget(parent) { _scenes = new SceneSelectionWidget(window(), false, false, true); - _sources = new QComboBox(); + _sources = new SceneItemSelectionWidget(parent); _actions = new QComboBox(); _position = new QSpinBox(); @@ -122,8 +168,11 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit( SLOT(ActionChanged(int))); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); + 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(_position, SIGNAL(valueChanged(int)), this, SLOT(PositionChanged(int))); @@ -152,9 +201,7 @@ void MacroActionSceneOrderEdit::UpdateEntryData() _actions->setCurrentIndex(static_cast(_entryData->_action)); _scenes->SetScene(_entryData->_scene); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); + _sources->SetSceneItem(_entryData->_source); _position->setValue(_entryData->_position); _position->setVisible(_entryData->_action == SceneOrderAction::POSITION); @@ -165,22 +212,19 @@ void MacroActionSceneOrderEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; } -void MacroActionSceneOrderEdit::SourceChanged(const QString &text) +void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } diff --git a/src/macro-action-scene-transform.cpp b/src/macro-action-scene-transform.cpp index 4f46fe3f..79a24556 100644 --- a/src/macro-action-scene-transform.cpp +++ b/src/macro-action-scene-transform.cpp @@ -12,13 +12,8 @@ bool MacroActionSceneTransform::_registered = MacroActionFactory::Register( bool MacroActionSceneTransform::PerformAction() { - auto s = obs_weak_source_get_source(_scene.GetScene(false)); - auto scene = obs_scene_from_source(s); - auto name = GetWeakSourceName(_source); - auto items = getSceneItemsWithName(scene, name); - + auto items = _source.GetSceneItems(_scene); for (auto &item : items) { - // Apply settings obs_sceneitem_defer_update_begin(item); obs_sceneitem_set_info(item, &_info); obs_sceneitem_set_crop(item, &_crop); @@ -26,8 +21,6 @@ bool MacroActionSceneTransform::PerformAction() obs_sceneitem_release(item); } - - obs_source_release(s); return true; } @@ -35,34 +28,40 @@ void MacroActionSceneTransform::LogAction() { vblog(LOG_INFO, "performed transform action for source \"%s\" on scene \"%s\"", - GetWeakSourceName(_source).c_str(), _scene.ToString().c_str()); + _source.ToString().c_str(), _scene.ToString().c_str()); } bool MacroActionSceneTransform::Save(obs_data_t *obj) { MacroAction::Save(obj); _scene.Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); + _source.Save(obj); saveTransformState(obj, _info, _crop); return true; } bool MacroActionSceneTransform::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); + } + MacroAction::Load(obj); _scene.Load(obj); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); + _source.Load(obj); loadTransformState(obj, _info, _crop); return true; } std::string MacroActionSceneTransform::GetShortDesc() { - if (_source) { - return _scene.ToString() + " - " + GetWeakSourceName(_source); + if (_source.ToString().empty()) { + return ""; } - return ""; + return _scene.ToString() + " - " + _source.ToString(); } std::string MacroActionSceneTransform::GetSettings() @@ -81,9 +80,13 @@ void MacroActionSceneTransform::SetSettings(std::string &settings) return; } loadTransformState(data, _info, _crop); + auto items = _source.GetSceneItems(_scene); + if (items.empty()) { + return; + } if (obs_data_has_user_value(data, "size")) { auto obj = obs_data_get_obj(data, "size"); - auto source = obs_weak_source_get_source(_source); + auto source = obs_sceneitem_get_source(items[0]); if (double h = obs_data_get_double(obj, "height")) { _info.scale.y = h / double(obs_source_get_height(source)); @@ -93,9 +96,10 @@ void MacroActionSceneTransform::SetSettings(std::string &settings) w / double(obs_source_get_width(source)); } obs_data_release(obj); - obs_source_release(source); } - + for (auto item : items) { + obs_sceneitem_release(item); + } obs_data_release(data); } @@ -104,15 +108,18 @@ MacroActionSceneTransformEdit::MacroActionSceneTransformEdit( : QWidget(parent) { _scenes = new SceneSelectionWidget(window(), false, false, true); - _sources = new QComboBox(); + _sources = new SceneItemSelectionWidget(parent); _getSettings = new QPushButton(obs_module_text( "AdvSceneSwitcher.action.sceneTransform.getTransform")); _settings = new QPlainTextEdit(); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); + 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(_getSettings, SIGNAL(clicked()), this, SLOT(GetSettingsClicked())); QWidget::connect(_settings, SIGNAL(textChanged()), this, @@ -152,13 +159,8 @@ void MacroActionSceneTransformEdit::UpdateEntryData() } _scenes->SetScene(_entryData->_scene); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); - if (_entryData->_source) { - _settings->setPlainText( - formatJsonString(_entryData->GetSettings())); - } + _sources->SetSceneItem(_entryData->_source); + _settings->setPlainText(formatJsonString(_entryData->GetSettings())); } void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s) @@ -166,44 +168,39 @@ void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; } -void MacroActionSceneTransformEdit::SourceChanged(const QString &text) +void MacroActionSceneTransformEdit::SourceChanged(const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } void MacroActionSceneTransformEdit::GetSettingsClicked() { - if (_loading || !_entryData || !_entryData->_scene.GetScene(false) || - !_entryData->_source) { + if (_loading || !_entryData || !_entryData->_scene.GetScene(false)) { return; } - auto s = obs_weak_source_get_source(_entryData->_scene.GetScene(false)); - auto scene = obs_scene_from_source(s); - auto name = GetWeakSourceName(_entryData->_source); - auto item = obs_scene_find_source_recursive(scene, name.c_str()); - obs_source_release(s); - - if (!item) { + auto items = _entryData->_source.GetSceneItems(_entryData->_scene); + if (items.empty()) { return; } - _settings->setPlainText(formatJsonString(getSceneItemTransform(item))); + auto settings = getSceneItemTransform(items[0]); + _settings->setPlainText(formatJsonString(settings)); + for (auto item : items) { + obs_sceneitem_release(item); + } } void MacroActionSceneTransformEdit::SettingsChanged() diff --git a/src/macro-action-scene-visibility.cpp b/src/macro-action-scene-visibility.cpp index e94c3980..80002352 100644 --- a/src/macro-action-scene-visibility.cpp +++ b/src/macro-action-scene-visibility.cpp @@ -29,23 +29,6 @@ struct VisibilityData { bool visible; }; -static bool visibilitySourceEnum(obs_scene_t *, obs_sceneitem_t *item, - void *ptr) -{ - VisibilityData *vInfo = reinterpret_cast(ptr); - auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item)); - if (vInfo->name == sourceName) { - obs_sceneitem_set_visible(item, vInfo->visible); - } - - if (obs_sceneitem_is_group(item)) { - obs_scene_t *scene = obs_sceneitem_group_get_scene(item); - obs_scene_enum_items(scene, visibilitySourceEnum, ptr); - } - - return true; -} - static bool visibilitySourceTypeEnum(obs_scene_t *, obs_sceneitem_t *item, void *ptr) { @@ -67,25 +50,29 @@ static bool visibilitySourceTypeEnum(obs_scene_t *, obs_sceneitem_t *item, bool MacroActionSceneVisibility::PerformAction() { - auto s = obs_weak_source_get_source(_scene.GetScene()); - auto scene = obs_scene_from_source(s); - auto sourceName = GetWeakSourceName(_source); - VisibilityData vInfo = {"", _action == SceneVisibilityAction::SHOW}; - switch (_sourceType) { - case SceneItemSourceType::SOURCE: - vInfo.name = sourceName; - obs_scene_enum_items(scene, visibilitySourceEnum, &vInfo); + case SceneItemSourceType::SOURCE: { + auto items = _source.GetSceneItems(_scene); + for (auto item : items) { + obs_sceneitem_set_visible( + item, _action == SceneVisibilityAction::SHOW); + obs_sceneitem_release(item); + } break; - case SceneItemSourceType::SOURCE_GROUP: - vInfo.name = _sourceGroup; + } + case SceneItemSourceType::SOURCE_GROUP: { + auto s = obs_weak_source_get_source(_scene.GetScene()); + auto scene = obs_scene_from_source(s); + VisibilityData vInfo = {_sourceGroup, + _action == SceneVisibilityAction::SHOW}; obs_scene_enum_items(scene, visibilitySourceTypeEnum, &vInfo); + obs_source_release(s); break; + } default: break; } - obs_source_release(s); return true; } @@ -96,8 +83,7 @@ void MacroActionSceneVisibility::LogAction() if (_sourceType == SceneItemSourceType::SOURCE) { vblog(LOG_INFO, "performed visibility action \"%s\" for source \"%s\" on scene \"%s\"", - it->second.c_str(), - GetWeakSourceName(_source).c_str(), + it->second.c_str(), _source.ToString().c_str(), _scene.ToString().c_str()); } else { vblog(LOG_INFO, @@ -116,10 +102,9 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj) MacroAction::Save(obj); _scene.Save(obj); if (_sourceType == SceneItemSourceType::SOURCE) { - obs_data_set_string(obj, "source", - GetWeakSourceName(_source).c_str()); + _source.Save(obj); } else { - obs_data_set_string(obj, "source", _sourceGroup.c_str()); + obs_data_set_string(obj, "sourceGroup", _sourceGroup.c_str()); } obs_data_set_int(obj, "action", static_cast(_action)); obs_data_set_int(obj, "sourceType", static_cast(_sourceType)); @@ -128,13 +113,20 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj) bool MacroActionSceneVisibility::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); + obs_data_set_string(obj, "sourceGroup", sourceName); + } + MacroAction::Load(obj); _scene.Load(obj); + _source.Load(obj); _sourceType = static_cast( obs_data_get_int(obj, "sourceType")); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); - _sourceGroup = sourceName; + _sourceGroup = obs_data_get_string(obj, "sourceGroup"); _action = static_cast( obs_data_get_int(obj, "action")); return true; @@ -142,8 +134,9 @@ bool MacroActionSceneVisibility::Load(obs_data_t *obj) std::string MacroActionSceneVisibility::GetShortDesc() { - if (_sourceType == SceneItemSourceType::SOURCE && _source) { - return _scene.ToString() + " - " + GetWeakSourceName(_source); + if (_sourceType == SceneItemSourceType::SOURCE && + !_source.ToString().empty()) { + return _scene.ToString() + " - " + _source.ToString(); } if (_sourceType == SceneItemSourceType::SOURCE_GROUP && !_sourceGroup.empty()) { @@ -175,11 +168,12 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit( { _scenes = new SceneSelectionWidget(window(), false, true, true); _sourceTypes = new QComboBox(); - _sources = new QComboBox(); - _sources->setSizeAdjustPolicy(QComboBox::AdjustToContents); + _sources = new SceneItemSelectionWidget(parent); + _sourceGroups = new QComboBox(); _actions = new QComboBox(); populateSourceItemTypeSelection(_sourceTypes); + populateSourceGroupSelection(_sourceGroups); populateActionSelection(_actions); QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, @@ -188,14 +182,19 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit( this, SLOT(SceneChanged(const SceneSelection &))); QWidget::connect(_sourceTypes, SIGNAL(currentIndexChanged(int)), this, SLOT(SourceTypeChanged(int))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); + 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(_sourceGroups, + SIGNAL(currentTextChanged(const QString &)), this, + SLOT(SourceGroupChanged(const QString &))); QHBoxLayout *mainLayout = new QHBoxLayout; std::unordered_map widgetPlaceholders = { - {"{{scenes}}", _scenes}, - {"{{sourceTypes}}", _sourceTypes}, - {"{{sources}}", _sources}, + {"{{scenes}}", _scenes}, {"{{sourceTypes}}", _sourceTypes}, + {"{{sources}}", _sources}, {"{{sourceGroups}}", _sourceGroups}, {"{{actions}}", _actions}, }; placeWidgets(obs_module_text( @@ -218,14 +217,10 @@ void MacroActionSceneVisibilityEdit::UpdateEntryData() _sourceTypes->setCurrentIndex( static_cast(_entryData->_sourceType)); _scenes->SetScene(_entryData->_scene); - if (_entryData->_sourceType == SceneItemSourceType::SOURCE) { - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); - } else { - populateSourceTypeSelection(_sources); - _sources->setCurrentText(_entryData->_sourceGroup.c_str()); - } + _sources->SetSceneItem((_entryData->_source)); + _sourceGroups->setCurrentText( + QString::fromStdString(_entryData->_sourceGroup)); + SetWidgetVisibility(); } void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s) @@ -233,13 +228,9 @@ void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->adjustSize(); + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; } void MacroActionSceneVisibilityEdit::SourceTypeChanged(int value) @@ -247,35 +238,36 @@ void MacroActionSceneVisibilityEdit::SourceTypeChanged(int value) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_sourceType = - static_cast(value); - } - _sources->clear(); - if (_entryData->_sourceType == SceneItemSourceType::SOURCE) { - populateSceneItemSelection(_sources, _entryData->_scene); - } else { - populateSourceTypeSelection(_sources); - } + std::lock_guard lock(switcher->m); + _entryData->_sourceType = static_cast(value); + SetWidgetVisibility(); } -void MacroActionSceneVisibilityEdit::SourceChanged(const QString &text) +void MacroActionSceneVisibilityEdit::SourceChanged( + const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - if (_entryData->_sourceType == SceneItemSourceType::SOURCE) { - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); +} + +void MacroActionSceneVisibilityEdit::SourceGroupChanged(const QString &text) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + if (text == obs_module_text("AdvSceneSwitcher.selectItem")) { + _entryData->_sourceGroup = ""; } else { - if (text == obs_module_text("AdvSceneSwitcher.selectItem")) { - _entryData->_sourceGroup = ""; - } else { - _entryData->_sourceGroup = text.toStdString(); - } + _entryData->_sourceGroup = text.toStdString(); } emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); @@ -290,3 +282,15 @@ void MacroActionSceneVisibilityEdit::ActionChanged(int value) std::lock_guard lock(switcher->m); _entryData->_action = static_cast(value); } + +void MacroActionSceneVisibilityEdit::SetWidgetVisibility() +{ + if (!_entryData) { + return; + } + _sources->setVisible(_entryData->_sourceType == + SceneItemSourceType::SOURCE); + _sourceGroups->setVisible(_entryData->_sourceType == + SceneItemSourceType::SOURCE_GROUP); + adjustSize(); +} diff --git a/src/macro-condition-scene-order.cpp b/src/macro-condition-scene-order.cpp index db54197e..1f13b104 100644 --- a/src/macro-condition-scene-order.cpp +++ b/src/macro-condition-scene-order.cpp @@ -19,78 +19,110 @@ static std::map sceneOrderConditionTypes = { "AdvSceneSwitcher.condition.sceneOrder.type.position"}, }; -struct PosInfo { - std::string name; - std::vector pos = {}; +struct PosInfo2 { + obs_scene_item *item; + int pos = -1; int curPos = 0; }; -static bool getSceneItemPositions(obs_scene_t *, obs_sceneitem_t *item, - void *ptr) +static bool getSceneItemPositionHelper(obs_scene_t *, obs_sceneitem_t *item, + void *ptr) { - PosInfo *posInfo = reinterpret_cast(ptr); - auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item)); - if (posInfo->name == sourceName) { - posInfo->pos.push_back(posInfo->curPos); + PosInfo2 *posInfo = reinterpret_cast(ptr); + if (posInfo->item == item) { + posInfo->pos = posInfo->curPos; + return false; } if (obs_sceneitem_is_group(item)) { obs_scene_t *scene = obs_sceneitem_group_get_scene(item); - obs_scene_enum_items(scene, getSceneItemPositions, ptr); + obs_scene_enum_items(scene, getSceneItemPositionHelper, ptr); } posInfo->curPos += 1; return true; } -static bool isAbove(std::vector &v1, std::vector &v2) +PosInfo2 getSceneItemPos(obs_scene_item *item, obs_scene *scene) { - for (int i : v1) { - for (int j : v2) { - if (i > j) { - return true; - } - } - } - return false; + PosInfo2 pos{item}; + obs_scene_enum_items(scene, getSceneItemPositionHelper, &pos); + return pos; } -static bool isBelow(std::vector &v1, std::vector &v2) +std::vector getSceneItemPositions(std::vector &items, + obs_scene *scene) { - for (int i : v1) { - for (int j : v2) { - if (i < j) { - return true; + std::vector positions; + for (auto item : items) { + auto pos = getSceneItemPos(item, scene); + if (pos.pos != -1) { + positions.emplace_back(pos.pos); + } + } + return positions; +} + +static bool isAbove(std::vector &pos1, std::vector &pos2) +{ + if (pos1.empty() || pos2.empty()) { + return false; + } + for (int i : pos1) { + for (int j : pos2) { + if (i <= j) { + return false; } } } - return false; + return true; +} + +static bool isBelow(std::vector &pos1, std::vector &pos2) +{ + if (pos1.empty() || pos2.empty()) { + return false; + } + for (int i : pos1) { + for (int j : pos2) { + if (i >= j) { + return false; + } + } + } + return true; } bool MacroConditionSceneOrder::CheckCondition() { - if (!_source) { + auto items1 = _source.GetSceneItems(_scene); + if (items1.empty()) { return false; } - bool ret = false; + auto items2 = _source2.GetSceneItems(_scene); auto s = obs_weak_source_get_source(_scene.GetScene(false)); auto scene = obs_scene_from_source(s); - auto name1 = GetWeakSourceName(_source); - auto name2 = GetWeakSourceName(_source2); - PosInfo pos1 = {name1}; - PosInfo pos2 = {name2}; - obs_scene_enum_items(scene, getSceneItemPositions, &pos1); - obs_scene_enum_items(scene, getSceneItemPositions, &pos2); + auto positions1 = getSceneItemPositions(items1, scene); + auto positions2 = getSceneItemPositions(items2, scene); + + for (auto i : items1) { + obs_sceneitem_release(i); + } + for (auto i : items2) { + obs_sceneitem_release(i); + } + + bool ret = false; switch (_condition) { case SceneOrderCondition::ABOVE: - ret = isAbove(pos1.pos, pos2.pos); + ret = isAbove(positions1, positions2); break; case SceneOrderCondition::BELOW: - ret = isBelow(pos1.pos, pos2.pos); + ret = isBelow(positions1, positions2); break; case SceneOrderCondition::POSITION: - for (int p : pos1.pos) { + for (int p : positions1) { if (p == _position) ret = true; } @@ -100,7 +132,6 @@ bool MacroConditionSceneOrder::CheckCondition() } obs_source_release(s); - return ret; } @@ -108,9 +139,8 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj) { MacroCondition::Save(obj); _scene.Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); - obs_data_set_string(obj, "source2", - GetWeakSourceName(_source2).c_str()); + _source.Save(obj); + _source2.Save(obj, "sceneItem2", "sceneItemTarget2", "sceneItemIdx2"); obs_data_set_int(obj, "condition", static_cast(_condition)); obs_data_set_int(obj, "position", _position); return true; @@ -118,12 +148,19 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj) bool MacroConditionSceneOrder::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); + auto sourceName2 = obs_data_get_string(obj, "source2"); + obs_data_set_string(obj, "sceneItem2", sourceName2); + } + MacroCondition::Load(obj); _scene.Load(obj); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); - const char *source2Name = obs_data_get_string(obj, "source2"); - _source2 = GetWeakSourceByName(source2Name); + _source.Load(obj); + _source2.Load(obj, "sceneItem2", "sceneItemTarget2", "sceneItemIdx2"); _condition = static_cast( obs_data_get_int(obj, "condition")); _position = obs_data_get_int(obj, "position"); @@ -132,15 +169,15 @@ bool MacroConditionSceneOrder::Load(obs_data_t *obj) std::string MacroConditionSceneOrder::GetShortDesc() { - if (_source) { - std::string header = - _scene.ToString() + " - " + GetWeakSourceName(_source); - if (_source2 && _condition != SceneOrderCondition::POSITION) { - header += " - " + GetWeakSourceName(_source2); - } - return header; + if (_source.ToString().empty()) { + return ""; } - return ""; + std::string header = _scene.ToString() + " - " + _source.ToString(); + if (!_source2.ToString().empty() && + _condition != SceneOrderCondition::POSITION) { + header += " - " + _source2.ToString(); + } + return header; } static inline void populateConditionSelection(QComboBox *list) @@ -155,21 +192,37 @@ MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit( : QWidget(parent) { _scenes = new SceneSelectionWidget(window(), false, false, true); - _sources = new QComboBox(); - _sources2 = new QComboBox(); + _sources = new SceneItemSelectionWidget(parent); + _sources2 = new SceneItemSelectionWidget(parent); _conditions = new QComboBox(); _position = new QSpinBox(); _posInfo = new QLabel(obs_module_text( "AdvSceneSwitcher.condition.sceneOrder.positionInfo")); populateConditionSelection(_conditions); + if (entryData.get()) { + if (entryData->_condition == SceneOrderCondition::POSITION) { + _sources->SetShowAllSelectionType( + SceneItemSelectionWidget::AllSelectionType::ANY); + } else { + _sources->SetShowAllSelectionType( + SceneItemSelectionWidget::AllSelectionType::ALL); + } + } QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); - QWidget::connect(_sources2, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(Source2Changed(const QString &))); + QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), + _sources, SLOT(SceneChanged(const SceneSelection &))); + QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), + _sources2, SLOT(SceneChanged(const SceneSelection &))); + QWidget::connect(_sources, + SIGNAL(SceneItemChanged(const SceneItemSelection &)), + this, SLOT(SourceChanged(const SceneItemSelection &))); + QWidget::connect(_sources2, + SIGNAL(SceneItemChanged(const SceneItemSelection &)), + this, + SLOT(Source2Changed(const SceneItemSelection &))); QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this, SLOT(ConditionChanged(int))); QWidget::connect(_position, SIGNAL(valueChanged(int)), this, @@ -199,36 +252,31 @@ void MacroConditionSceneOrderEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - _sources2->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); - populateSceneItemSelection(_sources2, _entryData->_scene); + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; } -void MacroConditionSceneOrderEdit::SourceChanged(const QString &text) +void MacroConditionSceneOrderEdit::SourceChanged(const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } -void MacroConditionSceneOrderEdit::Source2Changed(const QString &text) +void MacroConditionSceneOrderEdit::Source2Changed(const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source2 = GetWeakSourceByQString(text); + _entryData->_source2 = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } @@ -238,11 +286,21 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index) if (_loading || !_entryData) { return; } - - std::lock_guard lock(switcher->m); - _entryData->_condition = static_cast(index); + { + std::lock_guard lock(switcher->m); + _entryData->_condition = + static_cast(index); + } SetWidgetVisibility(_entryData->_condition == SceneOrderCondition::POSITION); + if (_entryData->_condition == SceneOrderCondition::POSITION) { + _sources->SetShowAllSelectionType( + SceneItemSelectionWidget::AllSelectionType::ANY); + } else { + _sources->SetShowAllSelectionType( + SceneItemSelectionWidget::AllSelectionType::ALL); + } + emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } @@ -272,12 +330,9 @@ void MacroConditionSceneOrderEdit::UpdateEntryData() } _scenes->SetScene(_entryData->_scene); - populateSceneItemSelection(_sources, _entryData->_scene); - populateSceneItemSelection(_sources2, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); - _sources2->setCurrentText( - GetWeakSourceName(_entryData->_source2).c_str()); + _sources->SetSceneItem(_entryData->_source); + _sources2->SetSceneItem(_entryData->_source2); + _position->setValue(_entryData->_position); _conditions->setCurrentIndex(static_cast(_entryData->_condition)); SetWidgetVisibility(_entryData->_condition == SceneOrderCondition::POSITION); diff --git a/src/macro-condition-scene-transform.cpp b/src/macro-condition-scene-transform.cpp index 818cf54e..aac47752 100644 --- a/src/macro-condition-scene-transform.cpp +++ b/src/macro-condition-scene-transform.cpp @@ -15,10 +15,7 @@ bool MacroConditionSceneTransform::_registered = bool MacroConditionSceneTransform::CheckCondition() { bool ret = false; - auto s = obs_weak_source_get_source(_scene.GetScene(false)); - auto scene = obs_scene_from_source(s); - auto name = GetWeakSourceName(_source); - auto items = getSceneItemsWithName(scene, name); + auto items = _source.GetSceneItems(_scene); for (auto &item : items) { auto json = getSceneItemTransform(item); @@ -27,8 +24,6 @@ bool MacroConditionSceneTransform::CheckCondition() } obs_sceneitem_release(item); } - - obs_source_release(s); return ret; } @@ -36,7 +31,7 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj) { MacroCondition::Save(obj); _scene.Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); + _source.Save(obj); obs_data_set_string(obj, "settings", _settings.c_str()); obs_data_set_bool(obj, "regex", _regex); return true; @@ -44,10 +39,16 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj) bool MacroConditionSceneTransform::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); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); + _source.Load(obj); _settings = obs_data_get_string(obj, "settings"); _regex = obs_data_get_bool(obj, "regex"); return true; @@ -55,10 +56,11 @@ bool MacroConditionSceneTransform::Load(obs_data_t *obj) std::string MacroConditionSceneTransform::GetShortDesc() { - if (_source) { - return _scene.ToString() + " - " + GetWeakSourceName(_source); + if (_source.ToString().empty()) { + return ""; } - return ""; + + return _scene.ToString() + " - " + _source.ToString(); } MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( @@ -67,7 +69,8 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( : QWidget(parent) { _scenes = new SceneSelectionWidget(window(), false, false, true); - _sources = new QComboBox(); + _sources = new SceneItemSelectionWidget( + parent, true, SceneItemSelectionWidget::AllSelectionType::ANY); _getSettings = new QPushButton(obs_module_text( "AdvSceneSwitcher.condition.sceneTransform.getTransform")); _settings = new QPlainTextEdit(); @@ -76,8 +79,11 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit( QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); + 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(_getSettings, SIGNAL(clicked()), this, SLOT(GetSettingsClicked())); QWidget::connect(_settings, SIGNAL(textChanged()), this, @@ -125,14 +131,9 @@ void MacroConditionSceneTransformEdit::UpdateEntryData() } _scenes->SetScene(_entryData->_scene); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); + _sources->SetSceneItem(_entryData->_source); _regex->setChecked(_entryData->_regex); - if (_entryData->_source) { - _settings->setPlainText( - QString::fromStdString(_entryData->_settings)); - } + _settings->setPlainText(QString::fromStdString(_entryData->_settings)); } void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s) @@ -140,48 +141,45 @@ void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; } -void MacroConditionSceneTransformEdit::SourceChanged(const QString &text) +void MacroConditionSceneTransformEdit::SourceChanged( + const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } void MacroConditionSceneTransformEdit::GetSettingsClicked() { - if (_loading || !_entryData || !_entryData->_scene.GetScene(false) || - !_entryData->_source) { + + if (_loading || !_entryData || !_entryData->_scene.GetScene(false)) { return; } - auto s = obs_weak_source_get_source(_entryData->_scene.GetScene(false)); - auto scene = obs_scene_from_source(s); - auto name = GetWeakSourceName(_entryData->_source); - auto item = obs_scene_find_source_recursive(scene, name.c_str()); - obs_source_release(s); - - if (!item) { + auto items = _entryData->_source.GetSceneItems(_entryData->_scene); + if (items.empty()) { return; } - QString json = formatJsonString(getSceneItemTransform(item)); + auto settings = formatJsonString(getSceneItemTransform(items[0])); if (_entryData->_regex) { - json = escapeForRegex(json); + settings = escapeForRegex(settings); + } + _settings->setPlainText(settings); + + for (auto item : items) { + obs_sceneitem_release(item); } - _settings->setPlainText(json); } void MacroConditionSceneTransformEdit::SettingsChanged() diff --git a/src/macro-condition-scene-visibility.cpp b/src/macro-condition-scene-visibility.cpp index 03b1fd48..2d070a7b 100644 --- a/src/macro-condition-scene-visibility.cpp +++ b/src/macro-condition-scene-visibility.cpp @@ -22,52 +22,54 @@ static std::map "AdvSceneSwitcher.condition.sceneVisibility.type.hidden"}, }; -struct VisibilityData { - std::string name; - bool visible; - bool result; -}; - -static bool visibilityEnum(obs_scene_t *, obs_sceneitem_t *item, void *ptr) +bool areAllSceneItemsShown(std::vector &items) { - VisibilityData *vInfo = reinterpret_cast(ptr); - auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item)); - if (vInfo->name == sourceName && - obs_sceneitem_visible(item) == vInfo->visible) { - vInfo->result = true; - return false; + bool ret = true; + for (auto item : items) { + if (!obs_sceneitem_visible(item)) { + ret = false; + } + obs_sceneitem_release(item); } + return ret; +} - if (obs_sceneitem_is_group(item)) { - obs_scene_t *scene = obs_sceneitem_group_get_scene(item); - obs_scene_enum_items(scene, visibilityEnum, ptr); +bool areAllSceneItemsHidden(std::vector &items) +{ + bool ret = true; + for (auto item : items) { + if (obs_sceneitem_visible(item)) { + ret = false; + } + obs_sceneitem_release(item); } - - return true; + return ret; } bool MacroConditionSceneVisibility::CheckCondition() { - if (!_source) { + auto items = _source.GetSceneItems(_scene); + if (items.empty()) { return false; } - auto s = obs_weak_source_get_source(_scene.GetScene()); - auto scene = obs_scene_from_source(s); - auto sourceName = GetWeakSourceName(_source); - VisibilityData data = {sourceName, - _condition == SceneVisibilityCondition::SHOWN, - false}; - obs_scene_enum_items(scene, visibilityEnum, &data); - obs_source_release(s); - return data.result; + switch (_condition) { + case SceneVisibilityCondition::SHOWN: + return areAllSceneItemsShown(items); + case SceneVisibilityCondition::HIDDEN: + return areAllSceneItemsHidden(items); + break; + default: + break; + } + return false; } bool MacroConditionSceneVisibility::Save(obs_data_t *obj) { MacroCondition::Save(obj); _scene.Save(obj); - obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); + _source.Save(obj); obs_data_set_int(obj, "condition", static_cast(_condition)); @@ -76,10 +78,16 @@ bool MacroConditionSceneVisibility::Save(obs_data_t *obj) 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); - const char *sourceName = obs_data_get_string(obj, "source"); - _source = GetWeakSourceByName(sourceName); + _source.Load(obj); _condition = static_cast( obs_data_get_int(obj, "condition")); return true; @@ -87,10 +95,10 @@ bool MacroConditionSceneVisibility::Load(obs_data_t *obj) std::string MacroConditionSceneVisibility::GetShortDesc() { - if (_source) { - return _scene.ToString() + " - " + GetWeakSourceName(_source); + if (_source.ToString().empty()) { + return ""; } - return ""; + return _scene.ToString() + " - " + _source.ToString(); } static inline void populateConditionSelection(QComboBox *list) @@ -106,16 +114,18 @@ MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit( : QWidget(parent) { _scenes = new SceneSelectionWidget(window(), false, true, true); - _sources = new QComboBox(); - _sources->setSizeAdjustPolicy(QComboBox::AdjustToContents); + _sources = new SceneItemSelectionWidget(parent); _conditions = new QComboBox(); populateConditionSelection(_conditions); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), this, SLOT(SceneChanged(const SceneSelection &))); - QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), - this, SLOT(SourceChanged(const QString &))); + 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))); @@ -136,14 +146,17 @@ MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit( _loading = false; } -void MacroConditionSceneVisibilityEdit::SourceChanged(const QString &text) +void MacroConditionSceneVisibilityEdit::SourceChanged( + const SceneItemSelection &item) { if (_loading || !_entryData) { return; } std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + _entryData->_source = item; + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); } void MacroConditionSceneVisibilityEdit::SceneChanged(const SceneSelection &s) @@ -151,13 +164,10 @@ void MacroConditionSceneVisibilityEdit::SceneChanged(const SceneSelection &s) if (_loading || !_entryData) { return; } - { - std::lock_guard lock(switcher->m); - _entryData->_scene = s; - } - _sources->clear(); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->adjustSize(); + std::lock_guard lock(switcher->m); + _entryData->_scene = s; + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); } void MacroConditionSceneVisibilityEdit::ConditionChanged(int index) @@ -178,7 +188,5 @@ void MacroConditionSceneVisibilityEdit::UpdateEntryData() _conditions->setCurrentIndex(static_cast(_entryData->_condition)); _scenes->SetScene(_entryData->_scene); - populateSceneItemSelection(_sources, _entryData->_scene); - _sources->setCurrentText( - GetWeakSourceName(_entryData->_source).c_str()); + _sources->SetSceneItem(_entryData->_source); }