diff --git a/CMakeLists.txt b/CMakeLists.txt index eeaee0d9..cf7032a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,6 +234,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-condition-scene.hpp src/headers/macro-condition-source.hpp src/headers/macro-condition-streaming.hpp + src/headers/macro-condition-studio-mode.hpp src/headers/macro-condition-timer.hpp src/headers/macro-condition-transition.hpp src/headers/macro-condition-video.hpp @@ -329,6 +330,7 @@ set(advanced-scene-switcher_SOURCES src/macro-condition-scene.cpp src/macro-condition-source.cpp src/macro-condition-streaming.cpp + src/macro-condition-studio-mode.cpp src/macro-condition-timer.cpp src/macro-condition-transition.cpp src/macro-condition-video.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index b38e7442..45643812 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -249,7 +249,12 @@ 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" +AdvSceneSwitcher.condition.studioMode.state.previewScene="Preview scene is" +AdvSceneSwitcher.condition.studioMode.entry="{{conditions}}{{scenes}}" ; Macro Actions AdvSceneSwitcher.action.switchScene="Switch scene" diff --git a/src/headers/macro-condition-studio-mode.hpp b/src/headers/macro-condition-studio-mode.hpp new file mode 100644 index 00000000..9a9d8f7d --- /dev/null +++ b/src/headers/macro-condition-studio-mode.hpp @@ -0,0 +1,65 @@ +#pragma once +#include "macro.hpp" +#include "scene-selection.hpp" + +#include +#include + +enum class StudioModeCondition { + STUDIO_MODE_ACTIVE, + STUDIO_MODE_NOT_ACTIVE, + PREVIEW_SCENE, +}; + +class MacroConditionStudioMode : public MacroCondition { +public: + bool CheckCondition(); + bool Save(obs_data_t *obj); + bool Load(obs_data_t *obj); + std::string GetShortDesc(); + std::string GetId() { return id; }; + static std::shared_ptr Create() + { + return std::make_shared(); + } + + StudioModeCondition _condition = + StudioModeCondition::STUDIO_MODE_ACTIVE; + SceneSelection _scene; + +private: + static bool _registered; + static const std::string id; +}; + +class MacroConditionStudioModeEdit : public QWidget { + Q_OBJECT + +public: + MacroConditionStudioModeEdit( + QWidget *parent, + std::shared_ptr cond = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr cond) + { + return new MacroConditionStudioModeEdit( + parent, + std::dynamic_pointer_cast( + cond)); + } +private slots: + void ConditionChanged(int cond); + void SceneChanged(const SceneSelection &); +signals: + void HeaderInfoChanged(const QString &); + +protected: + QComboBox *_condition; + SceneSelectionWidget *_scenes; + std::shared_ptr _entryData; + +private: + void SetWidgetVisibility(); + bool _loading = true; +}; diff --git a/src/macro-condition-studio-mode.cpp b/src/macro-condition-studio-mode.cpp new file mode 100644 index 00000000..be6bc537 --- /dev/null +++ b/src/macro-condition-studio-mode.cpp @@ -0,0 +1,151 @@ +#include "headers/macro-condition-edit.hpp" +#include "headers/macro-condition-studio-mode.hpp" +#include "headers/utility.hpp" +#include "headers/advanced-scene-switcher.hpp" + +const std::string MacroConditionStudioMode::id = "studio_mode"; + +bool MacroConditionStudioMode::_registered = MacroConditionFactory::Register( + MacroConditionStudioMode::id, + {MacroConditionStudioMode::Create, MacroConditionStudioModeEdit::Create, + "AdvSceneSwitcher.condition.studioMode"}); + +static std::map studioModeConditionTypes = { + {StudioModeCondition::STUDIO_MODE_ACTIVE, + "AdvSceneSwitcher.condition.studioMode.state.active"}, + {StudioModeCondition::STUDIO_MODE_NOT_ACTIVE, + "AdvSceneSwitcher.condition.studioMode.state.notActive"}, + {StudioModeCondition::PREVIEW_SCENE, + "AdvSceneSwitcher.condition.studioMode.state.previewScene"}, +}; + +bool MacroConditionStudioMode::CheckCondition() +{ + bool ret = false; + switch (_condition) { + case StudioModeCondition::STUDIO_MODE_ACTIVE: + ret = obs_frontend_preview_program_mode_active(); + break; + case StudioModeCondition::STUDIO_MODE_NOT_ACTIVE: + ret = !obs_frontend_preview_program_mode_active(); + break; + case StudioModeCondition::PREVIEW_SCENE: { + auto s = obs_frontend_get_current_preview_scene(); + auto scene = obs_source_get_weak_source(s); + ret = _scene.GetScene() == scene; + obs_weak_source_release(scene); + obs_source_release(s); + break; + } + default: + break; + } + return ret; +} + +bool MacroConditionStudioMode::Save(obs_data_t *obj) +{ + MacroCondition::Save(obj); + obs_data_set_int(obj, "condition", static_cast(_condition)); + _scene.Save(obj); + return true; +} + +bool MacroConditionStudioMode::Load(obs_data_t *obj) +{ + MacroCondition::Load(obj); + _condition = static_cast( + obs_data_get_int(obj, "condition")); + _scene.Load(obj); + return true; +} + +std::string MacroConditionStudioMode::GetShortDesc() +{ + if (_condition == StudioModeCondition::PREVIEW_SCENE) { + return _scene.ToString(); + } + return ""; +} + +static inline void populateConditionSelection(QComboBox *list) +{ + for (auto entry : studioModeConditionTypes) { + list->addItem(obs_module_text(entry.second.c_str())); + } +} + +MacroConditionStudioModeEdit::MacroConditionStudioModeEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _condition = new QComboBox(); + _scenes = new SceneSelectionWidget(window()); + + populateConditionSelection(_condition); + + QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, + SLOT(ConditionChanged(int))); + QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), + this, SLOT(SceneChanged(const SceneSelection &))); + + QHBoxLayout *layout = new QHBoxLayout; + std::unordered_map widgetPlaceholders = { + {"{{conditions}}", _condition}, + {"{{scenes}}", _scenes}, + }; + placeWidgets( + obs_module_text("AdvSceneSwitcher.condition.studioMode.entry"), + layout, widgetPlaceholders); + setLayout(layout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroConditionStudioModeEdit::ConditionChanged(int cond) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_condition = static_cast(cond); + SetWidgetVisibility(); + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); +} + +void MacroConditionStudioModeEdit::SceneChanged(const SceneSelection &s) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_scene = s; + emit HeaderInfoChanged( + QString::fromStdString(_entryData->GetShortDesc())); +} + +void MacroConditionStudioModeEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _condition->setCurrentIndex(static_cast(_entryData->_condition)); + _scenes->SetScene(_entryData->_scene); + SetWidgetVisibility(); +} + +void MacroConditionStudioModeEdit::SetWidgetVisibility() +{ + if (!_entryData) { + return; + } + + _scenes->setVisible(_entryData->_condition == + StudioModeCondition::PREVIEW_SCENE); +}