libgimp, libgimpbase: create special functions to get/set boxed array properties.

While the work on NULL-terminated array types make it much easier in C,
bindings don't have enough information to create native array/list types
in some generic functions such as g_object_get|set(), or else we just
don't know the right annotations to use for this to be possible. This is
report gobject-introspection#492.

So for the time being, we are creating dedicated functions for GeglColor
arrays and for other core object arrays (arrays of images, items, etc.).

E.g. in Python, while you can set a single GimpImage like this:

> config.set_property('image', image)

… you need to set a list of images like this:

> config.set_core_object_array('images', [image1, image2])
This commit is contained in:
Jehan 2024-10-28 19:18:22 +01:00
parent a42142d5a0
commit 86f588224b
6 changed files with 296 additions and 7 deletions

View file

@ -877,12 +877,16 @@ EXPORTS
gimp_procedure_add_unit_aux_argument
gimp_procedure_add_unit_return_value
gimp_procedure_config_get_choice_id
gimp_procedure_config_get_color_array
gimp_procedure_config_get_core_object_array
gimp_procedure_config_get_procedure
gimp_procedure_config_get_type
gimp_procedure_config_has_default
gimp_procedure_config_load_default
gimp_procedure_config_save_default
gimp_procedure_config_save_metadata
gimp_procedure_config_set_color_array
gimp_procedure_config_set_core_object_array
gimp_procedure_create_config
gimp_procedure_find_argument
gimp_procedure_find_aux_argument

View file

@ -447,6 +447,227 @@ gimp_procedure_config_save_metadata (GimpProcedureConfig *config,
}
}
/**
* gimp_procedure_config_get_core_object_array:
* @config: a #GimpProcedureConfig
* @property_name: the name of a [struct@ParamSpecCoreObjectArray] param spec.
*
* A function for bindings to get a [type@CoreObjectArray] property. Getting
* these with [method@GObject.Object.get] or [method@GObject.Object.get_property] won't
* [work for the time being](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492)
* so all our boxed array types must be set and get using alternative
* functions instead.
*
* C plug-ins should just use [method@GObject.Object.get].
*
* Returns: (array zero-terminated) (transfer container): an array of #GObjects.
*
* Since: 3.0
**/
GObject **
gimp_procedure_config_get_core_object_array (GimpProcedureConfig *config,
const gchar *property_name)
{
GObject **objects = NULL;
GParamSpec *param_spec;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), property_name);
if (! param_spec)
{
g_warning ("%s: %s has no property named '%s'",
G_STRFUNC,
g_type_name (G_TYPE_FROM_INSTANCE (config)),
property_name);
return objects;
}
if (! g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY))
{
g_warning ("%s: property '%s' of %s is not a GimpParamCoreObjectArray.",
G_STRFUNC,
param_spec->name,
g_type_name (param_spec->owner_type));
return objects;
}
g_object_get (config,
property_name, &objects,
NULL);
return objects;
}
/**
* gimp_procedure_config_set_core_object_array:
* @config: a #GimpProcedureConfig
* @property_name: the name of a [struct@ParamSpecCoreObjectArray] param spec.
* @objects: (array length=n_objects) (transfer none): an array of #GObjects.
* @n_objects: the numbers of @objects.
*
* A function for bindings to set a [type@CoreObjectArray] property. Setting
* these with [method@GObject.Object.set] or [method@GObject.Object.set_property] won't
* [work for the time being](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492)
* so all our boxed array types must be set and get using alternative
* functions instead.
*
* C plug-ins should just use [method@GObject.Object.set].
*
* Since: 3.0
**/
void
gimp_procedure_config_set_core_object_array (GimpProcedureConfig *config,
const gchar *property_name,
GObject **objects,
gsize n_objects)
{
GObject **null_objects;
GParamSpec *param_spec;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
property_name);
if (! param_spec)
{
g_warning ("%s: %s has no property named '%s'",
G_STRFUNC,
g_type_name (G_TYPE_FROM_INSTANCE (config)),
property_name);
return;
}
if (! g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY))
{
g_warning ("%s: property '%s' of %s is not a GimpParamCoreObjectArray.",
G_STRFUNC,
param_spec->name,
g_type_name (param_spec->owner_type));
return;
}
null_objects = g_new0 (GObject *, n_objects + 1);
for (gint i = 0; i < n_objects; i++)
null_objects[i] = objects[i];
g_object_set (config,
property_name, null_objects,
NULL);
g_free (null_objects);
}
/**
* gimp_procedure_config_get_color_array:
* @config: a #GimpProcedureConfig
* @property_name: the name of a [struct@ParamSpecCoreObjectArray] param spec.
*
* A function for bindings to get a [type@ColorArray] property. Getting
* these with [method@GObject.Object.get] or [method@GObject.Object.get_property] won't
* [work for the time being](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492)
* so all our boxed array types must be set and get using these
* alternative functions instead.
*
* C plug-ins should just use [method@GObject.Object.get].
*
* Returns: (array zero-terminated) (transfer full): an array of #GObjects.
*
* Since: 3.0
**/
GeglColor **
gimp_procedure_config_get_color_array (GimpProcedureConfig *config,
const gchar *property_name)
{
GeglColor **colors = NULL;
GParamSpec *param_spec;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), property_name);
if (! param_spec)
{
g_warning ("%s: %s has no property named '%s'",
G_STRFUNC,
g_type_name (G_TYPE_FROM_INSTANCE (config)),
property_name);
return colors;
}
if (! g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_BOXED) ||
! g_type_is_a (param_spec->value_type, GIMP_TYPE_COLOR_ARRAY))
{
g_warning ("%s: property '%s' of %s is not a GimpColorArray boxed type.",
G_STRFUNC,
param_spec->name,
g_type_name (param_spec->owner_type));
return colors;
}
g_object_get (config,
property_name, &colors,
NULL);
return colors;
}
/**
* gimp_procedure_config_set_color_array:
* @config: a #GimpProcedureConfig
* @property_name: the name of a [struct@ParamSpecCoreObjectArray] param spec.
* @colors: (array length=n_colors) (transfer none): an array of [class@Gegl.Color].
* @n_colors: the numbers of @colors.
*
* A function for bindings to set a [type@ColorArray] property. Setting
* these with [method@GObject.Object.set] or [method@GObject.Object.set_property] won't
* [work for the time being](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492)
* so all our boxed array types must be set and get using these
* alternative functions instead.
*
* C plug-ins should just use [method@GObject.Object.set].
*
* Since: 3.0
**/
void
gimp_procedure_config_set_color_array (GimpProcedureConfig *config,
const gchar *property_name,
GeglColor **colors,
gsize n_colors)
{
GeglColor **null_colors;
GParamSpec *param_spec;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), property_name);
if (! param_spec)
{
g_warning ("%s: %s has no property named '%s'",
G_STRFUNC,
g_type_name (G_TYPE_FROM_INSTANCE (config)),
property_name);
return;
}
if (! g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_BOXED) ||
! g_type_is_a (param_spec->value_type, GIMP_TYPE_COLOR_ARRAY))
{
g_warning ("%s: property '%s' of %s is not a GimpColorArray boxed type.",
G_STRFUNC,
param_spec->name,
g_type_name (param_spec->owner_type));
return;
}
null_colors = g_new0 (GeglColor *, n_colors + 1);
for (gint i = 0; i < n_colors; i++)
null_colors[i] = colors[i];
g_object_set (config,
property_name, null_colors,
NULL);
g_free (null_colors);
}
/**
* gimp_procedure_config_get_choice_id:
* @config: a #GimpProcedureConfig

View file

@ -50,19 +50,34 @@ struct _GimpProcedureConfigClass
};
GimpProcedure *
gimp_procedure_config_get_procedure (GimpProcedureConfig *config);
GimpProcedure * gimp_procedure_config_get_procedure (GimpProcedureConfig *config);
void gimp_procedure_config_save_metadata (GimpProcedureConfig *config,
GimpImage *exported_image,
GFile *file);
void gimp_procedure_config_save_metadata (GimpProcedureConfig *config,
GimpImage *exported_image,
GFile *file);
/* Binding functions */
GObject ** gimp_procedure_config_get_core_object_array (GimpProcedureConfig *config,
const gchar *property_name);
void gimp_procedure_config_set_core_object_array (GimpProcedureConfig *config,
const gchar *property_name,
GObject **objects,
gsize n_objects);
GeglColor ** gimp_procedure_config_get_color_array (GimpProcedureConfig *config,
const gchar *property_name);
void gimp_procedure_config_set_color_array (GimpProcedureConfig *config,
const gchar *property_name,
GeglColor **colors,
gsize n_colors);
/* Utility functions */
gint gimp_procedure_config_get_choice_id (GimpProcedureConfig *config,
const gchar *property_name);
gint gimp_procedure_config_get_choice_id (GimpProcedureConfig *config,
const gchar *property_name);
G_END_DECLS

View file

@ -234,6 +234,7 @@ EXPORTS
gimp_value_array_append
gimp_value_array_copy
gimp_value_array_get_color_array
gimp_value_array_get_core_object_array
gimp_value_array_get_type
gimp_value_array_index
gimp_value_array_insert

View file

@ -105,6 +105,14 @@ gimp_value_array_index (const GimpValueArray *value_array,
* Return a pointer to the value at @index contained in @value_array. This value
* is supposed to be a [type@ColorArray].
*
* *Note*: most of the time, you should use the generic [method@Gimp.ValueArray.index]
* to retrieve a value, then the relevant `g_value_get_*()` function.
* This alternative function is mostly there for bindings because
* GObject-Introspection is [not able yet to process correctly known
* boxed array types](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492).
*
* There are no reasons to use this function in C code.
*
* Returns: (transfer none) (array zero-terminated=1): the [type@ColorArray] stored at @index in @value_array.
*
* Since: 3.0
@ -131,6 +139,44 @@ gimp_value_array_get_color_array (const GimpValueArray *value_array,
return colors;
}
/**
* gimp_value_array_get_core_object_array:
* @value_array: #GimpValueArray to get a value from
* @index: index of the value of interest
*
* Return a pointer to the value at @index contained in @value_array. This value
* is supposed to be a [type@CoreObjectArray].
*
* *Note*: most of the time, you should use the generic [method@Gimp.ValueArray.index]
* to retrieve a value, then the relevant `g_value_get_*()` function.
* This alternative function is mostly there for bindings because
* GObject-Introspection is [not able yet to process correctly known
* boxed array types](https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/492).
*
* There are no reasons to use this function in C code.
*
* Returns: (transfer none) (array zero-terminated=1): the [type@CoreObjectArray] stored at @index in @value_array.
*
* Since: 3.0
*/
GObject **
gimp_value_array_get_core_object_array (const GimpValueArray *value_array,
gint index)
{
GValue *value;
GObject **objects;
g_return_val_if_fail (value_array != NULL, NULL);
g_return_val_if_fail (index < value_array->n_values, NULL);
value = value_array->values + index;
g_return_val_if_fail (GIMP_VALUE_HOLDS_CORE_OBJECT_ARRAY (value), NULL);
objects = g_value_get_boxed (value);
return objects;
}
static inline void
value_array_grow (GimpValueArray *value_array,
gint n_values,

View file

@ -61,6 +61,8 @@ GValue * gimp_value_array_index (const GimpValueArray *
gint index);
GeglColor ** gimp_value_array_get_color_array (const GimpValueArray *value_array,
gint index);
GObject ** gimp_value_array_get_core_object_array (const GimpValueArray *value_array,
gint index);
GimpValueArray * gimp_value_array_prepend (GimpValueArray *value_array,
const GValue *value);