mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-07-08 12:45:25 -05:00
309 lines
7.6 KiB
C++
309 lines
7.6 KiB
C++
#include "headers/macro-action-random.hpp"
|
|
#include "headers/advanced-scene-switcher.hpp"
|
|
#include "headers/name-dialog.hpp"
|
|
#include "headers/utility.hpp"
|
|
|
|
#include <QDialogButtonBox>
|
|
#include <cstdlib>
|
|
|
|
const std::string MacroActionRandom::id = "random";
|
|
|
|
bool MacroActionRandom::_registered = MacroActionFactory::Register(
|
|
MacroActionRandom::id,
|
|
{MacroActionRandom::Create, MacroActionRandomEdit::Create,
|
|
"AdvSceneSwitcher.action.random"});
|
|
|
|
std::vector<MacroRef> getPossibleMacros(std::vector<MacroRef> ¯os,
|
|
MacroRef &lastRandomMacro)
|
|
{
|
|
std::vector<MacroRef> res;
|
|
if (macros.size() == 1) {
|
|
if (macros[0]->Paused()) {
|
|
return res;
|
|
} else {
|
|
return macros;
|
|
}
|
|
}
|
|
|
|
for (auto &m : macros) {
|
|
if (m.get() && !m->Paused() &&
|
|
!(lastRandomMacro.get() == m.get())) {
|
|
res.push_back(m);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool MacroActionRandom::PerformAction()
|
|
{
|
|
if (_macros.size() == 0) {
|
|
return true;
|
|
}
|
|
|
|
auto macros = getPossibleMacros(_macros, lastRandomMacro);
|
|
if (macros.size() == 0) {
|
|
return true;
|
|
}
|
|
if (macros.size() == 1) {
|
|
lastRandomMacro = macros[0];
|
|
return macros[0]->PerformAction();
|
|
}
|
|
|
|
size_t idx = std::rand() % (macros.size());
|
|
lastRandomMacro = macros[idx];
|
|
return macros[idx]->PerformAction();
|
|
}
|
|
|
|
void MacroActionRandom::LogAction()
|
|
{
|
|
vblog(LOG_INFO, "running random macro");
|
|
}
|
|
|
|
bool MacroActionRandom::Save(obs_data_t *obj)
|
|
{
|
|
MacroAction::Save(obj);
|
|
obs_data_array_t *args = obs_data_array_create();
|
|
for (auto &m : _macros) {
|
|
obs_data_t *array_obj = obs_data_create();
|
|
m.Save(array_obj);
|
|
obs_data_array_push_back(args, array_obj);
|
|
obs_data_release(array_obj);
|
|
}
|
|
obs_data_set_array(obj, "macros", args);
|
|
obs_data_array_release(args);
|
|
return true;
|
|
}
|
|
|
|
bool MacroActionRandom::Load(obs_data_t *obj)
|
|
{
|
|
MacroAction::Load(obj);
|
|
obs_data_array_t *args = obs_data_get_array(obj, "macros");
|
|
size_t count = obs_data_array_count(args);
|
|
for (size_t i = 0; i < count; i++) {
|
|
obs_data_t *array_obj = obs_data_array_item(args, i);
|
|
MacroRef ref;
|
|
ref.Load(array_obj);
|
|
_macros.push_back(ref);
|
|
obs_data_release(array_obj);
|
|
}
|
|
obs_data_array_release(args);
|
|
return true;
|
|
}
|
|
|
|
MacroActionRandomEdit::MacroActionRandomEdit(
|
|
QWidget *parent, std::shared_ptr<MacroActionRandom> entryData)
|
|
: QWidget(parent)
|
|
{
|
|
_macroList = new QListWidget();
|
|
_macroList->setSortingEnabled(true);
|
|
_add = new QPushButton();
|
|
_add->setMaximumSize(QSize(22, 22));
|
|
_add->setProperty("themeID",
|
|
QVariant(QString::fromUtf8("addIconSmall")));
|
|
_add->setFlat(true);
|
|
_remove = new QPushButton();
|
|
_remove->setMaximumSize(QSize(22, 22));
|
|
_remove->setProperty("themeID",
|
|
QVariant(QString::fromUtf8("removeIconSmall")));
|
|
_remove->setFlat(true);
|
|
|
|
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(AddMacro()));
|
|
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(RemoveMacro()));
|
|
QWidget::connect(_macroList, SIGNAL(currentRowChanged(int)), this,
|
|
SLOT(MacroSelectionChanged(int)));
|
|
QWidget::connect(window(),
|
|
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
|
this,
|
|
SLOT(MacroRename(const QString &, const QString &)));
|
|
|
|
auto *entryLayout = new QHBoxLayout;
|
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {};
|
|
placeWidgets(obs_module_text("AdvSceneSwitcher.action.random.entry"),
|
|
entryLayout, widgetPlaceholders);
|
|
|
|
auto *argButtonLayout = new QHBoxLayout;
|
|
argButtonLayout->addWidget(_add);
|
|
argButtonLayout->addWidget(_remove);
|
|
argButtonLayout->addStretch();
|
|
|
|
auto *mainLayout = new QVBoxLayout;
|
|
mainLayout->addLayout(entryLayout);
|
|
mainLayout->addWidget(_macroList);
|
|
mainLayout->addLayout(argButtonLayout);
|
|
setLayout(mainLayout);
|
|
|
|
_entryData = entryData;
|
|
UpdateEntryData();
|
|
_loading = false;
|
|
}
|
|
|
|
void MacroActionRandomEdit::UpdateEntryData()
|
|
{
|
|
if (!_entryData) {
|
|
return;
|
|
}
|
|
|
|
for (auto &m : _entryData->_macros) {
|
|
if (!m.get()) {
|
|
continue;
|
|
}
|
|
auto name = QString::fromStdString(m->Name());
|
|
QListWidgetItem *item = new QListWidgetItem(name, _macroList);
|
|
item->setData(Qt::UserRole, name);
|
|
}
|
|
SetMacroListSize();
|
|
}
|
|
|
|
void MacroActionRandomEdit::MacroRemove(const QString &name)
|
|
{
|
|
if (_entryData) {
|
|
auto it = _entryData->_macros.begin();
|
|
while (it != _entryData->_macros.end()) {
|
|
if (it->get()->Name() == name.toStdString()) {
|
|
it = _entryData->_macros.erase(it);
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MacroActionRandomEdit::MacroRename(const QString &oldName,
|
|
const QString &newName)
|
|
{
|
|
auto count = _macroList->count();
|
|
for (int idx = 0; idx < count; ++idx) {
|
|
QListWidgetItem *item = _macroList->item(idx);
|
|
QString itemString = item->data(Qt::UserRole).toString();
|
|
if (oldName == itemString) {
|
|
item->setData(Qt::UserRole, newName);
|
|
item->setText(newName);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MacroActionRandomEdit::AddMacro()
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
std::string macroName;
|
|
bool accepted = MacroDialog::AskForMacro(this, macroName);
|
|
|
|
if (!accepted || macroName.empty()) {
|
|
return;
|
|
}
|
|
|
|
MacroRef macro(macroName);
|
|
|
|
if (!macro.get()) {
|
|
return;
|
|
}
|
|
|
|
if (FindEntry(macro->Name()) != -1) {
|
|
return;
|
|
}
|
|
|
|
QVariant v = QVariant::fromValue(QString::fromStdString(macroName));
|
|
QListWidgetItem *item = new QListWidgetItem(
|
|
QString::fromStdString(macroName), _macroList);
|
|
item->setData(Qt::UserRole, QString::fromStdString(macroName));
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
_entryData->_macros.push_back(macro);
|
|
SetMacroListSize();
|
|
}
|
|
|
|
void MacroActionRandomEdit::RemoveMacro()
|
|
{
|
|
if (_loading || !_entryData) {
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(switcher->m);
|
|
auto item = _macroList->currentItem();
|
|
if (!item) {
|
|
return;
|
|
}
|
|
std::string name = item->data(Qt::UserRole).toString().toStdString();
|
|
for (auto it = _entryData->_macros.begin();
|
|
it != _entryData->_macros.end(); ++it) {
|
|
auto m = *it;
|
|
if (m.get() && m->Name() == name) {
|
|
_entryData->_macros.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
delete item;
|
|
SetMacroListSize();
|
|
}
|
|
|
|
int MacroActionRandomEdit::FindEntry(const std::string ¯o)
|
|
{
|
|
int count = _macroList->count();
|
|
int idx = -1;
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
QListWidgetItem *item = _macroList->item(i);
|
|
QString itemString = item->data(Qt::UserRole).toString();
|
|
if (QString::fromStdString(macro) == itemString) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return idx;
|
|
}
|
|
|
|
void MacroActionRandomEdit::SetMacroListSize()
|
|
{
|
|
setHeightToContentHeight(_macroList);
|
|
adjustSize();
|
|
}
|
|
|
|
MacroDialog::MacroDialog(QWidget *)
|
|
{
|
|
setModal(true);
|
|
setWindowModality(Qt::WindowModality::ApplicationModal);
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
setMinimumWidth(350);
|
|
setMinimumHeight(70);
|
|
|
|
QDialogButtonBox *buttonbox = new QDialogButtonBox(
|
|
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
|
|
|
buttonbox->setCenterButtons(true);
|
|
connect(buttonbox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
|
connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
|
|
_macroSelection = new MacroSelection(window());
|
|
auto *selectionLayout = new QHBoxLayout;
|
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
|
{"{{macroSelection}}", _macroSelection},
|
|
};
|
|
placeWidgets(obs_module_text("AdvSceneSwitcher.askForMacro"),
|
|
selectionLayout, widgetPlaceholders);
|
|
auto *layout = new QVBoxLayout();
|
|
layout->addLayout(selectionLayout);
|
|
layout->addWidget(buttonbox);
|
|
setLayout(layout);
|
|
}
|
|
|
|
bool MacroDialog::AskForMacro(QWidget *parent, std::string ¯oName)
|
|
{
|
|
MacroDialog dialog(parent);
|
|
dialog.setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
|
|
|
if (dialog.exec() != DialogCode::Accepted) {
|
|
return false;
|
|
}
|
|
macroName = dialog._macroSelection->currentText().toUtf8().constData();
|
|
if (macroName == obs_module_text("AdvSceneSwitcher.selectMacro")) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|