Initial checkin of Pika from heckimp
This commit is contained in:
272
devel-docs/PIKA3-plug-in-porting-guide/API-for-resources.md
Normal file
272
devel-docs/PIKA3-plug-in-porting-guide/API-for-resources.md
Normal file
@ -0,0 +1,272 @@
|
||||
# API changes in libpika and the PDB for resources
|
||||
|
||||
This explains changes to the PIKA API from v2 to v3,
|
||||
concerning resources.
|
||||
|
||||
The audience is plugin authors, and PIKA developers.
|
||||
|
||||
### Resources
|
||||
|
||||
A resource is a chunk of data that can be installed with PIKA
|
||||
and is used by painting tools or for other rendering tasks.
|
||||
Usually known as brush, font, palette, pattern, gradient and so forth.
|
||||
|
||||
### Resources are now first class objects
|
||||
|
||||
PikaResource is now a class in libpika.
|
||||
|
||||
It has subclasses:
|
||||
|
||||
- Brush
|
||||
- Font
|
||||
- Gradient
|
||||
- Palette
|
||||
- Pattern
|
||||
|
||||
Formerly, the PIKA API had functions operating on resources by name.
|
||||
Now, there are methods on resource objects.
|
||||
Methods take an instance of the object as the first argument,
|
||||
often called "self."
|
||||
|
||||
This means that where you formerly used a string name to refer to a resource object,
|
||||
now you usually should pass an instance of an object.
|
||||
|
||||
### Changes to reference documents
|
||||
|
||||
#### libpika API reference
|
||||
|
||||
Shows classes Brush, Font, and so forth.
|
||||
The classes have instance methods taking the instance as the first argument.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
gboolean gboolean pika_brush_delete(gcharray) => gboolean pika_brush_delete ( PikaBrush*)
|
||||
```
|
||||
|
||||
The classes may also have class methods still taking string names.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
gboolean pika_brush_id_is_valid (const gchar* id)
|
||||
```
|
||||
|
||||
Is a class method (in the "Functions" section of the class) taking the ID
|
||||
(same as the name) to test whether such a brush is installed in Pika core.
|
||||
|
||||
#### PDB Browser
|
||||
|
||||
Remember the PDB Browser shows the C API. You must mentally convert
|
||||
to the API in bound languages.
|
||||
|
||||
Shows some procedures that now take type e.g. PikaBrush
|
||||
where formerly they took type gcharray i.e. strings.
|
||||
|
||||
Shows some procedures that take a string name of a brush.
|
||||
These are usually class methods.
|
||||
|
||||
#### Other changes to the API
|
||||
|
||||
Many of the Pika functions dealing with the context
|
||||
now take or return an instance of a resource.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
gcharray* pika_context_get_brush (void) => PikaBrush* pika_context_get_brush (void)
|
||||
```
|
||||
|
||||
A few functions have even more changed signature:
|
||||
|
||||
```
|
||||
gint pika_palette_get_info (gcharray) =>
|
||||
gint pika_palette_get_color_count (PikaPalette*)
|
||||
```
|
||||
|
||||
The name and description of this function are changed
|
||||
to accurately describe that the function only returns an integer
|
||||
(formerly, the description said it also returned the name of the palette.)
|
||||
|
||||
### New resource objects
|
||||
|
||||
FUTURE
|
||||
|
||||
Formerly there were no methods in the libpika API or the PDB for objects:
|
||||
|
||||
- Dynamics
|
||||
- ColorProfile
|
||||
- ToolPreset
|
||||
|
||||
These classes exist primarily so that plugins can let a user choose an instance,
|
||||
and pass the instance on to other procedures.
|
||||
|
||||
### Traits
|
||||
|
||||
Informally, resources can have these traits:
|
||||
|
||||
- Nameable
|
||||
- Creatable/Deleable
|
||||
- Cloneable (Duplicatable)
|
||||
- Editable
|
||||
|
||||
Some resource subclasses don't have all traits.
|
||||
|
||||
### ID's and names
|
||||
|
||||
The ID and name of a resource are currently the same.
|
||||
(Some documents and method names may use either word, inconsistently.)
|
||||
|
||||
You usually use resource instances instead of their IDs.
|
||||
This will insulate your code from changes to PIKA re ID versus name.
|
||||
|
||||
A plugin should not use a resource's ID.
|
||||
A plugin should not show the ID/name to a user.
|
||||
The PIKA app shows the names of resources as a convenience to users,
|
||||
but usually shows resources visually, that is, iconically.
|
||||
An ID is opaque, that is, used internally by PIKA.
|
||||
|
||||
FUTURE: the ID and name of a resource are distinct.
|
||||
Different resource instances may have the same name.
|
||||
Methods returning lists of resources or resource names may return
|
||||
lists having duplicate names.
|
||||
|
||||
### Resource instances are references to underlying data
|
||||
|
||||
A resource instance is a proxy, or reference, to the underlying data.
|
||||
Methods on the instance act on the underlying data.
|
||||
The underlying data is in PIKA's store of resources.
|
||||
|
||||
It is possible for a resource instance to be "invalid"
|
||||
that is, referring to underlying data that does not exist,
|
||||
usually when a user uninstalls the thing.
|
||||
|
||||
### Creating Resources
|
||||
|
||||
Installing a resource is distinct from creating a resource.
|
||||
|
||||
PIKA lets you create some resources.
|
||||
You can't create fonts in PIKA, you can only install them.
|
||||
For those resources that PIKA lets you create,
|
||||
the act of creating it also installs it.
|
||||
|
||||
For resources that you can create in PIKA:
|
||||
|
||||
- some you create using menu items
|
||||
- some you can create using the API
|
||||
|
||||
The API does not let you create a raster brush.
|
||||
|
||||
The API does let you create a parametric brush.
|
||||
For example, in Python:
|
||||
```
|
||||
brush = Pika.Brush.new("Foo")
|
||||
```
|
||||
creates a new parametric brush.
|
||||
|
||||
Note that the passed name is a proposed name.
|
||||
If the name is already in use,
|
||||
the new brush will have a different name.
|
||||
The brush instance will always be valid.
|
||||
|
||||
### Getting Resources by ID
|
||||
|
||||
Currently, you usually ask the user to interactively choose a resource.
|
||||
|
||||
If you must get a reference to a resource for which you know the ID,
|
||||
you can new() the resource class and set it's ID property.
|
||||
See below.
|
||||
|
||||
FUTURE Resource classes have get_by_id() methods.
|
||||
|
||||
If such a named resource is currently installed,
|
||||
get_by_id() returns a valid instance of the resource class.
|
||||
If such a named resource is not currently installed,
|
||||
the method returns an error.
|
||||
|
||||
### Uninitialized or invalid resource instances
|
||||
|
||||
You can create an instance of a resource class that is invalid.
|
||||
|
||||
For example, in Python:
|
||||
|
||||
```
|
||||
brush = Pika.Brush()
|
||||
brush.set_property("id", "Foo")
|
||||
```
|
||||
creates an instance that is invalid because there is no underlying data in the PIKA store
|
||||
(assuming a brush named "Foo" is not installed.)
|
||||
|
||||
Ordinarily, you would not use such a construct.
|
||||
Instead, you should use the new() method
|
||||
(for resource classes where it is defined)
|
||||
which creates, installs, and returns a valid instance except in dire circumstances (out of memory.)
|
||||
|
||||
### Invalid resource instances due to uninstalls
|
||||
|
||||
A plugin may have a resource as a parameter.
|
||||
|
||||
An interactive plugin may show a chooser widget to let a user choose a resource.
|
||||
The user's choices may be saved in settings.
|
||||
|
||||
In the same sesssion of PIKA, or in a subsequent session,
|
||||
a user may invoke the plugin again.
|
||||
Then the saved settings are displayed in the plugin's dialog
|
||||
(when the second invocation is also interactive).
|
||||
|
||||
When, in the meantime (between invocations of the plugin)
|
||||
a user has uninstalled the reference resource,
|
||||
the resource, as a reference, is invalid.
|
||||
A well-written plugin should handle this case.
|
||||
|
||||
Resource classes have:
|
||||
|
||||
- is_valid() instance method
|
||||
- id_is_valid(char * name) class method
|
||||
|
||||
Well-written plugins should use these methods to ensure
|
||||
that saved (deserialized) resource instances
|
||||
are valid before subsequently using them.
|
||||
|
||||
|
||||
### Naming and renaming
|
||||
|
||||
As mentioned above, currently names must be unique.
|
||||
|
||||
For some resources, the method rename(char * name) changes the name.
|
||||
The method fails if the new name is already used.
|
||||
|
||||
When the instance is invalid to start with
|
||||
(it has an ID that does not refer to any installed data)
|
||||
renaming it can succeed and then it creates a valid instance.
|
||||
|
||||
### Duplicating
|
||||
|
||||
Duplicating a resource creates and installs the underlying data,
|
||||
under a new, generated name.
|
||||
|
||||
The duplicate() method on an instance returns a new instance.
|
||||
|
||||
### Deleting
|
||||
|
||||
You can delete some resources. This uninstalls them.
|
||||
You can delete some brushes, palettes, and gradients,
|
||||
when they are writeable i.e. editable,
|
||||
which usually means that a user previously created them.
|
||||
You can't delete fonts and patterns.
|
||||
|
||||
You can delete using the delete() instance method
|
||||
|
||||
When you delete a resource, the instance (the proxy in a variable) continues to exist, but is invalid.
|
||||
|
||||
### Resource lists
|
||||
|
||||
Some functions in PIKA return lists of resource names,
|
||||
representing the set of resources installed.
|
||||
|
||||
For example: pika_brushes_get_list.
|
||||
|
||||
This returns a list of strings, the ID's of the resources.
|
||||
The list will have no duplicates.
|
||||
|
||||
FUTURE: this will return a list of resource instances, and their names may have duplicates.
|
15
devel-docs/PIKA3-plug-in-porting-guide/README.md
Normal file
15
devel-docs/PIKA3-plug-in-porting-guide/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
Here you'll find documentation useful for porting older PIKA
|
||||
plug-ins, especially Python ones, to the PIKA 3.0 APIs.
|
||||
|
||||
Files:
|
||||
|
||||
- [classes.md:](classes.md)
|
||||
A list of some of the important classes and modules in PIKA 3.0.
|
||||
|
||||
- [pdb-calls.md:](pdb-calls.md)
|
||||
An incomplete list of old PDB functions and their equivalents,
|
||||
using Python classes.
|
||||
|
||||
- [removed_functions.md:](removed_functions.md)
|
||||
Functions that have been removed from PIKA, and their replacements.
|
||||
|
100
devel-docs/PIKA3-plug-in-porting-guide/classes.md
Normal file
100
devel-docs/PIKA3-plug-in-porting-guide/classes.md
Normal file
@ -0,0 +1,100 @@
|
||||
# Useful Modules/Classes in PIKA 3.0+
|
||||
|
||||
Here's a guide to the modules you're likely to need.
|
||||
It's a work in progress: feel free to add to it.
|
||||
|
||||
Eventually we'll have online documentation for these classes.
|
||||
In the meantime, you can generate your own:
|
||||
```
|
||||
HTMLDOCDIR=/path/to/doc/dir
|
||||
g-ir-doc-tool -I /path/to/share/gir-1.0/ --language=Python -o $HTMLDOCDIR Gimp-3.0.gir
|
||||
```
|
||||
Then browse $HTMLDOCDIR with yelp, or generate HTML from it:
|
||||
```
|
||||
cd $HTMLDOCDIR
|
||||
yelp-build cache *.page
|
||||
yelp-build html .
|
||||
|
||||
```
|
||||
|
||||
You can also get some information in PIKA's Python console with
|
||||
*help(module)* or *help(object)*, and you can get a list of functions
|
||||
with *dir(object)*.
|
||||
|
||||
## Gimp
|
||||
|
||||
The base module: almost everything is under Pika.
|
||||
|
||||
## Pika.Image
|
||||
|
||||
The image object.
|
||||
|
||||
Some operations that used to be PDB calls, like
|
||||
```
|
||||
pdb.pika_selection_layer_alpha(layer)
|
||||
```
|
||||
are now in the Image object, e.g.
|
||||
```
|
||||
img.select_item(Pika.ChannelOps.REPLACE, layer)
|
||||
```
|
||||
|
||||
## Pika.Layer
|
||||
|
||||
The layer object.
|
||||
|
||||
```
|
||||
fog = Pika.Layer.new(image, name,
|
||||
drawable.width(), drawable.height(), type, opacity,
|
||||
Pika.LayerMode.NORMAL)
|
||||
```
|
||||
|
||||
## Pika.Selection
|
||||
|
||||
Selection operations that used to be in the PDB, e.g.
|
||||
```
|
||||
pdb.pika_selection_none(img)
|
||||
```
|
||||
are now in the Pika.Selection module, e.g.
|
||||
```
|
||||
Pika.Selection.none(img)
|
||||
```
|
||||
|
||||
## Pika.ImageType
|
||||
|
||||
A home for image types like RGBA, GRAY, etc:
|
||||
```
|
||||
Pika.ImageType.RGBA_IMAGE
|
||||
```
|
||||
|
||||
## Pika.FillType
|
||||
|
||||
e.g. Pika.FillType.TRANSPARENT, Pika.FillType.BACKGROUND
|
||||
|
||||
## Pika.ChannelOps
|
||||
|
||||
The old channel op definitions in the pikafu module, like
|
||||
```
|
||||
CHANNEL_OP_REPLACE
|
||||
```
|
||||
are now in their own module:
|
||||
|
||||
```
|
||||
Pika.ChannelOps.REPLACE
|
||||
```
|
||||
|
||||
## Pika.RGB
|
||||
|
||||
In legacy plug-ins you could pass a simple list of integers, like (0, 0, 0).
|
||||
In 3.0+, create a Pika.RGB object:
|
||||
|
||||
```
|
||||
c = Pika.RGB()
|
||||
c.set(240.0, 180.0, 70.0)
|
||||
```
|
||||
or
|
||||
```
|
||||
c.r = 0
|
||||
c.g = 0
|
||||
c.b = 0
|
||||
c.a = 1
|
||||
```
|
76
devel-docs/PIKA3-plug-in-porting-guide/pdb-calls.md
Normal file
76
devel-docs/PIKA3-plug-in-porting-guide/pdb-calls.md
Normal file
@ -0,0 +1,76 @@
|
||||
# PDB equivalence
|
||||
|
||||
A table of old PDB calls, and their equivalents in the PIKA 3.0+ world.
|
||||
|
||||
This document is a work in progress. Feel free to add to it.
|
||||
|
||||
## Undo/Context
|
||||
|
||||
| Removed function | Replacement |
|
||||
| -------------------------------- | ----------------------------
|
||||
| pika_undo_push_group_start | image.undo_group_start() |
|
||||
| pika_undo_push_group_end | image.undo_group_end() |
|
||||
| pika.context_push() | Pika.context_push() |
|
||||
| pika.context_push() | Pika.context_push() |
|
||||
| pika_context_get_background | Pika.context_get_background
|
||||
| pika_context_set_background | Pika.context_set_background
|
||||
|
||||
## File load/save
|
||||
|
||||
| Removed function | Replacement |
|
||||
| -------------------------------- | ----------------------------
|
||||
| pika_file_load | Pika.file_load |
|
||||
| pika_file_save | Pika.file_save |
|
||||
|
||||
## Selection operations
|
||||
|
||||
Selection operations are now in the Pika.Selection class (except
|
||||
a few in the Image class). E.g.
|
||||
|
||||
| Removed function | Replacement |
|
||||
| -------------------------------- | ----------------------------
|
||||
| pdb.pika_selection_invert(img) | Pika.Selection.invert(img) |
|
||||
| pdb.pika_selection_none(img) | Pika.Selection.none(img) |
|
||||
| pdb.pika_selection_layer_alpha(layer) | img.select_item(Pika.ChannelOps.REPLACE, layer) |
|
||||
| pika_image_select_item | img.select_item(channel_op, layer) |
|
||||
|
||||
## Filling and Masks
|
||||
|
||||
| Removed function | Replacement |
|
||||
| -------------------------------- | ----------------------------
|
||||
| Pika.drawable_fill() | layer.fill() |
|
||||
| pdb.pika_edit_fill(FILL_BACKGROUND) | layer.edit_fill(Pika.FillType.BACKGROUND) |
|
||||
| pika_layer_add_mask | layer.add_mask
|
||||
| pika_layer_remove_mask | layer.remove_mask
|
||||
|
||||
## Miscellaneous and Non-PDB Calls
|
||||
|
||||
| Removed function | Replacement |
|
||||
| -------------------------------- | ----------------------------
|
||||
| pika_displays_flush | Pika.displays_flush
|
||||
| pika_image_insert_layer | image.insert_layer
|
||||
|
||||
|
||||
## Plug-ins
|
||||
|
||||
Calling other plug-ins is trickier than before. The old
|
||||
```
|
||||
pdb.script_fu_drop_shadow(img, layer, -3, -3, blur,
|
||||
(0, 0, 0), 80.0, False)
|
||||
```
|
||||
becomes
|
||||
```
|
||||
c = Pika.RGB()
|
||||
c.set(240.0, 180.0, 70.0)
|
||||
Pika.get_pdb().run_procedure('script-fu-drop-shadow',
|
||||
[ Pika.RunMode.NONINTERACTIVE,
|
||||
GObject.Value(Pika.Image, img),
|
||||
GObject.Value(Pika.Drawable, layer),
|
||||
GObject.Value(GObject.TYPE_DOUBLE, -3),
|
||||
GObject.Value(GObject.TYPE_DOUBLE, -3),
|
||||
GObject.Value(GObject.TYPE_DOUBLE,blur),
|
||||
c,
|
||||
GObject.Value(GObject.TYPE_DOUBLE, 80.0),
|
||||
GObject.Value(GObject.TYPE_BOOLEAN, False)
|
||||
])
|
||||
```
|
@ -0,0 +1,175 @@
|
||||
|
||||
|
||||
## About this document
|
||||
|
||||
This describes *some* changes needed to port a Scriptfu script to PIKA 3:
|
||||
- changes in types
|
||||
- changes in PDB signatures for multi-layer support
|
||||
- changes in error messages
|
||||
- changes in logging
|
||||
|
||||
It does *not* document:
|
||||
- PDB procedures whose names have changed (see pdb-calls.md)
|
||||
- PDB procedures that have been removed (see removed_functions.md)
|
||||
- PDB procedures that have been added
|
||||
- other changes in signature where arguments are reordered or changed in number
|
||||
|
||||
## Changes in types of PDB signatures
|
||||
|
||||
Calls from a script to PIKA are calls to PDB procedures.
|
||||
PDB procedures are documented in terms of C and GLib types.
|
||||
|
||||
This table summarizes the changes:
|
||||
|
||||
| Purpose | Old C type | New C type | Old Scheme type | New Scheme type |
|
||||
| ---------------|-----------------------|-----------------------| ----------------|-----------------------|
|
||||
| Pass file name | gchar*, gchar* | GFile | string string | string |
|
||||
| Recv file name | gchar* | GFile | string | string |
|
||||
| pass drawable | PikaDrawable | gint, PikaObjectArray | int (an ID) | int (a length) vector |
|
||||
| Pass obj array | gint, PikaInt32Array | gint, PikaObjectArray | int vector | int vector |
|
||||
| Recv obj array | gint, PikaInt32Array | gint, PikaObjectArray | int vector | int vector |
|
||||
| Pass set of str | gint, PikaStringArray | GStrv | int list | list |
|
||||
| Recv set of str | gint, PikaStringArray | GStrv | int list | list |
|
||||
|
||||
(Where "obj" means an object of a PIKA type such as PikaDrawable or similar.)
|
||||
|
||||
### Use one string for a filename instead of two.
|
||||
|
||||
Formerly a PDB procedure taking a filename (usually a full path) required two strings (two gchar* .)
|
||||
Now such PDB procedures require a GFile.
|
||||
|
||||
In Scheme, where formerly you passed two strings, now pass one string.
|
||||
|
||||
Formerly a script passed the second string for a URI, to specify a remote file.
|
||||
Formerly, in most cases you passed an empty second string.
|
||||
Now, the single string in a script can be either a local file path or a remote URI.
|
||||
|
||||
Example:
|
||||
|
||||
(pika-file-load RUN-NONINTERACTIVE "/tmp/foo" "")
|
||||
=> (pika-file-load RUN-NONINTERACTIVE "/tmp/foo")
|
||||
|
||||
|
||||
### PDB procedures still return a string for a filename
|
||||
|
||||
All PDB procedures returning a filename return a single string to Scheme scripts.
|
||||
That is unchanged.
|
||||
|
||||
Formerly a PDB signature for a procedure returning a filename
|
||||
specifies a returned type gchar*, but now specifies a returned type GFile.
|
||||
But a Scheme script continues to receive a string.
|
||||
|
||||
The returned string is either a local file path or a URI.
|
||||
|
||||
|
||||
### Use a vector of drawables for PDB procedures that now take an array of drawables
|
||||
|
||||
Formerly, some PDB procedures took a single PikaDrawable,
|
||||
but now they take an array of PikaDrawable ( type PikaObjectArray.)
|
||||
(Formerly, no PDB procedure took an array of drawables.
|
||||
Some that formerly took a single drawable still take a single drawable.
|
||||
See the list below. )
|
||||
|
||||
For such PDB procedures, in Scheme pass a numeric length and a vector of numeric drawable ID's.
|
||||
|
||||
These changes support a user selecting multiple layers for an operation.
|
||||
|
||||
Example:
|
||||
|
||||
(pika-edit-copy drawable) => (pika-edit-copy 1 (vector drawable))
|
||||
|
||||
(pika-edit-copy 2) => (pika-edit-copy 1 '#(2))
|
||||
|
||||
### The PDB procedures which formerly took single Drawable and now take PikaObjectArray
|
||||
|
||||
- Many of the file load/save procedures.
|
||||
- pika-color-picker
|
||||
- pika-edit-copy
|
||||
- pika-edit-cut
|
||||
- pika-edit-named-copy
|
||||
- pika-edit-named-cut
|
||||
- pika-file-save
|
||||
- pika-image-pick-color
|
||||
- pika-selection-float
|
||||
- pika-xcf-save
|
||||
|
||||
|
||||
### Receiving an array of drawables
|
||||
|
||||
Formerly a PDB procedure returning an array of drawables (or other PIKA objects)
|
||||
had a signature specifying a returned gint and PikaInt32Array.
|
||||
Now the signature specifies a returned gint and PikaObjectArray.
|
||||
A script receives an int and a vector.
|
||||
The elements of the vector are numeric ID's,
|
||||
but are opaque to scripts
|
||||
(a script can pass them around, but should not for example use arithmetic on them.)
|
||||
|
||||
No changes are needed to a script.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
(pika-image-get-layers image)
|
||||
|
||||
Will return a list whose first element is a length,
|
||||
and whose second element is a vector of drawables (Scheme numerics for drawable ID's)
|
||||
|
||||
In the ScriptFu console,
|
||||
|
||||
(pika-image-get-layers (car (pika-image-new 10 30 1)))
|
||||
|
||||
would print:
|
||||
|
||||
(0 #())
|
||||
|
||||
Meaning a list length of zero, and an empty vector.
|
||||
(Since a new image has no layers.)
|
||||
|
||||
### Passing or receiving a set of strings
|
||||
|
||||
Formerly, you passed an integer count of strings, and a list of strings.
|
||||
Now you only pass the list.
|
||||
ScriptFu converts to/from the C type GStrv
|
||||
(which is an object knowing its own length.)
|
||||
An example is the PDB procedure file-gih-save.
|
||||
|
||||
Formerly, you received an integer count of strings, and a list of strings.
|
||||
Now you only receive the list
|
||||
(and subsequently get its length using "(length list)").
|
||||
Examples are the many PDB procedures whose name ends in "-list".
|
||||
Remember that the result of a call to the PDB is a list of values,
|
||||
in this case the result is a list containing a list,
|
||||
and for example you get the list of strings like "(car (pika-fonts-get-list ".*"))"
|
||||
|
||||
## Changes in error messages
|
||||
|
||||
ScriptFu is now more forgiving.
|
||||
|
||||
Formerly, ScriptFu would not accept a call construct where the argument count was wrong,
|
||||
except for the case when you provided one argument to a PDB procedure
|
||||
that took zero arguments (sometimes called a nullary function.)
|
||||
|
||||
Now, when a script has the wrong count of arguments to a PDB procedure:
|
||||
|
||||
- too many actual arguments: ScriptFu will give a warning to the console
|
||||
and call the PDB procedure with a prefix of the actual arguments.
|
||||
This is now true no matter how many arguments the PDB procedure takes.
|
||||
Extra arguments in the script are ignored by Scriptfu,
|
||||
not evaluated and not passed to the PDB.
|
||||
|
||||
- too few actual arguments: ScriptFu will give a warning to the console
|
||||
and call the PDB procedure with the given actual arguments.
|
||||
The warning will say the expected Scheme formal type of the first missing actual argument.
|
||||
Usually the PDB procedure will fail and return its own error message.
|
||||
|
||||
When you suspect errors in a script,
|
||||
it is now important to run PIKA from a console to see warnings.
|
||||
|
||||
|
||||
## ScriptFu logging
|
||||
|
||||
ScriptFu now does some logging using GLib logging.
|
||||
When you define in the environment "G_MESSAGES_DEBUG=scriptfu"
|
||||
ScriptFu will print many messages to the console.
|
||||
|
||||
This is mostly useful for PIKA developers.
|
222
devel-docs/PIKA3-plug-in-porting-guide/removed_functions.md
Normal file
222
devel-docs/PIKA3-plug-in-porting-guide/removed_functions.md
Normal file
@ -0,0 +1,222 @@
|
||||
## Removed Functions
|
||||
|
||||
These functions have been removed from PIKA 3. Most of them were deprecated
|
||||
since PIKA 2.10.x or older versions. As we bump the major version, it is time
|
||||
to start with a clean slate.
|
||||
|
||||
Below is a correspondence table with replacement function. The replacement is
|
||||
not necessarily a direct search-and-replace equivalent. Some may have different
|
||||
parameters, and in some case, it may require to think a bit about how things
|
||||
work to reproduce the same functionality. Nevertheless everything which was
|
||||
possible in the previous API is obviously still possible.
|
||||
|
||||
| Removed function | Replacement |
|
||||
| ----------------------------------------------- | ------------------------------------------------- |
|
||||
| `pika_attach_new_parasite()` | `pika_attach_parasite()` |
|
||||
| `pika_brightness_contrast()` | `pika_drawable_brightness_contrast()` |
|
||||
| `pika_brushes_get_brush()` | `pika_context_get_brush()` |
|
||||
| `pika_brushes_get_brush_data()` | `pika_brush_get_pixels()` |
|
||||
| `pika_brushes_get_spacing()` | `pika_brush_get_spacing()` |
|
||||
| `pika_brushes_set_spacing()` | `pika_brush_set_spacing()` |
|
||||
| `pika_by_color_select()` | `pika_image_select_color()` |
|
||||
| `pika_by_color_select_full()` | `pika_image_select_color()` |
|
||||
| `pika_channel_menu_new()` | `pika_channel_combo_box_new()` |
|
||||
| `pika_checks_get_shades()` | `pika_checks_get_colors()` |
|
||||
| `pika_color_balance()` | `pika_drawable_color_color_balance()` |
|
||||
| `pika_color_display_convert()` | `pika_color_display_convert_buffer()` |
|
||||
| `pika_color_display_convert_surface()` | `pika_color_display_convert_buffer()` |
|
||||
| `pika_color_display_stack_convert()` | `pika_color_display_stack_convert_buffer()` |
|
||||
| `pika_color_display_stack_convert_surface()` | `pika_color_display_stack_convert_buffer()` |
|
||||
| `pika_color_profile_combo_box_add()` | `pika_color_profile_combo_box_add_file()` |
|
||||
| `pika_color_profile_combo_box_get_active()` | `pika_color_profile_combo_box_get_active_file()` |
|
||||
| `pika_color_profile_combo_box_set_active()` | `pika_color_profile_combo_box_set_active_file()` |
|
||||
| `pika_color_profile_store_add()` | `pika_color_profile_store_add_file()` |
|
||||
| `pika_colorize()` | `pika_drawable_colorize_hsl()` |
|
||||
| `pika_context_get_transform_recursion()` | *N/A* |
|
||||
| `pika_context_set_transform_recursion()` | *N/A* |
|
||||
| `pika_curves_explicit()` | `pika_drawable_curves_explicit()` |
|
||||
| `pika_curves_spline()` | `pika_drawable_curves_spline()` |
|
||||
| `pika_desaturate()` | `pika_drawable_desaturate()` |
|
||||
| `pika_desaturate_full()` | `pika_drawable_desaturate()` |
|
||||
| `pika_drawable_attach_new_parasite()` | `pika_item_attach_parasite()` |
|
||||
| `pika_drawable_bpp()` | `pika_drawable_get_bpp()` |
|
||||
| `pika_drawable_delete()` | `pika_item_delete()` |
|
||||
| `pika_drawable_get_image()` | `pika_item_get_image()` |
|
||||
| `pika_drawable_get_linked()` | *N/A* |
|
||||
| `pika_drawable_get_name()` | `pika_item_get_name()` |
|
||||
| `pika_drawable_get_tattoo()` | `pika_item_get_tattoo()` |
|
||||
| `pika_drawable_get_visible()` | `pika_item_get_visible()` |
|
||||
| `pika_drawable_height()` | `pika_drawable_get_height()` |
|
||||
| `pika_drawable_is_channel()` | `pika_item_is_channel()` |
|
||||
| `pika_drawable_is_layer()` | `pika_item_is_layer()` |
|
||||
| `pika_drawable_is_layer_mask()` | `pika_item_is_layer_mask()` |
|
||||
| `pika_drawable_is_text_layer()` | `pika_item_is_text_layer()` |
|
||||
| `pika_drawable_is_valid()` | `pika_item_is_valid()` |
|
||||
| `pika_drawable_menu_new()` | `pika_drawable_combo_box_new()` |
|
||||
| `pika_drawable_offsets()` | `pika_drawable_get_offsets()` |
|
||||
| `pika_drawable_parasite_attach()` | `pika_item_attach_parasite()` |
|
||||
| `pika_drawable_parasite_detach()` | `pika_item_detach_parasite()` |
|
||||
| `pika_drawable_parasite_find()` | `pika_item_get_parasite()` |
|
||||
| `pika_drawable_parasite_list()` | `pika_item_get_parasite_list()` |
|
||||
| `pika_drawable_preview_new()` | `pika_drawable_preview_new_from_drawable()` |
|
||||
| `pika_drawable_preview_new_from_drawable_id()` | `pika_drawable_preview_new_from_drawable()` |
|
||||
| `pika_drawable_set_image()` | *N/A* |
|
||||
| `pika_drawable_set_linked()` | *N/A* |
|
||||
| `pika_drawable_set_name()` | `pika_item_set_name()` |
|
||||
| `pika_drawable_set_tattoo()` | `pika_item_set_tattoo()` |
|
||||
| `pika_drawable_set_visible()` | `pika_item_set_visible()` |
|
||||
| `pika_drawable_transform_2d()` | `pika_item_transform_2d()` |
|
||||
| `pika_drawable_transform_2d_default()` | `pika_item_transform_2d()` |
|
||||
| `pika_drawable_transform_flip()` | `pika_item_transform_flip()` |
|
||||
| `pika_drawable_transform_flip_default()` | `pika_item_transform_flip()` |
|
||||
| `pika_drawable_transform_flip_simple()` | `pika_item_transform_flip_simple()` |
|
||||
| `pika_drawable_transform_matrix()` | `pika_item_transform_matrix()` |
|
||||
| `pika_drawable_transform_matrix_default()` | `pika_item_transform_matrix()` |
|
||||
| `pika_drawable_transform_perspective()` | `pika_item_transform_perspective()` |
|
||||
| `pika_drawable_transform_perspective_default()` | `pika_item_transform_perspective()` |
|
||||
| `pika_drawable_transform_rotate()` | `pika_item_transform_rotate()` |
|
||||
| `pika_drawable_transform_rotate_default()` | `pika_item_transform_rotate()` |
|
||||
| `pika_drawable_transform_rotate_simple()` | `pika_item_transform_rotate_simple()` |
|
||||
| `pika_drawable_transform_scale()` | `pika_item_transform_scale()` |
|
||||
| `pika_drawable_transform_scale_default()` | `pika_item_transform_scale()` |
|
||||
| `pika_drawable_transform_shear()` | `pika_item_transform_shear()` |
|
||||
| `pika_drawable_transform_shear_default()` | `pika_item_transform_shear()` |
|
||||
| `pika_drawable_width()` | `pika_drawable_get_width()` |
|
||||
| `pika_edit_blend()` | `pika_drawable_edit_gradient_fill()` |
|
||||
| `pika_edit_bucket_fill()` | `pika_drawable_edit_bucket_fill()` |
|
||||
| `pika_edit_bucket_fill_full()` | `pika_drawable_edit_bucket_fill()` |
|
||||
| `pika_edit_clear()` | `pika_drawable_edit_clear()` |
|
||||
| `pika_edit_fill()` | `pika_drawable_edit_fill()` |
|
||||
| `pika_edit_paste_as_new()` | `pika_edit_paste_as_new_image()` |
|
||||
| `pika_edit_named_paste_as_new()` | `pika_edit_named_paste_as_new_image()` |
|
||||
| `pika_edit_stroke()` | `pika_drawable_edit_stroke_selection()` |
|
||||
| `pika_edit_stroke_vectors()` | `pika_drawable_edit_stroke_item()` |
|
||||
| `pika_ellipse_select()` | `pika_image_select_ellipse()` |
|
||||
| `pika_enum_combo_box_set_stock_prefix()` | `pika_enum_combo_box_set_icon_prefix()` |
|
||||
| `pika_enum_stock_box_new()` | `pika_enum_icon_box_new()` |
|
||||
| `pika_enum_stock_box_new_with_range()` | `pika_enum_icon_box_new_with_range()` |
|
||||
| `pika_enum_stock_box_set_child_padding()` | `pika_enum_icon_box_set_child_padding()` |
|
||||
| `pika_enum_store_set_stock_prefix()` | `pika_enum_store_set_icon_prefix()` |
|
||||
| `pika_equalize()` | `pika_drawable_equalize()` |
|
||||
| `pika_flip()` | `pika_item_transform_flip_simple()` |
|
||||
| `pika_floating_sel_relax()` | *N/A* |
|
||||
| `pika_floating_sel_rigor()` | *N/A* |
|
||||
| `pika_free_select()` | `pika_image_select_polygon()` |
|
||||
| `pika_fuzzy_select()` | `pika_image_select_contiguous_color()` |
|
||||
| `pika_fuzzy_select_full()` | `pika_image_select_contiguous_color()` |
|
||||
| `pika_gamma()` | `pika_drawable_get_format()` |
|
||||
| `pika_get_icon_theme_dir()` | *N/A* |
|
||||
| `pika_get_path_by_tattoo()` | `pika_image_get_vectors_by_tattoo()` |
|
||||
| `pika_get_theme_dir()` | *N/A* |
|
||||
| `pika_gradients_get_gradient_data()` | `pika_gradient_get_uniform_samples()` |
|
||||
| `pika_gradients_sample_custom()` | `pika_gradient_get_custom_samples()` |
|
||||
| `pika_gradients_sample_uniform()` | `pika_gradient_get_uniform_samples()` |
|
||||
| `pika_histogram()` | `pika_drawable_histogram()` |
|
||||
| `pika_hue_saturation()` | `pika_drawable_hue_saturation()` |
|
||||
| `pika_image_add_channel()` | `pika_image_insert_channel()` |
|
||||
| `pika_image_add_layer()` | `pika_image_insert_layer()` |
|
||||
| `pika_image_add_vectors()` | `pika_image_insert_vectors()` |
|
||||
| `pika_image_attach_new_parasite()` | `pika_image_attach_parasite()` |
|
||||
| `pika_image_base_type()` | `pika_image_get_base_type()` |
|
||||
| `pika_image_free_shadow()` | `pika_drawable_free_shadow()` |
|
||||
| `pika_image_get_channel_position()` | `pika_image_get_item_position()` |
|
||||
| `pika_image_get_cmap()` | `pika_image_get_colormap()` |
|
||||
| `pika_image_get_layer_position()` | `pika_image_get_item_position()` |
|
||||
| `pika_image_get_vectors_position()` | `pika_image_get_item_position()` |
|
||||
| `pika_image_height()` | `pika_image_get_height()` |
|
||||
| `pika_image_lower_channel()` | `pika_image_lower_item()` |
|
||||
| `pika_image_lower_layer()` | `pika_image_lower_item()` |
|
||||
| `pika_image_lower_layer_to_bottom()` | `pika_image_lower_item_to_bottom()` |
|
||||
| `pika_image_lower_vectors()` | `pika_image_lower_item()` |
|
||||
| `pika_image_lower_vectors_to_bottom()` | `pika_image_lower_item_to_bottom()` |
|
||||
| `pika_image_menu_new()` | `pika_image_combo_box_new()` |
|
||||
| `pika_image_parasite_attach()` | `pika_image_attach_parasite()` |
|
||||
| `pika_image_parasite_detach()` | `pika_image_detach_parasite()` |
|
||||
| `pika_image_parasite_find()` | `pika_image_get_parasite()` |
|
||||
| `pika_image_parasite_list()` | `pika_image_get_parasite_list()` |
|
||||
| `pika_image_raise_channel()` | `pika_image_raise_item()` |
|
||||
| `pika_image_raise_layer()` | `pika_image_raise_item()` |
|
||||
| `pika_image_raise_layer_to_top()` | `pika_image_raise_item_to_top()` |
|
||||
| `pika_image_raise_vectors()` | `pika_image_raise_item()` |
|
||||
| `pika_image_raise_vectors_to_top()` | `pika_image_raise_item_to_top()` |
|
||||
| `pika_image_scale_full()` | `pika_image_scale()` |
|
||||
| `pika_image_set_cmap()` | `pika_image_set_colormap()` |
|
||||
| `pika_image_width()` | `pika_image_get_width()` |
|
||||
| `pika_install_cmap()` | *N/A* |
|
||||
| `pika_invert()` | `pika_drawable_invert()` |
|
||||
| `pika_item_get_linked()` | *N/A* |
|
||||
| `pika_item_set_linked()` | *N/A* |
|
||||
| `pika_layer_menu_new()` | `pika_layer_combo_box_new()` |
|
||||
| `pika_layer_scale_full()` | `pika_layer_scale()` |
|
||||
| `pika_layer_translate()` | `pika_item_transform_translate()` |
|
||||
| `pika_levels()` | `pika_drawable_levels()` |
|
||||
| `pika_levels_auto()` | `pika_drawable_levels_stretch()` |
|
||||
| `pika_levels_stretch()` | `pika_drawable_levels_stretch()` |
|
||||
| `pika_min_colors()` | *N/A* |
|
||||
| `pika_palettes_get_palette()` | `pika_context_get_palette()` |
|
||||
| `pika_palettes_get_palette_entry()` | `pika_palette_entry_get_color()` |
|
||||
| `pika_parasite_attach()` | `pika_attach_parasite()` |
|
||||
| `pika_parasite_data()` | `pika_parasite_get_data()` |
|
||||
| `pika_parasite_data_size()` | `pika_parasite_get_data()` |
|
||||
| `pika_parasite_detach()` | `pika_detach_parasite()` |
|
||||
| `pika_parasite_find()` | `pika_get_parasite()` |
|
||||
| `pika_parasite_flags()` | `pika_parasite_get_flags()` |
|
||||
| `pika_parasite_list()` | `pika_get_parasite_list()` |
|
||||
| `pika_parasite_name()` | `pika_parasite_get_name()` |
|
||||
| `pika_path_delete()` | `pika_image_remove_vectors()` |
|
||||
| `pika_path_get_current()` | `pika_image_get_active_vectors()` |
|
||||
| `pika_path_get_locked()` | *N/A* |
|
||||
| `pika_path_get_points()` | `pika_vectors_stroke_get_points()` |
|
||||
| `pika_path_get_point_at_dist()` | `pika_vectors_stroke_get_point_at_dist()` |
|
||||
| `pika_path_get_tattoo()` | `pika_item_get_tattoo()` |
|
||||
| `pika_path_import()` | `pika_vectors_import_from_file()` |
|
||||
| `pika_path_list()` | `pika_image_get_vectors()` |
|
||||
| `pika_path_set_current()` | `pika_image_set_active_vectors()` |
|
||||
| `pika_path_set_locked()` | *N/A* |
|
||||
| `pika_path_set_points()` | `pika_vectors_stroke_new_from_points()` |
|
||||
| `pika_path_set_tattoo()` | `pika_item_set_tattoo()` |
|
||||
| `pika_path_stroke_current()` | `pika_edit_stroke_vectors()` |
|
||||
| `pika_path_to_selection()` | `pika_image_select_item()` |
|
||||
| `pika_patterns_get_pattern()` | `pika_context_get_pattern()` |
|
||||
| `pika_patterns_get_pattern_data()` | `pika_pattern_get_pixels()` |
|
||||
| `pika_perspective()` | `pika_item_transform_perspective()` |
|
||||
| `pika_posterize()` | `pika_drawable_posterize()` |
|
||||
| `pika_prop_enum_stock_box_new()` | `pika_prop_enum_icon_box_new()` |
|
||||
| `pika_prop_stock_image_new()` | `pika_prop_icon_image_new()` |
|
||||
| `pika_prop_unit_menu_new()` | `pika_prop_unit_combo_box_new()` |
|
||||
| `pika_rect_select()` | `pika_image_select_rectangle()` |
|
||||
| `pika_rotate()` | `pika_item_transform_rotate()` |
|
||||
| `pika_round_rect_select()` | `pika_image_select_round_rectangle()` |
|
||||
| `pika_scale()` | `pika_item_transform_scale()` |
|
||||
| `pika_selection_combine()` | `pika_image_select_item()` |
|
||||
| `pika_selection_layer_alpha()` | `pika_image_select_item()` |
|
||||
| `pika_selection_load()` | `pika_image_select_item()` |
|
||||
| `pika_shear()` | `pika_item_transform_shear()` |
|
||||
| `pika_stock_init()` | `pika_icons_init()` |
|
||||
| `pika_text()` | `pika_text_fontname()` |
|
||||
| `pika_text_get_extents()` | `pika_text_get_extents_fontname()` |
|
||||
| `pika_text_layer_get_hinting()` | `pika_text_layer_get_hint_style()` |
|
||||
| `pika_text_layer_set_hinting()` | `pika_text_layer_set_hint_style()` |
|
||||
| `pika_threshold()` | `pika_drawable_threshold()` |
|
||||
| `pika_toggle_button_sensitive_update()` | `g_object_bind_property()` |
|
||||
| `pika_transform_2d()` | `pika_item_transform_2d()` |
|
||||
| `pika_unit_menu_update()` | `#PikaUnitComboBox` |
|
||||
| `pika_vectors_get_image()` | `pika_item_get_image()` |
|
||||
| `pika_vectors_get_linked()` | *N/A* |
|
||||
| `pika_vectors_get_name()` | `pika_item_get_name()` |
|
||||
| `pika_vectors_get_tattoo()` | `pika_item_get_tattoo()` |
|
||||
| `pika_vectors_get_visible()` | `pika_item_get_visible()` |
|
||||
| `pika_vectors_is_valid()` | `pika_item_is_valid()` |
|
||||
| `pika_vectors_parasite_attach()` | `pika_item_attach_parasite()` |
|
||||
| `pika_vectors_parasite_detach()` | `pika_item_detach_parasite()` |
|
||||
| `pika_vectors_parasite_find()` | `pika_item_get_parasite()` |
|
||||
| `pika_vectors_parasite_list()` | `pika_item_get_parasite_list()` |
|
||||
| `pika_vectors_set_linked()` | *N/A* |
|
||||
| `pika_vectors_set_name()` | `pika_item_set_name()` |
|
||||
| `pika_vectors_set_tattoo()` | `pika_item_set_tattoo()` |
|
||||
| `pika_vectors_set_visible()` | `pika_item_set_visible()` |
|
||||
| `pika_vectors_to_selection()` | `pika_image_select_item()` |
|
||||
| `pika_zoom_preview_get_drawable_id()` | `pika_zoom_preview_get_drawable()` |
|
||||
| `pika_zoom_preview_new()` | `pika_zoom_preview_new_from_drawable()` |
|
||||
| `pika_zoom_preview_new_from_drawable_id()` | `pika_zoom_preview_new_from_drawable()` |
|
||||
| `pika_zoom_preview_new_with_model()` | `pika_zoom_preview_new_with_model_from_drawable()`|
|
451
devel-docs/PIKA3-plug-in-porting-guide/script-fu-author-guide.md
Normal file
451
devel-docs/PIKA3-plug-in-porting-guide/script-fu-author-guide.md
Normal file
@ -0,0 +1,451 @@
|
||||
# Guide to changes to ScriptFu v3 for script authors
|
||||
|
||||
*Draft, until PIKA 3 is final. FIXME: rearrange and rename the cited documents*
|
||||
|
||||
## About
|
||||
|
||||
The audience is authors of Scriptfu plugins.
|
||||
This discusses how to edit v2 scripts so they will run in PIKA 3.
|
||||
|
||||
This is only about changes to ScriptFu proper.
|
||||
The PIKA PDB, which you can call in scripts, has also changed.
|
||||
That also may require you to edit scripts.
|
||||
|
||||
- For changes in signatures of PDB procedures,
|
||||
see devel-docs/PIKA3-plug-in-porting-guide/porting_scriptfu_scripts.md
|
||||
- For added, removed, and replaced PDB procedures,
|
||||
see devel-docs/PIKA3-plug-in-porting-guide/removed_functions.md
|
||||
|
||||
## Quickstart
|
||||
|
||||
A lucky few existing scripts may work in PIKA v3.
|
||||
|
||||
Some changes are most likely to break an existing plugin.:
|
||||
|
||||
- SF-VALUE is obsolete
|
||||
- TRUE and FALSE are obsolete
|
||||
- many PDB procedures are obsolete or renamed, or their signature changed
|
||||
|
||||
Once you edit a script for these changes, the script won't work in PIKA v2.
|
||||
|
||||
Other changes:
|
||||
|
||||
- you can install scripts like plugins in other languages
|
||||
- scripts can use the new mult-layer selection feature of PIKA
|
||||
- a script can abort with an error message
|
||||
- a script's settings are more fully saved
|
||||
|
||||
Those changes might not affect an existing plugin.
|
||||
You need only understand those changes when you want to use new features of PIKA.
|
||||
|
||||
A word of explanation: the PIKA developers understand these changes may be onerous.
|
||||
Script developers might need to maintain two different versions of their scripts.
|
||||
Some users will stick with PIKA 2 for a while and some will switch to PIKA 3.
|
||||
But PIKA 3 is a major version change with new features.
|
||||
A clean break is necessary to move forward with improvements.
|
||||
The situation is similar to the disruption caused by the move from Python 2 to 3.
|
||||
|
||||
|
||||
### SF-VALUE kind of argument is obsolete
|
||||
|
||||
The symbol SF-VALUE is obsolete.
|
||||
You can edit v2 scripts and replace that symbol.
|
||||
|
||||
In v2, SF-VALUE declared a formal argument that is an unquoted, arbitrary string.
|
||||
Usually, SF-VALUE was used for an integer valued argument.
|
||||
In the dialog for a script, ScriptFu showed a text entry widget.
|
||||
Usually the widget showed a default integer literal,
|
||||
but the widget let you enter any text into the string.
|
||||
|
||||
You usually will replace it with an SF-ADJUSTMENT kind of formal argument,
|
||||
where the "digits" field of the SF-ADJUSTMENT is 0,
|
||||
meaning no decimal places, i.e. integer valued.
|
||||
You must also add the other fields, e.g. the lower and upper limits.
|
||||
|
||||
A script that has been edited to replace SF-VALUE with SF-ADJUSTMENT
|
||||
will remain compatible with PIKA 2.
|
||||
|
||||
Example:
|
||||
|
||||
SF-VALUE "Font size (pixels)" "50"
|
||||
=>
|
||||
SF-ADJUSTMENT "Font size (pixels)" '(50 1 1000 1 10 0 SF-SPINNER)
|
||||
|
||||
Here, in the seven-tuple, the 0 denotes: no decimal places.
|
||||
|
||||
Another example, where you formerly
|
||||
used SF-VALUE to declare a formal argument that is float valued:
|
||||
|
||||
SF-VALUE "Lighting (degrees)" "45.0"
|
||||
=>
|
||||
SF-ADJUSTMENT "Lighting (degrees)" '(45.0 0 360 5 10 1 SF-SLIDER)
|
||||
|
||||
Here, the 1 denotes: show 1 decimal place, for example "45.0",
|
||||
in the dialog widget.
|
||||
|
||||
#### Use SF-STRING for some use cases
|
||||
|
||||
In v2, a SF-VALUE argument let a user enter executable Scheme code,
|
||||
say "'(1 g 1)", which is a list literal,
|
||||
to be injected into a Scheme call to a plugin.
|
||||
That use is no longer possible.
|
||||
If you must do that, use SF_STRING to get a string,
|
||||
and then your plugin can eval the string.
|
||||
|
||||
#### Arbitrary precision floats
|
||||
|
||||
In v2, a SF-VALUE argument let a user enter a float with arbitrary precision,
|
||||
e.g. "0.00000001"
|
||||
|
||||
That is no longer possible. You as a script author must use SF-ADJUSTMENT
|
||||
and specify the maximum precision that makes sense. The user won't be able to
|
||||
enter a value with more precision (more digits after the decimal point.)
|
||||
You should understand the math of your algorithm and know what precision
|
||||
is excess in terms of visible results.
|
||||
|
||||
Example:
|
||||
|
||||
SF-ADJUSTMENT "Lighting (degrees)" '(45.0 0 360 5 10 4 SF-SLIDER)
|
||||
|
||||
Here, the user will only be able to enter four decimal places,
|
||||
for example by typing "0.0001" into the widget.
|
||||
|
||||
If you actually need arbitrary precision, use SF_STRING to get a string,
|
||||
and then your plugin can eval the string to get a Scheme numeric
|
||||
of the maximum precision that Scheme supports.
|
||||
|
||||
#### Rationale
|
||||
|
||||
Formerly, a SF-VALUE argument let a user enter garbage for an argument,
|
||||
which caused an error in the script.
|
||||
SF-ADJUSTMENT is more user-friendly.
|
||||
|
||||
### FALSE and TRUE symbols obsolete
|
||||
|
||||
FALSE and TRUE symbols are no longer defined symbols in the ScriptFu language.
|
||||
They never were in the Scheme language.
|
||||
Instead, the Scheme language has symbols #f and #t.
|
||||
|
||||
In ScriptFu v2, FALSE was equivalent to 0
|
||||
and TRUE was equivalent to 1.
|
||||
But FALSE was not equivalent to #f.
|
||||
|
||||
Formerly, you could use the = operator to compare to FALSE and TRUE.
|
||||
The = operator in Scheme is a numeric operator, not a logical operator.
|
||||
Now you can use the eq? or eqv? operators.
|
||||
|
||||
In Scheme, all values are truthy except for #f.
|
||||
The empty list is truthy.
|
||||
The numeric 0 is truthy.
|
||||
Only #f is not truthy.
|
||||
|
||||
A PDB procedure returning a single Boolean (a predicate)
|
||||
returns a list containing one element, for example (#f) or (#t).
|
||||
|
||||
#### Rationale
|
||||
|
||||
The ScriptFu language is simpler and smaller; TRUE and FALSE duplicated concepts already in the Scheme language.
|
||||
|
||||
#### Example changes
|
||||
|
||||
Registering a script:
|
||||
|
||||
SF-TOGGLE "Gradient reverse" FALSE
|
||||
=>
|
||||
SF-TOGGLE "Gradient reverse" #f
|
||||
|
||||
Calling a PDB procedure taking a boolean:
|
||||
|
||||
(pika-context-set-feather TRUE)
|
||||
=>
|
||||
(pika-context-set-feather #t)
|
||||
|
||||
Logically examining a variable for truth:
|
||||
|
||||
(if (= shadow TRUE) ...
|
||||
=>
|
||||
(if shadow ...
|
||||
|
||||
### In scripts, calls to PDB procedures that return boolean yield (#t) or (#f)
|
||||
|
||||
In ScriptFu v2, PDB procedures returning a boolean returned 1 or 0 to a script,
|
||||
that is, numeric values.
|
||||
Those were equal to the old TRUE and FALSE values.
|
||||
|
||||
Remember that a call to the PDB returns a list to the script.
|
||||
So in ScriptFu v3,
|
||||
a PDB procedure that returns a single boolean (a predicate function)
|
||||
returns (#t) or (#f), a list containing one boolean element.
|
||||
|
||||
#### Rationale
|
||||
|
||||
#t and #f are more precise representations of boolean values.
|
||||
0 and 1 are binary, but not strictly boolean.
|
||||
|
||||
The ScriptFu language is smaller if concepts of truth are not duplicated.
|
||||
|
||||
#### Example changes
|
||||
|
||||
Calling a PDB procedure that is a predicate function:
|
||||
|
||||
(if (= FALSE (car (pika-selection-is-empty theImage))) ...
|
||||
=>
|
||||
(if (car (pika-selection-is-empty theImage)) ...
|
||||
|
||||
Here, the call to the PDB returns a list of one element.
|
||||
The "car" function returns that element.
|
||||
The "if" function evaluates that element for truthy.
|
||||
|
||||
Note that to evaluate the result of a PDB call for truth,
|
||||
you should just use as above, and not use "eq?" or "eqv?".
|
||||
Such a result is always a list, and a list is truthy,
|
||||
but not equivalent to #t.
|
||||
In the ScriptFu console:
|
||||
|
||||
>(eq? #t '())
|
||||
#f
|
||||
>(eqv? #t '())
|
||||
#f
|
||||
|
||||
### Use script-fu-script-abort to throw an error
|
||||
|
||||
The function "script-fu-script-abort" is new to ScriptFu v3.
|
||||
|
||||
It causes the interpreter to stop evaluating a script
|
||||
and yield an error of type PikaPDBStatus.
|
||||
That is, it immediately returns an error to the caller.
|
||||
It is similar to the "return" statement in other languages,
|
||||
but the Scheme language has no "return" statement.
|
||||
|
||||
The function takes an error message string.
|
||||
|
||||
When the caller is the PIKA app,
|
||||
the PIKA app will show an error dialog
|
||||
having the message string.
|
||||
|
||||
When the caller is another PDB procedure (a plugin or script)
|
||||
the caller must check the result of a call to the PDB
|
||||
and propagate the error.
|
||||
ScriptFu itself always checks the result of a call to the PDB
|
||||
and propagates the error,
|
||||
concatenating error message strings.
|
||||
|
||||
The function can be used anywhere in a script,
|
||||
like you would a "return" statement in other languages.
|
||||
|
||||
Alternatively, a script can yield #f to yield a PDB error.
|
||||
See below.
|
||||
|
||||
#### Rationale
|
||||
|
||||
Formerly, scripts usually called pika-message on errors,
|
||||
without yielding an error to the caller.
|
||||
It was easy for a user to overlook the error message.
|
||||
An abort shows an error message that a user must acknowledge
|
||||
by choosing an OK button.
|
||||
|
||||
#### Example
|
||||
|
||||
This script defines a PDB procedure that aborts:
|
||||
|
||||
(define (script-fu-abort)
|
||||
(script-fu-script-abort "Too many drawables.")
|
||||
(pika-message "this never evaluated")
|
||||
)
|
||||
...
|
||||
|
||||
### A script can yield #f to throw an error
|
||||
|
||||
Here we use the word "yield" instead of the word "return".
|
||||
Neither "yield" nor "return" are reserved words in the Scheme language.
|
||||
|
||||
A Scheme text evaluates to, or yields, the value of its last expression.
|
||||
Any value other than #f, even the empty list or the list containing #f,
|
||||
is truthy.
|
||||
|
||||
A ScriptFu plugin
|
||||
(the PDB procedure that a script defines in its run func)
|
||||
whose last evaluated expression is #f
|
||||
will yield an error of type PikaPDBStatus.
|
||||
|
||||
If you don't want a ScriptFu plugin to yield an error,
|
||||
it must not evaluate to #f.
|
||||
Most existing plugins won't, since their last evaluated expression
|
||||
is usually a call to the PDB yielding a list, which is not equivalent to #f.
|
||||
|
||||
*Remember that ScriptFu does not yet let you register PDB procedures
|
||||
that return values to the caller.
|
||||
That is, you can only register a void procedure, having only side effects.
|
||||
So to yield #f does not mean to return a boolean to the caller.*
|
||||
|
||||
*Also, you can define Scheme functions internal to a script
|
||||
that yield #f but that do not signify errors.
|
||||
It is only the "run func" that defines a PDB procedure that,
|
||||
yielding #f, yields a PDB error to the caller.*
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
(define (script-fu-always-fail)
|
||||
(begin
|
||||
; this will be evaluated and show a message in PIKA status bar
|
||||
(pika-message "Failing")
|
||||
; since last expression, is the result, and will mean error
|
||||
#f
|
||||
)
|
||||
)
|
||||
|
||||
### You can optionally install scripts like plugins in other languages
|
||||
|
||||
In v3 you can install ScriptFu scripts to a /plug-ins directory.
|
||||
You must edit the script to include a shebang in the first line:
|
||||
|
||||
#!/usr/bin/env pika-script-fu-interpreter-3.0
|
||||
|
||||
In v2 all ScriptFu scripts were usually installed in a /scripts directory.
|
||||
In v3 you may install ScriptFu scripts with a shebang
|
||||
in a subdirectory of a /plug-ins directory.
|
||||
|
||||
Installation of scripts with a shebang must follow rules for interpreted plugins.
|
||||
A script file must:
|
||||
|
||||
- have a shebang on the first line
|
||||
- be in a directory having the same base name
|
||||
- have executable permission
|
||||
- have a file suffix corresponding to an interpreter
|
||||
|
||||
An example path to a script:
|
||||
|
||||
~/.config/PIKA/2.99/plug-ins/myScript/myScript.scm
|
||||
|
||||
Such a script will execute in its own process.
|
||||
If it crashes, it doesn't affect PIKA or other scripts.
|
||||
In v2, all scripts in the /scripts directory are executed by the long-lived
|
||||
process "extension-script-fu."
|
||||
If one of those scripts crash, menu items implemented by ScriptFu dissappear
|
||||
from the PIKA app, and you should restart PIKA.
|
||||
|
||||
### Use script-fu-register-filter to register PDB procedures that take images
|
||||
|
||||
The function *script-fu-register-filter* is new to v3.
|
||||
It lets you declare a script that:
|
||||
|
||||
- is multi-layer capable filter, taking an image and many drawables
|
||||
- can save its settings between sessions
|
||||
|
||||
You don't specify the first two arguments "image" and "drawable"
|
||||
as you do with script-fu-register in v2.
|
||||
Those arguments are implicit.
|
||||
As a convenience, ScriptFu and PIKA registers those arguments in the PDB for you.
|
||||
|
||||
The run func that you define in your script
|
||||
must have those formal arguments. For example:
|
||||
|
||||
(define script-fu-my-plugin (image drawables arg1 arg2) body)
|
||||
|
||||
ScriptFu passes a Scheme vector of drawables, not just one, to a script
|
||||
registering with script-fu-register-filter.
|
||||
|
||||
#### Multi-layer capabilily
|
||||
|
||||
script-fu-register-filter has an argument "multilayer-capability".
|
||||
Some documents may refer to the argument as "drawable arity."
|
||||
The argument follows the "image types" argument
|
||||
and precedes the argument triples that declare formally the "other" arguments
|
||||
of your plugin.
|
||||
|
||||
Here is an abbreviated example:
|
||||
|
||||
(script-fu-register-filter "script-fu-test-sphere-v3"
|
||||
"Sphere v3..."
|
||||
"Test script-fu-register-filter: needs 2 selected layers."
|
||||
"authors"
|
||||
"copyright holders"
|
||||
"copyright dates"
|
||||
"*" ; image types any
|
||||
SF-TWO-OR-MORE-DRAWABLE ; multi-layer capability argument
|
||||
SF-ADJUSTMENT "Radius (in pixels)" (list 100 1 5000 1 10 0 SF-SPINNER)
|
||||
|
||||
The "multilayer-capability" argument can have the following values:
|
||||
|
||||
SF_ONE_DRAWABLE expects exactly one drawable
|
||||
SF_ONE_OR_MORE_DRAWABLE expects and will process one or more drawables
|
||||
SF_TWO_OR_MORE_DRAWABLE expects and will process two or more drawables
|
||||
|
||||
This is only a declaration; whether your run func does what it promises is another matter.
|
||||
|
||||
A script declaring SF_ONE_DRAWABLE still receives a vector of drawables,
|
||||
but the vector should be of length one.
|
||||
|
||||
These do not specify how the script will process the drawables.
|
||||
Typically, SF_ONE_OR_MORE_DRAWABLE means a script will filter
|
||||
the given drawables independently and sequentially.
|
||||
Typically, SF_TWO_OR_MORE_DRAWABLE means a script will
|
||||
combine the given drawables, say into another drawable by a binary operation.
|
||||
|
||||
The "multilayer-capability" argument tells PIKA to enable the script's menu item
|
||||
when a user has selected the appropriate count of drawables.
|
||||
|
||||
#### Settings are handled by PIKA, not ScriptFu
|
||||
|
||||
Scripts declared with script-fu-register-filter have settings that are persisted
|
||||
within and between Pika sessions. That is, the next time a user chooses the filter,
|
||||
the dialog will show the same settings as the last time they chose the filter.
|
||||
This is not true for v2 script-register-filter,
|
||||
where settings are only kept during a PIKA session.
|
||||
|
||||
The dialog for a script declared with script-fu-register-filter
|
||||
will also have buttons for resetting to initial or factory values of settings.
|
||||
|
||||
#### A script should check how many drawables were passed
|
||||
|
||||
A well-written script should throw an error if a caller does not pass the expected number of drawables, either more or fewer than declared. See below.
|
||||
|
||||
### Deprecated: using script-fu-register-filter to register PDB procedures that take images
|
||||
|
||||
Existing scripts that use script-fu-register to declare a procedure
|
||||
that takes an image and single drawable,
|
||||
are deprecated.
|
||||
They will still work and have a correct dialog in v3.
|
||||
In some future version of PIKA,
|
||||
such scripts may become obsolete.
|
||||
All newly written scripts taking an image and one or more drawables
|
||||
should use script-fu-register-filter.
|
||||
|
||||
PIKA enables the menu item for such deprecated scripts if and only if a user
|
||||
selects exactly one drawable (layer or other.)
|
||||
|
||||
### ScriptFu plugins are expected to throw errors for improper count of drawables
|
||||
|
||||
Starting with PIKA 3,
|
||||
a plugin that takes an image takes a container of possibly many drawables.
|
||||
This is the so-called "multi-layer selection" feature.
|
||||
Existing plugins that don't are deprecated,
|
||||
and may become obsoleted in a future version of PIKA.
|
||||
|
||||
Plugins should declare how many drawables they can process,
|
||||
also called the "multi-layer capability" or "drawable arity" of the algorithm.
|
||||
|
||||
The declared drawable arity
|
||||
only describes how many drawables the algorithm is able to process.
|
||||
The declared drawable arity does not denote the signature of the PDB procedure.
|
||||
Well-written image procedures always receive a container of drawables.
|
||||
|
||||
For calls invoked by a user, the drawable arity describes
|
||||
how many drawables the user is expected to select.
|
||||
PIKA disables/enables the menu item for a plugin procedure
|
||||
according to its declared drawable arity.
|
||||
So a plugin procedure invoked directly by a user should never receive
|
||||
a count of drawables that the plugin can't handle.
|
||||
|
||||
*But PDB procedures are also called from other PDB procedures.*
|
||||
A call from another procedure may in fact
|
||||
pass more drawables than declared for drawable arity.
|
||||
That is a programming error on behalf of the caller.
|
||||
|
||||
A well-written callee plugin that is passed more drawables than declared
|
||||
should return an error instead of processing any of the drawables.
|
||||
Similarly for fewer than declared.
|
||||
|
||||
A ScriptFu plugin can use script-fu-script-abort to declare an error
|
||||
when passed an improper count of drawables.
|
Reference in New Issue
Block a user