let me try to come up with a list of requirements for a simple preview
widget that allows to be extended to a full-featured beast later.
- It should be a GtkWidget so that if can be embedded into the plug-in
dialog like any other widget. This is not the case with the
GimpOldPreview code which returns a struct and forces you to access
struct members in order to pack and show the preview.
- We will want to add scrollbars and optionally zoom controls. Perhaps
not in the very first version, but this should be foreseen. I see two
possible ways to do this:
(1) Derive the preview widget from GtkTable and put all possibly
needed controls into the table. Provide an API to switch them
on/off. This is what Ernst Lippe's widget does.
(2) Keep the actual preview code in GimpPreviewArea, probably
derived from GtkDrawingArea. This is just the preview, no
frame, no scrollbars, no controls. Make this widget export the
preview API as an interface (called GimpPreview). Then add
the following convenience widgets:
- GimpPreviewFrame, a sunken GtkFrame holding a GimpPreviewArea
- GimpPreviewScrolled(?), a GtkScrolledWindow that holds a
GimpPreviewArea (no need for the frame since
GtkScrolledWindow draws a shadow already). GimpPreviewArea
will have to implement gtk_widget_set_scroll_adjustments for
this to work.
Later we might want to add GimpPreviewZoom(?) that adds zoom
controls but I think it will make our life easier to postpone
this for now.
All these widgets will provide the GimpPreview interface, so
that you can use the GimpPreview API on all of them, without
the need to do ugly things such as
gimp_preview_set_foo (GIMP_PREVIEW (GIMP_PREVIEW_SCROLLED (widget)->preview),
Instead you simply use
gimp_preview_set_foo (GIMP_PREVIEW (widget), bar);
and don't need to care whether widget is a GimpPreviewArea, a
GimpPreviewFrame or a GimpPreviewScrolled.
- It should handle RGB, grayscale and indexed data and should provide
an API that allows to add other types later.
- It should handle an alpha channel. The preview needs to be able to
draw a checkerboard pattern below the preview in case the preview
has translucent areas. Perhaps we also need a mode that renders on
a solid colored background but I'm not sure if that's needed at
all. If we ever get around to export the user preference for the
checkerboard to the plug-ins, then GimpPreview should handle this
transparently, i.e. it should do the PDB calls to retrieve these
settings from the core.
So what about the API to actually draw the preview? IMO in the first
version this should be kept as simple as possible. The plug-in needs
to fill the preview with data. It can do this by setting the data
row-by-row, column-by-column or in rectangular areas, very similar to
the API provided by GtkPreview but also close to the way that most
plug-ins operate on the pixel data.
In case the preview is scrollable, the plug-in will have to connect to
the "value_changed" signals of the adjustments that it passed to
gimp_preview_scrolled_new() (remember that GimpPreviewScrolled is a
GtkScrolledWindow). Whenever the preview is scrolled, the plug-in will
have to redraw the preview. We could later try to make this
transparent for the plug-in and have the preview pull in the drawable
data and call the plug-in to render it's effect. But I'd like to
implement this later.
As you can see, my proposal for now is basically a widget that can
replace GtkPreview and implements the common UI code that is
duplicated every so often in our plug-ins. It does not yet handle the
more sophisticated stuff, it doesn't know about drawables or other
GIMP types except perhaps the GimpImageType enum.
Later I'd like to see this widget be used by a more complex preview
framework. Ideally the plug-in author wouldn't have to write a special
function to preview the effect, instead she should be given a
pseudo-drawable to work on. That would allow to use the same code that
is used on the real drawable. As a nice side-effect this ensures that
the preview matches the actual effect. Contrary to the implementation
in refocus (http://refocus.sourceforge.net/preview) I'd like this
pseudo drawable to exist in the plug-in process only. The GIMP core
doesn't need to know about it. This will also make sure that no
temporary drawables are left around when a plug-in dies.
Alternatively, instead of using an pseudo drawable, we could make the
preview work on an extra set of tiles on the real drawable (or rather
the GimpDrawable wrapper provided by libgimp since the plug-in never
sees the real GimpDrawable object that lives in the core). This would
work pretty much like shadow tiles work now only that the tiles would
only be flushed to the core when a preview on the image window is
requested. Unfortunately we weren't smart enough to add some padding
to the GimpDrawable struct so it will be difficult to get this done in
a backward-compatible fashion :( But perhaps we decide that it's worth
to break binary-compatibility for GIMP-2.4.
The things outlined in the last two paragraphs are definitely not for
GIMP-2.2 but I'd like to get the other parts done real soon now. So
Gimp-developer mailing list