mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add SourceSetting helpers
They enable easy modification of single setting value of sources compared to working with the raw json string
This commit is contained in:
parent
569b915c07
commit
4686fc2b01
|
|
@ -307,6 +307,8 @@ target_sources(
|
|||
src/utils/slider-spinbox.hpp
|
||||
src/utils/source-selection.cpp
|
||||
src/utils/source-selection.hpp
|
||||
src/utils/source-setting.cpp
|
||||
src/utils/source-setting.hpp
|
||||
src/utils/string-list.cpp
|
||||
src/utils/string-list.hpp
|
||||
src/utils/striped-frame.cpp
|
||||
|
|
|
|||
|
|
@ -1419,6 +1419,7 @@ AdvSceneSwitcher.enterText="--enter text--"
|
|||
AdvSceneSwitcher.enterURL="--enter URL--"
|
||||
AdvSceneSwitcher.selectHotkey="--select hotkey--"
|
||||
AdvSceneSwitcher.selectDisplay="--select display--"
|
||||
AdvSceneSwitcher.selectSetting="--select setting--"
|
||||
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
|
||||
AdvSceneSwitcher.selectWindowTip="Use \"OBS\" to specify OBS window\nUse \"Task Switching\"to specify ALT + TAB"
|
||||
|
||||
|
|
|
|||
229
src/utils/source-setting.cpp
Normal file
229
src/utils/source-setting.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
#include "source-setting.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "math-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
Q_DECLARE_METATYPE(advss::SourceSetting);
|
||||
|
||||
namespace advss {
|
||||
|
||||
SourceSetting::SourceSetting(const std::string &id,
|
||||
const std::string &description,
|
||||
const std::string &longDescription)
|
||||
: _id(id), _description(description), _longDescription(longDescription)
|
||||
{
|
||||
}
|
||||
|
||||
bool SourceSetting::Save(obs_data_t *obj) const
|
||||
{
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_string(data, "id", _id.c_str());
|
||||
obs_data_set_string(data, "description", _description.c_str());
|
||||
obs_data_set_obj(obj, "sourceSetting", data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourceSetting::Load(obs_data_t *obj)
|
||||
{
|
||||
OBSDataAutoRelease data = obs_data_get_obj(obj, "sourceSetting");
|
||||
_id = obs_data_get_string(data, "id");
|
||||
_description = obs_data_get_string(data, "description");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SourceSetting::operator==(const SourceSetting &other) const
|
||||
{
|
||||
return _id == other._id;
|
||||
}
|
||||
|
||||
std::vector<SourceSetting> GetSoruceSettings(obs_source_t *source)
|
||||
{
|
||||
auto properties = obs_source_properties(source);
|
||||
if (!properties) {
|
||||
return {};
|
||||
}
|
||||
std::vector<SourceSetting> settings;
|
||||
auto it = obs_properties_first(properties);
|
||||
do {
|
||||
if (!it) {
|
||||
continue;
|
||||
}
|
||||
SourceSetting setting(
|
||||
obs_property_name(it), obs_property_description(it),
|
||||
obs_property_long_description(it)
|
||||
? obs_property_long_description(it)
|
||||
: "");
|
||||
settings.emplace_back(setting);
|
||||
} while (obs_property_next(&it));
|
||||
obs_properties_destroy(properties);
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::string GetSourceSettingValue(const OBSWeakSource &ws,
|
||||
const SourceSetting &setting)
|
||||
{
|
||||
OBSSourceAutoRelease source = obs_weak_source_get_source(ws);
|
||||
OBSDataAutoRelease data = obs_source_get_settings(source);
|
||||
if (!data) {
|
||||
return "";
|
||||
}
|
||||
OBSDataAutoRelease dataWithDefaults = obs_data_get_defaults(data);
|
||||
obs_data_apply(dataWithDefaults, data);
|
||||
auto json = obs_data_get_json(dataWithDefaults);
|
||||
if (!json) {
|
||||
return "";
|
||||
}
|
||||
auto value = GetJsonField(json, setting.GetID());
|
||||
return value.value_or("");
|
||||
}
|
||||
|
||||
void SetSourceSetting(obs_source_t *source, const SourceSetting &setting,
|
||||
const std::string &value)
|
||||
{
|
||||
auto id = setting.GetID();
|
||||
OBSDataAutoRelease data = obs_source_get_settings(source);
|
||||
auto item = obs_data_item_byname(data, id.c_str());
|
||||
auto type = obs_data_item_gettype(item);
|
||||
switch (type) {
|
||||
case OBS_DATA_NULL:
|
||||
break;
|
||||
case OBS_DATA_STRING:
|
||||
obs_data_set_string(data, id.c_str(), value.c_str());
|
||||
break;
|
||||
case OBS_DATA_NUMBER: {
|
||||
auto type = obs_data_item_numtype(item);
|
||||
switch (type) {
|
||||
case OBS_DATA_NUM_INVALID:
|
||||
break;
|
||||
case OBS_DATA_NUM_INT: {
|
||||
auto intValue = GetInt(value);
|
||||
if (intValue.has_value()) {
|
||||
obs_data_set_int(data, id.c_str(), *intValue);
|
||||
break;
|
||||
}
|
||||
auto doubleValue = GetDouble(value);
|
||||
if (doubleValue.has_value()) {
|
||||
obs_data_set_int(data, id.c_str(),
|
||||
*doubleValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OBS_DATA_NUM_DOUBLE: {
|
||||
auto numValue = GetDouble(value);
|
||||
if (!numValue.has_value()) {
|
||||
break;
|
||||
}
|
||||
obs_data_set_int(data, id.c_str(), *numValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OBS_DATA_BOOLEAN:
|
||||
obs_data_set_bool(data, id.c_str(), value == "true");
|
||||
break;
|
||||
case OBS_DATA_OBJECT: {
|
||||
OBSDataAutoRelease json =
|
||||
obs_data_create_from_json(value.c_str());
|
||||
obs_data_set_obj(data, id.c_str(), json);
|
||||
break;
|
||||
}
|
||||
case OBS_DATA_ARRAY: {
|
||||
auto jsonStr = obs_data_get_json(data);
|
||||
if (!jsonStr) {
|
||||
break;
|
||||
}
|
||||
std::string resultJsonStr;
|
||||
try {
|
||||
auto json = nlohmann::json::parse(jsonStr);
|
||||
auto jsonArray = nlohmann::json::parse(value);
|
||||
json[id] = jsonArray;
|
||||
resultJsonStr = json.dump();
|
||||
|
||||
} catch (const nlohmann::json::exception &) {
|
||||
break;
|
||||
}
|
||||
OBSDataAutoRelease newData =
|
||||
obs_data_create_from_json(resultJsonStr.c_str());
|
||||
if (!newData) {
|
||||
break;
|
||||
}
|
||||
obs_data_clear(data);
|
||||
obs_data_apply(data, newData);
|
||||
}
|
||||
}
|
||||
obs_data_item_release(&item);
|
||||
obs_source_update(source, data);
|
||||
}
|
||||
|
||||
SourceSettingSelection::SourceSettingSelection(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_settings(new FilterComboBox(
|
||||
this, obs_module_text("AdvSceneSwitcher.selectSetting"))),
|
||||
_tooltip(new QLabel())
|
||||
{
|
||||
QString path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
QIcon icon(path);
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
_tooltip->setPixmap(pixmap);
|
||||
_tooltip->hide();
|
||||
|
||||
QWidget::connect(_settings, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(SelectionIdxChanged(int)));
|
||||
|
||||
auto layout = new QHBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(_settings);
|
||||
layout->addWidget(_tooltip);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void SourceSettingSelection::SetSource(const OBSWeakSource &source)
|
||||
{
|
||||
_settings->clear();
|
||||
Populate(source);
|
||||
}
|
||||
|
||||
void SourceSettingSelection::SetSetting(const SourceSetting &setting)
|
||||
{
|
||||
QVariant variant;
|
||||
variant.setValue(setting);
|
||||
_settings->setCurrentIndex(_settings->findData(variant));
|
||||
}
|
||||
|
||||
void SourceSettingSelection::SelectionIdxChanged(int idx)
|
||||
{
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
auto setting = _settings->itemData(idx).value<SourceSetting>();
|
||||
if (setting._longDescription.empty()) {
|
||||
_tooltip->setToolTip("");
|
||||
_tooltip->hide();
|
||||
} else {
|
||||
_tooltip->setToolTip(
|
||||
QString::fromStdString(setting._longDescription));
|
||||
_tooltip->show();
|
||||
}
|
||||
emit SelectionChanged(setting);
|
||||
}
|
||||
|
||||
void SourceSettingSelection::Populate(const OBSWeakSource &source)
|
||||
{
|
||||
OBSSourceAutoRelease s = obs_weak_source_get_source(source);
|
||||
auto settings = GetSoruceSettings(s);
|
||||
for (const auto &setting : settings) {
|
||||
QVariant variant;
|
||||
variant.setValue(setting);
|
||||
_settings->addItem(QString::fromStdString(setting._description),
|
||||
variant);
|
||||
}
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
57
src/utils/source-setting.hpp
Normal file
57
src/utils/source-setting.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class SourceSetting {
|
||||
public:
|
||||
SourceSetting() = default;
|
||||
SourceSetting(const std::string &id, const std::string &description,
|
||||
const std::string &longDescription = "");
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetID() const { return _id; }
|
||||
bool operator==(const SourceSetting &other) const;
|
||||
|
||||
private:
|
||||
std::string _id = "";
|
||||
std::string _description = "";
|
||||
std::string _longDescription = "";
|
||||
|
||||
friend class SourceSettingSelection;
|
||||
};
|
||||
|
||||
std::vector<SourceSetting> GetSoruceSettings(obs_source_t *source);
|
||||
std::string GetSourceSettingValue(const OBSWeakSource &source,
|
||||
const SourceSetting &setting);
|
||||
void SetSourceSetting(obs_source_t *source, const SourceSetting &setting,
|
||||
const std::string &value);
|
||||
|
||||
class SourceSettingSelection : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceSettingSelection(QWidget *parent = nullptr);
|
||||
void SetSource(const OBSWeakSource &);
|
||||
void SetSetting(const SourceSetting &);
|
||||
|
||||
private slots:
|
||||
void SelectionIdxChanged(int);
|
||||
|
||||
signals:
|
||||
void SelectionChanged(const SourceSetting &);
|
||||
|
||||
private:
|
||||
void Populate(const OBSWeakSource &);
|
||||
|
||||
FilterComboBox *_settings;
|
||||
QLabel *_tooltip;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
Loading…
Reference in New Issue
Block a user