M3.17: interactive gradient annotator — drag the start handle or the bar to move the gradient, the end handle to change length and angle, just past the end to rotate (Shift snaps to 45°); a bar click adds a stop, stops drag along the bar, off it to delete (never below two), Alt-drag copies, diamonds move midpoints; a click inside selected art applies the gradient from that point; double-clicking a stop opens a popover (Color/Swatches, Opacity, Location); the selected stop lives in the session (gradient.selectStop), shared by the tool, the Gradient and Color panels and agents, and takes Delete/Backspace and ←/→ ahead of their shortcuts (Tool::claims_key, also headless); stop chips draw as Overlay::Swatch with generated add/remove-stop cursors; the stop math moves into the color crate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bflatastic
2026-10-04 17:39:36 +07:00
co-authored by Claude Opus 5.5
parent aa1b592935
commit 3786cfaf36
20 changed files with 1263 additions and 216 deletions
+1
View File
@@ -19,3 +19,4 @@
| `ui.render` | `{path?, scale?}` | render the artboard headlessly (PNG) |
| `ui.resize` / `ui.focus` | | |
| `app.open` / `app.save` / `app.export` / `app.quit` | `{path}` / `{path?}` / `{path?, format?, artboard?, range?, scale?, …}` | `app.open` reads every format `document.open` reads (see `document.formats`). `app.export` encodes through the engine's `document.export` (same options; the document keeps its path) and writes `path` through the host; without `path` it returns `{dataBase64, format, bytes}`, as headless mode does. `app.quit`, `file.close` and `file.closeAll` first open a `saveChanges` dialog for each modified document (they return `{"pending": "saveChanges"}`): `ui.dialog.confirm` saves, `ui.dialog.set {field: "discard", value: true}` then confirm discards, `ui.dialog.cancel` cancels the whole close or quit |
| `ui.dialog.*` on `gradientStop` | `{field: "color" \| "opacity" \| "location", value}` | double-clicking a stop on the Gradient tool's annotator opens its popover (fields `index`, `x`, `y`, `tab`); set `color` (hex), `opacity` or `location` (percentages) and `ui.dialog.confirm` to apply them to the selected stop. `gradient.selectStop {index}` picks the stop the annotator, the panels and Delete/←/→ (`ui.key`) act on |