@pixerate/editor 0.255.0 → 0.256.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/paint-editor/collaboration-tools.d.cts +19 -0
- package/dist/paint-editor/collaboration-tools.d.ts +19 -0
- package/dist/paint-editor/collaboration.d.cts +180 -0
- package/dist/paint-editor/collaboration.d.ts +180 -0
- package/dist/paint-editor/controller.d.cts +54 -0
- package/dist/paint-editor/controller.d.ts +54 -0
- package/dist/paint-editor/index.cjs +738 -205
- package/dist/paint-editor/index.d.cts +2 -0
- package/dist/paint-editor/index.d.ts +2 -0
- package/dist/paint-editor/index.js +554 -21
- package/package.json +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +31 -46
- package/skills/pixerate-paint-editor/references/painting-alongside.md +19 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for paint proposals: `propose_paint`, `list_paint_proposals`,
|
|
3
|
+
* `accept_paint_proposal` and `reject_paint_proposal`. An agent suggests paint as a ghost the user
|
|
4
|
+
* can take or leave, instead of painting it outright. They drive a {@link PaintProposals} store.
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentToolProvider } from '../tools/registry.cjs';
|
|
7
|
+
import type { PaintProposals } from './collaboration.cjs';
|
|
8
|
+
export interface PaintProposalToolProviderOptions {
|
|
9
|
+
/** Provider id (unique per registry). Default `paint-proposals`. */
|
|
10
|
+
id?: string;
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
|
+
namespace?: string;
|
|
13
|
+
/** Accepting is not allowed: `accept_paint_proposal` refuses with this reason (a sentence). */
|
|
14
|
+
readOnly?: boolean | string | (() => boolean | string);
|
|
15
|
+
/** Origin of proposals from calls that name no actor (default the store's). */
|
|
16
|
+
fallbackOrigin?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The proposal tools for a paint editor (see the module comment). */
|
|
19
|
+
export declare function createPaintProposalToolProvider(proposals: PaintProposals, options?: PaintProposalToolProviderOptions): AgentToolProvider;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for paint proposals: `propose_paint`, `list_paint_proposals`,
|
|
3
|
+
* `accept_paint_proposal` and `reject_paint_proposal`. An agent suggests paint as a ghost the user
|
|
4
|
+
* can take or leave, instead of painting it outright. They drive a {@link PaintProposals} store.
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentToolProvider } from '../tools/registry.js';
|
|
7
|
+
import type { PaintProposals } from './collaboration.js';
|
|
8
|
+
export interface PaintProposalToolProviderOptions {
|
|
9
|
+
/** Provider id (unique per registry). Default `paint-proposals`. */
|
|
10
|
+
id?: string;
|
|
11
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
12
|
+
namespace?: string;
|
|
13
|
+
/** Accepting is not allowed: `accept_paint_proposal` refuses with this reason (a sentence). */
|
|
14
|
+
readOnly?: boolean | string | (() => boolean | string);
|
|
15
|
+
/** Origin of proposals from calls that name no actor (default the store's). */
|
|
16
|
+
fallbackOrigin?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The proposal tools for a paint editor (see the module comment). */
|
|
19
|
+
export declare function createPaintProposalToolProvider(proposals: PaintProposals, options?: PaintProposalToolProviderOptions): AgentToolProvider;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Painting alongside an agent: a change feed that says what the user (or an agent) just painted,
|
|
3
|
+
* and proposals, the paint an agent suggests without painting it. A proposal is a few operations
|
|
4
|
+
* (strokes, a wash, an echo of strokes already on the canvas) that `previewPaint` renders as a
|
|
5
|
+
* ghost the user sees over the canvas; accepting paints them as one undo step recorded as the
|
|
6
|
+
* proposer's, on a layer of their own, and dismissing changes nothing. The canvas equivalents are
|
|
7
|
+
* `createCanvasChangeFeed` and `createCanvasProposals`.
|
|
8
|
+
*/
|
|
9
|
+
import type { RasterRect } from '../raster/surface.cjs';
|
|
10
|
+
import { type PaintCommitEvent, type PaintEditorController } from './controller.cjs';
|
|
11
|
+
import type { PaintEvent } from './document.cjs';
|
|
12
|
+
import type { RecordedStroke } from './strokes.cjs';
|
|
13
|
+
/** A layer as the feed reports it. */
|
|
14
|
+
export interface PaintChangeLayer {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
/** What changed in the painting since the feed's last report. */
|
|
19
|
+
export interface PaintChange {
|
|
20
|
+
/** Counts up from 1 for each change reported. */
|
|
21
|
+
seq: number;
|
|
22
|
+
/** `user`, or `agent:<id>` when an agent's step made it (see `PaintEditorController.withOrigin`). */
|
|
23
|
+
origin: string;
|
|
24
|
+
/** The history step behind it, when there was one. */
|
|
25
|
+
commit?: PaintCommitEvent;
|
|
26
|
+
addedStrokes: RecordedStroke[];
|
|
27
|
+
removedStrokes: RecordedStroke[];
|
|
28
|
+
/** Fills, clears and other recorded operations that aren't strokes. */
|
|
29
|
+
events: PaintEvent[];
|
|
30
|
+
addedLayers: PaintChangeLayer[];
|
|
31
|
+
removedLayers: PaintChangeLayer[];
|
|
32
|
+
/** Layers whose name, visibility, opacity or blend changed, with the fields. */
|
|
33
|
+
changedLayers: (PaintChangeLayer & {
|
|
34
|
+
fields: string[];
|
|
35
|
+
})[];
|
|
36
|
+
/** A stroke is being painted: more of the same gesture will follow. */
|
|
37
|
+
inGesture: boolean;
|
|
38
|
+
/** A stroke started since the last report (reported even when nothing else changed). */
|
|
39
|
+
gestureStarted?: true;
|
|
40
|
+
/** The stroke in progress ended (reported even when it painted nothing). */
|
|
41
|
+
gestureEnded?: true;
|
|
42
|
+
/** Milliseconds since the epoch. */
|
|
43
|
+
at: number;
|
|
44
|
+
}
|
|
45
|
+
export interface PaintChangeFeed {
|
|
46
|
+
/** Compares the painting with the last snapshot and reports the change, if any. Runs on every controller change. */
|
|
47
|
+
check(): PaintChange | null;
|
|
48
|
+
subscribe(listener: (change: PaintChange) => void): () => void;
|
|
49
|
+
/** Takes a new snapshot without reporting the difference (e.g. after opening a document). */
|
|
50
|
+
reset(): void;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* What changed in a painting, after each controller change: strokes added or removed (undo
|
|
55
|
+
* included), fills and clears, layers added, removed or changed, and the start and end of each
|
|
56
|
+
* stroke, tagged with who made it. Agents that paint alongside the user read it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createPaintChangeFeed(controller: PaintEditorController, options?: {
|
|
59
|
+
now?: () => number;
|
|
60
|
+
}): PaintChangeFeed;
|
|
61
|
+
/** A stroke to paint: pen samples in document pixels. */
|
|
62
|
+
export interface PaintProposalStrokeOp {
|
|
63
|
+
kind: 'stroke';
|
|
64
|
+
points: {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
pressure?: number;
|
|
68
|
+
}[];
|
|
69
|
+
/** A dry brush from the library (default the editor's brush). */
|
|
70
|
+
brushId?: string;
|
|
71
|
+
/** #rrggbb (default the editor colour). */
|
|
72
|
+
color?: string;
|
|
73
|
+
/** Brush size in document pixels (default the brush's). */
|
|
74
|
+
size?: number;
|
|
75
|
+
}
|
|
76
|
+
/** A wash over the suggestion's whole layer, like a ground or a glaze. */
|
|
77
|
+
export interface PaintProposalWashOp {
|
|
78
|
+
kind: 'wash';
|
|
79
|
+
color: string;
|
|
80
|
+
/** 0..1 (default 0.35). */
|
|
81
|
+
opacity?: number;
|
|
82
|
+
/** Paper grain response 0..1 (default 0.4). */
|
|
83
|
+
grain?: number;
|
|
84
|
+
}
|
|
85
|
+
/** Strokes already on the canvas, painted again moved, turned, scaled or mirrored. */
|
|
86
|
+
export interface PaintProposalEchoOp {
|
|
87
|
+
kind: 'echo';
|
|
88
|
+
strokeIds: string[];
|
|
89
|
+
dx?: number;
|
|
90
|
+
dy?: number;
|
|
91
|
+
/** Degrees clockwise about the strokes' centre (default 0). */
|
|
92
|
+
rotate?: number;
|
|
93
|
+
scale?: number;
|
|
94
|
+
flipX?: boolean;
|
|
95
|
+
/** Repeat the move this many times, each on top of the last (default 1). */
|
|
96
|
+
repeat?: number;
|
|
97
|
+
/** Recolour (default each stroke's colour). */
|
|
98
|
+
color?: string;
|
|
99
|
+
}
|
|
100
|
+
export type PaintProposalOp = PaintProposalStrokeOp | PaintProposalWashOp | PaintProposalEchoOp;
|
|
101
|
+
/** Where accepted paint goes: a new layer of its own (above a layer, on top, or at the bottom, behind everything). */
|
|
102
|
+
export interface PaintProposalPlacement {
|
|
103
|
+
/** Default `top`. `above` needs `layerId`. */
|
|
104
|
+
place?: 'top' | 'bottom' | 'above';
|
|
105
|
+
layerId?: string;
|
|
106
|
+
/** The new layer's name (default the proposal's title). */
|
|
107
|
+
layerName?: string;
|
|
108
|
+
}
|
|
109
|
+
export interface PaintProposalInput extends PaintProposalPlacement {
|
|
110
|
+
/** What the suggestion adds, in a few words. Also the undo step's name once accepted. */
|
|
111
|
+
title: string;
|
|
112
|
+
/** Why it fits what the user is doing, in a sentence. */
|
|
113
|
+
rationale?: string;
|
|
114
|
+
/** Who suggests it (`agent:<id>`); defaults to the store's `origin`. */
|
|
115
|
+
origin?: string;
|
|
116
|
+
ops: PaintProposalOp[];
|
|
117
|
+
}
|
|
118
|
+
export interface PaintProposal {
|
|
119
|
+
id: string;
|
|
120
|
+
title: string;
|
|
121
|
+
rationale?: string;
|
|
122
|
+
origin: string;
|
|
123
|
+
ops: PaintProposalOp[];
|
|
124
|
+
placement: PaintProposalPlacement;
|
|
125
|
+
/** Where the ghost sits (document pixels), or `null` when it painted nothing. */
|
|
126
|
+
bounds: RasterRect | null;
|
|
127
|
+
/** The ghost: the picture as it would look, inside `bounds` (straight RGBA). */
|
|
128
|
+
ghost: Uint8ClampedArray;
|
|
129
|
+
/** Strokes on the canvas it builds on (echo ops). */
|
|
130
|
+
anchors: string[];
|
|
131
|
+
createdAt: number;
|
|
132
|
+
}
|
|
133
|
+
export interface PaintProposalAcceptResult {
|
|
134
|
+
proposalId: string;
|
|
135
|
+
layerId: string;
|
|
136
|
+
/** The strokes it painted. */
|
|
137
|
+
strokeIds: string[];
|
|
138
|
+
/** The undo step's name. */
|
|
139
|
+
label: string;
|
|
140
|
+
}
|
|
141
|
+
export interface PaintProposalsState {
|
|
142
|
+
proposals: readonly PaintProposal[];
|
|
143
|
+
}
|
|
144
|
+
export interface PaintProposals {
|
|
145
|
+
getState(): PaintProposalsState;
|
|
146
|
+
subscribe(listener: (state: PaintProposalsState) => void): () => void;
|
|
147
|
+
/** Validates and previews a suggestion, and adds it to the pending list. Throws, changing nothing, when it can't be painted. */
|
|
148
|
+
propose(input: PaintProposalInput): PaintProposal;
|
|
149
|
+
/** Paints a pending proposal as one undo step recorded as the proposer's. The active layer stays the user's. */
|
|
150
|
+
accept(id: string): PaintProposalAcceptResult;
|
|
151
|
+
/** Drops a pending proposal; the painting is unchanged. */
|
|
152
|
+
reject(id: string): PaintProposal;
|
|
153
|
+
/** Drops every pending proposal (or those of one origin). Returns the ids dropped. */
|
|
154
|
+
clear(origin?: string): string[];
|
|
155
|
+
get(id: string): PaintProposal | undefined;
|
|
156
|
+
/** Strokes an echo builds on that are no longer on the canvas (it can't be accepted until re-proposed). */
|
|
157
|
+
missing(id: string): string[];
|
|
158
|
+
}
|
|
159
|
+
export interface PaintProposalsOptions {
|
|
160
|
+
controller: PaintEditorController;
|
|
161
|
+
/** Origin of proposals that name none (default `agent:anonymous`). */
|
|
162
|
+
origin?: string;
|
|
163
|
+
/** The most points one proposal may paint (default 4000). */
|
|
164
|
+
maxPoints?: number;
|
|
165
|
+
now?: () => number;
|
|
166
|
+
idGenerator?: () => string;
|
|
167
|
+
}
|
|
168
|
+
/** A store of paint an agent suggests (see the module comment). */
|
|
169
|
+
export declare function createPaintProposals(options: PaintProposalsOptions): PaintProposals;
|
|
170
|
+
/**
|
|
171
|
+
* Where to draw a proposal's ghost and its pixels, for a canvas element placed at `bounds` in
|
|
172
|
+
* document pixels (`new ImageData(data, width, height)`), or `null` when it paints nothing.
|
|
173
|
+
*/
|
|
174
|
+
export declare function paintProposalGhost(proposal: PaintProposal): {
|
|
175
|
+
x: number;
|
|
176
|
+
y: number;
|
|
177
|
+
width: number;
|
|
178
|
+
height: number;
|
|
179
|
+
data: Uint8ClampedArray;
|
|
180
|
+
} | null;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Painting alongside an agent: a change feed that says what the user (or an agent) just painted,
|
|
3
|
+
* and proposals, the paint an agent suggests without painting it. A proposal is a few operations
|
|
4
|
+
* (strokes, a wash, an echo of strokes already on the canvas) that `previewPaint` renders as a
|
|
5
|
+
* ghost the user sees over the canvas; accepting paints them as one undo step recorded as the
|
|
6
|
+
* proposer's, on a layer of their own, and dismissing changes nothing. The canvas equivalents are
|
|
7
|
+
* `createCanvasChangeFeed` and `createCanvasProposals`.
|
|
8
|
+
*/
|
|
9
|
+
import type { RasterRect } from '../raster/surface.js';
|
|
10
|
+
import { type PaintCommitEvent, type PaintEditorController } from './controller.js';
|
|
11
|
+
import type { PaintEvent } from './document.js';
|
|
12
|
+
import type { RecordedStroke } from './strokes.js';
|
|
13
|
+
/** A layer as the feed reports it. */
|
|
14
|
+
export interface PaintChangeLayer {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}
|
|
18
|
+
/** What changed in the painting since the feed's last report. */
|
|
19
|
+
export interface PaintChange {
|
|
20
|
+
/** Counts up from 1 for each change reported. */
|
|
21
|
+
seq: number;
|
|
22
|
+
/** `user`, or `agent:<id>` when an agent's step made it (see `PaintEditorController.withOrigin`). */
|
|
23
|
+
origin: string;
|
|
24
|
+
/** The history step behind it, when there was one. */
|
|
25
|
+
commit?: PaintCommitEvent;
|
|
26
|
+
addedStrokes: RecordedStroke[];
|
|
27
|
+
removedStrokes: RecordedStroke[];
|
|
28
|
+
/** Fills, clears and other recorded operations that aren't strokes. */
|
|
29
|
+
events: PaintEvent[];
|
|
30
|
+
addedLayers: PaintChangeLayer[];
|
|
31
|
+
removedLayers: PaintChangeLayer[];
|
|
32
|
+
/** Layers whose name, visibility, opacity or blend changed, with the fields. */
|
|
33
|
+
changedLayers: (PaintChangeLayer & {
|
|
34
|
+
fields: string[];
|
|
35
|
+
})[];
|
|
36
|
+
/** A stroke is being painted: more of the same gesture will follow. */
|
|
37
|
+
inGesture: boolean;
|
|
38
|
+
/** A stroke started since the last report (reported even when nothing else changed). */
|
|
39
|
+
gestureStarted?: true;
|
|
40
|
+
/** The stroke in progress ended (reported even when it painted nothing). */
|
|
41
|
+
gestureEnded?: true;
|
|
42
|
+
/** Milliseconds since the epoch. */
|
|
43
|
+
at: number;
|
|
44
|
+
}
|
|
45
|
+
export interface PaintChangeFeed {
|
|
46
|
+
/** Compares the painting with the last snapshot and reports the change, if any. Runs on every controller change. */
|
|
47
|
+
check(): PaintChange | null;
|
|
48
|
+
subscribe(listener: (change: PaintChange) => void): () => void;
|
|
49
|
+
/** Takes a new snapshot without reporting the difference (e.g. after opening a document). */
|
|
50
|
+
reset(): void;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* What changed in a painting, after each controller change: strokes added or removed (undo
|
|
55
|
+
* included), fills and clears, layers added, removed or changed, and the start and end of each
|
|
56
|
+
* stroke, tagged with who made it. Agents that paint alongside the user read it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createPaintChangeFeed(controller: PaintEditorController, options?: {
|
|
59
|
+
now?: () => number;
|
|
60
|
+
}): PaintChangeFeed;
|
|
61
|
+
/** A stroke to paint: pen samples in document pixels. */
|
|
62
|
+
export interface PaintProposalStrokeOp {
|
|
63
|
+
kind: 'stroke';
|
|
64
|
+
points: {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
pressure?: number;
|
|
68
|
+
}[];
|
|
69
|
+
/** A dry brush from the library (default the editor's brush). */
|
|
70
|
+
brushId?: string;
|
|
71
|
+
/** #rrggbb (default the editor colour). */
|
|
72
|
+
color?: string;
|
|
73
|
+
/** Brush size in document pixels (default the brush's). */
|
|
74
|
+
size?: number;
|
|
75
|
+
}
|
|
76
|
+
/** A wash over the suggestion's whole layer, like a ground or a glaze. */
|
|
77
|
+
export interface PaintProposalWashOp {
|
|
78
|
+
kind: 'wash';
|
|
79
|
+
color: string;
|
|
80
|
+
/** 0..1 (default 0.35). */
|
|
81
|
+
opacity?: number;
|
|
82
|
+
/** Paper grain response 0..1 (default 0.4). */
|
|
83
|
+
grain?: number;
|
|
84
|
+
}
|
|
85
|
+
/** Strokes already on the canvas, painted again moved, turned, scaled or mirrored. */
|
|
86
|
+
export interface PaintProposalEchoOp {
|
|
87
|
+
kind: 'echo';
|
|
88
|
+
strokeIds: string[];
|
|
89
|
+
dx?: number;
|
|
90
|
+
dy?: number;
|
|
91
|
+
/** Degrees clockwise about the strokes' centre (default 0). */
|
|
92
|
+
rotate?: number;
|
|
93
|
+
scale?: number;
|
|
94
|
+
flipX?: boolean;
|
|
95
|
+
/** Repeat the move this many times, each on top of the last (default 1). */
|
|
96
|
+
repeat?: number;
|
|
97
|
+
/** Recolour (default each stroke's colour). */
|
|
98
|
+
color?: string;
|
|
99
|
+
}
|
|
100
|
+
export type PaintProposalOp = PaintProposalStrokeOp | PaintProposalWashOp | PaintProposalEchoOp;
|
|
101
|
+
/** Where accepted paint goes: a new layer of its own (above a layer, on top, or at the bottom, behind everything). */
|
|
102
|
+
export interface PaintProposalPlacement {
|
|
103
|
+
/** Default `top`. `above` needs `layerId`. */
|
|
104
|
+
place?: 'top' | 'bottom' | 'above';
|
|
105
|
+
layerId?: string;
|
|
106
|
+
/** The new layer's name (default the proposal's title). */
|
|
107
|
+
layerName?: string;
|
|
108
|
+
}
|
|
109
|
+
export interface PaintProposalInput extends PaintProposalPlacement {
|
|
110
|
+
/** What the suggestion adds, in a few words. Also the undo step's name once accepted. */
|
|
111
|
+
title: string;
|
|
112
|
+
/** Why it fits what the user is doing, in a sentence. */
|
|
113
|
+
rationale?: string;
|
|
114
|
+
/** Who suggests it (`agent:<id>`); defaults to the store's `origin`. */
|
|
115
|
+
origin?: string;
|
|
116
|
+
ops: PaintProposalOp[];
|
|
117
|
+
}
|
|
118
|
+
export interface PaintProposal {
|
|
119
|
+
id: string;
|
|
120
|
+
title: string;
|
|
121
|
+
rationale?: string;
|
|
122
|
+
origin: string;
|
|
123
|
+
ops: PaintProposalOp[];
|
|
124
|
+
placement: PaintProposalPlacement;
|
|
125
|
+
/** Where the ghost sits (document pixels), or `null` when it painted nothing. */
|
|
126
|
+
bounds: RasterRect | null;
|
|
127
|
+
/** The ghost: the picture as it would look, inside `bounds` (straight RGBA). */
|
|
128
|
+
ghost: Uint8ClampedArray;
|
|
129
|
+
/** Strokes on the canvas it builds on (echo ops). */
|
|
130
|
+
anchors: string[];
|
|
131
|
+
createdAt: number;
|
|
132
|
+
}
|
|
133
|
+
export interface PaintProposalAcceptResult {
|
|
134
|
+
proposalId: string;
|
|
135
|
+
layerId: string;
|
|
136
|
+
/** The strokes it painted. */
|
|
137
|
+
strokeIds: string[];
|
|
138
|
+
/** The undo step's name. */
|
|
139
|
+
label: string;
|
|
140
|
+
}
|
|
141
|
+
export interface PaintProposalsState {
|
|
142
|
+
proposals: readonly PaintProposal[];
|
|
143
|
+
}
|
|
144
|
+
export interface PaintProposals {
|
|
145
|
+
getState(): PaintProposalsState;
|
|
146
|
+
subscribe(listener: (state: PaintProposalsState) => void): () => void;
|
|
147
|
+
/** Validates and previews a suggestion, and adds it to the pending list. Throws, changing nothing, when it can't be painted. */
|
|
148
|
+
propose(input: PaintProposalInput): PaintProposal;
|
|
149
|
+
/** Paints a pending proposal as one undo step recorded as the proposer's. The active layer stays the user's. */
|
|
150
|
+
accept(id: string): PaintProposalAcceptResult;
|
|
151
|
+
/** Drops a pending proposal; the painting is unchanged. */
|
|
152
|
+
reject(id: string): PaintProposal;
|
|
153
|
+
/** Drops every pending proposal (or those of one origin). Returns the ids dropped. */
|
|
154
|
+
clear(origin?: string): string[];
|
|
155
|
+
get(id: string): PaintProposal | undefined;
|
|
156
|
+
/** Strokes an echo builds on that are no longer on the canvas (it can't be accepted until re-proposed). */
|
|
157
|
+
missing(id: string): string[];
|
|
158
|
+
}
|
|
159
|
+
export interface PaintProposalsOptions {
|
|
160
|
+
controller: PaintEditorController;
|
|
161
|
+
/** Origin of proposals that name none (default `agent:anonymous`). */
|
|
162
|
+
origin?: string;
|
|
163
|
+
/** The most points one proposal may paint (default 4000). */
|
|
164
|
+
maxPoints?: number;
|
|
165
|
+
now?: () => number;
|
|
166
|
+
idGenerator?: () => string;
|
|
167
|
+
}
|
|
168
|
+
/** A store of paint an agent suggests (see the module comment). */
|
|
169
|
+
export declare function createPaintProposals(options: PaintProposalsOptions): PaintProposals;
|
|
170
|
+
/**
|
|
171
|
+
* Where to draw a proposal's ghost and its pixels, for a canvas element placed at `bounds` in
|
|
172
|
+
* document pixels (`new ImageData(data, width, height)`), or `null` when it paints nothing.
|
|
173
|
+
*/
|
|
174
|
+
export declare function paintProposalGhost(proposal: PaintProposal): {
|
|
175
|
+
x: number;
|
|
176
|
+
y: number;
|
|
177
|
+
width: number;
|
|
178
|
+
height: number;
|
|
179
|
+
data: Uint8ClampedArray;
|
|
180
|
+
} | null;
|
|
@@ -194,6 +194,29 @@ export interface PaintLayerInfo {
|
|
|
194
194
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
195
195
|
effects?: number;
|
|
196
196
|
}
|
|
197
|
+
/** One change to the paint history, for hosts and change feeds (`onCommit`). */
|
|
198
|
+
export interface PaintCommitEvent {
|
|
199
|
+
/** `execute`: a new undo step. `merge`: folded into the last one (a slider drag). */
|
|
200
|
+
kind: 'execute' | 'merge' | 'undo' | 'redo';
|
|
201
|
+
/** The step's name. */
|
|
202
|
+
label: string;
|
|
203
|
+
/** Who made the step: `user`, or `agent:<id>` (see `withOrigin`). */
|
|
204
|
+
origin: string;
|
|
205
|
+
}
|
|
206
|
+
/** Paint a preview produced (`previewPaint`), in document coordinates, straight RGBA. */
|
|
207
|
+
export interface PaintPreview {
|
|
208
|
+
/** Where the new paint sits, or `null` when nothing was painted. */
|
|
209
|
+
bounds: RasterRect | null;
|
|
210
|
+
/** The new paint alone: `bounds.width × bounds.height` pixels (empty when nothing was painted). */
|
|
211
|
+
pixels: Uint8ClampedArray;
|
|
212
|
+
/** The whole picture as it would look with the new paint, inside `bounds` (with the paper; empty when nothing was painted). */
|
|
213
|
+
composite: Uint8ClampedArray;
|
|
214
|
+
}
|
|
215
|
+
/** Where `previewPaint` puts its layer: above a layer (default the active one), or at the bottom of the stack. */
|
|
216
|
+
export interface PaintPreviewPlacement {
|
|
217
|
+
aboveId?: string;
|
|
218
|
+
bottom?: boolean;
|
|
219
|
+
}
|
|
197
220
|
export interface PaintStrokeInit {
|
|
198
221
|
/** Default the active layer. */
|
|
199
222
|
layerId?: string;
|
|
@@ -337,6 +360,13 @@ export declare class PaintEditorController {
|
|
|
337
360
|
private stickerPreview;
|
|
338
361
|
private readonly encodeImage;
|
|
339
362
|
private listeners;
|
|
363
|
+
private commitListeners;
|
|
364
|
+
/** Origins set by `withOrigin`, innermost last. */
|
|
365
|
+
private origins;
|
|
366
|
+
/** `group` in progress: commits fold into one step, recorded when it ends. */
|
|
367
|
+
private grouping;
|
|
368
|
+
/** `previewPaint` in progress: nothing is emitted or recorded. */
|
|
369
|
+
private previewing;
|
|
340
370
|
private version;
|
|
341
371
|
private cached;
|
|
342
372
|
private session;
|
|
@@ -393,6 +423,30 @@ export declare class PaintEditorController {
|
|
|
393
423
|
private paperEffectNodeCache;
|
|
394
424
|
constructor(options?: PaintEditorOptions);
|
|
395
425
|
subscribe(listener: () => void): () => void;
|
|
426
|
+
/** Hears each undo step recorded, merged, undone or redone, with who made it. Returns an unsubscribe function. */
|
|
427
|
+
onCommit(listener: (event: PaintCommitEvent) => void): () => void;
|
|
428
|
+
private notifyCommit;
|
|
429
|
+
/** The origin steps are recorded with now: the innermost `withOrigin`, else `user`. */
|
|
430
|
+
getOrigin(): string;
|
|
431
|
+
/**
|
|
432
|
+
* Records the steps `fn` makes as made by `origin` (`agent:<id>` for an agent). When `fn` returns
|
|
433
|
+
* a promise, the origin holds until it settles. Satisfies `createOriginMiddleware`'s history target,
|
|
434
|
+
* so agent tool calls are recorded as the calling agent's.
|
|
435
|
+
*/
|
|
436
|
+
withOrigin<T>(origin: string, fn: () => T): T;
|
|
437
|
+
/**
|
|
438
|
+
* Runs `fn` as one undo step named `label`: every change it makes (strokes, fills, new layers) is
|
|
439
|
+
* undone together. Wet paint can't be grouped. Nested groups join the outer one. If `fn` throws,
|
|
440
|
+
* its changes are put back and nothing is recorded.
|
|
441
|
+
*/
|
|
442
|
+
group<T>(label: string, fn: () => T): T;
|
|
443
|
+
/**
|
|
444
|
+
* What `fn` would paint, without changing anything: it runs on a new empty layer (above the
|
|
445
|
+
* active layer, another one, or at the bottom), and the layer's pixels and the picture with them
|
|
446
|
+
* come back while the document, history and listeners stay as they were. `fn` gets that layer's id and must paint on it with dry brushes (strokes, replays and
|
|
447
|
+
* fills); wet paint can't be previewed. For ghost paint an agent suggests (`createPaintProposals`).
|
|
448
|
+
*/
|
|
449
|
+
previewPaint(fn: (layerId: string) => void, placement?: PaintPreviewPlacement): PaintPreview;
|
|
396
450
|
private emit;
|
|
397
451
|
/** A snapshot of the editor (the same object until something changes). */
|
|
398
452
|
getState(): PaintEditorState;
|
|
@@ -194,6 +194,29 @@ export interface PaintLayerInfo {
|
|
|
194
194
|
/** How many live layer effects (glows, shadows, strokes…) it has, when any (`getLayerEffects`). */
|
|
195
195
|
effects?: number;
|
|
196
196
|
}
|
|
197
|
+
/** One change to the paint history, for hosts and change feeds (`onCommit`). */
|
|
198
|
+
export interface PaintCommitEvent {
|
|
199
|
+
/** `execute`: a new undo step. `merge`: folded into the last one (a slider drag). */
|
|
200
|
+
kind: 'execute' | 'merge' | 'undo' | 'redo';
|
|
201
|
+
/** The step's name. */
|
|
202
|
+
label: string;
|
|
203
|
+
/** Who made the step: `user`, or `agent:<id>` (see `withOrigin`). */
|
|
204
|
+
origin: string;
|
|
205
|
+
}
|
|
206
|
+
/** Paint a preview produced (`previewPaint`), in document coordinates, straight RGBA. */
|
|
207
|
+
export interface PaintPreview {
|
|
208
|
+
/** Where the new paint sits, or `null` when nothing was painted. */
|
|
209
|
+
bounds: RasterRect | null;
|
|
210
|
+
/** The new paint alone: `bounds.width × bounds.height` pixels (empty when nothing was painted). */
|
|
211
|
+
pixels: Uint8ClampedArray;
|
|
212
|
+
/** The whole picture as it would look with the new paint, inside `bounds` (with the paper; empty when nothing was painted). */
|
|
213
|
+
composite: Uint8ClampedArray;
|
|
214
|
+
}
|
|
215
|
+
/** Where `previewPaint` puts its layer: above a layer (default the active one), or at the bottom of the stack. */
|
|
216
|
+
export interface PaintPreviewPlacement {
|
|
217
|
+
aboveId?: string;
|
|
218
|
+
bottom?: boolean;
|
|
219
|
+
}
|
|
197
220
|
export interface PaintStrokeInit {
|
|
198
221
|
/** Default the active layer. */
|
|
199
222
|
layerId?: string;
|
|
@@ -337,6 +360,13 @@ export declare class PaintEditorController {
|
|
|
337
360
|
private stickerPreview;
|
|
338
361
|
private readonly encodeImage;
|
|
339
362
|
private listeners;
|
|
363
|
+
private commitListeners;
|
|
364
|
+
/** Origins set by `withOrigin`, innermost last. */
|
|
365
|
+
private origins;
|
|
366
|
+
/** `group` in progress: commits fold into one step, recorded when it ends. */
|
|
367
|
+
private grouping;
|
|
368
|
+
/** `previewPaint` in progress: nothing is emitted or recorded. */
|
|
369
|
+
private previewing;
|
|
340
370
|
private version;
|
|
341
371
|
private cached;
|
|
342
372
|
private session;
|
|
@@ -393,6 +423,30 @@ export declare class PaintEditorController {
|
|
|
393
423
|
private paperEffectNodeCache;
|
|
394
424
|
constructor(options?: PaintEditorOptions);
|
|
395
425
|
subscribe(listener: () => void): () => void;
|
|
426
|
+
/** Hears each undo step recorded, merged, undone or redone, with who made it. Returns an unsubscribe function. */
|
|
427
|
+
onCommit(listener: (event: PaintCommitEvent) => void): () => void;
|
|
428
|
+
private notifyCommit;
|
|
429
|
+
/** The origin steps are recorded with now: the innermost `withOrigin`, else `user`. */
|
|
430
|
+
getOrigin(): string;
|
|
431
|
+
/**
|
|
432
|
+
* Records the steps `fn` makes as made by `origin` (`agent:<id>` for an agent). When `fn` returns
|
|
433
|
+
* a promise, the origin holds until it settles. Satisfies `createOriginMiddleware`'s history target,
|
|
434
|
+
* so agent tool calls are recorded as the calling agent's.
|
|
435
|
+
*/
|
|
436
|
+
withOrigin<T>(origin: string, fn: () => T): T;
|
|
437
|
+
/**
|
|
438
|
+
* Runs `fn` as one undo step named `label`: every change it makes (strokes, fills, new layers) is
|
|
439
|
+
* undone together. Wet paint can't be grouped. Nested groups join the outer one. If `fn` throws,
|
|
440
|
+
* its changes are put back and nothing is recorded.
|
|
441
|
+
*/
|
|
442
|
+
group<T>(label: string, fn: () => T): T;
|
|
443
|
+
/**
|
|
444
|
+
* What `fn` would paint, without changing anything: it runs on a new empty layer (above the
|
|
445
|
+
* active layer, another one, or at the bottom), and the layer's pixels and the picture with them
|
|
446
|
+
* come back while the document, history and listeners stay as they were. `fn` gets that layer's id and must paint on it with dry brushes (strokes, replays and
|
|
447
|
+
* fills); wet paint can't be previewed. For ghost paint an agent suggests (`createPaintProposals`).
|
|
448
|
+
*/
|
|
449
|
+
previewPaint(fn: (layerId: string) => void, placement?: PaintPreviewPlacement): PaintPreview;
|
|
396
450
|
private emit;
|
|
397
451
|
/** A snapshot of the editor (the same object until something changes). */
|
|
398
452
|
getState(): PaintEditorState;
|