mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-22 01:44:49 -05:00
423 lines
11 KiB
C++
423 lines
11 KiB
C++
#include "advanced-scene-switcher.hpp"
|
|
#include "layout-helpers.hpp"
|
|
#include "selection-helpers.hpp"
|
|
#include "source-helpers.hpp"
|
|
#include "switcher-data.hpp"
|
|
#include "ui-helpers.hpp"
|
|
#include "utility.hpp"
|
|
|
|
#include <regex>
|
|
|
|
namespace advss {
|
|
|
|
static QObject *addPulse = nullptr;
|
|
|
|
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()),
|
|
&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 = HighlightWidget(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
|