Browse Source

Simplify and improve 'list' property

When a source/output/etc has a property of a 'list' type, there was no
way to get the names associated with its values.  That, and it only
supported lists of either text, or enums (0..[value] only).

Now, you can associate translated names with those values, and use
integer, float, or string values.  Put it all in to one function as well
to simplify its usage.

I plan on using this to help get enumerations from devices/etc for
certain types of sources.  For example, if I get the properties of an
audio source, I'd like to have a list of available devices with it as
well.
jp9000 11 năm trước cách đây
mục cha
commit
1eeece5b97
4 tập tin đã thay đổi với 113 bổ sung45 xóa
  1. 1 1
      libobs/callback/proc.c
  2. 4 4
      libobs/callback/proc.h
  3. 88 27
      libobs/obs-properties.c
  4. 20 13
      libobs/obs-properties.h

+ 1 - 1
libobs/callback/proc.c

@@ -61,7 +61,7 @@ void proc_handler_add(proc_handler_t handler, const char *decl_string,
 	memset(&pi, 0, sizeof(struct proc_info));
 
 	if (!parse_decl_string(&pi.func, decl_string)) {
-		blog(LOG_ERROR, "Dynamic function declaration invalid: %s",
+		blog(LOG_ERROR, "Function declaration invalid: %s",
 				decl_string);
 		return;
 	}

+ 4 - 4
libobs/callback/proc.h

@@ -25,11 +25,11 @@ extern "C" {
 #endif
 
 /*
- * Dynamic procedure handler
+ * Procedure handler
  *
- *   This handler is used to allow dynamic access to one or more procedures
- * that can be dynamically added and called without having to have direct
- * access to declarations or procedure callback pointers.
+ *   This handler is used to allow access to one or more procedures that can be
+ *   added and called without having to have direct access to declarations or
+ *   procedure callback pointers.
  */
 
 struct proc_handler;

+ 88 - 27
libobs/obs-properties.c

@@ -18,6 +18,18 @@
 #include "util/bmem.h"
 #include "obs-properties.h"
 
+static inline void *get_property_data(struct obs_property *prop);
+
+static inline void free_str_list(char **str_list)
+{
+	char **temp_list = str_list;
+	while (*temp_list)
+		bfree(*(temp_list++));
+	bfree(str_list);
+}
+
+/* ------------------------------------------------------------------------- */
+
 struct float_data {
 	double min, max, step;
 };
@@ -27,10 +39,18 @@ struct int_data {
 };
 
 struct list_data {
-	const char             **strings;
-	enum obs_dropdown_type type;
+	char                   **names;
+	char                   **values;
+	enum obs_combo_type    type;
+	enum obs_combo_format  format;
 };
 
+static inline void list_data_free(struct list_data *data)
+{
+	free_str_list(data->names);
+	free_str_list(data->values);
+}
+
 struct obs_property {
 	const char             *name;
 	const char             *desc;
@@ -59,6 +79,11 @@ obs_properties_t obs_properties_create()
 
 static void obs_property_destroy(struct obs_property *property)
 {
+	if (property->type == OBS_PROPERTY_LIST) {
+		struct list_data *data = get_property_data(property);
+		list_data_free(data);
+	}
+
 	bfree(property);
 }
 
@@ -123,8 +148,7 @@ static inline size_t get_property_size(enum obs_property_type type)
 	case OBS_PROPERTY_FLOAT:     return sizeof(struct float_data);
 	case OBS_PROPERTY_TEXT:      return 0;
 	case OBS_PROPERTY_PATH:      return 0;
-	case OBS_PROPERTY_ENUM:      return sizeof(struct list_data);
-	case OBS_PROPERTY_TEXT_LIST: return sizeof(struct list_data);
+	case OBS_PROPERTY_LIST:     return sizeof(struct list_data);
 	case OBS_PROPERTY_COLOR:     return 0;
 	}
 
@@ -199,28 +223,48 @@ void obs_category_add_path(obs_category_t cat, const char *name,
 	new_prop(cat, name, desc, OBS_PROPERTY_PATH);
 }
 
-void obs_category_add_enum_list(obs_category_t cat, const char *name,
-		const char *desc, const char **strings)
+static char **dup_str_list(const char **str_list)
 {
-	if (!cat) return;
+	int count = 0;
+	char **new_list;
+	const char **temp_list = str_list;
 
-	struct obs_property *p = new_prop(cat, name, desc, OBS_PROPERTY_ENUM);
-	struct list_data *data = get_property_data(p);
-	data->strings = strings;
-	data->type    = OBS_DROPDOWN_LIST;
+	if (!str_list)
+		return NULL;
+
+	while (*(temp_list++) != NULL)
+		count++;
+
+	new_list  = bmalloc((count+1) * sizeof(char*));
+	new_list[count] = NULL;
+	for (int i = 0; i < count; i++)
+		new_list[i] = bstrdup(str_list[i]);
+
+	return new_list;
 }
 
-void obs_category_add_text_list(obs_category_t cat, const char *name,
-		const char *desc, const char **strings,
-		enum obs_dropdown_type type)
+void obs_category_add_list(obs_category_t cat,
+		const char *name, const char *desc,
+		const char **value_names, const char **values,
+		enum obs_dropdown_type type,
+		enum obs_dropdown_format format)
 {
 	if (!cat) return;
 
-	struct obs_property *p = new_prop(cat, name, desc,
-			OBS_PROPERTY_TEXT_LIST);
+	if (type   == OBS_COMBO_TYPE_EDITABLE &&
+	    format != OBS_COMBO_FORMAT_STRING) {
+		blog(LOG_WARNING, "Catagory '%s', list '%s', error: "
+		                  "Editable combo boxes must be strings",
+		                  cat->name, name);
+		return;
+	}
+
+	struct obs_property *p = new_prop(cat, name, desc, OBS_PROPERTY_LIST);
 	struct list_data *data = get_property_data(p);
-	data->strings = strings;
-	data->type    = type;
+	data->names  = dup_str_list(value_names);
+	data->values = dup_str_list(values);
+	data->format = format;
+	data->type   = type;
 }
 
 void obs_category_add_color(obs_category_t cat, const char *name,
@@ -309,26 +353,43 @@ double obs_property_float_step(obs_property_t p)
 	return data ? data->step : 0;
 }
 
-static inline bool is_dropdown(struct obs_property *p)
+static inline bool is_combo(struct obs_property *p)
 {
-	return p->type == OBS_PROPERTY_ENUM ||
-	       p->type == OBS_PROPERTY_TEXT_LIST;
+	return p->type == OBS_PROPERTY_LIST;
 }
 
-const char **obs_property_dropdown_strings(obs_property_t p)
+const char **obs_property_list_names(obs_property_t p)
 {
-	if (!p || !is_dropdown(p))
+	if (!p || !is_combo(p))
 		return NULL;
 
 	struct list_data *data = get_property_data(p);
-	return data->strings;
+	return data->names;
 }
 
-enum obs_dropdown_type obs_property_dropdown_type(obs_property_t p)
+const char **obs_property_list_values(obs_property_t p)
 {
-	if (!p || !is_dropdown(p))
-		return OBS_DROPDOWN_INVALID;
+	if (!p || !is_combo(p))
+		return NULL;
+
+	struct list_data *data = get_property_data(p);
+	return data->values;
+}
+
+enum obs_combo_type obs_property_list_type(obs_property_t p)
+{
+	if (!p || !is_combo(p))
+		return OBS_COMBO_TYPE_INVALID;
 
 	struct list_data *data = get_property_data(p);
 	return data->type;
 }
+
+enum obs_combo_type obs_property_list_format(obs_property_t p)
+{
+	if (!p || !is_combo(p))
+		return OBS_COMBO_FORMAT_INVALID;
+
+	struct list_data *data = get_property_data(p);
+	return data->format;
+}

+ 20 - 13
libobs/obs-properties.h

@@ -29,15 +29,21 @@ enum obs_property_type {
 	OBS_PROPERTY_FLOAT,
 	OBS_PROPERTY_TEXT,
 	OBS_PROPERTY_PATH,
-	OBS_PROPERTY_ENUM,
-	OBS_PROPERTY_TEXT_LIST,
+	OBS_PROPERTY_LIST,
 	OBS_PROPERTY_COLOR,
 };
 
-enum obs_dropdown_type {
-	OBS_DROPDOWN_INVALID,
-	OBS_DROPDOWN_EDIT,
-	OBS_DROPDOWN_LIST,
+enum obs_combo_format {
+	OBS_COMBO_FORMAT_INVALID,
+	OBS_COMBO_FORMAT_INT,
+	OBS_COMBO_FORMAT_FLOAT,
+	OBS_COMBO_FORMAT_STRING
+};
+
+enum obs_combo_type {
+	OBS_COMBO_TYPE_INVALID,
+	OBS_COMBO_TYPE_EDITABLE,
+	OBS_COMBO_TYPE_LIST,
 };
 
 struct obs_properties;
@@ -67,12 +73,11 @@ EXPORT void obs_category_add_text(obs_category_t cat, const char *name,
 		const char *description);
 EXPORT void obs_category_add_path(obs_category_t cat, const char *name,
 		const char *description);
-EXPORT void obs_category_add_enum_list(obs_category_t cat,
-		const char *name, const char *description,
-		const char **strings);
-EXPORT void obs_category_add_text_list(obs_category_t cat,
+EXPORT void obs_category_add_list(obs_category_t cat,
 		const char *name, const char *description,
-		const char **strings, enum obs_dropdown_type type);
+		const char **value_names, const char **values,
+		enum obs_combo_type type,
+		enum obs_combo_format format);
 EXPORT void obs_category_add_color(obs_category_t cat, const char *name,
 		const char *description);
 
@@ -93,8 +98,10 @@ EXPORT int                    obs_property_int_step(obs_property_t p);
 EXPORT double                 obs_property_float_min(obs_property_t p);
 EXPORT double                 obs_property_float_max(obs_property_t p);
 EXPORT double                 obs_property_float_step(obs_property_t p);
-EXPORT const char **          obs_property_dropdown_strings(obs_property_t p);
-EXPORT enum obs_dropdown_type obs_property_dropdown_type(obs_property_t p);
+EXPORT const char **          obs_property_list_names(obs_property_t p);
+EXPORT const char **          obs_property_list_values(obs_property_t p);
+EXPORT enum obs_combo_type    obs_property_list_type(obs_property_t p);
+EXPORT enum obs_combo_format  obs_property_list_format(obs_property_t p);
 
 #ifdef __cplusplus
 }