@zylem/editor 0.6.9 → 0.7.3
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/zylem-editor.d.ts +450 -116
- package/dist/zylem-editor.js +126 -11
- package/package.json +16 -11
- package/LICENSE +0 -21
package/dist/zylem-editor.d.ts
CHANGED
|
@@ -1,121 +1,7 @@
|
|
|
1
1
|
import { Component } from 'solid-js';
|
|
2
2
|
import { LucideProps } from 'lucide-solid';
|
|
3
3
|
import * as _zylem_bridge from '@zylem/bridge';
|
|
4
|
-
import { BridgeDebugTool } from '@zylem/bridge';
|
|
5
|
-
|
|
6
|
-
type EditorLauncherMode = 'floating' | 'hidden';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Configuration options for the ZylemEditorElement
|
|
10
|
-
*/
|
|
11
|
-
interface ZylemEditorConfig {
|
|
12
|
-
/**
|
|
13
|
-
* External debug state to sync with.
|
|
14
|
-
* If provided, the editor will use this state instead of its internal state.
|
|
15
|
-
*/
|
|
16
|
-
debugState?: any;
|
|
17
|
-
/**
|
|
18
|
-
* External game state to sync with.
|
|
19
|
-
*/
|
|
20
|
-
gameState?: any;
|
|
21
|
-
/**
|
|
22
|
-
* External stage state to sync with.
|
|
23
|
-
*/
|
|
24
|
-
stageState?: any;
|
|
25
|
-
/**
|
|
26
|
-
* Whether to include default styles.
|
|
27
|
-
* @default true
|
|
28
|
-
*/
|
|
29
|
-
includeStyles?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Controls whether the internal floating launcher is rendered.
|
|
32
|
-
* @default 'floating'
|
|
33
|
-
*/
|
|
34
|
-
launcherMode?: EditorLauncherMode;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* ZylemEditorElement - A web component that wraps the Zylem Editor.
|
|
38
|
-
*
|
|
39
|
-
* This component is fully self-contained with bundled styles.
|
|
40
|
-
* It can be imported and used in any project without additional CSS configuration.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```html
|
|
44
|
-
* <!-- Standalone usage -->
|
|
45
|
-
* <zylem-editor></zylem-editor>
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```js
|
|
50
|
-
* // Configured usage
|
|
51
|
-
* const editor = document.querySelector('zylem-editor');
|
|
52
|
-
* editor.config = {
|
|
53
|
-
* debugState: myGame.debugState,
|
|
54
|
-
* gameState: myGame.gameState,
|
|
55
|
-
* stageState: myGame.stageState,
|
|
56
|
-
* };
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```js
|
|
61
|
-
* // Manual registration in another project
|
|
62
|
-
* import { ZylemEditorElement } from '@zylem/editor';
|
|
63
|
-
*
|
|
64
|
-
* // Optionally customize before registering
|
|
65
|
-
* customElements.define('my-editor', ZylemEditorElement);
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
declare class ZylemEditorElement extends HTMLElement {
|
|
69
|
-
private dispose;
|
|
70
|
-
private _config;
|
|
71
|
-
private _initialized;
|
|
72
|
-
private controller;
|
|
73
|
-
/** Releases this element's bridge subscription (reference-counted). */
|
|
74
|
-
private releaseBridge;
|
|
75
|
-
constructor();
|
|
76
|
-
/**
|
|
77
|
-
* Set configuration for the editor.
|
|
78
|
-
* Must be set before the element is connected to the DOM, or call `reinitialize()` after.
|
|
79
|
-
*/
|
|
80
|
-
set config(value: ZylemEditorConfig);
|
|
81
|
-
get config(): ZylemEditorConfig;
|
|
82
|
-
set launcherMode(value: EditorLauncherMode);
|
|
83
|
-
get launcherMode(): EditorLauncherMode;
|
|
84
|
-
/**
|
|
85
|
-
* Observed attributes for the web component
|
|
86
|
-
*/
|
|
87
|
-
static get observedAttributes(): string[];
|
|
88
|
-
attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
|
|
89
|
-
connectedCallback(): void;
|
|
90
|
-
private initialize;
|
|
91
|
-
openPanel(): void;
|
|
92
|
-
closePanel(): void;
|
|
93
|
-
togglePanel(): void;
|
|
94
|
-
/**
|
|
95
|
-
* Reinitialize the editor with new configuration.
|
|
96
|
-
* Call this after changing the `config` property if the element is already connected.
|
|
97
|
-
*/
|
|
98
|
-
reinitialize(): void;
|
|
99
|
-
disconnectedCallback(): void;
|
|
100
|
-
private teardown;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Register the ZylemEditorElement as a custom element.
|
|
104
|
-
* Call this function to use the default 'zylem-editor' tag name.
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```js
|
|
108
|
-
* import { registerZylemEditor } from '@zylem/editor';
|
|
109
|
-
* registerZylemEditor();
|
|
110
|
-
* // Now you can use <zylem-editor> in your HTML
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
|
-
declare function registerZylemEditor(tagName?: string): void;
|
|
114
|
-
|
|
115
|
-
interface IconProps extends LucideProps {
|
|
116
|
-
icon: Component<LucideProps>;
|
|
117
|
-
}
|
|
118
|
-
declare const Icon: Component<IconProps>;
|
|
4
|
+
import { BridgeDebugTool, BridgeVec3, BridgeQuat, BridgePose, SnapSettingsPayload, SceneOperationPayload, EntityTypeDescriptor } from '@zylem/bridge';
|
|
119
5
|
|
|
120
6
|
/**
|
|
121
7
|
* Editor Event Bus
|
|
@@ -178,7 +64,22 @@ interface DebugState {
|
|
|
178
64
|
paused: boolean;
|
|
179
65
|
tool: DebugTools;
|
|
180
66
|
selectedEntityId: string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Full selection, mirroring the game. `selectedEntityId` is its first entry,
|
|
69
|
+
* kept so single-select consumers need no change.
|
|
70
|
+
*/
|
|
71
|
+
selectedEntityIds: string[];
|
|
181
72
|
hoveredEntityId: string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Most recently selected or created entity, kept after it is deselected.
|
|
75
|
+
*
|
|
76
|
+
* What the gizmo tools fall back to: pressing Rotate with nothing selected
|
|
77
|
+
* should turn the thing you were last working on, rather than nothing. Never
|
|
78
|
+
* cleared on deselect — only overwritten — and validated against the current
|
|
79
|
+
* entity list at the point of use, since the entity it names can be deleted
|
|
80
|
+
* or undone away.
|
|
81
|
+
*/
|
|
82
|
+
lastTouchedEntityId: string | null;
|
|
182
83
|
flags: Set<string>;
|
|
183
84
|
}
|
|
184
85
|
declare const debugState: DebugState;
|
|
@@ -259,6 +160,58 @@ interface StageStateInterface {
|
|
|
259
160
|
|
|
260
161
|
declare const stageState: StageStateInterface;
|
|
261
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Dock layout geometry.
|
|
165
|
+
*
|
|
166
|
+
* Docking used to be per-panel: each panel snapped itself to a viewport edge
|
|
167
|
+
* and sized itself from `window.innerWidth`. That cannot express two panels
|
|
168
|
+
* sharing a side, or a bottom strip that stops at a left-docked panel, so the
|
|
169
|
+
* dock state lives in one registry (persisted in the editor store) and every
|
|
170
|
+
* panel's rect comes from `computeDockLayout`.
|
|
171
|
+
*
|
|
172
|
+
* This module is deliberately free of Solid and `window` so the geometry can
|
|
173
|
+
* be unit tested directly.
|
|
174
|
+
*/
|
|
175
|
+
type DockSide = 'left' | 'right' | 'top' | 'bottom';
|
|
176
|
+
/** `'main'` is the editor panel; any other id is a detached section id. */
|
|
177
|
+
type DockPanelId = string;
|
|
178
|
+
interface DockZoneState {
|
|
179
|
+
/** Occupants in slot order along the zone's long axis. */
|
|
180
|
+
panels: DockPanelId[];
|
|
181
|
+
/**
|
|
182
|
+
* Width for left/right, height for top/bottom.
|
|
183
|
+
* `0` means "not chosen yet"; the layout falls back to a viewport quarter.
|
|
184
|
+
*/
|
|
185
|
+
thickness: number;
|
|
186
|
+
}
|
|
187
|
+
type DockRegistry = Record<DockSide, DockZoneState>;
|
|
188
|
+
interface Viewport {
|
|
189
|
+
width: number;
|
|
190
|
+
height: number;
|
|
191
|
+
}
|
|
192
|
+
interface DockRect {
|
|
193
|
+
x: number;
|
|
194
|
+
y: number;
|
|
195
|
+
width: number;
|
|
196
|
+
height: number;
|
|
197
|
+
}
|
|
198
|
+
declare const DOCK_SIDES: readonly DockSide[];
|
|
199
|
+
declare const findDockedSide: (registry: DockRegistry, panelId: DockPanelId) => DockSide | null;
|
|
200
|
+
interface DockLayoutOptions {
|
|
201
|
+
/** Smallest slot extent along a zone's long axis. */
|
|
202
|
+
minSlotExtent?: number;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Rect for every docked panel.
|
|
206
|
+
*
|
|
207
|
+
* Left and right zones take the full viewport height and win over top and
|
|
208
|
+
* bottom, which inset horizontally to the space between them. Panels sharing a
|
|
209
|
+
* zone split its long axis evenly.
|
|
210
|
+
*/
|
|
211
|
+
declare const computeDockLayout: (registry: DockRegistry, viewport: Viewport, options?: DockLayoutOptions) => Record<DockPanelId, DockRect>;
|
|
212
|
+
|
|
213
|
+
/** Registry id of the main editor panel; detached sections use their panel id. */
|
|
214
|
+
declare const MAIN_PANEL_ID = "main";
|
|
262
215
|
interface DetachedPanelState {
|
|
263
216
|
position: {
|
|
264
217
|
x: number;
|
|
@@ -269,16 +222,25 @@ interface DetachedPanelState {
|
|
|
269
222
|
height: number;
|
|
270
223
|
};
|
|
271
224
|
}
|
|
225
|
+
/** First-run dock assignments a host can request; see `applyDefaultDocks`. */
|
|
226
|
+
type EditorDockDefaults = Partial<Record<DockSide, DockPanelId[]>>;
|
|
272
227
|
declare const debugStore: {
|
|
273
228
|
debug: boolean;
|
|
274
229
|
tool: DebugTools;
|
|
275
230
|
paused: boolean;
|
|
276
231
|
hovered: string | null;
|
|
277
232
|
selected: string[];
|
|
233
|
+
/** Fallback target for the gizmo tools; see `DebugState.lastTouchedEntityId`. */
|
|
234
|
+
lastTouched: string | null;
|
|
278
235
|
panelPosition: {
|
|
279
236
|
x: number;
|
|
280
237
|
y: number;
|
|
281
238
|
} | null;
|
|
239
|
+
/** Main panel's floating size; its docked size comes from the registry. */
|
|
240
|
+
panelSize: {
|
|
241
|
+
width: number;
|
|
242
|
+
height: number;
|
|
243
|
+
} | null;
|
|
282
244
|
toggleButtonPosition: {
|
|
283
245
|
x: number;
|
|
284
246
|
y: number;
|
|
@@ -287,9 +249,158 @@ declare const debugStore: {
|
|
|
287
249
|
detachedPanels: Record<string, DetachedPanelState>;
|
|
288
250
|
openSections: string[];
|
|
289
251
|
panelZOrder: string[];
|
|
252
|
+
docks: DockRegistry;
|
|
253
|
+
dockDefaultsApplied: boolean;
|
|
290
254
|
draggingPanelId: string | null;
|
|
291
255
|
dropTargetIndex: number | null;
|
|
292
256
|
};
|
|
257
|
+
declare const dockPanelToSide: (panelId: DockPanelId, side: DockSide, index?: number) => void;
|
|
258
|
+
declare const undockPanelFromSides: (panelId: DockPanelId) => void;
|
|
259
|
+
declare const getDockedSide: (panelId: DockPanelId) => DockSide | null;
|
|
260
|
+
|
|
261
|
+
type EditorLauncherMode = 'floating' | 'hidden';
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Configuration options for the ZylemEditorElement
|
|
265
|
+
*/
|
|
266
|
+
interface ZylemEditorConfig {
|
|
267
|
+
/**
|
|
268
|
+
* External debug state to sync with.
|
|
269
|
+
* If provided, the editor will use this state instead of its internal state.
|
|
270
|
+
*/
|
|
271
|
+
debugState?: any;
|
|
272
|
+
/**
|
|
273
|
+
* External game state to sync with.
|
|
274
|
+
*/
|
|
275
|
+
gameState?: any;
|
|
276
|
+
/**
|
|
277
|
+
* External stage state to sync with.
|
|
278
|
+
*/
|
|
279
|
+
stageState?: any;
|
|
280
|
+
/**
|
|
281
|
+
* Whether to include default styles.
|
|
282
|
+
* @default true
|
|
283
|
+
*/
|
|
284
|
+
includeStyles?: boolean;
|
|
285
|
+
/**
|
|
286
|
+
* Controls whether the internal floating launcher is rendered.
|
|
287
|
+
* @default 'floating'
|
|
288
|
+
*/
|
|
289
|
+
launcherMode?: EditorLauncherMode;
|
|
290
|
+
/**
|
|
291
|
+
* Dock layout to seed the first time the editor runs in this browser, keyed
|
|
292
|
+
* by viewport edge. Use `'main'` for the editor panel itself; any other id is
|
|
293
|
+
* a section (for example `'console'`), which gets detached from the accordion
|
|
294
|
+
* so it can hold a dock slot.
|
|
295
|
+
*
|
|
296
|
+
* Ignored once the user has a saved layout, so it sets a starting point
|
|
297
|
+
* rather than forcing one.
|
|
298
|
+
*/
|
|
299
|
+
defaultDocks?: EditorDockDefaults;
|
|
300
|
+
/**
|
|
301
|
+
* Whether the editor claims cmd/ctrl+z for its own undo stack.
|
|
302
|
+
*
|
|
303
|
+
* Disable it when embedding the editor in an app with its own history, and
|
|
304
|
+
* call the exported `undo()` / `redo()` from that app's handler instead.
|
|
305
|
+
* @default true
|
|
306
|
+
*/
|
|
307
|
+
enableUndoShortcut?: boolean;
|
|
308
|
+
/**
|
|
309
|
+
* Whether Escape disarms the active tool.
|
|
310
|
+
* @default true
|
|
311
|
+
*/
|
|
312
|
+
enableEscapeShortcut?: boolean;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* ZylemEditorElement - A web component that wraps the Zylem Editor.
|
|
316
|
+
*
|
|
317
|
+
* This component is fully self-contained with bundled styles.
|
|
318
|
+
* It can be imported and used in any project without additional CSS configuration.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```html
|
|
322
|
+
* <!-- Standalone usage -->
|
|
323
|
+
* <zylem-editor></zylem-editor>
|
|
324
|
+
* ```
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```js
|
|
328
|
+
* // Configured usage
|
|
329
|
+
* const editor = document.querySelector('zylem-editor');
|
|
330
|
+
* editor.config = {
|
|
331
|
+
* debugState: myGame.debugState,
|
|
332
|
+
* gameState: myGame.gameState,
|
|
333
|
+
* stageState: myGame.stageState,
|
|
334
|
+
* };
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```js
|
|
339
|
+
* // Manual registration in another project
|
|
340
|
+
* import { ZylemEditorElement } from '@zylem/editor';
|
|
341
|
+
*
|
|
342
|
+
* // Optionally customize before registering
|
|
343
|
+
* customElements.define('my-editor', ZylemEditorElement);
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
declare class ZylemEditorElement extends HTMLElement {
|
|
347
|
+
private dispose;
|
|
348
|
+
private _config;
|
|
349
|
+
private _initialized;
|
|
350
|
+
private controller;
|
|
351
|
+
/** Releases this element's bridge subscription (reference-counted). */
|
|
352
|
+
private releaseBridge;
|
|
353
|
+
/** Keyboard shortcuts and the snap/grid mirror, torn down with the element. */
|
|
354
|
+
private teardownHooks;
|
|
355
|
+
constructor();
|
|
356
|
+
/**
|
|
357
|
+
* Set configuration for the editor.
|
|
358
|
+
* Must be set before the element is connected to the DOM, or call `reinitialize()` after.
|
|
359
|
+
*/
|
|
360
|
+
set config(value: ZylemEditorConfig);
|
|
361
|
+
get config(): ZylemEditorConfig;
|
|
362
|
+
set launcherMode(value: EditorLauncherMode);
|
|
363
|
+
get launcherMode(): EditorLauncherMode;
|
|
364
|
+
/**
|
|
365
|
+
* Observed attributes for the web component
|
|
366
|
+
*/
|
|
367
|
+
static get observedAttributes(): string[];
|
|
368
|
+
attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
|
|
369
|
+
connectedCallback(): void;
|
|
370
|
+
private initialize;
|
|
371
|
+
openPanel(): void;
|
|
372
|
+
closePanel(): void;
|
|
373
|
+
togglePanel(): void;
|
|
374
|
+
/**
|
|
375
|
+
* Dock a panel to a viewport edge, or pass `null` to float it again.
|
|
376
|
+
* Defaults to the main editor panel.
|
|
377
|
+
*/
|
|
378
|
+
dockPanel(side: DockSide | null, panelId?: DockPanelId): void;
|
|
379
|
+
/**
|
|
380
|
+
* Reinitialize the editor with new configuration.
|
|
381
|
+
* Call this after changing the `config` property if the element is already connected.
|
|
382
|
+
*/
|
|
383
|
+
reinitialize(): void;
|
|
384
|
+
disconnectedCallback(): void;
|
|
385
|
+
private teardown;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Register the ZylemEditorElement as a custom element.
|
|
389
|
+
* Call this function to use the default 'zylem-editor' tag name.
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```js
|
|
393
|
+
* import { registerZylemEditor } from '@zylem/editor';
|
|
394
|
+
* registerZylemEditor();
|
|
395
|
+
* // Now you can use <zylem-editor> in your HTML
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
declare function registerZylemEditor(tagName?: string): void;
|
|
399
|
+
|
|
400
|
+
interface IconProps extends LucideProps {
|
|
401
|
+
icon: Component<LucideProps>;
|
|
402
|
+
}
|
|
403
|
+
declare const Icon: Component<IconProps>;
|
|
293
404
|
|
|
294
405
|
declare const channel: _zylem_bridge.BridgeChannel;
|
|
295
406
|
/**
|
|
@@ -318,6 +429,216 @@ declare function sendEntitySelect(uuid: string | null): void;
|
|
|
318
429
|
declare function sendEntityFocus(uuid: string): void;
|
|
319
430
|
/** Write a stage variable in the running game. */
|
|
320
431
|
declare function sendStageVariable(key: string, value: unknown): void;
|
|
432
|
+
/**
|
|
433
|
+
* Set an entity's transform absolutely.
|
|
434
|
+
*
|
|
435
|
+
* `quaternion` is authoritative when supplied; `rotation` is Euler radians for
|
|
436
|
+
* the numeric fields, and round-trips less cleanly.
|
|
437
|
+
*/
|
|
438
|
+
declare function sendEntityTransform(uuid: string, transform: {
|
|
439
|
+
position?: BridgeVec3;
|
|
440
|
+
rotation?: BridgeVec3;
|
|
441
|
+
quaternion?: BridgeQuat;
|
|
442
|
+
scale?: BridgeVec3;
|
|
443
|
+
}): void;
|
|
444
|
+
/** Arm the game's add tool with a catalog type, or `null` to disarm it. */
|
|
445
|
+
declare function sendAddType(typeId: string | null, props?: Record<string, unknown>): void;
|
|
446
|
+
/** Spawn a catalog entity without a placement click. */
|
|
447
|
+
declare function sendEntityCreate(typeId: string, options?: {
|
|
448
|
+
props?: Record<string, unknown>;
|
|
449
|
+
pose?: BridgePose;
|
|
450
|
+
}): void;
|
|
451
|
+
/** Push snap increments to the game's gizmo. */
|
|
452
|
+
declare function sendSnapSettings(snap: SnapSettingsPayload): void;
|
|
453
|
+
/** Show or hide the game's construction-plane grid. */
|
|
454
|
+
declare function sendGridVisible(visible: boolean): void;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Undo/redo history for scene edits.
|
|
458
|
+
*
|
|
459
|
+
* The editor owns the stack but never the inversion. Every edit originates in
|
|
460
|
+
* the game (gizmo drags, placement clicks, delete clicks), so the game publishes
|
|
461
|
+
* a committed before/after record and the editor stores it. Replaying one sends
|
|
462
|
+
* it back over the bridge: undoing a delete has to produce the original entity
|
|
463
|
+
* with its original uuid, which the editor could not do — all it ever receives
|
|
464
|
+
* is a summary of name, type, and transform.
|
|
465
|
+
*
|
|
466
|
+
* In-memory only. A reload drops history, which is correct: the game's entities
|
|
467
|
+
* are gone too, so the uuids every entry refers to would be dangling.
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Depth cap. Each entry holds two poses per affected entity, so this is cheap;
|
|
472
|
+
* the limit exists so a long editing session cannot grow without bound. The
|
|
473
|
+
* game's detached-entity bin is sized above this, so a uuid still reachable
|
|
474
|
+
* from here is still restorable.
|
|
475
|
+
*/
|
|
476
|
+
declare const MAX_HISTORY_DEPTH = 100;
|
|
477
|
+
interface HistoryState {
|
|
478
|
+
/** Oldest first; the last entry is what `undo()` reverts. */
|
|
479
|
+
undoStack: SceneOperationPayload[];
|
|
480
|
+
/** Operations that have been undone, newest last. */
|
|
481
|
+
redoStack: SceneOperationPayload[];
|
|
482
|
+
}
|
|
483
|
+
declare const historyState: HistoryState;
|
|
484
|
+
declare function canUndo(): boolean;
|
|
485
|
+
declare function canRedo(): boolean;
|
|
486
|
+
/** Label of the operation `undo()` would revert, for menu text. */
|
|
487
|
+
declare function undoLabel(): string | null;
|
|
488
|
+
/** Label of the operation `redo()` would replay. */
|
|
489
|
+
declare function redoLabel(): string | null;
|
|
490
|
+
/** Revert the most recent operation. */
|
|
491
|
+
declare function undo(): boolean;
|
|
492
|
+
/** Replay the most recently undone operation. */
|
|
493
|
+
declare function redo(): boolean;
|
|
494
|
+
/**
|
|
495
|
+
* Drop all history. Called on a fresh stage snapshot, because the entities the
|
|
496
|
+
* stack refers to are gone and replaying an entry would either do nothing or
|
|
497
|
+
* hit an unrelated entity that happens to share a uuid.
|
|
498
|
+
*/
|
|
499
|
+
declare function clearHistory(): void;
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* The placeable entity types the game offers, and which one the Add tool is
|
|
503
|
+
* armed with.
|
|
504
|
+
*
|
|
505
|
+
* The list is game-owned: it arrives over the bridge as `catalog:snapshot`, so
|
|
506
|
+
* a host that registers its own entity types game-side gets them in the palette
|
|
507
|
+
* with no editor change. Icons come through as inline SVG markup because the
|
|
508
|
+
* editor and its hosts do not share an icon library.
|
|
509
|
+
*/
|
|
510
|
+
|
|
511
|
+
interface CatalogState {
|
|
512
|
+
entities: EntityTypeDescriptor[];
|
|
513
|
+
/** Type the Add tool will place, or null when disarmed. */
|
|
514
|
+
armedTypeId: string | null;
|
|
515
|
+
/**
|
|
516
|
+
* Last type chosen from the palette, so re-arming the tool does not make the
|
|
517
|
+
* user re-pick. Survives disarming; cleared only when the catalog no longer
|
|
518
|
+
* contains it.
|
|
519
|
+
*/
|
|
520
|
+
lastTypeId: string | null;
|
|
521
|
+
}
|
|
522
|
+
declare const catalogState: CatalogState;
|
|
523
|
+
declare function setEntityCatalog(entities: EntityTypeDescriptor[]): void;
|
|
524
|
+
declare function setArmedType(typeId: string | null): void;
|
|
525
|
+
|
|
526
|
+
/** Drop the armed placement type and return to the neutral tool. */
|
|
527
|
+
declare function disarmTools(): boolean;
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Keeps the gizmo modes from outliving the selection they act on.
|
|
531
|
+
*
|
|
532
|
+
* The Move/Rotate/Scale buttons are only shown while something is selected, so
|
|
533
|
+
* a tool left active after the selection clears would be unreachable: no button
|
|
534
|
+
* to toggle it off, and the game keeps the simulation paused for the whole time
|
|
535
|
+
* a transform tool is held (see `StageTransformTool.setMode`). Escape already
|
|
536
|
+
* offers a manual way out via `disarmTools`; this is the automatic one.
|
|
537
|
+
*/
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Drop an active transform tool when nothing is selected.
|
|
541
|
+
*
|
|
542
|
+
* @returns `true` when a tool was reset.
|
|
543
|
+
*/
|
|
544
|
+
declare function releaseOrphanedTransformTool(): boolean;
|
|
545
|
+
interface TransformToolGuardOptions {
|
|
546
|
+
/** @default true */
|
|
547
|
+
enabled?: boolean;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Watch the selection and release orphaned transform tools.
|
|
551
|
+
*
|
|
552
|
+
* @returns An uninstall function.
|
|
553
|
+
*/
|
|
554
|
+
declare function installTransformToolGuard(options?: TransformToolGuardOptions): () => void;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Snap settings and grid visibility for the transform tools.
|
|
558
|
+
*
|
|
559
|
+
* Owned by the editor because it is the UI for them, and mirrored to the game
|
|
560
|
+
* over `snap:set` — the gizmo does the actual snapping, since only it knows the
|
|
561
|
+
* drag target.
|
|
562
|
+
*/
|
|
563
|
+
|
|
564
|
+
/** 15 degrees, the default rotation increment. */
|
|
565
|
+
declare const DEFAULT_ROTATE_SNAP: number;
|
|
566
|
+
interface TransformState extends SnapSettingsPayload {
|
|
567
|
+
/** Whether the game draws its construction-plane grid. */
|
|
568
|
+
gridVisible: boolean;
|
|
569
|
+
}
|
|
570
|
+
declare const transformState: TransformState;
|
|
571
|
+
declare function setSnapEnabled(enabled: boolean): void;
|
|
572
|
+
declare function setSnapIncrements(increments: Partial<Pick<TransformState, 'translate' | 'rotate' | 'scale'>>): void;
|
|
573
|
+
declare function setGridVisible(visible: boolean): void;
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Host observation of committed scene edits.
|
|
577
|
+
*
|
|
578
|
+
* Every edit the editor records is also announced here, so an embedding app can
|
|
579
|
+
* react to it — persisting a layout, marking a document dirty, or eventually
|
|
580
|
+
* writing changes back to source. Kept in its own module so `editor-bridge` does
|
|
581
|
+
* not have to import the host surface (which imports the bridge), which would be
|
|
582
|
+
* circular.
|
|
583
|
+
*/
|
|
584
|
+
|
|
585
|
+
type SceneOperationListener = (op: SceneOperationPayload) => void;
|
|
586
|
+
/**
|
|
587
|
+
* Observe committed scene operations.
|
|
588
|
+
*
|
|
589
|
+
* @returns An unsubscribe function.
|
|
590
|
+
*/
|
|
591
|
+
declare function onSceneOperation(listener: SceneOperationListener): () => void;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Stage export.
|
|
595
|
+
*
|
|
596
|
+
* Edits are runtime-only: moving a crate in the editor does not rewrite the
|
|
597
|
+
* source that created it. Export is the bridge between the two — it dumps the
|
|
598
|
+
* current stage as JSON so the values can be pasted back into the code that
|
|
599
|
+
* authored the scene. Source write-back is a later problem; this makes the work
|
|
600
|
+
* recoverable in the meantime.
|
|
601
|
+
*
|
|
602
|
+
* Built from the editor's own bridge state rather than `@zylem/game-lib/schema`,
|
|
603
|
+
* because the editor has no game-lib dependency at runtime and the entity
|
|
604
|
+
* blueprint schema stores 2D positions, which would drop the Z of every
|
|
605
|
+
* transform this feature exists to preserve.
|
|
606
|
+
*/
|
|
607
|
+
|
|
608
|
+
interface StageExportEntity {
|
|
609
|
+
uuid: string;
|
|
610
|
+
name?: string;
|
|
611
|
+
type?: string;
|
|
612
|
+
position?: Vector3Like;
|
|
613
|
+
/** Euler angles in radians, matching the game's own representation. */
|
|
614
|
+
rotation?: Vector3Like;
|
|
615
|
+
scale?: Vector3Like;
|
|
616
|
+
}
|
|
617
|
+
interface StageExport {
|
|
618
|
+
/** Bumped when the shape changes, so an old file is recognisable. */
|
|
619
|
+
version: 1;
|
|
620
|
+
exportedAt: string;
|
|
621
|
+
stage: {
|
|
622
|
+
id: string;
|
|
623
|
+
backgroundColor: string;
|
|
624
|
+
backgroundImage: string | null;
|
|
625
|
+
gravity: Vector3Like;
|
|
626
|
+
variables: Record<string, unknown>;
|
|
627
|
+
} | null;
|
|
628
|
+
entities: StageExportEntity[];
|
|
629
|
+
}
|
|
630
|
+
/** Snapshot the current stage as a plain, serializable object. */
|
|
631
|
+
declare function buildStageExport(): StageExport;
|
|
632
|
+
/** The export as formatted JSON. */
|
|
633
|
+
declare function stageExportToString(): string;
|
|
634
|
+
/**
|
|
635
|
+
* Copy the export to the clipboard.
|
|
636
|
+
*
|
|
637
|
+
* @returns The serialized stage when the copy succeeded, or `null` when the
|
|
638
|
+
* clipboard was unavailable — over plain HTTP, or without a user gesture, the
|
|
639
|
+
* API is either missing or rejects, and the caller falls back to the console.
|
|
640
|
+
*/
|
|
641
|
+
declare function copyStageExport(): Promise<string | null>;
|
|
321
642
|
|
|
322
643
|
/**
|
|
323
644
|
* Editor Host Helpers
|
|
@@ -401,6 +722,17 @@ interface MountZylemEditorOptions extends EditorStateBridgeOptions {
|
|
|
401
722
|
* @default 'floating'
|
|
402
723
|
*/
|
|
403
724
|
launcherMode?: EditorLauncherMode;
|
|
725
|
+
/**
|
|
726
|
+
* Dock layout to seed on first run, keyed by viewport edge. `'main'` is the
|
|
727
|
+
* editor panel; any other id is a section such as `'console'`. Ignored once
|
|
728
|
+
* the user has a saved layout.
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```ts
|
|
732
|
+
* mountZylemEditor({ defaultDocks: { left: ['main'], bottom: ['console'] } });
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
defaultDocks?: EditorDockDefaults;
|
|
404
736
|
/**
|
|
405
737
|
* Element the <zylem-editor> overlay is appended to.
|
|
406
738
|
* @default document.body
|
|
@@ -409,6 +741,8 @@ interface MountZylemEditorOptions extends EditorStateBridgeOptions {
|
|
|
409
741
|
}
|
|
410
742
|
interface MountedZylemEditor extends EditorStateBridge {
|
|
411
743
|
element: ZylemEditorElement;
|
|
744
|
+
/** Dock a panel to a viewport edge, or pass `null` to float it again. */
|
|
745
|
+
dockPanel(side: DockSide | null, panelId?: DockPanelId): void;
|
|
412
746
|
}
|
|
413
747
|
/**
|
|
414
748
|
* Imperatively mount a <zylem-editor> overlay and attach the state bridge.
|
|
@@ -422,4 +756,4 @@ interface MountedZylemEditor extends EditorStateBridge {
|
|
|
422
756
|
*/
|
|
423
757
|
declare function mountZylemEditor(options?: MountZylemEditorOptions): MountedZylemEditor;
|
|
424
758
|
|
|
425
|
-
export { type EditorEvent, type EditorEventType, type EditorStateBridge, type EditorStateBridgeOptions, type EditorUpdatePayload, Icon, type MountZylemEditorOptions, type MountedZylemEditor, type ZylemEditorConfig, ZylemEditorElement, attachEditorStateBridge, channel as bridgeChannel, connectEditorBridge, debugState, debugStore, disconnectEditorBridge, dispatchEditorUpdate, dispatchToEditor, editorEvents, gameState, mountZylemEditor, registerZylemEditor, sendDebugEnabled, sendEntityFocus, sendEntitySelect, sendPlayback, sendStageVariable, sendTool, stageState };
|
|
759
|
+
export { type CatalogState, DEFAULT_ROTATE_SNAP, DOCK_SIDES, type DockPanelId, type DockRect, type DockRegistry, type DockSide, type DockZoneState, type EditorDockDefaults, type EditorEvent, type EditorEventType, type EditorStateBridge, type EditorStateBridgeOptions, type EditorUpdatePayload, type HistoryState, Icon, MAIN_PANEL_ID, MAX_HISTORY_DEPTH, type MountZylemEditorOptions, type MountedZylemEditor, type SceneOperationListener, type StageExport, type StageExportEntity, type TransformState, type TransformToolGuardOptions, type ZylemEditorConfig, ZylemEditorElement, attachEditorStateBridge, channel as bridgeChannel, buildStageExport, canRedo, canUndo, catalogState, clearHistory, computeDockLayout, connectEditorBridge, copyStageExport, debugState, debugStore, disarmTools, disconnectEditorBridge, dispatchEditorUpdate, dispatchToEditor, dockPanelToSide, editorEvents, findDockedSide, gameState, getDockedSide, historyState, installTransformToolGuard, mountZylemEditor, onSceneOperation, redo, redoLabel, registerZylemEditor, releaseOrphanedTransformTool, sendAddType, sendDebugEnabled, sendEntityCreate, sendEntityFocus, sendEntitySelect, sendEntityTransform, sendGridVisible, sendPlayback, sendSnapSettings, sendStageVariable, sendTool, setArmedType, setEntityCatalog, setGridVisible, setSnapEnabled, setSnapIncrements, stageExportToString, stageState, transformState, undo, undoLabel, undockPanelFromSides };
|