mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-30 13:26:54 -06:00
Merge main into feat/widget-input
# Conflicts: # ROADMAP.md # crates/plugin/src/manifest.rs # crates/ui-egui/src/canvas.rs # docs/gaps.md # docs/plugins.md # docs/roadmap.md # docs/target-app-parity.md
This commit is contained in:
+15
-5
@@ -240,7 +240,8 @@ plugin directory requests (`plugin.directory.*` says so). Import plugins with `p
|
||||
| `version`, `description` | Optional text. A plugin published to a [directory](#plugin-directories) needs a `version` of one to four numbers (`1.2.0`), each version newer than the last. |
|
||||
| `author` | Optional: who made it, as you type it (64 characters at most); plugin directories show it. |
|
||||
| `main` | Required. The module, a `.wasm` path relative to the manifest, inside its folder. |
|
||||
| `api` | The plugin API version the plugin was written for: `1` (the default), `2` (panels and settings), `3` (widgets) or `4` (widget fields and property menus). A manifest asking for a newer one than FigCraft runs is refused, so a plugin that needs panels or widgets fails clearly on an older FigCraft. |
|
||||
| `api` | The plugin API version the plugin was written for: `1` (the default), `2` (panels and settings), `3` (widgets) or `4` (saving files, widget fields and property menus). A manifest asking for a newer one than FigCraft runs is refused, so a plugin that needs panels, widgets or `saveFile` fails clearly on an older FigCraft. |
|
||||
| `permissions.saveFile` | API 4: `true` lets the plugin offer a file to save (an exporter's output). FigCraft asks the user where it goes with its own Save dialog (a download in the browser); the plugin never gets a path. Manage plugins lists it ("can save files"). A plugin directory's entries don't carry it (their wire format stays as it is), so installing any API 4 plugin from one says it may offer files to save. |
|
||||
| `widget` | API 3: `true` when the plugin draws a widget (it's listed in Plugins ▸ Widgets). |
|
||||
| `permissions.access` | `read` (the default): commands that leave the document as it is; such plugins also run from Dev Mode's Inspect tab. `write`: edits too. |
|
||||
| `permissions.commands` | Optional allowlist: exact command ids or prefixes ending in `*` (`node.*`). Empty: any command the access allows. |
|
||||
@@ -252,6 +253,9 @@ plugin directory requests (`plugin.directory.*` says so). Import plugins with `p
|
||||
Whatever its manifest says, FigCraft refuses these calls (the plugin gets the refusal as an error
|
||||
it can handle):
|
||||
|
||||
- read or write files: a plugin never gets a path or the disk. With `permissions.saveFile` it can
|
||||
only hand FigCraft a file (one per run, 16 MB at most, a plain file name) for the user to save
|
||||
through FigCraft's own dialog; the user can cancel it;
|
||||
- files and the app: `file.*`, `app.*`, `pref.*`, `help.*`, `library.add`, `libraries.*`,
|
||||
`image.place` with a `path` (pass the image as base64 `data` instead), `variable.export`,
|
||||
`codeConnect.export` and `component.playground` with a `path` (leave it out to get the result
|
||||
@@ -287,8 +291,8 @@ every ABI import, including calls which only query the reply length.
|
||||
## ABI (version 4)
|
||||
|
||||
Version 2 adds panels and settings to version 1, version 3 adds widgets, and version 4 adds
|
||||
widget fields and property menus (new keys in the widget description and new widget events; no
|
||||
new imports); a module written for an older version runs unchanged and gets the input it always
|
||||
`save_file` and widget fields and property menus (new keys in the widget description and new
|
||||
widget events); a module written for an older version runs unchanged and gets the input it always
|
||||
got. A widget description with a field or a menu from a plugin whose manifest says `3` is refused,
|
||||
and a FigCraft that runs an older API refuses a manifest that asks for `4` when it's imported. Strings are UTF-8 `(ptr, len)` pairs in the plugin's linear memory; all values
|
||||
are `i32`.
|
||||
@@ -345,6 +349,7 @@ included, is refused when the plugin is imported):
|
||||
| `setting_get` | `(key_ptr, key_len) -> status` | API 2. `0`: the reply holds the setting's JSON. `1`: there is none. |
|
||||
| `setting_set` | `(key_ptr, key_len, value_ptr, value_len) -> status` | API 2. Stores JSON under the key, for this plugin only, kept with the preferences. `1`: refused (not JSON, a bad key, over 64 KB), the reply says why. |
|
||||
| `setting_delete` | `(key_ptr, key_len)` | API 2. Forgets a setting. |
|
||||
| `save_file` | `(name_ptr, name_len, mime_ptr, mime_len, data_ptr, data_len) -> status` | API 4, needs `permissions.saveFile`. Offers a file to save; FigCraft asks the user where it goes once the run succeeds. `1`: refused (no permission, a bad file name, over 16 MB, a second file in one run), the reply says why. |
|
||||
| `widget_render` | `(ptr, len) -> status` | API 3. Draws the widget being inserted or clicked (the widget description below, as JSON). `1`: the description is invalid, the reply says why. A widget call that doesn't draw keeps the widget as it was (inserting one must draw it). |
|
||||
|
||||
A pointer or length outside the plugin's memory traps, which fails the run. Host functions can only
|
||||
@@ -416,7 +421,7 @@ colours, and optionally `value`, one of them: the current one). Every redraw rep
|
||||
|
||||
`plugins/` in the repository is a workspace of its own: `plugins/sdk` (the crate
|
||||
`figcraft-plugin-sdk`, `no_std` with `alloc`) wraps the ABI with serde_json, and
|
||||
`plugins/examples` has three plugins:
|
||||
`plugins/examples` has four plugins:
|
||||
|
||||
- **Tidy names** (`tidy-names`): cleans up the selected layers' names (extra spaces, the "copy" left
|
||||
by duplicating) and optionally their letter case, inside the selection too. Two commands: one
|
||||
@@ -430,6 +435,9 @@ colours, and optionally `value`, one of them: the current one). Every redraw rep
|
||||
- **Counter** (`counter`, API 4): a widget, a count between − and + buttons under a label; each
|
||||
click changes the count kept in the widget's state, a double-click on the label edits it, and its
|
||||
menu resets the count, counts in tens or colours it. It only reads the document.
|
||||
- **Export names** (`export-names`, API 4): saves the names of the selected layers (optionally the
|
||||
layers inside them too) as `layer-names.txt`. It reads the document and offers the file with
|
||||
`save_file`; FigCraft asks where it goes.
|
||||
|
||||
`cargo xtask plugins` (part of `cargo xtask wasm` and `cargo xtask ci`; it needs the
|
||||
`wasm32-unknown-unknown` target: `rustup target add wasm32-unknown-unknown`) checks, tests and
|
||||
@@ -491,7 +499,9 @@ panel, `setting(key)`, `set_setting(key, &value)` and `delete_setting(key)` for
|
||||
`"api": 3` and `"widget": true`: `input.widget` (`id`, `state`, `target`) when the widget is
|
||||
inserted or clicked, and `render_widget(&json!({"state": ..., "root": ...}))` to draw it. With
|
||||
`"api": 4`, `input.widget` also has `field` or `menu` and the `value` that came with it, and the
|
||||
description may have fields and a `menu`. Outside
|
||||
description may have fields and a `menu`; with `"permissions": {"saveFile": true}` too,
|
||||
`save_file(name, mime, &bytes)` offers a file; FigCraft asks the user where it goes and the plugin
|
||||
never learns a path. Outside
|
||||
WebAssembly every host call fails, so the plugin's own logic can be unit-tested with `cargo test`.
|
||||
|
||||
Any language that compiles to WebAssembly works the same way: export `memory` and `figcraft_run`,
|
||||
|
||||
Reference in New Issue
Block a user