Skip to content

Wip/jehan/classy gimp

Jehan requested to merge wip/Jehan/classy-GIMP into master

This is my current work-in-progress for a more object-oriented API.

So far, I have added a GimpImage, GimpItem, GimpDrawable, GimpLayer, GimpChannel, GimpSelection, GimpLayerMask, GimpVectors and GimpDisplay.

Of course, as expected, classes are parented like in core, i.e. GimpItem > GimpDrawable > GimpLayer, and GimpItem, GimpDrawable > GimpChannel > GimpLayerMask, and so on. This means that we get all the perks of working on objects.

It is now possible for a plug-in to register object parameters for any of these classes instead of our custom Gimp*ID. libgimp will automatically transform back and forth the objects to their IDs on the wire, which is totally transparent to the plug-in developer who can work entirely with opaque objects (it is still possible to get the id with gimp_item_get_id(), gimp_image_get_id()andgimp_display_get_id()` if you really want/need integer IDs, but not necessary.

I have already modified gimp_load_procedure_new() and gimp_save_procedure_new() to return a GimpImage for the former and take a GimpImage and GimpDrawable for the latter, and I have already ported all plug-ins you started to port with this new API (file-raw, file-gih, gbr, pat and so on).

Finally, as I am aware this is a big change, I made it still possible to build with the old API. If a plug-in builds with -DGIMP_DEPRECATED_REPLACE_NEW_API, it will get the old API with IDs instead of objects. You can check in our tree, I did this on all plug-ins not yet ported. And they work perfectly too. I used the same macro trick as what used to be on the GeglBufferIterator when changing API to allow 2 incompatible APIs with seemingly same name on the same library.

Why I think this should go in:

  1. I did a loooot of work on this! 😛
  2. This makes for a much nicer API to work with objects, not IDs. Also we can work with inheritance, and GIMP_IS_LAYER() will replace happily gimp_item_is_layer() and alike.
  3. For the future, when we will finally have bidirectionnal communication, we can just hook it up on the glib signal API. For instance, our libgimp GimpImage can have "dirty" signal to indicate something changed, or "new-layer" to indicate a layer was added, or "destroyed" to indicate the image was destroyed on GIMP side (a very common issue we have on many plug-ins: when the image is destroyed on GIMP and the plug-in crashes). Plug-ins will even be able to make weak pointers on their images, etc.
  4. It makes for 100 times better binding API. In our non-C plug-ins, it changes this way:
-            buffer = Gimp.drawable_get_buffer(drawable_id)
-            shadow_buffer = Gimp.drawable_get_shadow_buffer(drawable_id)
+            buffer = drawable.get_buffer()
+            shadow_buffer = drawable.get_shadow_buffer()
  1. It also "fixed" my problem on the Python binding in a clean way by just using objects instead of custom IDs. Now the Python binding are fully operational. Without this change, Python plug-ins were basically broken as soon as you needed to exchange images and drawables. And I really don't feel like tinkering with pygobject code (I tried a bit, but my hands are really too full to spend all my time there!).
  2. With the (ugly, I admit) trick with a macro, old-style plug-ins are still buildable. We may even keep this trick in GIMP 3.0 to make a transition period.

I'm sure they are more points but not coming to mind right now! Can I push?! 😃

Merge request reports