mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Macro pause (#201)
* Add option to pause individual macros * Add macro action to pause and unpause macros
This commit is contained in:
parent
c1704f2164
commit
961ea655fd
|
|
@ -84,6 +84,7 @@ set(advanced-scene-switcher_HEADERS
|
|||
src/headers/macro-action-audio.hpp
|
||||
src/headers/macro-action-filter.hpp
|
||||
src/headers/macro-action-media.hpp
|
||||
src/headers/macro-action-pause.hpp
|
||||
src/headers/macro-action-recording.hpp
|
||||
src/headers/macro-action-replay-buffer.hpp
|
||||
src/headers/macro-action-run.hpp
|
||||
|
|
@ -145,6 +146,7 @@ set(advanced-scene-switcher_SOURCES
|
|||
src/macro-action-audio.cpp
|
||||
src/macro-action-filter.cpp
|
||||
src/macro-action-media.cpp
|
||||
src/macro-action-pause.cpp
|
||||
src/macro-action-recording.cpp
|
||||
src/macro-action-replay-buffer.cpp
|
||||
src/macro-action-run.cpp
|
||||
|
|
|
|||
|
|
@ -179,6 +179,10 @@ AdvSceneSwitcher.action.media.type.restart="Restart"
|
|||
AdvSceneSwitcher.action.media.type.next="Next"
|
||||
AdvSceneSwitcher.action.media.type.previous="Previous"
|
||||
AdvSceneSwitcher.action.media.entry="{{actions}} {{mediaSources}}"
|
||||
AdvSceneSwitcher.action.pause="Pause"
|
||||
AdvSceneSwitcher.action.pause.type.pause="Pause"
|
||||
AdvSceneSwitcher.action.pause.type.unpause="Unpause"
|
||||
AdvSceneSwitcher.action.pause.entry="{{actions}} {{macros}}"
|
||||
|
||||
|
||||
; Transition Tab
|
||||
|
|
@ -435,6 +439,7 @@ AdvSceneSwitcher.selectVideoSource="--select video source--"
|
|||
AdvSceneSwitcher.selectMediaSource="--select media source--"
|
||||
AdvSceneSwitcher.selectProcess="--select process--"
|
||||
AdvSceneSwitcher.selectFilter="--select filter--"
|
||||
AdvSceneSwitcher.selectMacro="--select macro--"
|
||||
AdvSceneSwitcher.selectItem="--select item--"
|
||||
AdvSceneSwitcher.enterPath="--enter path--"
|
||||
AdvSceneSwitcher.enterText="--enter text--"
|
||||
|
|
|
|||
|
|
@ -107,6 +107,9 @@ public:
|
|||
bool listMoveDown(QListWidget *list);
|
||||
|
||||
signals:
|
||||
void MacroAdded(const QString &name);
|
||||
void MacroRemoved(const QString &name);
|
||||
void MacroRenamed(const QString &oldName, const QString newName);
|
||||
void SceneGroupAdded(const QString &name);
|
||||
void SceneGroupRemoved(const QString &name);
|
||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||
|
|
@ -137,6 +140,7 @@ public slots:
|
|||
void on_macroDown_clicked();
|
||||
void on_macroName_editingFinished();
|
||||
void on_macros_currentRowChanged(int idx);
|
||||
void on_macros_itemChanged(QListWidgetItem *);
|
||||
void on_conditionAdd_clicked();
|
||||
void on_conditionRemove_clicked();
|
||||
void on_actionAdd_clicked();
|
||||
|
|
|
|||
61
src/headers/macro-action-pause.hpp
Normal file
61
src/headers/macro-action-pause.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#include <QDoubleSpinBox>
|
||||
#include "macro-action-edit.hpp"
|
||||
|
||||
enum class PauseAction {
|
||||
PAUSE,
|
||||
UNPAUSE,
|
||||
};
|
||||
|
||||
class MacroActionPause : public MacroAction {
|
||||
public:
|
||||
bool PerformAction();
|
||||
void LogAction();
|
||||
bool Save(obs_data_t *obj);
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetId() { return id; };
|
||||
static std::shared_ptr<MacroAction> Create()
|
||||
{
|
||||
return std::make_shared<MacroActionPause>();
|
||||
}
|
||||
|
||||
PauseAction _action = PauseAction::PAUSE;
|
||||
Macro *_macro = nullptr;
|
||||
|
||||
private:
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroActionPauseEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroActionPauseEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroActionPause> entryData = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroAction> action)
|
||||
{
|
||||
return new MacroActionPauseEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroActionPause>(action));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void MacroChanged(const QString &text);
|
||||
void ActionChanged(int value);
|
||||
void MacroAdd(const QString &name);
|
||||
void MacroRemove(const QString &name);
|
||||
void MacroRename(const QString &oldName, const QString &newName);
|
||||
|
||||
protected:
|
||||
QComboBox *_macros;
|
||||
QComboBox *_actions;
|
||||
std::shared_ptr<MacroActionPause> _entryData;
|
||||
|
||||
private:
|
||||
QHBoxLayout *_mainLayout;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include <map>
|
||||
#include <obs.hpp>
|
||||
#include <obs-module.h>
|
||||
#include <QString>
|
||||
|
||||
constexpr auto macro_func = 10;
|
||||
constexpr auto default_priority_10 = macro_func;
|
||||
|
|
@ -68,6 +69,8 @@ public:
|
|||
bool Matched() { return _matched; }
|
||||
std::string Name() { return _name; }
|
||||
void SetName(std::string name) { _name = name; }
|
||||
void SetPaused(bool pause = true) { _paused = pause; }
|
||||
bool Paused() { return _paused; }
|
||||
std::deque<std::shared_ptr<MacroCondition>> &Conditions()
|
||||
{
|
||||
return _conditions;
|
||||
|
|
@ -85,4 +88,8 @@ private:
|
|||
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
||||
std::deque<std::shared_ptr<MacroAction>> _actions;
|
||||
bool _matched = false;
|
||||
bool _paused = false;
|
||||
};
|
||||
|
||||
Macro *GetMacroByName(const char *name);
|
||||
Macro *GetMacroByQString(const QString &name);
|
||||
|
|
|
|||
189
src/macro-action-pause.cpp
Normal file
189
src/macro-action-pause.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "headers/macro-action-pause.hpp"
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
const std::string MacroActionPause::id = "pause";
|
||||
|
||||
bool MacroActionPause::_registered = MacroActionFactory::Register(
|
||||
MacroActionPause::id,
|
||||
{MacroActionPause::Create, MacroActionPauseEdit::Create,
|
||||
"AdvSceneSwitcher.action.pause"});
|
||||
|
||||
const static std::map<PauseAction, std::string> actionTypes = {
|
||||
{PauseAction::PAUSE, "AdvSceneSwitcher.action.pause.type.pause"},
|
||||
{PauseAction::UNPAUSE, "AdvSceneSwitcher.action.pause.type.unpause"},
|
||||
};
|
||||
|
||||
bool MacroActionPause::PerformAction()
|
||||
{
|
||||
if (!_macro) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (_action) {
|
||||
case PauseAction::PAUSE:
|
||||
_macro->SetPaused();
|
||||
break;
|
||||
case PauseAction::UNPAUSE:
|
||||
_macro->SetPaused(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionPause::LogAction()
|
||||
{
|
||||
if (!_macro) {
|
||||
return;
|
||||
}
|
||||
switch (_action) {
|
||||
case PauseAction::PAUSE:
|
||||
vblog(LOG_INFO, "paused \"%s\"", _macro->Name().c_str());
|
||||
break;
|
||||
case PauseAction::UNPAUSE:
|
||||
vblog(LOG_INFO, "unpaused \"%s\"", _macro->Name().c_str());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroActionPause::Save(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
if (_macro) {
|
||||
obs_data_set_string(obj, "macro", _macro->Name().c_str());
|
||||
}
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionPause::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_macro = GetMacroByName(obs_data_get_string(obj, "macro"));
|
||||
_action = static_cast<PauseAction>(obs_data_get_int(obj, "action"));
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : actionTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateMacroSelection(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.selectMacro"));
|
||||
for (auto &m : switcher->macros) {
|
||||
list->addItem(QString::fromStdString(m.Name()));
|
||||
}
|
||||
}
|
||||
|
||||
MacroActionPauseEdit::MacroActionPauseEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionPause> entryData)
|
||||
: QWidget(parent)
|
||||
{
|
||||
_macros = new QComboBox();
|
||||
_actions = new QComboBox();
|
||||
|
||||
populateActionSelection(_actions);
|
||||
populateMacroSelection(_macros);
|
||||
|
||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(MacroChanged(const QString &)));
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(parent, SIGNAL(MacroAdded(const QString &)), this,
|
||||
SLOT(MacroAdd(const QString &)));
|
||||
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
|
||||
SLOT(MacroRemove(const QString &)));
|
||||
QWidget::connect(parent,
|
||||
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
||||
this,
|
||||
SLOT(MacroRename(const QString &, const QString &)));
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{actions}}", _actions},
|
||||
{"{{macros}}", _macros},
|
||||
};
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.pause.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
if (_entryData->_macro) {
|
||||
_macros->setCurrentText(
|
||||
QString::fromStdString(_entryData->_macro->Name()));
|
||||
} else {
|
||||
_macros->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::MacroChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_macro = GetMacroByQString(text);
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::ActionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_action = static_cast<PauseAction>(value);
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::MacroAdd(const QString &name)
|
||||
{
|
||||
_macros->addItem(name);
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::MacroRemove(const QString &name)
|
||||
{
|
||||
int idx = _macros->findText(name);
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
_macros->removeItem(idx);
|
||||
if (_entryData && _entryData->_macro == GetMacroByQString(name)) {
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_macro = nullptr;
|
||||
}
|
||||
_macros->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void MacroActionPauseEdit::MacroRename(const QString &oldName,
|
||||
const QString &newName)
|
||||
{
|
||||
bool renameSelected = _macros->currentText() == oldName;
|
||||
int idx = _macros->findText(oldName);
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
_macros->removeItem(idx);
|
||||
_macros->insertItem(idx, newName);
|
||||
if (renameSelected) {
|
||||
_macros->setCurrentIndex(_macros->findText(newName));
|
||||
}
|
||||
}
|
||||
|
|
@ -13,13 +13,7 @@ const auto actionsCollapseThreshold = 2;
|
|||
|
||||
bool macroNameExists(std::string name)
|
||||
{
|
||||
for (auto &m : switcher->macros) {
|
||||
if (m.Name() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return !!GetMacroByName(name.c_str());
|
||||
}
|
||||
|
||||
bool AdvSceneSwitcher::addNewMacro(std::string &name)
|
||||
|
|
@ -69,10 +63,14 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
|
|||
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
|
||||
item->setData(Qt::UserRole, text);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(Qt::Checked);
|
||||
ui->macros->setCurrentItem(item);
|
||||
|
||||
ui->macroAdd->disconnect(addPulse);
|
||||
ui->macroHelp->setVisible(false);
|
||||
|
||||
emit MacroAdded(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroRemove_clicked()
|
||||
|
|
@ -81,9 +79,11 @@ void AdvSceneSwitcher::on_macroRemove_clicked()
|
|||
if (!item) {
|
||||
return;
|
||||
}
|
||||
QString name;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
int idx = ui->macros->currentRow();
|
||||
QString::fromStdString(switcher->macros[idx].Name());
|
||||
switcher->macros.erase(switcher->macros.begin() + idx);
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +92,7 @@ void AdvSceneSwitcher::on_macroRemove_clicked()
|
|||
if (ui->macros->count() == 0) {
|
||||
ui->macroHelp->setVisible(true);
|
||||
}
|
||||
emit MacroRemoved(name);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroUp_clicked()
|
||||
|
|
@ -147,12 +148,17 @@ void AdvSceneSwitcher::on_macroName_editingFinished()
|
|||
if (nameValid) {
|
||||
macro->SetName(newName.toUtf8().constData());
|
||||
QListWidgetItem *item = ui->macros->currentItem();
|
||||
item->setData(Qt::UserRole, newName);
|
||||
// Don't trigger itemChanged()
|
||||
// pause state remains as is
|
||||
ui->macros->blockSignals(true);
|
||||
item->setText(newName);
|
||||
ui->macros->blockSignals(false);
|
||||
} else {
|
||||
ui->macroName->setText(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
emit MacroRenamed(oldName, newName);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
||||
|
|
@ -196,22 +202,14 @@ void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
|||
|
||||
Macro *AdvSceneSwitcher::getSelectedMacro()
|
||||
{
|
||||
Macro *macro = nullptr;
|
||||
QListWidgetItem *item = ui->macros->currentItem();
|
||||
|
||||
if (!item) {
|
||||
return macro;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString name = item->data(Qt::UserRole).toString();
|
||||
for (auto &m : switcher->macros) {
|
||||
if (name.compare(m.Name().c_str()) == 0) {
|
||||
macro = &m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return macro;
|
||||
QString name = item->text();
|
||||
return GetMacroByQString(name);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macros_currentRowChanged(int idx)
|
||||
|
|
@ -226,13 +224,26 @@ void AdvSceneSwitcher::on_macros_currentRowChanged(int idx)
|
|||
}
|
||||
|
||||
QListWidgetItem *item = ui->macros->item(idx);
|
||||
QString macroName = item->data(Qt::UserRole).toString();
|
||||
QString macroName = item->text();
|
||||
|
||||
for (auto &m : switcher->macros) {
|
||||
if (macroName.compare(m.Name().c_str()) == 0) {
|
||||
SetEditMacro(m);
|
||||
break;
|
||||
}
|
||||
auto macro = GetMacroByQString(macroName);
|
||||
if (macro) {
|
||||
SetEditMacro(*macro);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macros_itemChanged(QListWidgetItem *item)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
QString name = item->text();
|
||||
|
||||
auto m = GetMacroByQString(name);
|
||||
if (m) {
|
||||
m->SetPaused(item->checkState() != Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,6 +254,12 @@ void AdvSceneSwitcher::setupMacroTab()
|
|||
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
|
||||
item->setData(Qt::UserRole, text);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
if (m.Paused()) {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
if (switcher->macros.size() == 0) {
|
||||
|
|
@ -286,5 +303,7 @@ void AdvSceneSwitcher::copyMacro()
|
|||
QString text = QString::fromStdString(name);
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
|
||||
item->setData(Qt::UserRole, text);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(Qt::Checked);
|
||||
ui->macros->setCurrentItem(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ Macro::~Macro() {}
|
|||
|
||||
bool Macro::CeckMatch()
|
||||
{
|
||||
if (_paused) {
|
||||
vblog(LOG_INFO, "Macro %s is paused", _name.c_str());
|
||||
return false;
|
||||
}
|
||||
_matched = false;
|
||||
for (auto &c : _conditions) {
|
||||
bool cond = c->CheckCondition();
|
||||
|
|
@ -80,6 +84,7 @@ bool Macro::PerformAction()
|
|||
bool Macro::Save(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_string(obj, "name", _name.c_str());
|
||||
obs_data_set_bool(obj, "pause", _paused);
|
||||
|
||||
obs_data_array_t *conditions = obs_data_array_create();
|
||||
for (auto &c : _conditions) {
|
||||
|
|
@ -145,6 +150,7 @@ void setValidLogic(MacroCondition *c, bool root, std::string name)
|
|||
bool Macro::Load(obs_data_t *obj)
|
||||
{
|
||||
_name = obs_data_get_string(obj, "name");
|
||||
_paused = obs_data_get_bool(obj, "pause");
|
||||
bool root = true;
|
||||
|
||||
obs_data_array_t *conditions = obs_data_get_array(obj, "conditions");
|
||||
|
|
@ -363,3 +369,19 @@ bool SwitcherData::runMacros()
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Macro *GetMacroByName(const char *name)
|
||||
{
|
||||
for (auto &m : switcher->macros) {
|
||||
if (m.Name() == name) {
|
||||
return &m;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Macro *GetMacroByQString(const QString &name)
|
||||
{
|
||||
return GetMacroByName(name.toUtf8().constData());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user