mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-04-04 16:25:39 -05:00
The "core" macro conditions and actions have been extracted out to the "base" plugin. The library now mostly contains functionality which is required across all plugins and (e.g. definitions for macro segments). The goal is to reduce the complexity and cross-dependencies and group the source files in a better way. This should relsove the "library limit of 65535 objects exceeded" build issue occuring in some Windows build environments.
418 lines
11 KiB
C++
418 lines
11 KiB
C++
#include "advanced-scene-switcher.hpp"
|
|
#include "switcher-data.hpp"
|
|
#include "utility.hpp"
|
|
|
|
#include <regex>
|
|
|
|
namespace advss {
|
|
|
|
static QMetaObject::Connection addPulse;
|
|
|
|
void AdvSceneSwitcher::on_pauseAdd_clicked()
|
|
{
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
switcher->pauseEntries.emplace_back();
|
|
|
|
listAddClicked(ui->pauseEntries,
|
|
new PauseEntryWidget(this,
|
|
&switcher->pauseEntries.back()),
|
|
ui->pauseAdd, &addPulse);
|
|
|
|
ui->pauseHelp->setVisible(false);
|
|
}
|
|
|
|
void AdvSceneSwitcher::on_pauseRemove_clicked()
|
|
{
|
|
QListWidgetItem *item = ui->pauseEntries->currentItem();
|
|
if (!item) {
|
|
return;
|
|
}
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
int idx = ui->pauseEntries->currentRow();
|
|
auto &switches = switcher->pauseEntries;
|
|
switches.erase(switches.begin() + idx);
|
|
}
|
|
|
|
delete item;
|
|
}
|
|
|
|
void AdvSceneSwitcher::on_pauseUp_clicked()
|
|
{
|
|
int index = ui->pauseEntries->currentRow();
|
|
if (!listMoveUp(ui->pauseEntries)) {
|
|
return;
|
|
}
|
|
|
|
PauseEntryWidget *s1 = (PauseEntryWidget *)ui->pauseEntries->itemWidget(
|
|
ui->pauseEntries->item(index));
|
|
PauseEntryWidget *s2 = (PauseEntryWidget *)ui->pauseEntries->itemWidget(
|
|
ui->pauseEntries->item(index - 1));
|
|
PauseEntryWidget::swapSwitchData(s1, s2);
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
|
|
std::swap(switcher->pauseEntries[index],
|
|
switcher->pauseEntries[index - 1]);
|
|
}
|
|
|
|
void AdvSceneSwitcher::on_pauseDown_clicked()
|
|
{
|
|
int index = ui->pauseEntries->currentRow();
|
|
|
|
if (!listMoveDown(ui->pauseEntries)) {
|
|
return;
|
|
}
|
|
|
|
PauseEntryWidget *s1 = (PauseEntryWidget *)ui->pauseEntries->itemWidget(
|
|
ui->pauseEntries->item(index));
|
|
PauseEntryWidget *s2 = (PauseEntryWidget *)ui->pauseEntries->itemWidget(
|
|
ui->pauseEntries->item(index + 1));
|
|
PauseEntryWidget::swapSwitchData(s1, s2);
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
|
|
std::swap(switcher->pauseEntries[index],
|
|
switcher->pauseEntries[index + 1]);
|
|
}
|
|
|
|
void resetPause()
|
|
{
|
|
DefaultSceneTransition::pause = false;
|
|
WindowSwitch::pause = false;
|
|
ExecutableSwitch::pause = false;
|
|
ScreenRegionSwitch::pause = false;
|
|
MediaSwitch::pause = false;
|
|
FileSwitch::pause = false;
|
|
RandomSwitch::pause = false;
|
|
TimeSwitch::pause = false;
|
|
IdleData::pause = false;
|
|
SceneSequenceSwitch::pause = false;
|
|
AudioSwitch::pause = false;
|
|
VideoSwitch::pause = false;
|
|
}
|
|
|
|
void setPauseTarget(PauseTarget &target)
|
|
{
|
|
switch (target) {
|
|
case PauseTarget::All:
|
|
vblog(LOG_INFO, "pause all switching");
|
|
break;
|
|
case PauseTarget::Transition:
|
|
vblog(LOG_INFO, "pause def_transition switching");
|
|
DefaultSceneTransition::pause = true;
|
|
break;
|
|
case PauseTarget::Window:
|
|
vblog(LOG_INFO, "pause window switching");
|
|
WindowSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Executable:
|
|
vblog(LOG_INFO, "pause exec switching");
|
|
ExecutableSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Region:
|
|
vblog(LOG_INFO, "pause region switching");
|
|
ScreenRegionSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Media:
|
|
vblog(LOG_INFO, "pause media switching");
|
|
MediaSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::File:
|
|
vblog(LOG_INFO, "pause file switching");
|
|
FileSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Random:
|
|
vblog(LOG_INFO, "pause random switching");
|
|
RandomSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Time:
|
|
vblog(LOG_INFO, "pause time switching");
|
|
TimeSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Idle:
|
|
vblog(LOG_INFO, "pause idle switching");
|
|
IdleData::pause = true;
|
|
break;
|
|
case PauseTarget::Sequence:
|
|
vblog(LOG_INFO, "pause sequence switching");
|
|
SceneSequenceSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Audio:
|
|
vblog(LOG_INFO, "pause audio switching");
|
|
AudioSwitch::pause = true;
|
|
break;
|
|
case PauseTarget::Video:
|
|
vblog(LOG_INFO, "pause video switching");
|
|
VideoSwitch::pause = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool checkPauseScene(obs_weak_source_t *currentScene, obs_weak_source_t *scene,
|
|
PauseTarget &target)
|
|
{
|
|
if (!currentScene || currentScene != scene) {
|
|
return false;
|
|
}
|
|
|
|
setPauseTarget(target);
|
|
return (target == PauseTarget::All);
|
|
}
|
|
bool checkPauseWindow(std::string ¤tTitle, std::string &title,
|
|
PauseTarget &target)
|
|
{
|
|
if (currentTitle != title) {
|
|
return false;
|
|
}
|
|
|
|
setPauseTarget(target);
|
|
return (target == PauseTarget::All);
|
|
}
|
|
|
|
bool SwitcherData::checkPause()
|
|
{
|
|
bool pauseAll = false;
|
|
std::string title = switcher->currentTitle;
|
|
|
|
resetPause();
|
|
|
|
for (PauseEntry &s : pauseEntries) {
|
|
if (s.pauseType == PauseType::Scene) {
|
|
pauseAll = checkPauseScene(currentScene, s.scene,
|
|
s.pauseTarget);
|
|
} else {
|
|
pauseAll = checkPauseWindow(title, s.window,
|
|
s.pauseTarget);
|
|
}
|
|
if (pauseAll) {
|
|
break;
|
|
}
|
|
}
|
|
return pauseAll;
|
|
}
|
|
|
|
void SwitcherData::savePauseSwitches(obs_data_t *obj)
|
|
{
|
|
obs_data_array_t *pauseScenesArray = obs_data_array_create();
|
|
for (PauseEntry &s : pauseEntries) {
|
|
obs_data_t *array_obj = obs_data_create();
|
|
|
|
obs_data_set_int(array_obj, "pauseType",
|
|
static_cast<int>(s.pauseType));
|
|
obs_data_set_int(array_obj, "pauseTarget",
|
|
static_cast<int>(s.pauseTarget));
|
|
obs_data_set_string(array_obj, "pauseWindow", s.window.c_str());
|
|
|
|
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
|
if (source) {
|
|
const char *n = obs_source_get_name(source);
|
|
obs_data_set_string(array_obj, "pauseScene", n);
|
|
}
|
|
|
|
obs_data_array_push_back(pauseScenesArray, array_obj);
|
|
|
|
obs_source_release(source);
|
|
obs_data_release(array_obj);
|
|
}
|
|
obs_data_set_array(obj, "pauseEntries", pauseScenesArray);
|
|
obs_data_array_release(pauseScenesArray);
|
|
}
|
|
|
|
void SwitcherData::loadPauseSwitches(obs_data_t *obj)
|
|
{
|
|
pauseEntries.clear();
|
|
|
|
obs_data_array_t *pauseArray = obs_data_get_array(obj, "pauseEntries");
|
|
size_t count = obs_data_array_count(pauseArray);
|
|
|
|
for (size_t i = 0; i < count; i++) {
|
|
obs_data_t *array_obj = obs_data_array_item(pauseArray, i);
|
|
|
|
PauseType type = static_cast<PauseType>(
|
|
obs_data_get_int(array_obj, "pauseType"));
|
|
PauseTarget target = static_cast<PauseTarget>(
|
|
obs_data_get_int(array_obj, "pauseTarget"));
|
|
const char *scene =
|
|
obs_data_get_string(array_obj, "pauseScene");
|
|
const char *window =
|
|
obs_data_get_string(array_obj, "pauseWindow");
|
|
|
|
pauseEntries.emplace_back(GetWeakSourceByName(scene), type,
|
|
target, window);
|
|
|
|
obs_data_release(array_obj);
|
|
}
|
|
obs_data_array_release(pauseArray);
|
|
}
|
|
|
|
void AdvSceneSwitcher::SetupPauseTab()
|
|
{
|
|
for (auto &s : switcher->pauseEntries) {
|
|
QListWidgetItem *item;
|
|
item = new QListWidgetItem(ui->pauseEntries);
|
|
ui->pauseEntries->addItem(item);
|
|
PauseEntryWidget *sw = new PauseEntryWidget(this, &s);
|
|
item->setSizeHint(sw->minimumSizeHint());
|
|
ui->pauseEntries->setItemWidget(item, sw);
|
|
}
|
|
|
|
if (switcher->pauseEntries.size() == 0) {
|
|
if (!switcher->disableHints) {
|
|
addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green));
|
|
}
|
|
ui->pauseHelp->setVisible(true);
|
|
} else {
|
|
ui->pauseHelp->setVisible(false);
|
|
}
|
|
}
|
|
|
|
void populatePauseTypes(QComboBox *list)
|
|
{
|
|
list->addItem(
|
|
obs_module_text("AdvSceneSwitcher.pauseTab.pauseTypeScene"));
|
|
list->addItem(
|
|
obs_module_text("AdvSceneSwitcher.pauseTab.pauseTypeWindow"));
|
|
}
|
|
|
|
void populatePauseTargets(QComboBox *list)
|
|
{
|
|
list->addItem(
|
|
obs_module_text("AdvSceneSwitcher.pauseTab.pauseTargetAll"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.transitionTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.windowTitleTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.executableTab.title"));
|
|
list->addItem(
|
|
obs_module_text("AdvSceneSwitcher.screenRegionTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.mediaTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.fileTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.randomTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.timeTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.idleTab.title"));
|
|
list->addItem(
|
|
obs_module_text("AdvSceneSwitcher.sceneSequenceTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.audioTab.title"));
|
|
list->addItem(obs_module_text("AdvSceneSwitcher.VideoTab.title"));
|
|
}
|
|
|
|
PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
|
: SwitchWidget(parent, s, false, false)
|
|
{
|
|
pauseTypes = new QComboBox();
|
|
pauseTargets = new QComboBox();
|
|
windows = new QComboBox();
|
|
|
|
QWidget::connect(pauseTypes, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(PauseTypeChanged(int)));
|
|
QWidget::connect(pauseTargets, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(PauseTargetChanged(int)));
|
|
QWidget::connect(windows, SIGNAL(currentTextChanged(const QString &)),
|
|
this, SLOT(WindowChanged(const QString &)));
|
|
|
|
populatePauseTypes(pauseTypes);
|
|
populatePauseTargets(pauseTargets);
|
|
PopulateWindowSelection(windows);
|
|
|
|
windows->setEditable(true);
|
|
windows->setMaxVisibleItems(20);
|
|
|
|
if (s) {
|
|
scenes->setCurrentText(GetWeakSourceName(s->scene).c_str());
|
|
pauseTypes->setCurrentIndex(static_cast<int>(s->pauseType));
|
|
pauseTargets->setCurrentIndex(static_cast<int>(s->pauseTarget));
|
|
windows->setCurrentText(s->window.c_str());
|
|
if (s->pauseType == PauseType::Scene) {
|
|
windows->setDisabled(true);
|
|
windows->setVisible(false);
|
|
} else {
|
|
scenes->setDisabled(true);
|
|
scenes->setVisible(false);
|
|
}
|
|
}
|
|
|
|
QHBoxLayout *mainLayout = new QHBoxLayout;
|
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
|
{"{{scenes}}", scenes},
|
|
{"{{pauseTypes}}", pauseTypes},
|
|
{"{{pauseTargets}}", pauseTargets},
|
|
{"{{windows}}", windows}};
|
|
|
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"),
|
|
mainLayout, widgetPlaceholders);
|
|
setLayout(mainLayout);
|
|
|
|
switchData = s;
|
|
|
|
loading = false;
|
|
}
|
|
|
|
PauseEntry *PauseEntryWidget::getSwitchData()
|
|
{
|
|
return switchData;
|
|
}
|
|
|
|
void PauseEntryWidget::setSwitchData(PauseEntry *s)
|
|
{
|
|
switchData = s;
|
|
}
|
|
|
|
void PauseEntryWidget::swapSwitchData(PauseEntryWidget *s1,
|
|
PauseEntryWidget *s2)
|
|
{
|
|
SwitchWidget::swapSwitchData(s1, s2);
|
|
|
|
PauseEntry *t = s1->getSwitchData();
|
|
s1->setSwitchData(s2->getSwitchData());
|
|
s2->setSwitchData(t);
|
|
}
|
|
|
|
void PauseEntryWidget::PauseTypeChanged(int index)
|
|
{
|
|
if (loading || !switchData) {
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
switchData->pauseType = static_cast<PauseType>(index);
|
|
|
|
if (switchData->pauseType == PauseType::Scene) {
|
|
windows->setDisabled(true);
|
|
windows->setVisible(false);
|
|
scenes->setDisabled(false);
|
|
scenes->setVisible(true);
|
|
} else {
|
|
scenes->setDisabled(true);
|
|
scenes->setVisible(false);
|
|
windows->setDisabled(false);
|
|
windows->setVisible(true);
|
|
}
|
|
}
|
|
|
|
void PauseEntryWidget::PauseTargetChanged(int index)
|
|
{
|
|
if (loading || !switchData) {
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
switchData->pauseTarget = static_cast<PauseTarget>(index);
|
|
}
|
|
|
|
void PauseEntryWidget::WindowChanged(const QString &text)
|
|
{
|
|
if (loading || !switchData) {
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
switchData->window = text.toStdString();
|
|
}
|
|
|
|
bool PauseEntry::valid()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
} // namespace advss
|