Skip to content

2.99 libgimp: add GimpResource, GimpBrush, GimpPropWidgetBrush

Lloyd Konneker requested to merge bootchk/gimp:testFontClassLibgimp into master

This MR makes gimp resources (brush, font etc.) first class objects in libgimp.

Related

14 year old #261. That is the main discussion.

A much cruder proposal !726 (closed).

WIP.

This MR demonstrates a slice, or part, of the completed solution. The slice is for GimpBrush, and only a few of the methods for GimpBrush. The complete solution is mostly replication of GimpBrush, and many changes to existing PDB procedures for Brush, etc. That is, much of this MR was just cut and paste, substituting Image=>Brush for example.

The MR illustrates the wide extent of changes in the code required for this feature:

Adding a few classes to libgimp (GimpResource and GimpBrush.)
Changes to
  GimpProcedureDialog,
  prop widgets,
  ParamSpecs (GimpParamSpecBrush),
  the wire implementation,
  PDB procedure definitions pdb/groups/brush.pdb
  pdbgen,
  ScriptFu

What is demonstrated.

  1. A PDB procedure can declare an argument of type GimpObject holding GimpBrush

  2. GimpProcedureDialog shows a brush select button for same.

  3. Interactive user choice of brush for a plugin is saved in settings.

  4. The API reference and the PDB Browser show the GimpBrush class, and a few changed libgimp and PDB procedures.

What it doesn't solve, but helps

It doesn't solve the problem that ID's (formerly called names) of brushes are not guaranteed unique. That problem is in the core. (The core should probably use a UUID?)

The MR does help isolate the API from future changes to the core to solve uniqueness. That is, with this MR, no PDB procedure should "know" or use the type of the identifier. The type of an identifier can be changed (in core and elsewhere) without changing the API.

For example, "char * gimp_brush_new(char* name) will change to "GimpBrush* gimp_brush_new(char *name)". Subsequently, GimpBrush.get_name() might return a different name than requested. But the plugin should not use the proposed name as the ID. For now, the implementation will still use the name as the ID. In the future, when core changes, the name will be distinct from the ID. Starting with this MR, a plugin can have a GimpBrush, and can get it's name, but won't use the name where a GimpBrush is required. A plugin can call "GimpBrush *gimp_brush_get_by_name(char *)".

An ID is serializable so it can cross the wire and be serialized in settings. But a plugin does not usually know about the ID. Except for "is valid", as for images. Whenever a choice of Brush in a Config (settings) is used, and the plugin is not well-written, it can happen that "a plugin is using a brush that no longer exists."

API changes

Python plugins can use GimpBrush (or other resources) as first class objects.

The signature of many PDB procedures changes.

ScriptFu will continue to use its own (string) representation for GimpBrush, converting back and forth from GimpBrush to/from string on calls from/to PDB procedures. But scripts will remain insulated from changes to the type of an ID.

Other notes about the MR

The MR only builds with meson.

A test case is Filter>Dev>ScriptFu>Test>Sphere v3. Expect to see a brush chooser widget.

Another test case is the procedure gimp_brush_is_generated. Expect in the PDB browser to see its argument is of type "GimpBrush" instead of "char *"

Also expect in the API reference document to see a "Brush" class, having instance method gimp_brush_is_generated(GimpBrush). The legacy functions on brushes are also under the Brush class, but shown as functions taking char*.

I didn't actually test that Brush.is_generated works.

There are a few holes: gimp_brush_is_valid is not correct.

Merge request reports