diff --git a/CMakeLists.txt b/CMakeLists.txt index 48ac403d..9a1e2251 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-action-scene-visibility.hpp src/headers/macro-action-source.hpp src/headers/macro-action-streaming.hpp + src/headers/macro-action-virtual-cam.hpp src/headers/macro-action-wait.hpp src/headers/macro-condition-edit.hpp src/headers/macro-condition-audio.hpp @@ -160,6 +161,7 @@ set(advanced-scene-switcher_SOURCES src/macro-action-scene-visibility.cpp src/macro-action-source.cpp src/macro-action-streaming.cpp + src/macro-action-virtual-cam.cpp src/macro-action-wait.cpp src/macro-condition-edit.cpp src/macro-condition-audio.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index be9f5813..d2ad9695 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -206,6 +206,10 @@ AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}" AdvSceneSwitcher.action.pluginState="Plugin state" AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin" AdvSceneSwitcher.action.pluginState.entry="{{actions}}" +AdvSceneSwitcher.action.virtualCamera="Virtual camera" +AdvSceneSwitcher.action.virtualCamera.type.stop="Stop virtual camera" +AdvSceneSwitcher.action.virtualCamera.type.start="Start virtual camera" +AdvSceneSwitcher.action.virtualCamera.entry="{{actions}}" ; Transition Tab AdvSceneSwitcher.transitionTab.title="Transition" diff --git a/src/headers/macro-action-virtual-cam.hpp b/src/headers/macro-action-virtual-cam.hpp new file mode 100644 index 00000000..5a180bdd --- /dev/null +++ b/src/headers/macro-action-virtual-cam.hpp @@ -0,0 +1,55 @@ +#pragma once +#include +#include "macro-action-edit.hpp" + +enum class VCamAction { + STOP, + START, +}; + +class MacroActionVCam : public MacroAction { +public: + bool PerformAction(); + void LogAction(); + bool Save(obs_data_t *obj); + bool Load(obs_data_t *obj); + std::string GetId() { return id; }; + static std::shared_ptr Create() + { + return std::make_shared(); + } + + VCamAction _action = VCamAction::STOP; + +private: + static bool _registered; + static const std::string id; +}; + +class MacroActionVCamEdit : public QWidget { + Q_OBJECT + +public: + MacroActionVCamEdit( + QWidget *parent, + std::shared_ptr entryData = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr action) + { + return new MacroActionVCamEdit( + parent, + std::dynamic_pointer_cast(action)); + } + +private slots: + void ActionChanged(int value); + +protected: + QComboBox *_actions; + std::shared_ptr _entryData; + +private: + QHBoxLayout *_mainLayout; + bool _loading = true; +}; diff --git a/src/macro-action-virtual-cam.cpp b/src/macro-action-virtual-cam.cpp new file mode 100644 index 00000000..28bd7a5c --- /dev/null +++ b/src/macro-action-virtual-cam.cpp @@ -0,0 +1,109 @@ +#include "headers/macro-action-virtual-cam.hpp" +#include "headers/advanced-scene-switcher.hpp" +#include "headers/utility.hpp" + +const std::string MacroActionVCam::id = "virtual_cam"; + +bool MacroActionVCam::_registered = MacroActionFactory::Register( + MacroActionVCam::id, + {MacroActionVCam::Create, MacroActionVCamEdit::Create, + "AdvSceneSwitcher.action.virtualCamera"}); + +const static std::map actionTypes = { + {VCamAction::STOP, "AdvSceneSwitcher.action.virtualCamera.type.stop"}, + {VCamAction::START, "AdvSceneSwitcher.action.virtualCamera.type.start"}, +}; + +bool MacroActionVCam::PerformAction() +{ + switch (_action) { + case VCamAction::STOP: + if (obs_frontend_virtualcam_active()) { + obs_frontend_stop_virtualcam(); + } + break; + case VCamAction::START: + if (!obs_frontend_virtualcam_active()) { + obs_frontend_start_virtualcam(); + } + break; + default: + break; + } + return true; +} + +void MacroActionVCam::LogAction() +{ + auto it = actionTypes.find(_action); + if (it != actionTypes.end()) { + vblog(LOG_INFO, "performed action \"%s\"", it->second.c_str()); + } else { + blog(LOG_WARNING, "ignored unknown virtual camera action %d", + static_cast(_action)); + } +} + +bool MacroActionVCam::Save(obs_data_t *obj) +{ + MacroAction::Save(obj); + obs_data_set_int(obj, "action", static_cast(_action)); + return true; +} + +bool MacroActionVCam::Load(obs_data_t *obj) +{ + MacroAction::Load(obj); + _action = static_cast(obs_data_get_int(obj, "action")); + return true; +} + +static inline void populateActionSelection(QComboBox *list) +{ + for (auto entry : actionTypes) { + list->addItem(obs_module_text(entry.second.c_str())); + } +} + +MacroActionVCamEdit::MacroActionVCamEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _actions = new QComboBox(); + + populateActionSelection(_actions); + + QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, + SLOT(ActionChanged(int))); + + QHBoxLayout *mainLayout = new QHBoxLayout; + std::unordered_map widgetPlaceholders = { + {"{{actions}}", _actions}, + }; + placeWidgets( + obs_module_text("AdvSceneSwitcher.action.virtualCamera.entry"), + mainLayout, widgetPlaceholders); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroActionVCamEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + _actions->setCurrentIndex(static_cast(_entryData->_action)); +} + +void MacroActionVCamEdit::ActionChanged(int value) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_action = static_cast(value); +}