Enable use of variables in filter selection

This commit is contained in:
WarmUpTill
2023-04-26 16:45:24 +02:00
committed by WarmUpTill
parent 530bbc07c5
commit 8cd818b80e
12 changed files with 441 additions and 122 deletions

View File

@@ -251,6 +251,8 @@ target_sources(
src/utils/log-helper.hpp
src/utils/file-selection.cpp
src/utils/file-selection.hpp
src/utils/filter-selection.cpp
src/utils/filter-selection.hpp
src/utils/macro-list.cpp
src/utils/macro-list.hpp
src/utils/math-helpers.cpp

View File

@@ -319,7 +319,7 @@ AdvSceneSwitcher.condition.filter.type.settings="Settings match"
AdvSceneSwitcher.condition.filter.getSettings="Get current settings"
AdvSceneSwitcher.condition.filter.entry.line1="On {{sources}} {{filters}} {{conditions}}"
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}} {{getSettings}}"
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}}{{getSettings}}"
AdvSceneSwitcher.condition.sceneOrder="Scene item order"
AdvSceneSwitcher.condition.sceneOrder.type.above="Is above"
AdvSceneSwitcher.condition.sceneOrder.type.below="Is below"

View File

@@ -19,24 +19,9 @@ const static std::map<MacroActionFilter::Action, std::string> actionTypes = {
"AdvSceneSwitcher.action.filter.type.settings"},
};
void MacroActionFilter::ResolveVariables()
{
if (_source.GetType() == SourceSelection::Type::SOURCE) {
return;
}
std::string name = GetWeakSourceName(_filter);
if (!name.empty()) {
_filterName = name;
}
_filter = GetWeakFilterByName(_source.GetSource(), _filterName.c_str());
}
bool MacroActionFilter::PerformAction()
{
ResolveVariables();
auto s = obs_weak_source_get_source(_filter);
auto s = obs_weak_source_get_source(_filter.GetFilter(_source));
switch (_action) {
case Action::ENABLE:
obs_source_set_enabled(s, true);
@@ -60,7 +45,7 @@ void MacroActionFilter::LogAction() const
if (it != actionTypes.end()) {
vblog(LOG_INFO,
"performed action \"%s\" for filter \"%s\" on source \"%s\"",
it->second.c_str(), GetWeakSourceName(_filter).c_str(),
it->second.c_str(), _filter.ToString().c_str(),
_source.ToString(true).c_str());
} else {
blog(LOG_WARNING, "ignored unknown filter action %d",
@@ -72,7 +57,7 @@ bool MacroActionFilter::Save(obs_data_t *obj) const
{
MacroAction::Save(obj);
_source.Save(obj);
obs_data_set_string(obj, "filter", _filterName.c_str());
_filter.Save(obj, "filter");
obs_data_set_int(obj, "action", static_cast<int>(_action));
_settings.Save(obj, "settings");
return true;
@@ -82,9 +67,7 @@ bool MacroActionFilter::Load(obs_data_t *obj)
{
MacroAction::Load(obj);
_source.Load(obj);
_filterName = obs_data_get_string(obj, "filter");
_filter = GetWeakFilterByQString(_source.GetSource(),
_filterName.c_str());
_filter.Load(obj, _source, "filter");
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
_settings.Load(obj, "settings");
return true;
@@ -92,8 +75,8 @@ bool MacroActionFilter::Load(obs_data_t *obj)
std::string MacroActionFilter::GetShortDesc() const
{
if (_filter && !_source.ToString().empty()) {
return _source.ToString() + " - " + GetWeakSourceName(_filter);
if (!_filter.ToString().empty() && !_source.ToString().empty()) {
return _source.ToString() + " - " + _filter.ToString();
}
return "";
}
@@ -109,7 +92,7 @@ MacroActionFilterEdit::MacroActionFilterEdit(
QWidget *parent, std::shared_ptr<MacroActionFilter> entryData)
: QWidget(parent),
_sources(new SourceSelectionWidget(this, QStringList(), true)),
_filters(new QComboBox()),
_filters(new FilterSelectionWidget(this, _sources, true)),
_actions(new QComboBox()),
_getSettings(new QPushButton(obs_module_text(
"AdvSceneSwitcher.action.filter.getSettings"))),
@@ -127,8 +110,9 @@ MacroActionFilterEdit::MacroActionFilterEdit(
QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
QWidget::connect(_filters, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(FilterChanged(const QString &)));
QWidget::connect(_filters,
SIGNAL(FilterChanged(const FilterSelection &)), this,
SLOT(FilterChanged(const FilterSelection &)));
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
SLOT(GetSettingsClicked()));
QWidget::connect(_settings, SIGNAL(textChanged()), this,
@@ -147,6 +131,7 @@ MacroActionFilterEdit::MacroActionFilterEdit(
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(_getSettings);
buttonLayout->addStretch();
buttonLayout->setContentsMargins(0, 0, 0, 0);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(entryLayout);
@@ -167,9 +152,7 @@ void MacroActionFilterEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_sources->SetSource(_entryData->_source);
PopulateFilterSelection(_filters, _entryData->_source.GetSource());
_filters->setCurrentText(
GetWeakSourceName(_entryData->_filter).c_str());
_filters->SetFilter(_entryData->_source, _entryData->_filter);
_settings->setPlainText(_entryData->_settings);
SetWidgetVisibility(_entryData->_action ==
MacroActionFilter::Action::SETTINGS);
@@ -183,25 +166,19 @@ void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
if (_loading || !_entryData) {
return;
}
{
auto lock = LockContext();
_entryData->_source = source;
}
_filters->clear();
PopulateFilterSelection(_filters, _entryData->_source.GetSource());
_filters->adjustSize();
auto lock = LockContext();
_entryData->_source = source;
}
void MacroActionFilterEdit::FilterChanged(const QString &text)
void MacroActionFilterEdit::FilterChanged(const FilterSelection &filter)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_filterName = text.toStdString();
_entryData->_filter =
GetWeakFilterByQString(_entryData->_source.GetSource(), text);
_entryData->_filter = filter;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
@@ -220,13 +197,13 @@ void MacroActionFilterEdit::ActionChanged(int value)
void MacroActionFilterEdit::GetSettingsClicked()
{
if (_loading || !_entryData || !_entryData->_source.GetSource() ||
!_entryData->_filter) {
if (_loading || !_entryData ||
!_entryData->_filter.GetFilter(_entryData->_source)) {
return;
}
_settings->setPlainText(
FormatJsonString(GetSourceSettings(_entryData->_filter)));
_settings->setPlainText(FormatJsonString(GetSourceSettings(
_entryData->_filter.GetFilter(_entryData->_source))));
}
void MacroActionFilterEdit::SettingsChanged()
@@ -247,6 +224,7 @@ void MacroActionFilterEdit::SetWidgetVisibility(bool showSettings)
_settings->setVisible(showSettings);
_getSettings->setVisible(showSettings);
adjustSize();
updateGeometry();
}
} // namespace advss

View File

@@ -2,6 +2,7 @@
#include "macro-action-edit.hpp"
#include "variable-text-edit.hpp"
#include "source-selection.hpp"
#include "filter-selection.hpp"
#include <QComboBox>
#include <QSpinBox>
@@ -30,18 +31,13 @@ public:
};
SourceSelection _source;
OBSWeakSource _filter;
FilterSelection _filter;
Action _action = Action::ENABLE;
StringVariable _settings = "";
private:
void ResolveVariables();
std::string _filterName = "";
static bool _registered;
static const std::string id;
friend class MacroActionFilterEdit;
};
class MacroActionFilterEdit : public QWidget {
@@ -62,7 +58,7 @@ public:
private slots:
void SourceChanged(const SourceSelection &);
void FilterChanged(const QString &);
void FilterChanged(const FilterSelection &);
void ActionChanged(int value);
void GetSettingsClicked();
void SettingsChanged();
@@ -71,7 +67,7 @@ signals:
protected:
SourceSelectionWidget *_sources;
QComboBox *_filters;
FilterSelectionWidget *_filters;
QComboBox *_actions;
QPushButton *_getSettings;
VariableTextEdit *_settings;

View File

@@ -22,47 +22,34 @@ static std::map<MacroConditionFilter::Condition, std::string>
"AdvSceneSwitcher.condition.filter.type.settings"},
};
void MacroConditionFilter::ResolveVariables()
{
if (_source.GetType() == SourceSelection::Type::SOURCE) {
return;
}
std::string name = GetWeakSourceName(_filter);
if (!name.empty()) {
_filterName = name;
}
_filter = GetWeakFilterByName(_source.GetSource(), _filterName.c_str());
}
bool MacroConditionFilter::CheckCondition()
{
ResolveVariables();
if (!_source.GetSource()) {
auto filterWeakSource = _filter.GetFilter(_source);
if (!filterWeakSource) {
return false;
}
auto filterSource = obs_weak_source_get_source(filterWeakSource);
bool ret = false;
auto s = obs_weak_source_get_source(_filter);
switch (_condition) {
case Condition::ENABLED:
ret = obs_source_enabled(s);
ret = obs_source_enabled(filterSource);
break;
case Condition::DISABLED:
ret = !obs_source_enabled(s);
ret = !obs_source_enabled(filterSource);
break;
case Condition::SETTINGS:
ret = CompareSourceSettings(_filter, _settings, _regex);
ret = CompareSourceSettings(filterWeakSource, _settings,
_regex);
if (IsReferencedInVars()) {
SetVariableValue(GetSourceSettings(_filter));
SetVariableValue(GetSourceSettings(filterWeakSource));
}
break;
default:
break;
}
obs_source_release(s);
obs_source_release(filterSource);
if (GetVariableValue().empty()) {
SetVariableValue(ret ? "true" : "false");
@@ -75,7 +62,7 @@ bool MacroConditionFilter::Save(obs_data_t *obj) const
{
MacroCondition::Save(obj);
_source.Save(obj);
obs_data_set_string(obj, "filter", _filterName.c_str());
_filter.Save(obj, "filter");
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
_settings.Save(obj, "settings");
_regex.Save(obj);
@@ -86,9 +73,7 @@ bool MacroConditionFilter::Load(obs_data_t *obj)
{
MacroCondition::Load(obj);
_source.Load(obj);
_filterName = obs_data_get_string(obj, "filter");
_filter = GetWeakFilterByQString(_source.GetSource(),
_filterName.c_str());
_filter.Load(obj, _source, "filter");
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
_settings.Load(obj, "settings");
_regex.Load(obj);
@@ -102,8 +87,8 @@ bool MacroConditionFilter::Load(obs_data_t *obj)
std::string MacroConditionFilter::GetShortDesc() const
{
if (_filter && !_source.ToString().empty()) {
return _source.ToString() + " - " + GetWeakSourceName(_filter);
if (!_filter.ToString().empty() && !_source.ToString().empty()) {
return _source.ToString() + " - " + _filter.ToString();
}
return "";
}
@@ -119,14 +104,13 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
QWidget *parent, std::shared_ptr<MacroConditionFilter> entryData)
: QWidget(parent),
_sources(new SourceSelectionWidget(this, QStringList(), true)),
_filters(new QComboBox()),
_filters(new FilterSelectionWidget(this, _sources, true)),
_conditions(new QComboBox()),
_getSettings(new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.filter.getSettings"))),
_settings(new VariableTextEdit(this)),
_regex(new RegexConfigWidget(parent))
{
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
populateConditionSelection(_conditions);
auto sources = GetSourcesWithFilterNames();
sources.sort();
@@ -135,8 +119,9 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
QWidget::connect(_filters, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(FilterChanged(const QString &)));
QWidget::connect(_filters,
SIGNAL(FilterChanged(const FilterSelection &)), this,
SLOT(FilterChanged(const FilterSelection &)));
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
@@ -146,20 +131,23 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
QWidget::connect(_regex, SIGNAL(RegexConfigChanged(RegexConfig)), this,
SLOT(RegexChanged(RegexConfig)));
QHBoxLayout *line1Layout = new QHBoxLayout;
QHBoxLayout *line2Layout = new QHBoxLayout;
QHBoxLayout *line3Layout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{sources}}", _sources}, {"{{filters}}", _filters},
{"{{conditions}}", _conditions}, {"{{settings}}", _settings},
{"{{getSettings}}", _getSettings}, {"{{regex}}", _regex},
};
auto line1Layout = new QHBoxLayout;
line1Layout->setContentsMargins(0, 0, 0, 0);
PlaceWidgets(obs_module_text(
"AdvSceneSwitcher.condition.filter.entry.line1"),
line1Layout, widgetPlaceholders);
auto line2Layout = new QHBoxLayout;
line2Layout->setContentsMargins(0, 0, 0, 0);
PlaceWidgets(obs_module_text(
"AdvSceneSwitcher.condition.filter.entry.line2"),
line2Layout, widgetPlaceholders, false);
auto line3Layout = new QHBoxLayout;
line3Layout->setContentsMargins(0, 0, 0, 0);
PlaceWidgets(obs_module_text(
"AdvSceneSwitcher.condition.filter.entry.line3"),
line3Layout, widgetPlaceholders);
@@ -180,25 +168,19 @@ void MacroConditionFilterEdit::SourceChanged(const SourceSelection &source)
if (_loading || !_entryData) {
return;
}
{
auto lock = LockContext();
_entryData->_source = source;
}
_filters->clear();
PopulateFilterSelection(_filters, _entryData->_source.GetSource());
_filters->adjustSize();
auto lock = LockContext();
_entryData->_source = source;
}
void MacroConditionFilterEdit::FilterChanged(const QString &text)
void MacroConditionFilterEdit::FilterChanged(const FilterSelection &filter)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_filterName = text.toStdString();
_entryData->_filter =
GetWeakFilterByQString(_entryData->_source.GetSource(), text);
_entryData->_filter = filter;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
@@ -218,11 +200,13 @@ void MacroConditionFilterEdit::ConditionChanged(int index)
void MacroConditionFilterEdit::GetSettingsClicked()
{
if (_loading || !_entryData || !_entryData->_source.GetSource()) {
if (_loading || !_entryData ||
!_entryData->_filter.GetFilter(_entryData->_source)) {
return;
}
QString json = FormatJsonString(GetSourceSettings(_entryData->_filter));
QString json = FormatJsonString(GetSourceSettings(
_entryData->_filter.GetFilter(_entryData->_source)));
if (_entryData->_regex.Enabled()) {
json = EscapeForRegex(json);
}
@@ -261,6 +245,7 @@ void MacroConditionFilterEdit::SetSettingsSelectionVisible(bool visible)
_getSettings->setVisible(visible);
_regex->setVisible(visible);
adjustSize();
updateGeometry();
}
void MacroConditionFilterEdit::UpdateEntryData()
@@ -270,9 +255,7 @@ void MacroConditionFilterEdit::UpdateEntryData()
}
_sources->SetSource(_entryData->_source);
PopulateFilterSelection(_filters, _entryData->_source.GetSource());
_filters->setCurrentText(
GetWeakSourceName(_entryData->_filter).c_str());
_filters->SetFilter(_entryData->_source, _entryData->_filter);
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_settings->setPlainText(_entryData->_settings);
_regex->SetRegexConfig(_entryData->_regex);

View File

@@ -3,6 +3,7 @@
#include "variable-text-edit.hpp"
#include "regex-config.hpp"
#include "source-selection.hpp"
#include "filter-selection.hpp"
#include <QComboBox>
#include <QPushButton>
@@ -30,19 +31,14 @@ public:
};
SourceSelection _source;
OBSWeakSource _filter;
FilterSelection _filter;
Condition _condition = Condition::ENABLED;
StringVariable _settings = "";
RegexConfig _regex;
private:
void ResolveVariables();
std::string _filterName = "";
static bool _registered;
static const std::string id;
friend class MacroConditionFilterEdit;
};
class MacroConditionFilterEdit : public QWidget {
@@ -63,7 +59,7 @@ public:
private slots:
void SourceChanged(const SourceSelection &);
void FilterChanged(const QString &text);
void FilterChanged(const FilterSelection &);
void ConditionChanged(int cond);
void GetSettingsClicked();
void SettingsChanged();
@@ -73,7 +69,7 @@ signals:
protected:
SourceSelectionWidget *_sources;
QComboBox *_filters;
FilterSelectionWidget *_filters;
QComboBox *_conditions;
QPushButton *_getSettings;
VariableTextEdit *_settings;

View File

@@ -0,0 +1,260 @@
#include "filter-selection.hpp"
#include "obs-module-helper.hpp"
namespace advss {
constexpr std::string_view typeSaveName = "type";
constexpr std::string_view nameSaveName = "name";
void FilterSelection::Save(obs_data_t *obj, const char *name) const
{
auto data = obs_data_create();
obs_data_set_int(data, typeSaveName.data(), static_cast<int>(_type));
switch (_type) {
case Type::SOURCE:
obs_data_set_string(data, nameSaveName.data(),
_filter ? GetWeakSourceName(_filter).c_str()
: _filterName.c_str());
break;
case Type::VARIABLE: {
auto var = _variable.lock();
if (!var) {
break;
}
obs_data_set_string(data, nameSaveName.data(),
var->Name().c_str());
break;
}
default:
break;
}
obs_data_set_obj(obj, name, data);
obs_data_release(data);
}
void FilterSelection::Load(obs_data_t *obj, const SourceSelection &source,
const char *name)
{
auto data = obs_data_get_obj(obj, name);
_type = static_cast<Type>(obs_data_get_int(data, typeSaveName.data()));
_filterName = obs_data_get_string(data, nameSaveName.data());
switch (_type) {
case Type::SOURCE:
_filter = GetWeakFilterByName(source.GetSource(),
_filterName.c_str());
break;
case Type::VARIABLE:
_variable = GetWeakVariableByName(_filterName);
break;
default:
break;
}
if (!obs_data_has_user_value(data, typeSaveName.data())) {
LoadFallback(obj, source, name);
}
obs_data_release(data);
}
void FilterSelection::LoadFallback(obs_data_t *obj,
const SourceSelection &source,
const char *name)
{
blog(LOG_INFO, "Falling back to Load() without variable support");
_type = Type::SOURCE;
_filter = GetWeakFilterByName(source.GetSource(), name);
_filterName = obs_data_get_string(obj, name);
}
OBSWeakSource FilterSelection::GetFilter(const SourceSelection &source) const
{
switch (_type) {
case Type::SOURCE:
return GetWeakFilterByName(
source.GetSource(),
_filter ? GetWeakSourceName(_filter).c_str()
: _filterName.c_str());
case Type::VARIABLE: {
auto var = _variable.lock();
if (!var) {
return nullptr;
}
return GetWeakFilterByName(source.GetSource(),
var->Value().c_str());
}
default:
break;
}
return nullptr;
}
std::string FilterSelection::ToString(bool resolve) const
{
switch (_type) {
case Type::SOURCE:
return _filter ? GetWeakSourceName(_filter) : _filterName;
case Type::VARIABLE: {
auto var = _variable.lock();
if (!var) {
return "";
}
if (resolve) {
return var->Name() + "[" + var->Value() + "]";
}
return var->Name();
}
default:
break;
}
return "";
}
FilterSelection FilterSelectionWidget::CurrentSelection()
{
FilterSelection s;
const int idx = currentIndex();
const auto name = currentText();
if (idx < _variablesEndIdx) {
s._type = FilterSelection::Type::VARIABLE;
s._variable = GetWeakVariableByQString(name);
} else if (idx < _filterEndIdx) {
s._type = FilterSelection::Type::SOURCE;
s._filter = GetWeakSourceByQString(name);
s._filterName = name.toStdString();
}
return s;
}
void FilterSelectionWidget::Reset()
{
auto previousSelection = _currentSelection;
PopulateSelection();
SetFilter(_source, previousSelection);
}
void FilterSelectionWidget::PopulateSelection()
{
const QSignalBlocker b(this);
clear();
AddSelectionEntry(this,
obs_module_text("AdvSceneSwitcher.selectFilter"));
insertSeparator(count());
if (_addVariables) {
const QStringList variables = GetVariablesNameList();
AddSelectionGroup(this, variables);
}
_variablesEndIdx = count();
AddSelectionGroup(this, GetFilterNames(_source.GetSource()));
_filterEndIdx = count();
// Remove last separator
removeItem(count() - 1);
setCurrentIndex(0);
}
FilterSelectionWidget::FilterSelectionWidget(QWidget *parent,
SourceSelectionWidget *sources,
bool addVariables)
: QComboBox(parent), _addVariables(addVariables)
{
setDuplicatesEnabled(true);
QWidget::connect(this, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SelectionChanged(const QString &)));
QWidget::connect(sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
// Variables
QWidget::connect(window(), SIGNAL(VariableAdded(const QString &)), this,
SLOT(ItemAdd(const QString &)));
QWidget::connect(window(), SIGNAL(VariableRemoved(const QString &)),
this, SLOT(ItemRemove(const QString &)));
QWidget::connect(
window(),
SIGNAL(VariableRenamed(const QString &, const QString &)), this,
SLOT(ItemRename(const QString &, const QString &)));
}
void FilterSelectionWidget::SetFilter(const SourceSelection &source,
const FilterSelection &filter)
{
_source = source;
PopulateSelection();
int idx = 0;
switch (filter.GetType()) {
case FilterSelection::Type::SOURCE: {
if (_filterEndIdx == -1) {
idx = 0;
break;
}
idx = FindIdxInRagne(this, _variablesEndIdx, _filterEndIdx,
filter.ToString());
break;
}
case FilterSelection::Type::VARIABLE: {
if (_variablesEndIdx == -1) {
idx = 0;
break;
}
idx = FindIdxInRagne(this, _selectIdx, _variablesEndIdx,
filter.ToString());
break;
default:
idx = 0;
break;
}
}
setCurrentIndex(idx);
_currentSelection = filter;
}
void FilterSelectionWidget::SourceChanged(const SourceSelection &source)
{
if (source == _source) {
return;
}
_source = source;
_currentSelection = FilterSelection();
Reset();
emit FilterChanged(_currentSelection);
}
void FilterSelectionWidget::SelectionChanged(const QString &)
{
emit FilterChanged(CurrentSelection());
}
void FilterSelectionWidget::ItemAdd(const QString &)
{
const QSignalBlocker b(this);
Reset();
}
bool FilterSelectionWidget::NameUsed(const QString &name)
{
return _currentSelection._type == FilterSelection::Type::VARIABLE &&
currentText() == name;
}
void FilterSelectionWidget::ItemRemove(const QString &name)
{
if (NameUsed(name)) {
_currentSelection = FilterSelection();
emit FilterChanged(_currentSelection);
}
const QSignalBlocker b(this);
Reset();
}
void FilterSelectionWidget::ItemRename(const QString &, const QString &)
{
const QSignalBlocker b(this);
Reset();
}
} // namespace advss

View File

@@ -0,0 +1,74 @@
#pragma once
#include "source-selection.hpp"
namespace advss {
class FilterSelection {
public:
void Save(obs_data_t *obj, const char *name = "filter") const;
void Load(obs_data_t *obj, const SourceSelection &source,
const char *name = "filter");
enum class Type {
SOURCE,
VARIABLE,
};
Type GetType() const { return _type; }
OBSWeakSource GetFilter(const SourceSelection &source) const;
std::string ToString(bool resolve = false) const;
private:
// TODO: Remove in future version
// Used for backwards compatability to older settings versions
void LoadFallback(obs_data_t *obj, const SourceSelection &source,
const char *name);
OBSWeakSource _filter;
// Storing the name separately as depending on the source selection
// the filter source might not be available at the moment.
std::string _filterName = "";
std::weak_ptr<Variable> _variable;
Type _type = Type::SOURCE;
friend class FilterSelectionWidget;
};
class FilterSelectionWidget : public QComboBox {
Q_OBJECT
public:
FilterSelectionWidget(QWidget *parent, SourceSelectionWidget *sources,
bool addVariables = true);
void SetFilter(const SourceSelection &, const FilterSelection &);
signals:
void FilterChanged(const FilterSelection &);
public slots:
void SourceChanged(const SourceSelection &);
private slots:
void SelectionChanged(const QString &name);
void ItemAdd(const QString &name);
void ItemRemove(const QString &name);
void ItemRename(const QString &oldName, const QString &newName);
private:
void Reset();
FilterSelection CurrentSelection();
void PopulateSelection();
bool NameUsed(const QString &name);
bool _addVariables;
FilterSelection _currentSelection;
SourceSelection _source;
// Order of entries
// 1. "select entry" entry
// 2. Variables
// 3. Regular filters
const int _selectIdx = 0;
int _variablesEndIdx = -1;
int _filterEndIdx = -1;
};
} // namespace advss

View File

@@ -105,6 +105,21 @@ std::string SourceSelection::ToString(bool resolve) const
return "";
}
bool SourceSelection::operator==(const SourceSelection &other) const
{
if (_type != other._type) {
return false;
}
if (_type == Type::SOURCE) {
return _source == other._source;
}
auto v1 = _variable.lock();
auto v2 = other._variable.lock();
return v1 == v2;
}
SourceSelection SourceSelectionWidget::CurrentSelection()
{
SourceSelection s;

View File

@@ -22,6 +22,8 @@ public:
void SetSource(OBSWeakSource);
std::string ToString(bool resolve = false) const;
bool operator==(const SourceSelection &) const;
private:
// TODO: Remove in future version
// Used for backwards compatability to older settings versions

View File

@@ -511,6 +511,25 @@ QStringList GetSourceNames()
return list;
}
QStringList GetFilterNames(OBSWeakSource weakSource)
{
if (!weakSource) {
return {};
}
QStringList list;
auto enumFilters = [](obs_source_t *, obs_source_t *filter, void *ptr) {
auto name = obs_source_get_name(filter);
QStringList *list = reinterpret_cast<QStringList *>(ptr);
*list << QString(name);
};
auto s = obs_weak_source_get_source(weakSource);
obs_source_enum_filters(s, enumFilters, &list);
obs_source_release(s);
return list;
}
void PopulateSourceSelection(QComboBox *list, bool addSelect)
{
auto sources = GetSourceNames();
@@ -815,18 +834,11 @@ void PopulateSourcesWithFilterSelection(QComboBox *list)
void PopulateFilterSelection(QComboBox *list, OBSWeakSource weakSource)
{
auto enumFilters = [](obs_source_t *, obs_source_t *filter, void *ptr) {
QComboBox *list = reinterpret_cast<QComboBox *>(ptr);
auto name = obs_source_get_name(filter);
list->addItem(name);
};
auto s = obs_weak_source_get_source(weakSource);
obs_source_enum_filters(s, enumFilters, list);
list->model()->sort(0);
auto filters = GetFilterNames(weakSource);
filters.sort();
list->addItems(filters);
AddSelectionEntry(list,
obs_module_text("AdvSceneSwitcher.selectFilter"));
obs_source_release(s);
list->setCurrentIndex(0);
}

View File

@@ -50,6 +50,7 @@ QStringList GetMediaSourceNames();
QStringList GetVideoSourceNames();
QStringList GetSceneNames();
QStringList GetSourceNames();
QStringList GetFilterNames(OBSWeakSource weakSource);
/* Populate list helpers */