Add macro condition "source"

This commit is contained in:
WarmUpTill 2021-05-24 13:43:34 +02:00 committed by WarmUpTill
parent a5edbc8b88
commit 2454ea8fa5
4 changed files with 312 additions and 0 deletions

View File

@ -104,6 +104,7 @@ set(advanced-scene-switcher_HEADERS
src/headers/macro-condition-recording.hpp
src/headers/macro-condition-region.hpp
src/headers/macro-condition-scene.hpp
src/headers/macro-condition-source.hpp
src/headers/macro-condition-streaming.hpp
src/headers/macro-condition-video.hpp
src/headers/macro-condition-window.hpp
@ -170,6 +171,7 @@ set(advanced-scene-switcher_SOURCES
src/macro-condition-recording.cpp
src/macro-condition-region.cpp
src/macro-condition-scene.cpp
src/macro-condition-source.cpp
src/macro-condition-streaming.cpp
src/macro-condition-video.cpp
src/macro-condition-window.cpp

View File

@ -133,6 +133,15 @@ AdvSceneSwitcher.condition.counter.type.equal="Exactly"
AdvSceneSwitcher.condition.counter.reset="Reset"
AdvSceneSwitcher.condition.counter.entry.line1="{{macros}} was executed {{conditions}} {{count}} times"
AdvSceneSwitcher.condition.counter.entry.line2="Current count: {{currentCount}} {{resetCount}}"
AdvSceneSwitcher.condition.source="Source"
AdvSceneSwitcher.condition.source.type.active="Is active"
AdvSceneSwitcher.condition.source.type.showing="Is showing"
AdvSceneSwitcher.condition.source.type.settings="Settings match"
AdvSceneSwitcher.condition.source.regex="Use regular expressions"
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
AdvSceneSwitcher.condition.source.entry.line1="{{sources}} {{conditions}}"
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
AdvSceneSwitcher.condition.source.entry.line3="{{regex}} {{getSettings}}"
; Macro Actions
AdvSceneSwitcher.action.switchScene="Switch scene"

View File

@ -0,0 +1,69 @@
#pragma once
#include "macro.hpp"
#include <limits>
#include <QWidget>
#include <QComboBox>
enum class SourceCondition {
ACTIVE,
SHOWING,
SETTINGS,
};
class MacroConditionSource : public MacroCondition {
public:
bool CheckCondition();
bool Save(obs_data_t *obj);
bool Load(obs_data_t *obj);
std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create()
{
return std::make_shared<MacroConditionSource>();
}
OBSWeakSource _source = nullptr;
SourceCondition _condition = SourceCondition::ACTIVE;
std::string _settings = "";
bool _regex = false;
private:
static bool _registered;
static const std::string id;
};
class MacroConditionSourceEdit : public QWidget {
Q_OBJECT
public:
MacroConditionSourceEdit(
QWidget *parent,
std::shared_ptr<MacroConditionSource> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionSourceEdit(
parent,
std::dynamic_pointer_cast<MacroConditionSource>(cond));
}
private slots:
void SourceChanged(const QString &text);
void ConditionChanged(int cond);
void GetSettingsClicked();
void SettingsChanged();
void RegexChanged(int);
protected:
QComboBox *_sources;
QComboBox *_conditions;
QPushButton *_getSettings;
QPlainTextEdit *_settings;
QCheckBox *_regex;
std::shared_ptr<MacroConditionSource> _entryData;
private:
void SetSettingsSelectionVisible(bool visible);
bool _loading = true;
};

View File

@ -0,0 +1,232 @@
#include "headers/macro-condition-edit.hpp"
#include "headers/macro-condition-source.hpp"
#include "headers/utility.hpp"
#include "headers/advanced-scene-switcher.hpp"
#include <regex>
const std::string MacroConditionSource::id = "source";
bool MacroConditionSource::_registered = MacroConditionFactory::Register(
MacroConditionSource::id,
{MacroConditionSource::Create, MacroConditionSourceEdit::Create,
"AdvSceneSwitcher.condition.source"});
static std::map<SourceCondition, std::string> sourceConditionTypes = {
{SourceCondition::ACTIVE,
"AdvSceneSwitcher.condition.source.type.active"},
{SourceCondition::SHOWING,
"AdvSceneSwitcher.condition.source.type.showing"},
{SourceCondition::SETTINGS,
"AdvSceneSwitcher.condition.source.type.settings"},
};
std::string getSourceSettings(OBSWeakSource ws)
{
auto s = obs_weak_source_get_source(ws);
obs_data_t *data = obs_source_get_settings(s);
std::string settings = obs_data_get_json(data);
obs_data_release(data);
obs_source_release(s);
return settings;
}
bool checkSettings(const OBSWeakSource &source, const std::string &settings,
bool useRegex)
{
bool ret = false;
std::string currentSettings = getSourceSettings(source);
if (useRegex) {
try {
std::regex expr(settings);
ret = std::regex_match(currentSettings, expr);
} catch (const std::regex_error &) {
}
} else {
ret = currentSettings == settings;
}
return ret;
}
bool MacroConditionSource::CheckCondition()
{
if (!_source) {
return false;
}
bool ret = false;
auto s = obs_weak_source_get_source(_source);
switch (_condition) {
case SourceCondition::ACTIVE:
ret = obs_source_active(s);
break;
case SourceCondition::SHOWING:
ret = obs_source_showing(s);
break;
case SourceCondition::SETTINGS:
ret = checkSettings(_source, _settings, _regex);
break;
default:
break;
}
obs_source_release(s);
return ret;
}
bool MacroConditionSource::Save(obs_data_t *obj)
{
MacroCondition::Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
return true;
}
bool MacroConditionSource::Load(obs_data_t *obj)
{
MacroCondition::Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_condition = static_cast<SourceCondition>(
obs_data_get_int(obj, "condition"));
return true;
}
static inline void populateConditionSelection(QComboBox *list)
{
for (auto entry : sourceConditionTypes) {
list->addItem(obs_module_text(entry.second.c_str()));
}
}
MacroConditionSourceEdit::MacroConditionSourceEdit(
QWidget *parent, std::shared_ptr<MacroConditionSource> entryData)
: QWidget(parent)
{
_sources = new QComboBox();
_conditions = new QComboBox();
_getSettings = new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.source.getSettings"));
_settings = new QPlainTextEdit();
_regex = new QCheckBox(
obs_module_text("AdvSceneSwitcher.condition.source.regex"));
populateConditionSelection(_conditions);
populateSourceSelection(_sources);
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
SLOT(GetSettingsClicked()));
QWidget::connect(_settings, SIGNAL(textChanged()), this,
SLOT(SettingsChanged()));
QWidget::connect(_regex, SIGNAL(stateChanged(int)), this,
SLOT(RegexChanged(int)));
QVBoxLayout *mainLayout = new QVBoxLayout;
QHBoxLayout *line1Layout = new QHBoxLayout;
QHBoxLayout *line2Layout = new QHBoxLayout;
QHBoxLayout *line3Layout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{sources}}", _sources}, {"{{conditions}}", _conditions},
{"{{settings}}", _settings}, {"{{getSettings}}", _getSettings},
{"{{regex}}", _regex},
};
placeWidgets(obs_module_text(
"AdvSceneSwitcher.condition.source.entry.line1"),
line1Layout, widgetPlaceholders);
placeWidgets(obs_module_text(
"AdvSceneSwitcher.condition.source.entry.line2"),
line2Layout, widgetPlaceholders, false);
placeWidgets(obs_module_text(
"AdvSceneSwitcher.condition.source.entry.line3"),
line3Layout, widgetPlaceholders);
mainLayout->addLayout(line1Layout);
mainLayout->addLayout(line2Layout);
mainLayout->addLayout(line3Layout);
setLayout(mainLayout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
}
void MacroConditionSourceEdit::SourceChanged(const QString &text)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
}
void MacroConditionSourceEdit::ConditionChanged(int index)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_condition = static_cast<SourceCondition>(index);
SetSettingsSelectionVisible(_entryData->_condition ==
SourceCondition::SETTINGS);
}
void MacroConditionSourceEdit::GetSettingsClicked()
{
if (_loading || !_entryData || !_entryData->_source) {
return;
}
_settings->setPlainText(
QString::fromStdString(getSourceSettings(_entryData->_source)));
}
void MacroConditionSourceEdit::SettingsChanged()
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_settings = _settings->toPlainText().toStdString();
}
void MacroConditionSourceEdit::RegexChanged(int state)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_regex = state;
}
void MacroConditionSourceEdit::SetSettingsSelectionVisible(bool visible)
{
_settings->setVisible(visible);
_getSettings->setVisible(visible);
_regex->setVisible(visible);
}
void MacroConditionSourceEdit::UpdateEntryData()
{
if (!_entryData) {
return;
}
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
_regex->setChecked(_entryData->_regex);
SetSettingsSelectionVisible(_entryData->_condition ==
SourceCondition::SETTINGS);
}