gimppdb: Allow more easy bindable API

Plug-ins that work from different bindings probably want to use their
own list-type to specify arguments, rather than working with a more
cumbersome `GimpValueArray`.

This new API should make it less verbose. For example:

```
args = Gimp.ValueArray.new(5)
args.insert(0, GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE))
args.insert(1, GObject.Value(Gimp.Image, image))
args.insert(2, GObject.Value(Gimp.Drawable, mask))
args.insert(3, GObject.Value(GObject.TYPE_INT, int(time.time())))
args.insert(4, GObject.Value(GObject.TYPE_DOUBLE, turbulence))
Gimp.get_pdb().run_procedure('plug-in-plasma', args)
```

becomes

```
Gimp.get_pdb().run_procedure('plug-in-plasma', [
    GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
    GObject.Value(Gimp.Image, image),
    GObject.Value(Gimp.Drawable, mask),
    GObject.Value(GObject.TYPE_INT, int(time.time())),
    GObject.Value(GObject.TYPE_DOUBLE, turbulence),
])
```
This commit is contained in:
Niels De Graef 2020-05-19 18:43:43 +02:00 committed by Jehan
parent ec26bc44ae
commit 43d0f0fbd2
12 changed files with 138 additions and 82 deletions

View File

@ -943,6 +943,7 @@ gimp_pdb_lookup_procedure
gimp_pdb_run_procedure
gimp_pdb_run_procedure_valist
gimp_pdb_run_procedure_array
gimp_pdb_run_procedure_argv
gimp_pdb_temp_procedure_name
gimp_pdb_dump_to_file
gimp_pdb_query_procedures

View File

@ -530,6 +530,7 @@ GimpValueArray
gimp_value_array_new
gimp_value_array_new_from_types
gimp_value_array_new_from_types_valist
gimp_value_array_new_from_values
gimp_value_array_ref
gimp_value_array_unref
gimp_value_array_length

View File

@ -667,6 +667,7 @@ EXPORTS
gimp_pdb_procedure_exists
gimp_pdb_query_procedures
gimp_pdb_run_procedure
gimp_pdb_run_procedure_argv
gimp_pdb_run_procedure_array
gimp_pdb_run_procedure_valist
gimp_pdb_set_data

View File

@ -193,7 +193,7 @@ gimp_pdb_lookup_procedure (GimpPDB *pdb,
}
/**
* gimp_pdb_run_procedure:
* gimp_pdb_run_procedure: (skip)
* @pdb: the #GimpPDB object.
* @procedure_name: the procedure registered name.
* @first_type: the #GType of the first argument, or #G_TYPE_NONE.
@ -229,7 +229,7 @@ gimp_pdb_run_procedure (GimpPDB *pdb,
}
/**
* gimp_pdb_run_procedure_valist:
* gimp_pdb_run_procedure_valist: (skip)
* @pdb: the #GimpPDB object.
* @procedure_name: the procedure registered name.
* @first_type: the #GType of the first argument, or #G_TYPE_NONE.
@ -280,7 +280,40 @@ gimp_pdb_run_procedure_valist (GimpPDB *pdb,
}
/**
* gimp_pdb_run_procedure_array: (rename-to gimp_pdb_run_procedure)
* gimp_pdb_run_procedure_argv: (rename-to gimp_pdb_run_procedure)
* @pdb: the #GimpPDB object.
* @procedure_name: the procedure registered name.
* @arguments: (array length=n_arguments): the call arguments.
* @n_arguments: the number of arguments.
*
* Runs the procedure named @procedure_name with @arguments.
*
* Returns: (transfer full): the return values for the procedure call.
*
* Since: 3.0
*/
GimpValueArray *
gimp_pdb_run_procedure_argv (GimpPDB *pdb,
const gchar *procedure_name,
const GValue *arguments,
gint n_arguments)
{
GimpValueArray *args;
GimpValueArray *return_values;
g_return_val_if_fail (GIMP_IS_PDB (pdb), NULL);
g_return_val_if_fail (gimp_is_canonical_identifier (procedure_name), NULL);
g_return_val_if_fail (arguments != NULL, NULL);
args = gimp_value_array_new_from_values (arguments, n_arguments);
return_values = gimp_pdb_run_procedure_array (pdb, procedure_name, args);
gimp_value_array_unref (args);
return return_values;
}
/**
* gimp_pdb_run_procedure_array:
* @pdb: the #GimpPDB object.
* @procedure_name: the procedure registered name.
* @arguments: the call arguments.

View File

@ -81,6 +81,10 @@ GimpValueArray * gimp_pdb_run_procedure_valist (GimpPDB *pdb,
const gchar *procedure_name,
GType first_type,
va_list args);
GimpValueArray * gimp_pdb_run_procedure_argv (GimpPDB *pdb,
const gchar *procedure_name,
const GValue *arguments,
gint n_arguments);
GimpValueArray * gimp_pdb_run_procedure_array (GimpPDB *pdb,
const gchar *procedure_name,
const GimpValueArray *arguments);

View File

@ -219,6 +219,7 @@ EXPORTS
gimp_value_array_new
gimp_value_array_new_from_types
gimp_value_array_new_from_types_valist
gimp_value_array_new_from_values
gimp_value_array_prepend
gimp_value_array_ref
gimp_value_array_remove

View File

@ -147,7 +147,7 @@ gimp_value_array_new (gint n_prealloced)
}
/**
* gimp_value_array_new_from_types:
* gimp_value_array_new_from_types: (skip)
* @error_msg: return location for an error message.
* @first_type: first type in the array, or #G_TYPE_NONE.
* @...: the remaining types in the array, terminated by #G_TYPE_NONE
@ -183,7 +183,7 @@ gimp_value_array_new_from_types (gchar **error_msg,
}
/**
* gimp_value_array_new_from_types_valist:
* gimp_value_array_new_from_types_valist: (skip)
* @error_msg: return location for an error message.
* @first_type: first type in the array, or #G_TYPE_NONE.
* @va_args: a va_list of GTypes and values, terminated by #G_TYPE_NONE
@ -250,6 +250,38 @@ gimp_value_array_new_from_types_valist (gchar **error_msg,
return value_array;
}
/**
* gimp_value_array_new_from_values:
* @values: (array length=n_values): The #GValue elements
* @n_values: the number of value elements
*
* Allocate and initialize a new #GimpValueArray, and fill it with
* the given #GValues.
*
* Returns: a newly allocated #GimpValueArray.
*
* Since: 3.0
*/
GimpValueArray *
gimp_value_array_new_from_values (const GValue *values,
gint n_values)
{
GimpValueArray *value_array;
gint i;
g_return_val_if_fail (values != NULL, NULL);
g_return_val_if_fail (n_values > 0, NULL);
value_array = gimp_value_array_new (n_values);
for (i = 0; i < n_values; i++)
{
gimp_value_array_insert (value_array, i, &values[i]);
}
return value_array;
}
/**
* gimp_value_array_ref:
* @value_array: #GimpValueArray to ref

View File

@ -49,6 +49,9 @@ GimpValueArray * gimp_value_array_new_from_types_valist
(gchar **error_msg,
GType first_type,
va_list va_args);
GimpValueArray * gimp_value_array_new_from_values
(const GValue *values,
gint n_values);
GimpValueArray * gimp_value_array_ref (GimpValueArray *value_array);
void gimp_value_array_unref (GimpValueArray *value_array);

View File

@ -267,10 +267,9 @@ def save_colorxhtml(procedure, run_mode, image, drawable, file, args, data):
if separate:
css.close()
retval = Gimp.ValueArray.new(1)
retval.insert(0, GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS))
return retval
return Gimp.ValueArray.new([
GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS)
])
class ColorXhtml(Gimp.PlugIn):

View File

@ -91,25 +91,24 @@ def thumbnail_ora(procedure, file, thumb_size, args, data):
with open(tmp, 'wb') as fid:
fid.write(orafile.read('Thumbnails/thumbnail.png'))
args = Gimp.ValueArray.new(2)
args.insert(0, GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE))
args.insert(1, GObject.Value(GObject.TYPE_STRING, tmp))
img = Gimp.get_pdb().run_procedure('file-png-load', args)
img = Gimp.get_pdb().run_procedure('file-png-load', [
GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
GObject.Value(GObject.TYPE_STRING, tmp),
])
img = img.index(1)
img = Gimp.Image.get_by_id(img)
# TODO: scaling
os.remove(tmp)
os.rmdir(tempdir)
retval = Gimp.ValueArray.new(2)
retval.insert(0, GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS))
retval.insert(1, GObject.Value(Gimp.Image, img))
retval.insert(2, GObject.Value(GObject.TYPE_INT, w))
retval.insert(3, GObject.Value(GObject.TYPE_INT, h))
retval.insert(4, GObject.Value(Gimp.ImageType, Gimp.ImageType.RGB_IMAGE))
retval.insert(5, GObject.Value(GObject.TYPE_INT, 1))
return retval
return Gimp.ValueArray.new_from_values([
GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS),
GObject.Value(Gimp.Image, img),
GObject.Value(GObject.TYPE_INT, w),
GObject.Value(GObject.TYPE_INT, h),
GObject.Value(Gimp.ImageType, Gimp.ImageType.RGB_IMAGE),
GObject.Value(GObject.TYPE_INT, 1)
])
def save_ora(procedure, run_mode, image, drawable, file, args, data):
def write_file_str(zfile, fname, data):
@ -137,20 +136,21 @@ def save_ora(procedure, run_mode, image, drawable, file, args, data):
def store_layer(image, drawable, path):
tmp = os.path.join(tempdir, 'tmp.png')
interlace, compression = 0, 2
args = Gimp.ValueArray.new(11)
args.insert(0, GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE))
args.insert(1, GObject.Value(Gimp.Image, image))
args.insert(2, GObject.Value(Gimp.Drawable, drawable))
args.insert(3, GObject.Value(GObject.TYPE_STRING, tmp))
args.insert(4, GObject.Value(GObject.TYPE_STRING, 'tmp.png'))
args.insert(5, GObject.Value(GObject.TYPE_BOOLEAN, interlace))
args.insert(6, GObject.Value(GObject.TYPE_INT, compression))
# write all PNG chunks except oFFs(ets)
args.insert(7, GObject.Value(GObject.TYPE_BOOLEAN, True))
args.insert(8, GObject.Value(GObject.TYPE_BOOLEAN, True))
args.insert(9, GObject.Value(GObject.TYPE_BOOLEAN, False))
args.insert(10, GObject.Value(GObject.TYPE_BOOLEAN, True))
Gimp.get_pdb().run_procedure('file-png-save', args)
Gimp.get_pdb().run_procedure('file-png-save', [
GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
GObject.Value(Gimp.Image, image),
GObject.Value(Gimp.Drawable, drawable),
GObject.Value(GObject.TYPE_STRING, tmp),
GObject.Value(GObject.TYPE_STRING, 'tmp.png'),
GObject.Value(GObject.TYPE_BOOLEAN, interlace),
GObject.Value(GObject.TYPE_INT, compression),
# write all PNG chunks except oFFs(ets)
GObject.Value(GObject.TYPE_BOOLEAN, True),
GObject.Value(GObject.TYPE_BOOLEAN, True),
GObject.Value(GObject.TYPE_BOOLEAN, False),
GObject.Value(GObject.TYPE_BOOLEAN, True),
])
orafile.write(tmp, path)
os.remove(tmp)
@ -220,9 +220,9 @@ def save_ora(procedure, run_mode, image, drawable, file, args, data):
add_layer(parent, x, y, opac, lay, path_name, lay.get_visible())
# save mergedimage
args = Gimp.ValueArray.new(1)
args.insert(0, GObject.Value(Gimp.Image, image))
thumb = Gimp.get_pdb().run_procedure('gimp-image-duplicate', args)
thumb = Gimp.get_pdb().run_procedure('gimp-image-duplicate', [
GObject.Value(Gimp.Image, image),
])
thumb = thumb.index(1)
thumb = Gimp.Image.get_by_id(thumb)
thumb_layer = thumb.merge_visible_layers (Gimp.MergeType.CLIP_TO_IMAGE)
@ -253,10 +253,9 @@ def save_ora(procedure, run_mode, image, drawable, file, args, data):
os.remove(file.peek_path()) # win32 needs that
os.rename(file.peek_path() + '.tmpsave', file.peek_path())
retval = Gimp.ValueArray.new(1)
retval.insert(0, GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS))
return retval
return Gimp.ValueArray.new_from_values([
GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS)
])
def load_ora(procedure, run_mode, file, args, data):
tempdir = tempfile.mkdtemp('gimp-plugin-file-openraster')
@ -312,14 +311,11 @@ def load_ora(procedure, run_mode, file, args, data):
fid.write(data)
# import layer, set attributes and add to image
args = Gimp.ValueArray.new(3)
arg0 = GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE)
args.insert(0, arg0)
arg1 = GObject.Value(Gimp.Image, img)
args.insert(1, arg1)
arg2 = GObject.Value(GObject.TYPE_STRING, tmp)
args.insert(2, arg2)
gimp_layer = Gimp.get_pdb().run_procedure('gimp-file-load-layer', args)
gimp_layer = Gimp.get_pdb().run_procedure('gimp-file-load-layer', [
GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
GObject.Value(Gimp.Image, img),
GObject.Value(GObject.TYPE_STRING, tmp),
])
gimp_layer = gimp_layer.index(1)
gimp_layer = Gimp.Item.get_by_id(gimp_layer)
os.remove(tmp)
@ -342,13 +338,10 @@ def load_ora(procedure, run_mode, file, args, data):
os.rmdir(tempdir)
retval = Gimp.ValueArray.new(2)
arg0 = GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS)
retval.insert(0, arg0)
arg1 = GObject.Value(Gimp.Image, img)
retval.insert(1, arg1)
return retval
return Gimp.ValueArray.new_from_values([
GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS),
GObject.Value(Gimp.Image, img),
])
class FileOpenRaster (Gimp.PlugIn):

View File

@ -58,13 +58,13 @@ def foggify(procedure, run_mode, image, drawable, args, data):
fog.add_mask(mask)
# add some clouds to the layer
args = Gimp.ValueArray.new(5)
args.insert(0, GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE))
args.insert(1, GObject.Value(Gimp.Image, image))
args.insert(2, GObject.Value(Gimp.Drawable, mask))
args.insert(3, GObject.Value(GObject.TYPE_INT, int(time.time())))
args.insert(4, GObject.Value(GObject.TYPE_DOUBLE, turbulence))
Gimp.get_pdb().run_procedure('plug-in-plasma', args)
Gimp.get_pdb().run_procedure('plug-in-plasma', [
GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
GObject.Value(Gimp.Image, image),
GObject.Value(Gimp.Drawable, mask),
GObject.Value(GObject.TYPE_INT, int(time.time())),
GObject.Value(GObject.TYPE_DOUBLE, turbulence),
])
# apply the clouds to the layer
fog.remove_mask(Gimp.MaskApplyMode.APPLY)

View File

@ -40,18 +40,6 @@ import math
import time
def pdb_call(proc_name, *args):
if len(args) % 2 == 1:
raise ValueError("The number of arguments after proc_name needs to be even. ")
num_args = len(args) // 2
proc_args = Gimp.ValueArray.new(num_args)
for i in range(num_args):
proc_args.append(GObject.Value(args[2 * i], args[2 * i + 1]))
return Gimp.get_pdb().run_procedure(proc_name, proc_args)
def result_success():
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
@ -388,11 +376,11 @@ class SelectionToPath:
else:
selection_was_empty = False
result = pdb_call('plug-in-sel2path',
Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE,
Gimp.Image, self.image,
Gimp.Drawable, self.image.get_active_layer()
)
result = Gimp.get_pdb().run_procedure('plug-in-sel2path', [
GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
GObject.Value(Gimp.Image, self.image),
GObject.Value(Gimp.Drawable, self.image.get_active_layer()),
])
self.path = self.image.get_vectors()[0]
self.stroke_ids = self.path.get_strokes()