mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-15 04:56:17 -05:00
Add scene trigger tab (#110)
This commit is contained in:
@@ -60,6 +60,7 @@ void AdvSceneSwitcher::loadUI()
|
||||
setupTimeTab();
|
||||
setupAudioTab();
|
||||
setupSceneGroupTab();
|
||||
setupTriggerTab();
|
||||
|
||||
setTabOrder();
|
||||
|
||||
@@ -364,22 +365,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
|
||||
obs_data_t *obj = obs_data_create();
|
||||
|
||||
switcher->saveSceneGroups(obj);
|
||||
switcher->saveWindowTitleSwitches(obj);
|
||||
switcher->saveScreenRegionSwitches(obj);
|
||||
switcher->savePauseSwitches(obj);
|
||||
switcher->saveSceneSequenceSwitches(obj);
|
||||
switcher->saveSceneTransitions(obj);
|
||||
switcher->saveIdleSwitches(obj);
|
||||
switcher->saveExecutableSwitches(obj);
|
||||
switcher->saveRandomSwitches(obj);
|
||||
switcher->saveFileSwitches(obj);
|
||||
switcher->saveMediaSwitches(obj);
|
||||
switcher->saveTimeSwitches(obj);
|
||||
switcher->saveAudioSwitches(obj);
|
||||
switcher->saveGeneralSettings(obj);
|
||||
switcher->saveHotkeys(obj);
|
||||
switcher->saveVersion(obj, g_GIT_SHA1);
|
||||
switcher->saveSettings(obj);
|
||||
|
||||
obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
|
||||
|
||||
@@ -395,21 +381,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
if (switcher->versionChanged(obj, g_GIT_SHA1))
|
||||
AdvSceneSwitcher::AskBackup(obj);
|
||||
|
||||
switcher->loadSceneGroups(obj);
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
switcher->loadSceneTransitions(obj);
|
||||
switcher->loadIdleSwitches(obj);
|
||||
switcher->loadExecutableSwitches(obj);
|
||||
switcher->loadRandomSwitches(obj);
|
||||
switcher->loadFileSwitches(obj);
|
||||
switcher->loadMediaSwitches(obj);
|
||||
switcher->loadTimeSwitches(obj);
|
||||
switcher->loadAudioSwitches(obj);
|
||||
switcher->loadGeneralSettings(obj);
|
||||
switcher->loadHotkeys(obj);
|
||||
switcher->loadSettings(obj);
|
||||
|
||||
obs_data_release(obj);
|
||||
|
||||
@@ -479,14 +451,6 @@ void SwitcherData::Thread()
|
||||
break;
|
||||
}
|
||||
|
||||
if (autoStopEnable) {
|
||||
autoStopStreamAndRecording();
|
||||
}
|
||||
|
||||
if (autoStartEnable) {
|
||||
autoStartStreamRecording();
|
||||
}
|
||||
|
||||
if (checkPause()) {
|
||||
continue;
|
||||
}
|
||||
@@ -675,13 +639,12 @@ void handleSceneChange(SwitcherData *s)
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(source);
|
||||
obs_source_release(source);
|
||||
obs_weak_source_release(ws);
|
||||
if (source && s->previousScene2 != ws) {
|
||||
s->previousScene = s->previousScene2;
|
||||
s->previousScene2 = ws;
|
||||
if (source && s->previousSceneHelper != ws) {
|
||||
s->previousScene = s->previousSceneHelper;
|
||||
s->previousSceneHelper = ws;
|
||||
}
|
||||
|
||||
//reset events only hanled on scene change
|
||||
s->autoStartedRecently = false;
|
||||
switcher->checkTriggers();
|
||||
}
|
||||
|
||||
void handleTransitionStop(SwitcherData *s)
|
||||
|
||||
311
src/general.cpp
311
src/general.cpp
@@ -2,8 +2,9 @@
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
#include "headers/version.h"
|
||||
|
||||
constexpr auto tab_count = 14;
|
||||
constexpr auto tab_count = 15;
|
||||
|
||||
QMetaObject::Connection inactivePluse;
|
||||
|
||||
@@ -136,160 +137,6 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
||||
obs_frontend_save();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStopScenes_currentTextChanged(const QString &text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
UpdateAutoStopScene(text);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStopSceneCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
if (!state) {
|
||||
ui->autoStopScenes->setDisabled(true);
|
||||
ui->autoStopType->setDisabled(true);
|
||||
switcher->autoStopEnable = false;
|
||||
} else {
|
||||
ui->autoStopScenes->setDisabled(false);
|
||||
ui->autoStopType->setDisabled(false);
|
||||
switcher->autoStopEnable = true;
|
||||
if (!switcher->autoStopScene)
|
||||
UpdateAutoStopScene(ui->autoStopScenes->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStopType_currentIndexChanged(int index)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->autoStopType = (AutoStartStopType)index;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::UpdateAutoStopScene(const QString &name)
|
||||
{
|
||||
obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->autoStopScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SwitcherData::autoStopStreamAndRecording()
|
||||
{
|
||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
if (ws && autoStopScene == ws) {
|
||||
if ((switcher->autoStopType == STREAMING ||
|
||||
switcher->autoStopType == RECORINDGSTREAMING) &&
|
||||
obs_frontend_streaming_active()) {
|
||||
blog(LOG_INFO,
|
||||
"Stopping stream because scene '%s' is active",
|
||||
obs_source_get_name(currentSource));
|
||||
obs_frontend_streaming_stop();
|
||||
}
|
||||
if ((switcher->autoStopType == RECORDING ||
|
||||
switcher->autoStopType == RECORINDGSTREAMING) &&
|
||||
obs_frontend_recording_active()) {
|
||||
blog(LOG_INFO,
|
||||
"Stopping record because scene '%s' is active",
|
||||
obs_source_get_name(currentSource));
|
||||
obs_frontend_recording_stop();
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStartType_currentIndexChanged(int index)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->autoStartType = (AutoStartStopType)index;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStartScenes_currentTextChanged(const QString &text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
UpdateAutoStartScene(text);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStartSceneCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
if (!state) {
|
||||
ui->autoStartScenes->setDisabled(true);
|
||||
ui->autoStartType->setDisabled(true);
|
||||
switcher->autoStartEnable = false;
|
||||
} else {
|
||||
ui->autoStartScenes->setDisabled(false);
|
||||
ui->autoStartType->setDisabled(false);
|
||||
switcher->autoStartEnable = true;
|
||||
if (!switcher->autoStartScene)
|
||||
UpdateAutoStartScene(
|
||||
ui->autoStartScenes->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::UpdateAutoStartScene(const QString &name)
|
||||
{
|
||||
obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->autoStartScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SwitcherData::autoStartStreamRecording()
|
||||
{
|
||||
if (autoStartedRecently)
|
||||
return;
|
||||
|
||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t *ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
if (ws && autoStartScene == ws) {
|
||||
if ((switcher->autoStartType == STREAMING ||
|
||||
switcher->autoStartType == RECORINDGSTREAMING) &&
|
||||
!obs_frontend_streaming_active()) {
|
||||
blog(LOG_INFO,
|
||||
"Starting stream because scene '%s' is active",
|
||||
obs_source_get_name(currentSource));
|
||||
obs_frontend_streaming_start();
|
||||
}
|
||||
if ((switcher->autoStartType == RECORDING ||
|
||||
switcher->autoStartType == RECORINDGSTREAMING) &&
|
||||
!obs_frontend_recording_active()) {
|
||||
blog(LOG_INFO,
|
||||
"Starting record because scene '%s' is active",
|
||||
obs_source_get_name(currentSource));
|
||||
obs_frontend_recording_start();
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
|
||||
autoStartedRecently = true;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_verboseLogging_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
@@ -347,20 +194,7 @@ void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||
|
||||
obs_data_t *obj = obs_data_create();
|
||||
|
||||
switcher->saveWindowTitleSwitches(obj);
|
||||
switcher->saveScreenRegionSwitches(obj);
|
||||
switcher->savePauseSwitches(obj);
|
||||
switcher->saveSceneSequenceSwitches(obj);
|
||||
switcher->saveSceneTransitions(obj);
|
||||
switcher->saveIdleSwitches(obj);
|
||||
switcher->saveExecutableSwitches(obj);
|
||||
switcher->saveRandomSwitches(obj);
|
||||
switcher->saveFileSwitches(obj);
|
||||
switcher->saveMediaSwitches(obj);
|
||||
switcher->saveTimeSwitches(obj);
|
||||
switcher->saveAudioSwitches(obj);
|
||||
switcher->saveGeneralSettings(obj);
|
||||
switcher->saveHotkeys(obj);
|
||||
switcher->saveSettings(obj);
|
||||
|
||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||
|
||||
@@ -399,20 +233,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
||||
return;
|
||||
}
|
||||
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
switcher->loadSceneTransitions(obj);
|
||||
switcher->loadIdleSwitches(obj);
|
||||
switcher->loadExecutableSwitches(obj);
|
||||
switcher->loadRandomSwitches(obj);
|
||||
switcher->loadFileSwitches(obj);
|
||||
switcher->loadMediaSwitches(obj);
|
||||
switcher->loadTimeSwitches(obj);
|
||||
switcher->loadAudioSwitches(obj);
|
||||
switcher->loadGeneralSettings(obj);
|
||||
switcher->loadHotkeys(obj);
|
||||
switcher->loadSettings(obj);
|
||||
|
||||
obs_data_release(obj);
|
||||
|
||||
@@ -473,6 +294,9 @@ int findTabIndex(QTabWidget *tabWidget, int pos)
|
||||
case 13:
|
||||
tabName = "sceneGroupTab";
|
||||
break;
|
||||
case 14:
|
||||
tabName = "sceneTriggerTab";
|
||||
break;
|
||||
}
|
||||
|
||||
QWidget *page = tabWidget->findChild<QWidget *>(tabName);
|
||||
@@ -515,6 +339,53 @@ void AdvSceneSwitcher::on_tabWidget_currentChanged(int index)
|
||||
SetShowFrames();
|
||||
}
|
||||
|
||||
void SwitcherData::loadSettings(obs_data_t *obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
switcher->loadSceneGroups(obj);
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
switcher->loadSceneTransitions(obj);
|
||||
switcher->loadIdleSwitches(obj);
|
||||
switcher->loadExecutableSwitches(obj);
|
||||
switcher->loadRandomSwitches(obj);
|
||||
switcher->loadFileSwitches(obj);
|
||||
switcher->loadMediaSwitches(obj);
|
||||
switcher->loadTimeSwitches(obj);
|
||||
switcher->loadAudioSwitches(obj);
|
||||
switcher->loadSceneTriggers(obj);
|
||||
switcher->loadGeneralSettings(obj);
|
||||
switcher->loadHotkeys(obj);
|
||||
}
|
||||
|
||||
void SwitcherData::saveSettings(obs_data_t *obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
saveSceneGroups(obj);
|
||||
saveWindowTitleSwitches(obj);
|
||||
saveScreenRegionSwitches(obj);
|
||||
savePauseSwitches(obj);
|
||||
saveSceneSequenceSwitches(obj);
|
||||
saveSceneTransitions(obj);
|
||||
saveIdleSwitches(obj);
|
||||
saveExecutableSwitches(obj);
|
||||
saveRandomSwitches(obj);
|
||||
saveFileSwitches(obj);
|
||||
saveMediaSwitches(obj);
|
||||
saveTimeSwitches(obj);
|
||||
saveAudioSwitches(obj);
|
||||
saveSceneTriggers(obj);
|
||||
saveGeneralSettings(obj);
|
||||
saveHotkeys(obj);
|
||||
saveVersion(obj, g_GIT_SHA1);
|
||||
}
|
||||
|
||||
void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_int(obj, "interval", switcher->interval);
|
||||
@@ -532,20 +403,6 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_bool(obj, "active", !switcher->stop);
|
||||
obs_data_set_int(obj, "startup_behavior", switcher->startupBehavior);
|
||||
|
||||
std::string autoStopSceneName =
|
||||
GetWeakSourceName(switcher->autoStopScene);
|
||||
obs_data_set_bool(obj, "autoStopEnable", switcher->autoStopEnable);
|
||||
obs_data_set_int(obj, "autoStopType", switcher->autoStopType);
|
||||
obs_data_set_string(obj, "autoStopSceneName",
|
||||
autoStopSceneName.c_str());
|
||||
|
||||
std::string autoStartSceneName =
|
||||
GetWeakSourceName(switcher->autoStartScene);
|
||||
obs_data_set_bool(obj, "autoStartEnable", switcher->autoStartEnable);
|
||||
obs_data_set_int(obj, "autoStartType", switcher->autoStartType);
|
||||
obs_data_set_string(obj, "autoStartSceneName",
|
||||
autoStartSceneName.c_str());
|
||||
|
||||
obs_data_set_bool(obj, "verbose", switcher->verbose);
|
||||
obs_data_set_bool(obj, "disableHints", switcher->disableHints);
|
||||
|
||||
@@ -592,6 +449,7 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_int(obj, "sequenceTabPos", switcher->tabOrder[11]);
|
||||
obs_data_set_int(obj, "audioTabPos", switcher->tabOrder[12]);
|
||||
obs_data_set_int(obj, "sceneGroupTabPos", switcher->tabOrder[13]);
|
||||
obs_data_set_int(obj, "triggerTabPos", switcher->tabOrder[14]);
|
||||
}
|
||||
|
||||
void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
@@ -618,20 +476,6 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
if (switcher->startupBehavior == STOP)
|
||||
switcher->stop = true;
|
||||
|
||||
std::string autoStopScene =
|
||||
obs_data_get_string(obj, "autoStopSceneName");
|
||||
switcher->autoStopEnable = obs_data_get_bool(obj, "autoStopEnable");
|
||||
switcher->autoStopType =
|
||||
(AutoStartStopType)obs_data_get_int(obj, "autoStopType");
|
||||
switcher->autoStopScene = GetWeakSourceByName(autoStopScene.c_str());
|
||||
|
||||
std::string autoStartScene =
|
||||
obs_data_get_string(obj, "autoStartSceneName");
|
||||
switcher->autoStartEnable = obs_data_get_bool(obj, "autoStartEnable");
|
||||
switcher->autoStartType =
|
||||
(AutoStartStopType)obs_data_get_int(obj, "autoStartType");
|
||||
switcher->autoStartScene = GetWeakSourceByName(autoStartScene.c_str());
|
||||
|
||||
switcher->verbose = obs_data_get_bool(obj, "verbose");
|
||||
switcher->disableHints = obs_data_get_bool(obj, "disableHints");
|
||||
|
||||
@@ -693,6 +537,7 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_default_int(obj, "sequenceTabPos", 11);
|
||||
obs_data_set_default_int(obj, "audioTabPos", 12);
|
||||
obs_data_set_default_int(obj, "sceneGroupTabPos", 13);
|
||||
obs_data_set_default_int(obj, "triggerTabPos", 14);
|
||||
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "generalTabPos")));
|
||||
@@ -722,6 +567,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
(int)(obs_data_get_int(obj, "audioTabPos")));
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "sceneGroupTabPos")));
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "triggerTabPos")));
|
||||
}
|
||||
|
||||
void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
@@ -767,21 +614,9 @@ void SwitcherData::checkSwitchCooldown(bool &match)
|
||||
blog(LOG_INFO, "cooldown active - ignoring match");
|
||||
}
|
||||
|
||||
void populateAutoStartStopTypeSelection(QComboBox *cb)
|
||||
{
|
||||
cb->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart.recording"));
|
||||
cb->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart.streaming"));
|
||||
cb->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart.recordingAndStreaming"));
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::setupGeneralTab()
|
||||
{
|
||||
populateSceneSelection(ui->noMatchSwitchScene, false);
|
||||
populateSceneSelection(ui->autoStopScenes, false);
|
||||
populateSceneSelection(ui->autoStartScenes, false);
|
||||
|
||||
if (switcher->switchIfNotMatching == SWITCH) {
|
||||
ui->noMatchSwitch->setChecked(true);
|
||||
@@ -804,36 +639,6 @@ void AdvSceneSwitcher::setupGeneralTab()
|
||||
ui->cooldownTime->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
||||
|
||||
populateAutoStartStopTypeSelection(ui->autoStopType);
|
||||
|
||||
ui->autoStopSceneCheckBox->setChecked(switcher->autoStopEnable);
|
||||
ui->autoStopScenes->setCurrentText(
|
||||
GetWeakSourceName(switcher->autoStopScene).c_str());
|
||||
ui->autoStopType->setCurrentIndex(switcher->autoStopType);
|
||||
|
||||
if (ui->autoStopSceneCheckBox->checkState()) {
|
||||
ui->autoStopScenes->setDisabled(false);
|
||||
ui->autoStopType->setDisabled(false);
|
||||
} else {
|
||||
ui->autoStopScenes->setDisabled(true);
|
||||
ui->autoStopType->setDisabled(true);
|
||||
}
|
||||
|
||||
populateAutoStartStopTypeSelection(ui->autoStartType);
|
||||
|
||||
ui->autoStartSceneCheckBox->setChecked(switcher->autoStartEnable);
|
||||
ui->autoStartScenes->setCurrentText(
|
||||
GetWeakSourceName(switcher->autoStartScene).c_str());
|
||||
ui->autoStartType->setCurrentIndex(switcher->autoStartType);
|
||||
|
||||
if (ui->autoStartSceneCheckBox->checkState()) {
|
||||
ui->autoStartScenes->setDisabled(false);
|
||||
ui->autoStartType->setDisabled(false);
|
||||
} else {
|
||||
ui->autoStartScenes->setDisabled(true);
|
||||
ui->autoStartType->setDisabled(true);
|
||||
}
|
||||
|
||||
ui->verboseLogging->setChecked(switcher->verbose);
|
||||
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ public:
|
||||
int IgnoreIdleWindowsFindByData(const QString &window);
|
||||
|
||||
void UpdateNonMatchingScene(const QString &name);
|
||||
void UpdateAutoStopScene(const QString &name);
|
||||
void UpdateAutoStartScene(const QString &name);
|
||||
void SetEditSceneGroup(SceneGroup &sg);
|
||||
|
||||
void loadUI();
|
||||
@@ -54,6 +52,7 @@ public:
|
||||
void setupTimeTab();
|
||||
void setupAudioTab();
|
||||
void setupSceneGroupTab();
|
||||
void setupTriggerTab();
|
||||
void setTabOrder();
|
||||
|
||||
static bool DisplayMessage(QString msg, bool question = false);
|
||||
@@ -130,14 +129,6 @@ public slots:
|
||||
void on_sceneSequenceUp_clicked();
|
||||
void on_sceneSequenceDown_clicked();
|
||||
|
||||
void on_autoStopSceneCheckBox_stateChanged(int state);
|
||||
void on_autoStopType_currentIndexChanged(int index);
|
||||
void on_autoStopScenes_currentTextChanged(const QString &text);
|
||||
|
||||
void on_autoStartSceneCheckBox_stateChanged(int state);
|
||||
void on_autoStartType_currentIndexChanged(int index);
|
||||
void on_autoStartScenes_currentTextChanged(const QString &text);
|
||||
|
||||
void on_verboseLogging_stateChanged(int state);
|
||||
void on_uiHintsDisable_stateChanged(int state);
|
||||
|
||||
@@ -207,6 +198,11 @@ public slots:
|
||||
void on_sceneGroupSceneUp_clicked();
|
||||
void on_sceneGroupSceneDown_clicked();
|
||||
|
||||
void on_triggerAdd_clicked();
|
||||
void on_triggerRemove_clicked();
|
||||
void on_triggerUp_clicked();
|
||||
void on_triggerDown_clicked();
|
||||
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
void on_threadPriority_currentTextChanged(const QString &text);
|
||||
|
||||
68
src/headers/scene-trigger.hpp
Normal file
68
src/headers/scene-trigger.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
enum class sceneTriggerType {
|
||||
NONE = 0,
|
||||
SCENE_ACTIVE = 1,
|
||||
SCENE_INACTIVE = 2,
|
||||
SCENE_LEAVE = 3,
|
||||
};
|
||||
|
||||
enum class sceneTriggerAction {
|
||||
NONE = 0,
|
||||
START_RECORDING,
|
||||
PAUSE_RECORDING,
|
||||
UNPAUSE_RECORDING,
|
||||
STOP_RECORDING,
|
||||
|
||||
START_STREAMING,
|
||||
STOP_STREAMING,
|
||||
|
||||
START_REPLAY_BUFFER,
|
||||
STOP_REPLAY_BUFFER,
|
||||
|
||||
MUTE_SOURCE,
|
||||
};
|
||||
|
||||
struct SceneTrigger : SceneSwitcherEntry {
|
||||
static bool pause;
|
||||
sceneTriggerType triggerType = sceneTriggerType::NONE;
|
||||
sceneTriggerAction triggerAction = sceneTriggerAction::NONE;
|
||||
double duration = 0;
|
||||
OBSWeakSource audioSource = nullptr;
|
||||
|
||||
const char *getType() { return "trigger"; }
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
|
||||
bool checkMatch(OBSWeakSource previousScene);
|
||||
void performAction();
|
||||
void logMatch();
|
||||
};
|
||||
|
||||
class SceneTriggerWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SceneTriggerWidget(QWidget *parent, SceneTrigger *s);
|
||||
SceneTrigger *getSwitchData();
|
||||
void setSwitchData(SceneTrigger *s);
|
||||
|
||||
static void swapSwitchData(SceneTriggerWidget *s1,
|
||||
SceneTriggerWidget *s2);
|
||||
|
||||
private slots:
|
||||
void TriggerTypeChanged(int index);
|
||||
void TriggerActionChanged(int index);
|
||||
void DurationChanged(double dur);
|
||||
void AudioSourceChanged(const QString &text);
|
||||
|
||||
private:
|
||||
QComboBox *triggers;
|
||||
QComboBox *actions;
|
||||
QDoubleSpinBox *duration;
|
||||
QComboBox *audioSources;
|
||||
|
||||
SceneTrigger *switchData;
|
||||
};
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "scene-group.hpp"
|
||||
#include "scene-trigger.hpp"
|
||||
#include "switch-audio.hpp"
|
||||
#include "switch-executable.hpp"
|
||||
#include "switch-file.hpp"
|
||||
@@ -26,11 +27,6 @@ constexpr auto previous_scene_name = "Previous Scene";
|
||||
|
||||
typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch;
|
||||
typedef enum { PERSIST = 0, START = 1, STOP = 2 } StartupBehavior;
|
||||
typedef enum {
|
||||
RECORDING = 0,
|
||||
STREAMING = 1,
|
||||
RECORINDGSTREAMING = 2
|
||||
} AutoStartStopType;
|
||||
|
||||
typedef struct transitionData {
|
||||
std::string name = "";
|
||||
@@ -61,7 +57,7 @@ struct SwitcherData {
|
||||
|
||||
obs_source_t *waitScene = nullptr;
|
||||
OBSWeakSource previousScene = nullptr;
|
||||
OBSWeakSource previousScene2 = nullptr;
|
||||
OBSWeakSource previousSceneHelper = nullptr;
|
||||
OBSWeakSource lastRandomScene;
|
||||
OBSWeakSource nonMatchingScene;
|
||||
NoMatch switchIfNotMatching = NO_SWITCH;
|
||||
@@ -92,14 +88,7 @@ struct SwitcherData {
|
||||
|
||||
std::deque<ExecutableSwitch> executableSwitches;
|
||||
|
||||
bool autoStopEnable = false;
|
||||
AutoStartStopType autoStopType = RECORINDGSTREAMING;
|
||||
OBSWeakSource autoStopScene;
|
||||
|
||||
bool autoStartEnable = false;
|
||||
AutoStartStopType autoStartType = RECORDING;
|
||||
OBSWeakSource autoStartScene;
|
||||
bool autoStartedRecently = false;
|
||||
std::deque<SceneTrigger> sceneTriggers;
|
||||
|
||||
std::deque<SceneTransition> sceneTransitions;
|
||||
std::deque<DefaultSceneTransition> defaultSceneTransitions;
|
||||
@@ -166,8 +155,6 @@ struct SwitcherData {
|
||||
bool prioFuncsValid();
|
||||
void writeSceneInfoToFile();
|
||||
void writeToStatusFile(QString status);
|
||||
void autoStopStreamAndRecording();
|
||||
void autoStartStreamRecording();
|
||||
bool checkPause();
|
||||
void checkDefaultSceneTransitions(bool &match,
|
||||
OBSWeakSource &transition);
|
||||
@@ -199,7 +186,9 @@ struct SwitcherData {
|
||||
void checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition, int &sleep);
|
||||
void checkSwitchCooldown(bool &match);
|
||||
void checkTriggers();
|
||||
|
||||
void saveSettings(obs_data_t *obj);
|
||||
void saveWindowTitleSwitches(obs_data_t *obj);
|
||||
void saveScreenRegionSwitches(obs_data_t *obj);
|
||||
void savePauseSwitches(obs_data_t *obj);
|
||||
@@ -213,10 +202,12 @@ struct SwitcherData {
|
||||
void saveTimeSwitches(obs_data_t *obj);
|
||||
void saveAudioSwitches(obs_data_t *obj);
|
||||
void saveSceneGroups(obs_data_t *obj);
|
||||
void saveSceneTriggers(obs_data_t *obj);
|
||||
void saveGeneralSettings(obs_data_t *obj);
|
||||
void saveHotkeys(obs_data_t *obj);
|
||||
void saveVersion(obs_data_t *obj, std::string currentVersion);
|
||||
|
||||
void loadSettings(obs_data_t *obj);
|
||||
void loadWindowTitleSwitches(obs_data_t *obj);
|
||||
void loadScreenRegionSwitches(obs_data_t *obj);
|
||||
void loadPauseSwitches(obs_data_t *obj);
|
||||
@@ -231,6 +222,7 @@ struct SwitcherData {
|
||||
void loadTimeSwitches(obs_data_t *obj);
|
||||
void loadAudioSwitches(obs_data_t *obj);
|
||||
void loadSceneGroups(obs_data_t *obj);
|
||||
void loadSceneTriggers(obs_data_t *obj);
|
||||
void loadGeneralSettings(obs_data_t *obj);
|
||||
void loadHotkeys(obs_data_t *obj);
|
||||
|
||||
|
||||
571
src/scene-trigger.cpp
Normal file
571
src/scene-trigger.cpp
Normal file
@@ -0,0 +1,571 @@
|
||||
#include <thread>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
bool SceneTrigger::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
void AdvSceneSwitcher::on_triggerAdd_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
|
||||
listAddClicked(ui->sceneTriggers,
|
||||
new SceneTriggerWidget(this,
|
||||
&switcher->sceneTriggers.back()),
|
||||
ui->triggerAdd, &addPulse);
|
||||
|
||||
ui->triggerHelp->setVisible(false);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_triggerRemove_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->sceneTriggers->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
int idx = ui->sceneTriggers->currentRow();
|
||||
auto &switches = switcher->sceneTriggers;
|
||||
switches.erase(switches.begin() + idx);
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_triggerUp_clicked()
|
||||
{
|
||||
int index = ui->sceneTriggers->currentRow();
|
||||
if (!listMoveUp(ui->sceneTriggers))
|
||||
return;
|
||||
|
||||
SceneTriggerWidget *s1 =
|
||||
(SceneTriggerWidget *)ui->sceneTriggers->itemWidget(
|
||||
ui->sceneTriggers->item(index));
|
||||
SceneTriggerWidget *s2 =
|
||||
(SceneTriggerWidget *)ui->sceneTriggers->itemWidget(
|
||||
ui->sceneTriggers->item(index - 1));
|
||||
SceneTriggerWidget::swapSwitchData(s1, s2);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
std::swap(switcher->sceneTriggers[index],
|
||||
switcher->sceneTriggers[index - 1]);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_triggerDown_clicked()
|
||||
{
|
||||
int index = ui->sceneTriggers->currentRow();
|
||||
|
||||
if (!listMoveDown(ui->sceneTriggers))
|
||||
return;
|
||||
|
||||
SceneTriggerWidget *s1 =
|
||||
(SceneTriggerWidget *)ui->sceneTriggers->itemWidget(
|
||||
ui->sceneTriggers->item(index));
|
||||
SceneTriggerWidget *s2 =
|
||||
(SceneTriggerWidget *)ui->sceneTriggers->itemWidget(
|
||||
ui->sceneTriggers->item(index + 1));
|
||||
SceneTriggerWidget::swapSwitchData(s1, s2);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
std::swap(switcher->sceneTriggers[index],
|
||||
switcher->sceneTriggers[index + 1]);
|
||||
}
|
||||
|
||||
void SceneTrigger::logMatch()
|
||||
{
|
||||
std::string sceneName = "";
|
||||
std::string statusName = "";
|
||||
std::string actionName = "";
|
||||
|
||||
switch (triggerType) {
|
||||
case sceneTriggerType::NONE:
|
||||
statusName = "NONE";
|
||||
break;
|
||||
case sceneTriggerType::SCENE_ACTIVE:
|
||||
statusName = "SCENE ACTIVE";
|
||||
break;
|
||||
case sceneTriggerType::SCENE_INACTIVE:
|
||||
statusName = "SCENE INACTIVE";
|
||||
break;
|
||||
case sceneTriggerType::SCENE_LEAVE:
|
||||
statusName = "SCENE LEAVE";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (triggerAction) {
|
||||
case sceneTriggerAction::NONE:
|
||||
actionName = "NONE";
|
||||
break;
|
||||
case sceneTriggerAction::START_RECORDING:
|
||||
actionName = "START RECORDING";
|
||||
break;
|
||||
case sceneTriggerAction::PAUSE_RECORDING:
|
||||
actionName = "PAUSE RECORDING";
|
||||
break;
|
||||
case sceneTriggerAction::UNPAUSE_RECORDING:
|
||||
actionName = "UNPAUSE RECORDING";
|
||||
break;
|
||||
case sceneTriggerAction::STOP_RECORDING:
|
||||
actionName = "STOP RECORDING";
|
||||
break;
|
||||
case sceneTriggerAction::START_STREAMING:
|
||||
actionName = "START STREAMING";
|
||||
break;
|
||||
case sceneTriggerAction::STOP_STREAMING:
|
||||
actionName = "STOP STREAMING";
|
||||
break;
|
||||
case sceneTriggerAction::START_REPLAY_BUFFER:
|
||||
actionName = "START REPLAY BUFFER";
|
||||
break;
|
||||
case sceneTriggerAction::STOP_REPLAY_BUFFER:
|
||||
actionName = "STOP REPLAY BUFFER";
|
||||
break;
|
||||
case sceneTriggerAction::MUTE_SOURCE:
|
||||
actionName = "MUTE (" + GetWeakSourceName(audioSource) + ")";
|
||||
break;
|
||||
default:
|
||||
actionName = "UNKOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
blog(LOG_INFO,
|
||||
"scene '%s' in status '%s' triggering action '%s' after %f seconds",
|
||||
GetWeakSourceName(scene).c_str(), statusName.c_str(),
|
||||
actionName.c_str(), duration);
|
||||
}
|
||||
|
||||
void frontEndActionThread(sceneTriggerAction action, double delay)
|
||||
{
|
||||
long long mil = delay * 1000;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mil));
|
||||
|
||||
switch (action) {
|
||||
case sceneTriggerAction::NONE:
|
||||
break;
|
||||
case sceneTriggerAction::START_RECORDING:
|
||||
obs_frontend_recording_start();
|
||||
break;
|
||||
case sceneTriggerAction::PAUSE_RECORDING:
|
||||
obs_frontend_recording_pause(true);
|
||||
break;
|
||||
case sceneTriggerAction::UNPAUSE_RECORDING:
|
||||
obs_frontend_recording_pause(false);
|
||||
break;
|
||||
case sceneTriggerAction::STOP_RECORDING:
|
||||
obs_frontend_recording_stop();
|
||||
break;
|
||||
case sceneTriggerAction::START_STREAMING:
|
||||
obs_frontend_streaming_start();
|
||||
break;
|
||||
case sceneTriggerAction::STOP_STREAMING:
|
||||
obs_frontend_streaming_stop();
|
||||
break;
|
||||
case sceneTriggerAction::START_REPLAY_BUFFER:
|
||||
obs_frontend_replay_buffer_start();
|
||||
break;
|
||||
case sceneTriggerAction::STOP_REPLAY_BUFFER:
|
||||
obs_frontend_replay_buffer_stop();
|
||||
break;
|
||||
case sceneTriggerAction::MUTE_SOURCE:
|
||||
obs_frontend_replay_buffer_stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void muteThread(OBSWeakSource source, double delay)
|
||||
{
|
||||
long long mil = delay * 1000;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mil));
|
||||
|
||||
auto s = obs_weak_source_get_source(source);
|
||||
obs_source_set_muted(s, true);
|
||||
obs_source_release(s);
|
||||
}
|
||||
|
||||
bool isFrontendAction(sceneTriggerAction triggerAction)
|
||||
{
|
||||
return triggerAction == sceneTriggerAction::START_RECORDING ||
|
||||
triggerAction == sceneTriggerAction::PAUSE_RECORDING ||
|
||||
triggerAction == sceneTriggerAction::UNPAUSE_RECORDING ||
|
||||
triggerAction == sceneTriggerAction::STOP_RECORDING ||
|
||||
triggerAction == sceneTriggerAction::START_STREAMING ||
|
||||
triggerAction == sceneTriggerAction::STOP_STREAMING ||
|
||||
triggerAction == sceneTriggerAction::START_REPLAY_BUFFER ||
|
||||
triggerAction == sceneTriggerAction::STOP_REPLAY_BUFFER;
|
||||
}
|
||||
|
||||
void SceneTrigger::performAction()
|
||||
{
|
||||
if (triggerAction == sceneTriggerAction::NONE)
|
||||
return;
|
||||
|
||||
std::thread t;
|
||||
|
||||
if (isFrontendAction(triggerAction))
|
||||
t = std::thread(frontEndActionThread, triggerAction, duration);
|
||||
else
|
||||
t = std::thread(muteThread, audioSource, duration);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
bool SceneTrigger::checkMatch(OBSWeakSource previousScene)
|
||||
{
|
||||
OBSSource source = obs_frontend_get_current_scene();
|
||||
OBSWeakSource currentScene = obs_source_get_weak_source(source);
|
||||
obs_source_release(source);
|
||||
obs_weak_source_release(currentScene);
|
||||
|
||||
switch (triggerType) {
|
||||
case sceneTriggerType::NONE:
|
||||
return false;
|
||||
case sceneTriggerType::SCENE_ACTIVE:
|
||||
return currentScene == scene;
|
||||
case sceneTriggerType::SCENE_INACTIVE:
|
||||
return currentScene != scene;
|
||||
case sceneTriggerType::SCENE_LEAVE:
|
||||
return previousScene == scene;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SwitcherData::checkTriggers()
|
||||
{
|
||||
if (SceneTrigger::pause || stop) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &t : sceneTriggers) {
|
||||
if (t.checkMatch(previousScene)) {
|
||||
t.logMatch();
|
||||
t.performAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::saveSceneTriggers(obs_data_t *obj)
|
||||
{
|
||||
obs_data_array_t *triggerArray = obs_data_array_create();
|
||||
for (auto &s : switcher->sceneTriggers) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(triggerArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "triggers", triggerArray);
|
||||
obs_data_array_release(triggerArray);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
void loadOldAutoStopStart(obs_data_t *obj)
|
||||
{
|
||||
typedef enum {
|
||||
RECORDING = 0,
|
||||
STREAMING = 1,
|
||||
RECORINDGSTREAMING = 2
|
||||
} AutoStartStopType;
|
||||
|
||||
if (obs_data_get_bool(obj, "autoStopEnable")) {
|
||||
std::string autoStopScene =
|
||||
obs_data_get_string(obj, "autoStopSceneName");
|
||||
int action = obs_data_get_int(obj, "autoStopType");
|
||||
|
||||
if (action == RECORDING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStopScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::STOP_RECORDING;
|
||||
}
|
||||
|
||||
if (action == STREAMING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStopScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::STOP_STREAMING;
|
||||
}
|
||||
|
||||
if (action == RECORINDGSTREAMING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStopScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::STOP_RECORDING;
|
||||
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s2 = switcher->sceneTriggers.back();
|
||||
s2.scene = GetWeakSourceByName(autoStopScene.c_str());
|
||||
s2.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s2.triggerAction = sceneTriggerAction::STOP_STREAMING;
|
||||
}
|
||||
}
|
||||
|
||||
if (obs_data_get_bool(obj, "autoStartEnable")) {
|
||||
std::string autoStartScene =
|
||||
obs_data_get_string(obj, "autoStartSceneName");
|
||||
int action = obs_data_get_int(obj, "autoStartType");
|
||||
|
||||
if (action == RECORDING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStartScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::START_RECORDING;
|
||||
}
|
||||
|
||||
if (action == STREAMING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStartScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::START_STREAMING;
|
||||
}
|
||||
|
||||
if (action == RECORINDGSTREAMING) {
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s = switcher->sceneTriggers.back();
|
||||
s.scene = GetWeakSourceByName(autoStartScene.c_str());
|
||||
s.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s.triggerAction = sceneTriggerAction::START_RECORDING;
|
||||
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
auto &s2 = switcher->sceneTriggers.back();
|
||||
s2.scene = GetWeakSourceByName(autoStartScene.c_str());
|
||||
s2.triggerType = sceneTriggerType::SCENE_ACTIVE;
|
||||
s2.triggerAction = sceneTriggerAction::START_STREAMING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::loadSceneTriggers(obs_data_t *obj)
|
||||
{
|
||||
switcher->sceneTriggers.clear();
|
||||
|
||||
loadOldAutoStopStart(obj);
|
||||
|
||||
obs_data_array_t *triggerArray = obs_data_get_array(obj, "triggers");
|
||||
size_t count = obs_data_array_count(triggerArray);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(triggerArray, i);
|
||||
|
||||
switcher->sceneTriggers.emplace_back();
|
||||
sceneTriggers.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(triggerArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::setupTriggerTab()
|
||||
{
|
||||
for (auto &s : switcher->sceneTriggers) {
|
||||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->sceneTriggers);
|
||||
ui->sceneTriggers->addItem(item);
|
||||
SceneTriggerWidget *sw = new SceneTriggerWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->sceneTriggers->setItemWidget(item, sw);
|
||||
}
|
||||
|
||||
if (switcher->sceneTriggers.size() == 0) {
|
||||
addPulse = PulseWidget(ui->triggerAdd, QColor(Qt::green));
|
||||
ui->triggerHelp->setVisible(true);
|
||||
} else {
|
||||
ui->triggerHelp->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneTrigger::save(obs_data_t *obj)
|
||||
{
|
||||
obs_source_t *sceneSource = obs_weak_source_get_source(scene);
|
||||
const char *sceneName = obs_source_get_name(sceneSource);
|
||||
obs_data_set_string(obj, "scene", sceneName);
|
||||
obs_source_release(sceneSource);
|
||||
|
||||
obs_data_set_int(obj, "triggerType", static_cast<int>(triggerType));
|
||||
obs_data_set_int(obj, "triggerAction", static_cast<int>(triggerAction));
|
||||
obs_data_set_double(obj, "duration", duration);
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(audioSource);
|
||||
const char *audioSourceName = obs_source_get_name(source);
|
||||
obs_data_set_string(obj, "audioSource", audioSourceName);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void SceneTrigger::load(obs_data_t *obj)
|
||||
{
|
||||
const char *sceneName = obs_data_get_string(obj, "scene");
|
||||
scene = GetWeakSourceByName(sceneName);
|
||||
|
||||
triggerType = static_cast<sceneTriggerType>(
|
||||
obs_data_get_int(obj, "triggerType"));
|
||||
triggerAction = static_cast<sceneTriggerAction>(
|
||||
obs_data_get_int(obj, "triggerAction"));
|
||||
duration = obs_data_get_double(obj, "duration");
|
||||
|
||||
const char *audioSourceName = obs_data_get_string(obj, "audioSource");
|
||||
audioSource = GetWeakSourceByName(audioSourceName);
|
||||
}
|
||||
|
||||
inline void populateTriggers(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneActive"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneInactive"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneLeave"));
|
||||
}
|
||||
|
||||
inline void populateActions(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startRecording"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.pauseRecording"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unpauseRecording"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopRecording"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startStreaming"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopStreaming"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startReplayBuffer"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopReplayBuffer"));
|
||||
list->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.muteSource"));
|
||||
}
|
||||
|
||||
SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
||||
: SwitchWidget(parent, s, false, false)
|
||||
{
|
||||
triggers = new QComboBox();
|
||||
actions = new QComboBox();
|
||||
duration = new QDoubleSpinBox();
|
||||
audioSources = new QComboBox();
|
||||
|
||||
duration->setMinimum(0.0);
|
||||
duration->setMaximum(99.000000);
|
||||
duration->setSuffix("s");
|
||||
|
||||
QWidget::connect(triggers, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TriggerTypeChanged(int)));
|
||||
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TriggerActionChanged(int)));
|
||||
QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(audioSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(AudioSourceChanged(const QString &)));
|
||||
|
||||
populateTriggers(triggers);
|
||||
populateActions(actions);
|
||||
AdvSceneSwitcher::populateAudioSelection(audioSources);
|
||||
|
||||
if (s) {
|
||||
triggers->setCurrentIndex(static_cast<int>(s->triggerType));
|
||||
actions->setCurrentIndex(static_cast<int>(s->triggerAction));
|
||||
duration->setValue(s->duration);
|
||||
|
||||
audioSources->setCurrentText(
|
||||
GetWeakSourceName(s->audioSource).c_str());
|
||||
if (s->triggerAction == sceneTriggerAction::MUTE_SOURCE)
|
||||
audioSources->show();
|
||||
else
|
||||
audioSources->hide();
|
||||
}
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{triggers}}", triggers},
|
||||
{"{{actions}}", actions},
|
||||
{"{{audioSources}}", audioSources},
|
||||
{"{{duration}}", duration},
|
||||
{"{{scenes}}", scenes}};
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.sceneTriggerTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
switchData = s;
|
||||
|
||||
loading = false;
|
||||
}
|
||||
|
||||
SceneTrigger *SceneTriggerWidget::getSwitchData()
|
||||
{
|
||||
return switchData;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::setSwitchData(SceneTrigger *s)
|
||||
{
|
||||
switchData = s;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::swapSwitchData(SceneTriggerWidget *s1,
|
||||
SceneTriggerWidget *s2)
|
||||
{
|
||||
SwitchWidget::swapSwitchData(s1, s2);
|
||||
|
||||
SceneTrigger *t = s1->getSwitchData();
|
||||
s1->setSwitchData(s2->getSwitchData());
|
||||
s2->setSwitchData(t);
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::TriggerTypeChanged(int index)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->triggerType = static_cast<sceneTriggerType>(index);
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::TriggerActionChanged(int index)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->triggerAction =
|
||||
static_cast<sceneTriggerAction>(index);
|
||||
}
|
||||
|
||||
if (switchData->triggerAction == sceneTriggerAction::MUTE_SOURCE)
|
||||
audioSources->show();
|
||||
else
|
||||
audioSources->hide();
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::DurationChanged(double dur)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration = dur;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->audioSource = GetWeakSourceByQString(text);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ void TimeSwitch::load(obs_data_t *obj)
|
||||
time = QTime::fromString(obs_data_get_string(obj, "time"));
|
||||
}
|
||||
|
||||
void populateTriggers(QComboBox *list)
|
||||
inline void populateTriggers(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.timeTab.anyDay"));
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.timeTab.mondays"));
|
||||
|
||||
@@ -40,11 +40,6 @@ void SwitcherData::Prune()
|
||||
sceneSequenceSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(autoStopScene)) {
|
||||
autoStopScene = nullptr;
|
||||
autoStopEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneTransitions.size(); i++) {
|
||||
SceneTransition &s = sceneTransitions[i];
|
||||
if (!s.valid())
|
||||
|
||||
Reference in New Issue
Block a user