[gimp] ScriptFu: register args with proper GParamSpecs
- From: Lloyd Konneker <lkonneker src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] ScriptFu: register args with proper GParamSpecs
- Date: Tue, 5 Jul 2022 20:20:04 +0000 (UTC)
commit c2b13d6f911421b24ea9a783627d0ee3ea22fe1b
Author: lloyd konneker <konnekerl gmail com>
Date: Mon Jul 4 10:37:40 2022 -0400
ScriptFu: register args with proper GParamSpecs
Resolves #8328
Except existing GimpParamSpecs seem inadequate to specify less generic widget kinds.
plug-ins/script-fu/libscriptfu/script-fu-arg.c | 155 ++++++++++++++++++++++---
1 file changed, 140 insertions(+), 15 deletions(-)
---
diff --git a/plug-ins/script-fu/libscriptfu/script-fu-arg.c b/plug-ins/script-fu/libscriptfu/script-fu-arg.c
index e39ed775a9..d24c9e586e 100644
--- a/plug-ins/script-fu/libscriptfu/script-fu-arg.c
+++ b/plug-ins/script-fu/libscriptfu/script-fu-arg.c
@@ -44,6 +44,7 @@
* and result values of widgets are written back to SFArg.
*
* In GIMP 3, SFArg might be somewhat replaced with GimpConfig.
+ * Then many of these methods are not needed.
*
* Roughly, the methods hide how to convert/represent SFArgs back/forth
* to [GParamSpec, GValue, Scheme string representation.]
@@ -51,7 +52,35 @@
* Since SFArg is a union, similar to a GValue, the code is mostly switch on type.
*/
+/*
+ * An SFArg has a type SFArgType that denotes not only a type, but a kind of widget.
+ * For example, SF_STRING denotes string type and a string entry widget,
+ * while SF_TEXT denotes a string type and a multiline text editing widget.
+ *
+ * But the SFArgType:SF_ADJUSTMENT further specifies a kind of widget,
+ * either spinner or slider.
+ * I.E. SFArgType is not one-to-one with widget kind.
+ *
+ * Unlike PythonFu, there is no SFArgType.SF_INT.
+ * Thus a ScriptFu author cannot specify an int-valued widget.
+ * While Scheme speakers understand Scheme uses "numeric" for both float and int,
+ * this might be confusing to script authors using other programming languages.
+ *
+ * SF_VALUE probably should be obsoleted.
+ * Search ChangeLog for mention of "SF_VALUE"
+ * See below, the only difference is that one get string escaped.
+ * Otherwise, SF_VALUE is identical to SF_STRING.
+ * Probably SF_VALUE still exists just for backward compatibility.
+ *
+ * SFArgType denotes not only a C type, but also a Scheme type.
+ * For example, SF_ADJUSTMENT denotes the C type "float"
+ * and the Scheme type "numeric" (which encompasses float and int.)
+ * Another example, SF_PATTERN denotes the C type GimpPattern
+ * and the Scheme type string (names of brushes are used in scripts.)
+ */
+
+static void pspec_set_default_file (GParamSpec *pspec, const gchar *filepath);
/* Free any allocated members.
@@ -92,6 +121,11 @@ script_fu_arg_free (SFArg *arg)
g_free (arg->value.sfa_file.filename);
break;
+ /* FUTURE: font..gradient could all use the same code.
+ * Since the type in the union are all the same: gchar*.
+ * That is, group these cases with SF_VALUE.
+ * But this method should go away altogether.
+ */
case SF_FONT:
g_free (arg->default_value.sfa_font);
g_free (arg->value.sfa_font);
@@ -179,6 +213,10 @@ script_fu_arg_reset (SFArg *arg, gboolean should_reset_ids)
value->sfa_file.filename = g_strdup (default_value->sfa_file.filename);
break;
+ /* FUTURE: font..gradient could all use the same code.
+ * Since the type in the union are all the same: gchar*.
+ * That is, group these cases with SF_VALUE.
+ */
case SF_FONT:
g_free (value->sfa_font);
value->sfa_font = g_strdup (default_value->sfa_font);
@@ -221,9 +259,17 @@ script_fu_arg_reset (SFArg *arg, gboolean should_reset_ids)
* Convert instance of SFArg to instance of GParamSpec.
*
* Used to specify an arg to the PDB proc which this script implements.
+ * The GParamSpec is "floating" meaning ownership will transfer
+ * to the GimpPDBProcedure.
+ *
+ * Ensure GParamSpec has a default except as noted below.
+ * Default value from self.
+ *
+ * FUTURE: use GimpProcedureDialog
+ * Because GimpProcedureDialog creates widgets from properties/paramspecs,
+ * this should convey what SFArg denotes about desired widget kind,
+ * but it doesn't fully do that yet.
*/
-// FIXME set defaults correctly from arg->default_value.foo.value
-// FIXME set limits correctly
GParamSpec *
script_fu_arg_get_param_spec (SFArg *arg,
const gchar *name,
@@ -233,11 +279,12 @@ script_fu_arg_get_param_spec (SFArg *arg,
switch (arg->type)
{
+ /* No defaults for GIMP objects: Image, Item subclasses, Display */
case SF_IMAGE:
pspec = gimp_param_spec_image (name,
nick,
arg->label,
- TRUE,
+ TRUE, /* None is valid. */
G_PARAM_READWRITE);
break;
@@ -282,65 +329,104 @@ script_fu_arg_get_param_spec (SFArg *arg,
break;
case SF_COLOR:
+ /* Pass address of default color i.e. instance of GimpRGB.
+ * Color is owned by ScriptFu and exists for lifetime of SF process.
+ */
pspec = gimp_param_spec_rgb (name,
nick,
arg->label,
- TRUE, NULL,
+ TRUE, /* is alpha relevant */
+ &arg->default_value.sfa_color,
G_PARAM_READWRITE);
+ /* FUTURE: Default not now appear in PDB browser, but appears in widgets? */
break;
case SF_TOGGLE:
+ /* Implicit conversion from gint32 to gboolean. */
pspec = g_param_spec_boolean (name,
nick,
arg->label,
- FALSE,
+ arg->default_value.sfa_toggle,
G_PARAM_READWRITE);
break;
+ /* FUTURE special widgets for multiline text.
+ * script-fu-interface does, but GimpProcedureDialog does not.
+ */
case SF_VALUE:
case SF_STRING:
case SF_TEXT:
+ /* FUTURE special widgets.
+ * script-fu-interface does, but GimpProcedureDialog does not?
+ */
case SF_FONT:
case SF_PALETTE:
case SF_PATTERN:
- case SF_BRUSH:
case SF_GRADIENT:
+ /* These cases the same type: gchar *.
+ * Use arbitrary SFArg field of that type.
+ */
pspec = g_param_spec_string (name,
nick,
arg->label,
- NULL,
+ arg->default_value.sfa_value,
G_PARAM_READWRITE);
break;
+ case SF_BRUSH:
+ /* FUTURE: brush object has more fields.
+ * ?? Implement gimp_param_spec_brush
+ */
+ pspec = g_param_spec_string (name,
+ nick,
+ arg->label,
+ arg->default_value.sfa_brush.name,
+ G_PARAM_READWRITE);
+ break;
case SF_ADJUSTMENT:
pspec = g_param_spec_double (name,
nick,
arg->label,
- -G_MAXDOUBLE, G_MAXDOUBLE, 0,
+ arg->default_value.sfa_adjustment.lower,
+ arg->default_value.sfa_adjustment.upper,
+ arg->default_value.sfa_adjustment.value,
G_PARAM_READWRITE);
break;
- // FIXME GFile
case SF_FILENAME:
case SF_DIRNAME:
- pspec = g_param_spec_string (name,
+ pspec = g_param_spec_object (name,
nick,
arg->label,
- NULL,
+ G_TYPE_FILE,
G_PARAM_READWRITE |
GIMP_PARAM_NO_VALIDATE);
+ pspec_set_default_file (pspec, arg->default_value.sfa_file.filename);
+ /* FUTURE: Default not now appear in PDB browser, but appears in widgets? */
break;
- // FIXME SF_ENUM should be g_param_spec_enum( g_type_from_name (arg->default_value.sfa_enum.type_name))
case SF_ENUM:
+ /* history is the last used value AND the default. */
+ pspec = g_param_spec_enum (name,
+ nick,
+ arg->label,
+ g_type_from_name (arg->default_value.sfa_enum.type_name),
+ arg->default_value.sfa_enum.history,
+ G_PARAM_READWRITE);
+ break;
+
case SF_OPTION:
pspec = g_param_spec_int (name,
nick,
arg->label,
- G_MININT, G_MAXINT, 0,
+ 0, /* Always zero based. */
+ g_slist_length (arg->default_value.sfa_option.list),
+ arg->default_value.sfa_option.history,
G_PARAM_READWRITE);
+ /* FUTURE: Model values not now appear in PDB browser NOR in widgets? */
+ /* FUTURE: Does not show a combo box widget ??? */
break;
}
@@ -406,8 +492,6 @@ script_fu_arg_append_repr_from_gvalue (SFArg *arg,
case SF_STRING:
case SF_TEXT:
- case SF_FILENAME:
- case SF_DIRNAME:
{
gchar *tmp;
@@ -417,6 +501,25 @@ script_fu_arg_append_repr_from_gvalue (SFArg *arg,
}
break;
+ case SF_FILENAME:
+ case SF_DIRNAME:
+ {
+ gchar * filepath = NULL;
+
+ if (g_value_get_gtype (gvalue) == G_TYPE_FILE)
+ {
+ filepath = g_file_get_path (g_value_get_object (gvalue));
+ /* Not escape special chars for whitespace or double quote. */
+ }
+ else
+ {
+ g_warning ("Expecting GFile in gvalue.");
+ }
+
+ g_string_append_printf (result_string, "\"%s\"", filepath);
+ }
+ break;
+
case SF_ADJUSTMENT:
{
gchar buffer[G_ASCII_DTOSTR_BUF_SIZE];
@@ -570,6 +673,11 @@ script_fu_arg_reset_name_generator (void)
/*
* Return a unique name, and non-unique nick, for self.
*
+ * Self's label came from a call to script-fu-register ()
+ * and was not lexically checked so is unsuitable for a property name.
+ * ScriptFu does not require script author to provide a unique name
+ * for args in a call to script-fu-register.
+ *
* This is a generator.
* Returned name is a canonical name for a GParamSpec, i.e. a property name.
* It meets the lexical requirements for a property name.
@@ -695,3 +803,20 @@ script_fu_arg_generate_name_and_nick (SFArg *arg,
/* nick is what the script author said describes the arg */
*returned_nick = arg->label;
}
+
+
+/* Set the default of a GParamSpec to a GFile for a path string.
+ * The GFile is allocated and ownership is transferred to the GParamSpec.
+ * The GFile is only a name and a so-named file might not exist.
+ */
+static void
+pspec_set_default_file (GParamSpec *pspec, const gchar *filepath)
+{
+ GValue gvalue = G_VALUE_INIT;
+ GFile *gfile = NULL;
+
+ g_value_init (&gvalue, G_TYPE_FILE);
+ gfile = g_file_new_for_path (filepath);
+ g_value_set_object (&gvalue, gfile);
+ g_param_value_set_default (pspec, &gvalue);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]