diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a1e2251..07ffd687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-condition-source.hpp src/headers/macro-condition-streaming.hpp src/headers/macro-condition-video.hpp + src/headers/macro-condition-virtual-cam.hpp src/headers/macro-condition-window.hpp src/headers/macro.hpp src/headers/macro-selection.hpp @@ -178,6 +179,7 @@ set(advanced-scene-switcher_SOURCES src/macro-condition-source.cpp src/macro-condition-streaming.cpp src/macro-condition-video.cpp + src/macro-condition-virtual-cam.cpp src/macro-condition-window.cpp src/macro.cpp src/macro-selection.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index d2ad9695..6b45f142 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -142,6 +142,10 @@ AdvSceneSwitcher.condition.source.getSettings="Get current settings" AdvSceneSwitcher.condition.source.entry.line1="{{sources}} {{conditions}}" AdvSceneSwitcher.condition.source.entry.line2="{{settings}}" AdvSceneSwitcher.condition.source.entry.line3="{{regex}} {{getSettings}}" +AdvSceneSwitcher.condition.virtualCamera="Virtual camera" +AdvSceneSwitcher.condition.virtualCamera.state.start="Virtual camera started" +AdvSceneSwitcher.condition.virtualCamera.state.stop="Virtual camera stopped" +AdvSceneSwitcher.condition.virtualCamera.entry="{{states}}" ; Macro Actions AdvSceneSwitcher.action.switchScene="Switch scene" diff --git a/src/headers/macro-condition-virtual-cam.hpp b/src/headers/macro-condition-virtual-cam.hpp new file mode 100644 index 00000000..180cc170 --- /dev/null +++ b/src/headers/macro-condition-virtual-cam.hpp @@ -0,0 +1,54 @@ +#pragma once +#include "macro.hpp" +#include +#include + +enum class VCamState { + STOP, + START, +}; + +class MacroConditionVCam : public MacroCondition { +public: + bool CheckCondition(); + 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(); + } + + VCamState _state; + +private: + static bool _registered; + static const std::string id; +}; + +class MacroConditionVCamEdit : public QWidget { + Q_OBJECT + +public: + MacroConditionVCamEdit( + QWidget *parent, + std::shared_ptr cond = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr cond) + { + return new MacroConditionVCamEdit( + parent, + std::dynamic_pointer_cast(cond)); + } + +private slots: + void StateChanged(int value); + +protected: + QComboBox *_states; + std::shared_ptr _entryData; + +private: + bool _loading = true; +}; diff --git a/src/macro-condition-virtual-cam.cpp b/src/macro-condition-virtual-cam.cpp new file mode 100644 index 00000000..8b8a75f9 --- /dev/null +++ b/src/macro-condition-virtual-cam.cpp @@ -0,0 +1,101 @@ +#include "headers/macro-condition-edit.hpp" +#include "headers/macro-condition-virtual-cam.hpp" +#include "headers/utility.hpp" +#include "headers/advanced-scene-switcher.hpp" + +const std::string MacroConditionVCam::id = "virtual_cam"; + +bool MacroConditionVCam::_registered = MacroConditionFactory::Register( + MacroConditionVCam::id, + {MacroConditionVCam::Create, MacroConditionVCamEdit::Create, + "AdvSceneSwitcher.condition.virtualCamera"}); + +static std::map VCamStates = { + {VCamState::STOP, + "AdvSceneSwitcher.condition.virtualCamera.state.stop"}, + {VCamState::START, + "AdvSceneSwitcher.condition.virtualCamera.state.start"}, +}; + +bool MacroConditionVCam::CheckCondition() +{ + bool stateMatch = false; + switch (_state) { + case VCamState::STOP: + stateMatch = !obs_frontend_virtualcam_active(); + break; + case VCamState::START: + stateMatch = obs_frontend_virtualcam_active(); + break; + default: + break; + } + return stateMatch; +} + +bool MacroConditionVCam::Save(obs_data_t *obj) +{ + MacroCondition::Save(obj); + obs_data_set_int(obj, "state", static_cast(_state)); + return true; +} + +bool MacroConditionVCam::Load(obs_data_t *obj) +{ + MacroCondition::Load(obj); + _state = static_cast(obs_data_get_int(obj, "state")); + return true; +} + +static inline void populateStateSelection(QComboBox *list) +{ + for (auto entry : VCamStates) { + list->addItem(obs_module_text(entry.second.c_str())); + } +} + +MacroConditionVCamEdit::MacroConditionVCamEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _states = new QComboBox(); + + QWidget::connect(_states, SIGNAL(currentIndexChanged(int)), this, + SLOT(StateChanged(int))); + + populateStateSelection(_states); + + QHBoxLayout *mainLayout = new QHBoxLayout; + + std::unordered_map widgetPlaceholders = { + {"{{states}}", _states}, + }; + + placeWidgets(obs_module_text( + "AdvSceneSwitcher.condition.virtualCamera.entry"), + mainLayout, widgetPlaceholders); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroConditionVCamEdit::StateChanged(int value) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_state = static_cast(value); +} + +void MacroConditionVCamEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _states->setCurrentIndex(static_cast(_entryData->_state)); +}