Some questions about ImageProcedure creation and its autogenerated UI

Playing with the 3.00 RC1 on Linux. Starting with this:

I can’t help notice that there is a disagreement on the centering or left-formatting of the labels (left-formatting is more to my taste… ). And the boolean on the other side looks a bit out of place. The gradient problem is already reported.

Now for the real questions:

There are many parameter types for which I get parameter XXX has non supported type GimpParamYYYY for value type GimpYYYY. Does this means that there could be a widget for this someday? But it’s not implemented yet?

There are parameter types for which I don’t get a message but there are no entries in the dialog: image, bytes, resource (what is this), selection (what is this?). Is it expected?

add_pattern_argument crashes and burns: gimp_resource_chooser_set_resource: assertion 'resource != NULL' failed + Segfault. Code is:

        procedure.add_pattern_argument( 'pattern',                  # Name
                                        'Pattern',                  # Nick
                                        'Pattern blurb',            # Blurb
                                        True,                       # noneOK
                                        None,                       # Default value
                                        True,                       # Default to context
                                        GObject.ParamFlags.READWRITE)

Any of the above to report as a bug?

The code I have uses an ImageProcedure but I can’t find a way to have a plain Procedure. The ImageProcedure appears to be a Procedure with baked-in run_mode, image and drawables arg. So, if I want to start from a Procedure, I have to add a run_mode parameter but there is no call for this? This is somewhat important because over half of my Gimp2.x scripts are not amenable to ImageProcedure (almost half of them take an image and a path (called form the Paths list), and a significant number take just an image). Or should I play with the procedure sensitivity mask (but this would only solve the case of no drawables)?

Random additional thoughts

  • The sensitivity of individual items in a “choice” is nice but I’ll have to figure out a way to change this on the fly when the dialog is shown…
  • Given that there are specific parameter types for layers, layer masks, channels, text layers and layer groups, wouldn’t it make sense to have Procedure sensitivity flags to pre-filter on these types?
  • Maybe include a Procedure sensitivity flags for Paths

Looks more like a GUI bug rather than a “disagreement”. Obviously the goal is to have it all pretty-generated by default.

Yes the goal is to be able to support a “good default” widget for every supported procedure argument, and variants for when the defaults are not what you were aiming for.

Resources is the parent class for brushes, patterns, palettes, fonts, etc. It’s not a class you can instantiate (you can only instantiate a subclass). Also I don’t think it makes sense to have a widget for “any kind of resource”. At least I’d be waiting for a real use case brought by someone before starting thinking of what could be a good UI for “any resource”.

Selection is an actual image selection, which is a child type of channel, itself a drawable.

Any of the above to report as a bug?

Possibly. I’d have to look closer at it. You may report it and when we have time, someone can take time to check.

There is a gimp_procedure_new function which works fine and we use it for a bunch of core plug-ins.

I guess you mean that some choices would be sensitive or not depending on other settings?

It is completely possible. In fact, we do this in a bunch of plug-ins (grep gimp_choice_set_sensitive plug-ins/). In particular, it looks like the DDS plug-in has on-the-fly sensitivity changing. What we do is to connect a handler to the “notify” signal of the GimpProcedureConfig object. When the other settings (supposed to trigger a choice update) is the one which triggered the signal, then we update the choice list sensitivity.

Check config_notify() function in plug-ins/file-dds/ddswrite.c. You’ll see how we change some options of the “existing” item in a choice list depending on the “save-type” arg with gimp_choice_set_sensitive(). You can also see how we enable/disable whole widgets with gimp_procedure_dialog_set_sensitive() depending on other settings.

Since the config values are synced with the generated GUI, this allows on-the-fly settings updates very very easily.

It was planned for 3.0.0 (in fact you were in the discussion, I see! :wink:). I was hoping to think of a powerful API to tell core when a plug-in should be active or not. It’s just that at some point, if we don’t want to release in 5 more years, we need to skim off a bit of cool new features. This was one of them.

There is a gimp_procedure_new function which works fine and we use it for a bunch of core plug-ins.

Yes, Gimp.Procedure.new() also works in Python. By I can’t add a run_mode argument to it… because there is no API for this. Or is it already there? In which case the doc is wrong?

Btw, found the root cause of the Pattern crash. This is because there is no current active pattern (crash despite the noneOK flag…). The same thing can happen with a brush. It seems that if you filter the Brushes or Patterns list and the filter results in an empty list, your current brush or pattern is deactivated and not replaced:

No there is indeed no “run-mode” argument for GimpProcedure (I thought there would be, but I just checked and no). There is indeed no dedicated arg, but it’s just an enum so you can use gimp_procedure_add_enum_argument, this way:

  gimp_procedure_add_enum_argument (procedure, "run-mode", 
                                    "Run mode",
                                    "The run mode",
                                    GIMP_TYPE_RUN_MODE,
                                    GIMP_RUN_NONINTERACTIVE,
                                    G_PARAM_READWRITE);

In Python, that would be something like this:

  procedure.add_enum_argument ("run-mode", 
                               "Run mode",
                               "The run mode",
                               Gimp.RunMode.__gtype__
                               Gimp.RunMode.NONINTERACTIVE,
                               GObject.ParamFlags.READWRITE)

Thanks. Will have to look at that. I think to remember that this was in fact seen at some point, but probably forgotten. I’m not sure if there is a report for this. Would you mind opening one?

Done:

Can’t wrap my head around the need for this. If we have the image we have the selection? Or is there more than one selection now?

Yes with gimp_image_get_selection().

Anyway the need is pretty obvious: ability to grab or edit a selection (which is just another channel in the end) as any other type of drawables. It’s like if you were asking “why would we need alpha to selection? Or save selection to channel?” or other features. These are all special cases, but in the end, if you have access to the selection buffer directly, you can do anything (these things and more). You can run filters on selection, process it. Just anything.

Now these all are for sure not your basic use cases. But for someone like you, who does complex image processing, I’m pretty sure you had more than once a need to edit or use the selection data and you surely will still have this need some day again in the future. When this day comes, you will have access to the selection data in read/write.

Of course I use the selection. And I [can get it with an API](file:///Gimp-dev/3.00/run/share/doc/gimp-3.0/libgimp-3.0/method.Image.get_selection.html) already. What I don’t see is why it should be an argument.
In other words, in what cases could it be something different from what is returned by image.get_selection()? Putting it as an argument implies that someone would want to pass something else to the plugin (but then there is the Channel argument type for this).

Ah sure, well you are right that it’s probably not the most useful type for an arg. Well a selection could definitely be passed to a PDB procedure, but as you say, that would likely be more a channel arg (which could pass a selection, but also a layer mask or just generic named channels).

Now does it really matter that it’s not a common usage? It’s a type we have in GIMP, so we make it usable as an argument (doing this is “cheap”, the infra is the same). Maybe it’s never used. So what? On the other hand, if someone, somewhere, ever has a use case for this, they’d be rightly annoyed that it’s not possible for GIMP to use its own types as procedure argument. :person_shrugging:

Doesn’t appear to work. If I use a plain Procedure at execution time I get:

TypeError: executePlain() missing 3 required positional arguments: 'drawables', 'config', and 'data'

Things are a tad better if I use an ImageProcedure. I can install the plugin (that just takes an additional path argument) in <Paths> and it appears in the right click menu of a path, but if I try to execute it,

  • the path argument has noneOK=True, the config entry is not set, and I can’t use a dialog because there i no widget yet for path arguments
  • considering that many of my scripts don’t require a dialog, I tried with noneOK=False and no dialog creation, and this seems to produce a path argument, but I get a Gimp warning;
Procedure 'OfnTestPath' has been called with value '<not transformable to string>' for argument 'path' (#4, type GimpPath). This value is out of range