mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-29 13:25:29 -05:00
This required the following adjustments: Instead of having a dedicated entry indicating the empty selection the setPlaceholderText() mechanism is used. Thus the locations where the 1st entry was assumed to be the empty selection would have to be adjusted. Additional checks for the empty string / index -1 have been added. FindIdxInRagne() was adjusted to return -1 instead of 0 in case the given string was not found. Switched to index based singal instead of text based signal to be notified about selection changes.
263 lines
6.1 KiB
C++
263 lines
6.1 KiB
C++
#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 == -1 || name.isEmpty()) {
|
|
return s;
|
|
}
|
|
|
|
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();
|
|
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(-1);
|
|
}
|
|
|
|
FilterSelectionWidget::FilterSelectionWidget(QWidget *parent,
|
|
SourceSelectionWidget *sources,
|
|
bool addVariables)
|
|
: FilterComboBox(parent,
|
|
obs_module_text("AdvSceneSwitcher.selectFilter")),
|
|
_addVariables(addVariables)
|
|
{
|
|
setDuplicatesEnabled(true);
|
|
|
|
QWidget::connect(this, SIGNAL(currentIndexChanged(int)), this,
|
|
SLOT(SelectionChanged(int)));
|
|
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 = -1;
|
|
|
|
switch (filter.GetType()) {
|
|
case FilterSelection::Type::SOURCE: {
|
|
if (_filterEndIdx == -1) {
|
|
idx = -1;
|
|
break;
|
|
}
|
|
idx = FindIdxInRagne(this, _variablesEndIdx, _filterEndIdx,
|
|
filter.ToString());
|
|
break;
|
|
}
|
|
case FilterSelection::Type::VARIABLE: {
|
|
if (_variablesEndIdx == -1) {
|
|
idx = -1;
|
|
break;
|
|
}
|
|
idx = FindIdxInRagne(this, _selectIdx, _variablesEndIdx,
|
|
filter.ToString());
|
|
break;
|
|
default:
|
|
idx = -1;
|
|
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(int)
|
|
{
|
|
_currentSelection = CurrentSelection();
|
|
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
|