diff --git a/plugins/base/utils/source-setting.cpp b/plugins/base/utils/source-setting.cpp index 83ec5734..c732071c 100644 --- a/plugins/base/utils/source-setting.cpp +++ b/plugins/base/utils/source-setting.cpp @@ -280,6 +280,59 @@ GetSourceSettingListEntryName(const OBSWeakSource &source, return {}; } +static std::pair +getListDataType(obs_source_t *source, const SourceSetting &setting) +{ + const auto &[property, properties] = + findListPropertyById(source, setting.GetID()); + if (!property) { + return {OBS_DATA_NULL, OBS_DATA_NUM_INVALID}; + } + + switch (obs_property_list_format(property)) { + case OBS_COMBO_FORMAT_INT: + return {OBS_DATA_NUMBER, OBS_DATA_NUM_INT}; + case OBS_COMBO_FORMAT_FLOAT: + return {OBS_DATA_NUMBER, OBS_DATA_NUM_DOUBLE}; + case OBS_COMBO_FORMAT_STRING: + return {OBS_DATA_STRING, OBS_DATA_NUM_INVALID}; + case OBS_COMBO_FORMAT_BOOL: + return {OBS_DATA_BOOLEAN, OBS_DATA_NUM_INVALID}; + default: + break; + } + return {OBS_DATA_NULL, OBS_DATA_NUM_INVALID}; +} + +// Used for settings which have neither a value nor a default value yet, e.g. +// the "text" setting of a text source which was not created via the OBS UI +static std::pair +getDataTypeFromProperty(obs_source_t *source, const SourceSetting &setting) +{ + switch (setting.GetType()) { + case OBS_PROPERTY_BOOL: + return {OBS_DATA_BOOLEAN, OBS_DATA_NUM_INVALID}; + case OBS_PROPERTY_INT: + case OBS_PROPERTY_COLOR: + case OBS_PROPERTY_COLOR_ALPHA: + return {OBS_DATA_NUMBER, OBS_DATA_NUM_INT}; + case OBS_PROPERTY_FLOAT: + return {OBS_DATA_NUMBER, OBS_DATA_NUM_DOUBLE}; + case OBS_PROPERTY_TEXT: + case OBS_PROPERTY_PATH: + return {OBS_DATA_STRING, OBS_DATA_NUM_INVALID}; + case OBS_PROPERTY_FONT: + return {OBS_DATA_OBJECT, OBS_DATA_NUM_INVALID}; + case OBS_PROPERTY_EDITABLE_LIST: + return {OBS_DATA_ARRAY, OBS_DATA_NUM_INVALID}; + case OBS_PROPERTY_LIST: + return getListDataType(source, setting); + default: + break; + } + return {OBS_DATA_NULL, OBS_DATA_NUM_INVALID}; +} + void SetSourceSetting(obs_source_t *source, const SourceSetting &setting, const std::string &value) { @@ -289,6 +342,11 @@ void SetSourceSetting(obs_source_t *source, const SourceSetting &setting, obs_data_apply(dataWithDefaults, data); auto item = obs_data_item_byname(dataWithDefaults, id.c_str()); auto type = obs_data_item_gettype(item); + auto numType = obs_data_item_numtype(item); + if (type == OBS_DATA_NULL) { + std::tie(type, numType) = + getDataTypeFromProperty(source, setting); + } switch (type) { case OBS_DATA_NULL: vblog(LOG_WARNING, @@ -298,8 +356,7 @@ void SetSourceSetting(obs_source_t *source, const SourceSetting &setting, 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) { + switch (numType) { case OBS_DATA_NUM_INVALID: break; case OBS_DATA_NUM_INT: { diff --git a/plugins/base/utils/source-setting.hpp b/plugins/base/utils/source-setting.hpp index 7b17a3b7..a0748733 100644 --- a/plugins/base/utils/source-setting.hpp +++ b/plugins/base/utils/source-setting.hpp @@ -20,6 +20,7 @@ public: bool Save(obs_data_t *obj) const; bool Load(obs_data_t *obj); std::string GetID() const { return _id; } + obs_property_type GetType() const { return _type; } bool IsList() const; bool operator==(const SourceSetting &other) const;