@umicat/phaser-sdk 1.0.11 → 1.0.13
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/editor/EditorBridge.d.ts +15 -0
- package/dist/editor/EditorBridge.js +1 -1
- package/dist/editor/EditorOverlayScene.d.ts +2 -0
- package/dist/editor/EditorOverlayScene.js +27 -1
- package/dist/protocol.d.ts +20 -0
- package/dist/scene/HudRuntime.js +4 -1
- package/dist/scene/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -3,6 +3,21 @@ import { AssetRecord } from '../scene/types.js';
|
|
|
3
3
|
import { TilemapEditOp } from '../protocol.js';
|
|
4
4
|
export declare function setupEditorBridge(game: Phaser.Game): void;
|
|
5
5
|
export declare function postSelectionRect(game: Phaser.Game): void;
|
|
6
|
+
/**
|
|
7
|
+
* Compute the entity's DOM screen rect — viewport pixels relative to the
|
|
8
|
+
* iframe's top-left. The host adds the iframe's bounding rect to translate
|
|
9
|
+
* into page coords.
|
|
10
|
+
*
|
|
11
|
+
* Path: world coords → camera transform → canvas pixels → iframe pixels.
|
|
12
|
+
* Phaser's Scale.FIT may letterbox/pillarbox the canvas inside the iframe,
|
|
13
|
+
* so we factor in the canvas's parent offset too.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeScreenRect(game: Phaser.Game, go: Phaser.GameObjects.GameObject): {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
} | null;
|
|
6
21
|
/**
|
|
7
22
|
* FB.9a — return ALL entities at the given world coords, sorted by depth
|
|
8
23
|
* DESC (topmost first). Used by EditorOverlayScene's Alt+click handler
|
|
@@ -574,7 +574,7 @@ function doPostSelectionRect(game) {
|
|
|
574
574
|
* Phaser's Scale.FIT may letterbox/pillarbox the canvas inside the iframe,
|
|
575
575
|
* so we factor in the canvas's parent offset too.
|
|
576
576
|
*/
|
|
577
|
-
function computeScreenRect(game, go) {
|
|
577
|
+
export function computeScreenRect(game, go) {
|
|
578
578
|
// Pull entity-local bounds — same logic the editor uses for hit-test.
|
|
579
579
|
const hitW = go.getData('editorHitWidth');
|
|
580
580
|
const hitH = go.getData('editorHitHeight');
|
|
@@ -84,6 +84,8 @@ export declare class EditorOverlayScene extends Phaser.Scene {
|
|
|
84
84
|
private postDragEnd;
|
|
85
85
|
private postShortcut;
|
|
86
86
|
private applyPanZoom;
|
|
87
|
+
/** Last pointerdown's entity + time — used to detect a double-click (inline text edit). */
|
|
88
|
+
private lastDownInfo;
|
|
87
89
|
private panActive;
|
|
88
90
|
private spaceHeld;
|
|
89
91
|
private panStartScreen;
|
|
@@ -4,7 +4,7 @@ import { findHudEntity, findHudRegistry, UMICAT_HUD_SCENE_KEY, } from '../scene/
|
|
|
4
4
|
import { isPerFrameHitbox } from '../scene/types.js';
|
|
5
5
|
import { getManifest } from '../scene/SceneLoader.js';
|
|
6
6
|
import { getEditorState, startDrag, clearDrag, getDrag, getSelection, getEditorMode, getDebugOverlayState, getTilemapToolState, isTilemapPaintMode, beginTilemapStroke, beginAutotileStroke, appendTilemapStrokeCell, appendAutotileStrokeClick, endTilemapStroke, getTilemapStroke, beginTilemapRect, updateTilemapRect, endTilemapRect, getTilemapRect, getTilemapResize, beginTilemapResize, updateTilemapResize, endTilemapResize, getEntityResize, beginEntityResize, updateEntityResize, endEntityResize, } from './EditorState.js';
|
|
7
|
-
import { applyTilemapOp, findTilemapLayerById, handleEditTilemap, postSelectionRect } from './EditorBridge.js';
|
|
7
|
+
import { applyTilemapOp, computeScreenRect, findTilemapLayerById, handleEditTilemap, postSelectionRect } from './EditorBridge.js';
|
|
8
8
|
import { applyAutotile, findTerrain, getAutotileKind } from '../scene/autotile.js';
|
|
9
9
|
/**
|
|
10
10
|
* Editor overlay — slice 2.
|
|
@@ -65,6 +65,8 @@ const ANCHOR_CROSS_LEN = 6;
|
|
|
65
65
|
export class EditorOverlayScene extends Phaser.Scene {
|
|
66
66
|
constructor() {
|
|
67
67
|
super({ key: EDITOR_OVERLAY_KEY });
|
|
68
|
+
/** Last pointerdown's entity + time — used to detect a double-click (inline text edit). */
|
|
69
|
+
this.lastDownInfo = null;
|
|
68
70
|
// P1 infinite canvas — input state. Pan can be triggered by middle-button
|
|
69
71
|
// drag OR by space+left-drag. We accumulate a "pan active" flag so the
|
|
70
72
|
// existing selection / drag-to-move handlers don't fire while panning.
|
|
@@ -289,6 +291,30 @@ export class EditorOverlayScene extends Phaser.Scene {
|
|
|
289
291
|
this.postPick(null, modifiers);
|
|
290
292
|
return;
|
|
291
293
|
}
|
|
294
|
+
// Double-click a text-bearing HUD widget (icon-button label / text widget) →
|
|
295
|
+
// tell the host to open an inline text editor over it (Figma convention —
|
|
296
|
+
// beats hunting for the Inspector's Label field). The first click already
|
|
297
|
+
// selected it; the second opens the editor instead of starting a drag.
|
|
298
|
+
const dblKind = hit.getData('entityKind');
|
|
299
|
+
const downTime = pointer.downTime;
|
|
300
|
+
const isDoubleClick = this.lastDownInfo?.id === entityId && downTime - this.lastDownInfo.time < 350;
|
|
301
|
+
this.lastDownInfo = { id: entityId, time: downTime };
|
|
302
|
+
if (isDoubleClick &&
|
|
303
|
+
getEditorMode(this.game) === 'hud' &&
|
|
304
|
+
(dblKind === 'icon-button' || dblKind === 'text')) {
|
|
305
|
+
const rect = computeScreenRect(this.game, hit);
|
|
306
|
+
if (rect) {
|
|
307
|
+
const msg = {
|
|
308
|
+
type: 'umicat:editor:editText',
|
|
309
|
+
entityId,
|
|
310
|
+
kind: dblKind,
|
|
311
|
+
rect,
|
|
312
|
+
};
|
|
313
|
+
window.parent.postMessage(msg, '*');
|
|
314
|
+
event?.preventDefault?.();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
292
318
|
// Surface the prefab id when the picked GameObject was spawned via
|
|
293
319
|
// `spawnPrefab` (set on the data manager at spawn — see Prefabs.ts).
|
|
294
320
|
// The host routes prefab-instance picks to the Prefab Inspector.
|
package/dist/protocol.d.ts
CHANGED
|
@@ -715,6 +715,26 @@ export interface EditorEntityResizedMessage {
|
|
|
715
715
|
height: number;
|
|
716
716
|
};
|
|
717
717
|
}
|
|
718
|
+
/**
|
|
719
|
+
* Double-click on a text-bearing HUD widget (icon-button label / text widget) —
|
|
720
|
+
* the host renders an inline `<input>` over the widget so the user edits the
|
|
721
|
+
* text directly on the canvas (Figma/Canva convention) instead of hunting for
|
|
722
|
+
* the Inspector field. `rect` is iframe-relative px (host adds the iframe offset
|
|
723
|
+
* to position the overlay). The host reads the CURRENT text from its scene state
|
|
724
|
+
* and commits the edit via the normal applyEdit/patch path.
|
|
725
|
+
*/
|
|
726
|
+
export interface EditorEditTextMessage {
|
|
727
|
+
type: 'umicat:editor:editText';
|
|
728
|
+
entityId: string;
|
|
729
|
+
/** Which HUD widget kind — tells the host which field to edit (label vs source). */
|
|
730
|
+
kind: 'icon-button' | 'text';
|
|
731
|
+
rect: {
|
|
732
|
+
x: number;
|
|
733
|
+
y: number;
|
|
734
|
+
width: number;
|
|
735
|
+
height: number;
|
|
736
|
+
};
|
|
737
|
+
}
|
|
718
738
|
/**
|
|
719
739
|
* Editor keyboard shortcut intercepted inside the iframe (user clicked the
|
|
720
740
|
* canvas, so focus is on the iframe and the host window doesn't see the
|
package/dist/scene/HudRuntime.js
CHANGED
|
@@ -264,6 +264,9 @@ export function spawnHudEntity(ctx, entity) {
|
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
go.setData('entityId', entity.id);
|
|
267
|
+
// Stamp the kind (mirrors spawnEntity for world entities) so the editor can
|
|
268
|
+
// branch on it — e.g. double-click an icon-button/text widget for inline edit.
|
|
269
|
+
go.setData('entityKind', entity.kind);
|
|
267
270
|
// Z-order. Layer first (base < overlay < modal), then explicit z within layer.
|
|
268
271
|
const layerDepth = LAYER_DEPTH[entity.layer ?? 'base'];
|
|
269
272
|
const z = typeof entity.z === 'number' ? entity.z : 0;
|
|
@@ -428,7 +431,7 @@ function createIconButton(ctx, entity, pos) {
|
|
|
428
431
|
}
|
|
429
432
|
if (v.label) {
|
|
430
433
|
const label = ctx.scene.add.text(0, 0, v.label, {
|
|
431
|
-
fontFamily: 'sans-serif',
|
|
434
|
+
fontFamily: v.fontFamily ?? 'sans-serif',
|
|
432
435
|
fontSize: `${v.fontSize ?? 16}px`,
|
|
433
436
|
color: v.textColor ?? '#ffffff',
|
|
434
437
|
});
|
package/dist/scene/types.d.ts
CHANGED
|
@@ -1213,6 +1213,8 @@ export interface HudIconButtonEntity extends HudEntityBase {
|
|
|
1213
1213
|
strokeWidth?: number;
|
|
1214
1214
|
pressedFillColor?: string;
|
|
1215
1215
|
textColor?: string;
|
|
1216
|
+
/** Label font family (matches a loaded font; default `sans-serif`). */
|
|
1217
|
+
fontFamily?: string;
|
|
1216
1218
|
fontSize?: number;
|
|
1217
1219
|
}
|
|
1218
1220
|
export interface HudProgressBarEntity extends HudEntityBase {
|