@pixi-ui-editor/runtime-pixi 0.14.0 → 0.15.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/SceneViewport.js.map +1 -1
- package/dist/assets/bitmapFonts.d.ts +2 -0
- package/dist/assets/bitmapFonts.d.ts.map +1 -1
- package/dist/assets/bitmapFonts.js +3 -1
- package/dist/assets/bitmapFonts.js.map +1 -1
- package/dist/assets/sounds.d.ts +1 -7
- package/dist/assets/sounds.d.ts.map +1 -1
- package/dist/assets/sounds.js +7 -90
- package/dist/assets/sounds.js.map +1 -1
- package/dist/assets/textures.d.ts +10 -0
- package/dist/assets/textures.d.ts.map +1 -1
- package/dist/assets/textures.js +10 -2
- package/dist/assets/textures.js.map +1 -1
- package/dist/audio/bus.d.ts +60 -0
- package/dist/audio/bus.d.ts.map +1 -0
- package/dist/audio/bus.js +38 -0
- package/dist/audio/bus.js.map +1 -0
- package/dist/audio/director.d.ts +35 -0
- package/dist/audio/director.d.ts.map +1 -0
- package/dist/audio/director.js +137 -0
- package/dist/audio/director.js.map +1 -0
- package/dist/controls.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/particles.js.map +1 -1
- package/dist/scene.d.ts +6 -2
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +5 -2
- package/dist/scene.js.map +1 -1
- package/dist/transformSpace.d.ts +119 -0
- package/dist/transformSpace.d.ts.map +1 -0
- package/dist/transformSpace.js +487 -0
- package/dist/transformSpace.js.map +1 -0
- package/dist/views/ButtonNodeView.d.ts +4 -3
- package/dist/views/ButtonNodeView.d.ts.map +1 -1
- package/dist/views/ButtonNodeView.js +9 -8
- package/dist/views/ButtonNodeView.js.map +1 -1
- package/dist/views/CheckboxNodeView.d.ts +4 -3
- package/dist/views/CheckboxNodeView.d.ts.map +1 -1
- package/dist/views/CheckboxNodeView.js +7 -7
- package/dist/views/CheckboxNodeView.js.map +1 -1
- package/dist/views/ItemTableNodeView.js.map +1 -1
- package/dist/views/PaginationNodeView.js.map +1 -1
- package/dist/views/ParticleEmitterNodeView.js.map +1 -1
- package/dist/views/StagedButtonNodeView.d.ts +4 -3
- package/dist/views/StagedButtonNodeView.d.ts.map +1 -1
- package/dist/views/StagedButtonNodeView.js +7 -9
- package/dist/views/StagedButtonNodeView.js.map +1 -1
- package/dist/views/basic.js.map +1 -1
- package/dist/views/createNodeView.d.ts +2 -2
- package/dist/views/createNodeView.d.ts.map +1 -1
- package/dist/views/createNodeView.js +4 -4
- package/dist/views/createNodeView.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"ButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAgD,OAAO,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAK7D;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAU;IAE9B,YAAY,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,UAAU,EAStI;IAED;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,MAAM,CAAC,eAAe;IAW9B,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAKnC;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAgCnB,uGAAuG;IACvG,OAAO,CAAC,YAAY;IAMpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAmDxE;IAED,2FAA2F;IAC3F,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAS/C;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAEpC;IAED,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,CAA+B;IAClE,IAAI,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,CAA6B;IAC5D,IAAI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,CAAgC;IACrE,IAAI,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,CAA8B;CAChE"}
|
|
@@ -17,13 +17,15 @@ export class ButtonNodeView extends NodeView {
|
|
|
17
17
|
button;
|
|
18
18
|
stateViews;
|
|
19
19
|
interaction;
|
|
20
|
-
|
|
20
|
+
audio;
|
|
21
|
+
nodeId;
|
|
21
22
|
soundAssetIds;
|
|
22
23
|
enabledState;
|
|
23
|
-
constructor(node, textures, interaction,
|
|
24
|
+
constructor(node, textures, interaction, audio) {
|
|
24
25
|
super(textures);
|
|
25
26
|
this.interaction = interaction;
|
|
26
|
-
this.
|
|
27
|
+
this.audio = audio;
|
|
28
|
+
this.nodeId = node.id;
|
|
27
29
|
this.soundAssetIds = node.sounds;
|
|
28
30
|
this.enabledState = node.enabled;
|
|
29
31
|
this.buildButton(node);
|
|
@@ -84,11 +86,10 @@ export class ButtonNodeView extends NodeView {
|
|
|
84
86
|
// Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.
|
|
85
87
|
if (this.interaction === "authoring")
|
|
86
88
|
button.eventMode = "none";
|
|
87
|
-
else if (this.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
button.onHover.connect(() =>
|
|
91
|
-
void result.catch(() => undefined); });
|
|
89
|
+
else if (this.audio !== undefined) {
|
|
90
|
+
// Вьюха только объявляет, что произошло: играть или нет — решает подписчик шины (см. audio/bus.ts).
|
|
91
|
+
button.onPress.connect(() => this.audio?.cue("button.press", this.nodeId, this.soundAssetIds?.pressAssetId));
|
|
92
|
+
button.onHover.connect(() => this.audio?.cue("button.hover", this.nodeId, this.soundAssetIds?.hoverAssetId));
|
|
92
93
|
}
|
|
93
94
|
this.button = button;
|
|
94
95
|
this.stateViews = stateViews;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport type { Sound } from \"@pixi/sound\";\r\nimport { Container, Graphics, NineSliceSprite, Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type ButtonNode = Extract<UINode, { type: \"button\" }>;\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\nconst KEY_BY_FANCY_STATE = { default: \"normal\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a button node to `@pixi/ui`'s `FancyButton`, which owns the pointer state machine —\r\n * this class never reimplements it. Optional states fall back to the normal image, and runtime\r\n * changes to `enabled` or the current state stay in the view: they never touch the document.\r\n *\r\n * `nineSlice`, when set, applies the same borders to all four state views (`NineSliceSprite`\r\n * instead of `Sprite`) — the button's frame shape is normally the same regardless of which state\r\n * image is currently shown.\r\n */\r\nexport class ButtonNodeView extends NodeView {\r\n private button!: FancyButton;\r\n private stateViews!: Record<ButtonStateKey, Container>;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly sounds: ReadonlyMap<string, Sound> | undefined;\r\n private soundAssetIds: ButtonNode[\"sounds\"];\r\n private enabledState: boolean;\r\n\r\n constructor(node: ButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, sounds?: ReadonlyMap<string, Sound>) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.sounds = sounds;\r\n this.soundAssetIds = node.sounds;\r\n this.enabledState = node.enabled;\r\n this.buildButton(node);\r\n this.applyEnabled(node.enabled);\r\n }\r\n\r\n /**\r\n * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry\r\n * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:\r\n * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to\r\n * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default\r\n * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.\r\n */\r\n private static paintPlaceholder(graphics: Graphics, width: number, height: number): void {\r\n graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });\r\n }\r\n\r\n private static createStateView(texture: Texture | undefined, nineSlice: LayoutPadding | undefined, size: { width: number; height: number }): Container {\r\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n ButtonNodeView.paintPlaceholder(graphics, size.width, size.height);\r\n return graphics;\r\n }\r\n return nineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });\r\n }\r\n\r\n private static applyStateAppearance(view: Container, node: ButtonNode, state: ButtonStateKey): void {\r\n view.tint = node.states[`${state}Tint`] ?? \"#ffffff\";\r\n view.alpha = node.states[`${state}Opacity`] ?? 1;\r\n }\r\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view\r\n * after construction, so any change to a view's *type* — nine-slice toggled, or an asset\r\n * finishing an async load — goes through here instead of `syncContent`'s cheap in-place path.\r\n *\r\n * `size` is the best size known *right now*: the resolved layout rectangle when called from\r\n * `syncContent`, or the authored transform when called from the constructor (before any layout\r\n * pass has run). Only feeds the initial placeholder paint above — see its doc comment for why.\r\n */\r\n private buildButton(node: ButtonNode, size?: { width: number; height: number }): void {\r\n const nineSlice = node.nineSlice;\r\n const resolvedSize = size ?? { width: node.transform.width, height: node.transform.height };\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n const stateViews = {} as Record<ButtonStateKey, Container>;\r\n const viewFor = (state: ButtonStateKey, assetId: string | undefined): Container => {\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", node.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", node.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", node.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", node.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна: FancyButton уже включил себе eventMode \"static\", снимаем его до applyEnabled.\r\n // Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else if (this.sounds !== undefined) {\r\n button.onPress.connect(() => { const result = this.soundAssetIds?.pressAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.pressAssetId)?.play(); if (result instanceof Promise) void result.catch(() => undefined); });\r\n button.onHover.connect(() => { const result = this.soundAssetIds?.hoverAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.hoverAssetId)?.play(); if (result instanceof Promise) void result.catch(() => undefined); });\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"runtime\") this.button.enabled = enabled;\r\n else this.button.setState(enabled ? \"default\" : \"disabled\");\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"button\") return;\r\n this.soundAssetIds = node.sounds;\r\n const nineSlice = node.nineSlice;\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n\r\n // A state view's required *type* (Graphics/Sprite/NineSliceSprite) may no longer match what's\r\n // needed — nine-slice toggled, or a texture finished loading after this view had to fall back\r\n // to Graphics. FancyButton can't swap a view after construction, so that goes through a full\r\n // rebuild; everything else (texture identity, border values, size) updates the live views in\r\n // place, which is the path a nine-slice gizmo drag runs every frame.\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = this.stateViews[state];\r\n const wantsNineSlice = texture !== undefined && nineSlice !== undefined;\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite && !(view instanceof NineSliceSprite);\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton(node, transform);\r\n } else {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n // Set the texture before the layout size: Sprite/NineSliceSprite preserve scale when their\r\n // texture changes, so sizing first would shift visual bounds for a differently-sized source.\r\n if (view instanceof NineSliceSprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n if (nineSlice !== undefined) {\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Graphics) {\r\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\r\n }\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n }\r\n }\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n /** Editor-only live preview of nine-slice border edits while dragging the canvas gizmo. */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (!(view instanceof NineSliceSprite)) continue;\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get state(): ButtonStateKey {\r\n return KEY_BY_FANCY_STATE[this.button.state];\r\n }\r\n\r\n /** Forces a visual state without changing `enabled`, so a disabled button still emits no press. */\r\n setState(state: ButtonStateKey): void {\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n\r\n get onPress(): FancyButton[\"onPress\"] { return this.button.onPress; }\r\n get onDown(): FancyButton[\"onDown\"] { return this.button.onDown; }\r\n get onUp(): FancyButton[\"onUp\"] { return this.button.onUp; }\r\n get onHover(): FancyButton[\"onHover\"] { return this.button.onHover; }\r\n get onOut(): FancyButton[\"onOut\"] { return this.button.onOut; }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport { Container, Graphics, NineSliceSprite, Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\n\r\nexport type ButtonNode = Extract<UINode, { type: \"button\" }>;\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\nconst KEY_BY_FANCY_STATE = { default: \"normal\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a button node to `@pixi/ui`'s `FancyButton`, which owns the pointer state machine —\r\n * this class never reimplements it. Optional states fall back to the normal image, and runtime\r\n * changes to `enabled` or the current state stay in the view: they never touch the document.\r\n *\r\n * `nineSlice`, when set, applies the same borders to all four state views (`NineSliceSprite`\r\n * instead of `Sprite`) — the button's frame shape is normally the same regardless of which state\r\n * image is currently shown.\r\n */\r\nexport class ButtonNodeView extends NodeView {\r\n private button!: FancyButton;\r\n private stateViews!: Record<ButtonStateKey, Container>;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly audio: SceneAudio | undefined;\r\n private readonly nodeId: string;\r\n private soundAssetIds: ButtonNode[\"sounds\"];\r\n private enabledState: boolean;\r\n\r\n constructor(node: ButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.audio = audio;\r\n this.nodeId = node.id;\r\n this.soundAssetIds = node.sounds;\r\n this.enabledState = node.enabled;\r\n this.buildButton(node);\r\n this.applyEnabled(node.enabled);\r\n }\r\n\r\n /**\r\n * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry\r\n * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:\r\n * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to\r\n * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default\r\n * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.\r\n */\r\n private static paintPlaceholder(graphics: Graphics, width: number, height: number): void {\r\n graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });\r\n }\r\n\r\n private static createStateView(texture: Texture | undefined, nineSlice: LayoutPadding | undefined, size: { width: number; height: number }): Container {\r\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n ButtonNodeView.paintPlaceholder(graphics, size.width, size.height);\r\n return graphics;\r\n }\r\n return nineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });\r\n }\r\n\r\n private static applyStateAppearance(view: Container, node: ButtonNode, state: ButtonStateKey): void {\r\n view.tint = node.states[`${state}Tint`] ?? \"#ffffff\";\r\n view.alpha = node.states[`${state}Opacity`] ?? 1;\r\n }\r\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view\r\n * after construction, so any change to a view's *type* — nine-slice toggled, or an asset\r\n * finishing an async load — goes through here instead of `syncContent`'s cheap in-place path.\r\n *\r\n * `size` is the best size known *right now*: the resolved layout rectangle when called from\r\n * `syncContent`, or the authored transform when called from the constructor (before any layout\r\n * pass has run). Only feeds the initial placeholder paint above — see its doc comment for why.\r\n */\r\n private buildButton(node: ButtonNode, size?: { width: number; height: number }): void {\r\n const nineSlice = node.nineSlice;\r\n const resolvedSize = size ?? { width: node.transform.width, height: node.transform.height };\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n const stateViews = {} as Record<ButtonStateKey, Container>;\r\n const viewFor = (state: ButtonStateKey, assetId: string | undefined): Container => {\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", node.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", node.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", node.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", node.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна: FancyButton уже включил себе eventMode \"static\", снимаем его до applyEnabled.\r\n // Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else if (this.audio !== undefined) {\r\n // Вьюха только объявляет, что произошло: играть или нет — решает подписчик шины (см. audio/bus.ts).\r\n button.onPress.connect(() => this.audio?.cue(\"button.press\", this.nodeId, this.soundAssetIds?.pressAssetId));\r\n button.onHover.connect(() => this.audio?.cue(\"button.hover\", this.nodeId, this.soundAssetIds?.hoverAssetId));\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"runtime\") this.button.enabled = enabled;\r\n else this.button.setState(enabled ? \"default\" : \"disabled\");\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"button\") return;\r\n this.soundAssetIds = node.sounds;\r\n const nineSlice = node.nineSlice;\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n\r\n // A state view's required *type* (Graphics/Sprite/NineSliceSprite) may no longer match what's\r\n // needed — nine-slice toggled, or a texture finished loading after this view had to fall back\r\n // to Graphics. FancyButton can't swap a view after construction, so that goes through a full\r\n // rebuild; everything else (texture identity, border values, size) updates the live views in\r\n // place, which is the path a nine-slice gizmo drag runs every frame.\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = this.stateViews[state];\r\n const wantsNineSlice = texture !== undefined && nineSlice !== undefined;\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite && !(view instanceof NineSliceSprite);\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton(node, transform);\r\n } else {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n // Set the texture before the layout size: Sprite/NineSliceSprite preserve scale when their\r\n // texture changes, so sizing first would shift visual bounds for a differently-sized source.\r\n if (view instanceof NineSliceSprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n if (nineSlice !== undefined) {\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Graphics) {\r\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\r\n }\r\n ButtonNodeView.applyStateAppearance(view, node, state);\r\n }\r\n }\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n /** Editor-only live preview of nine-slice border edits while dragging the canvas gizmo. */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (!(view instanceof NineSliceSprite)) continue;\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get state(): ButtonStateKey {\r\n return KEY_BY_FANCY_STATE[this.button.state];\r\n }\r\n\r\n /** Forces a visual state without changing `enabled`, so a disabled button still emits no press. */\r\n setState(state: ButtonStateKey): void {\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n\r\n get onPress(): FancyButton[\"onPress\"] { return this.button.onPress; }\r\n get onDown(): FancyButton[\"onDown\"] { return this.button.onDown; }\r\n get onUp(): FancyButton[\"onUp\"] { return this.button.onUp; }\r\n get onHover(): FancyButton[\"onHover\"] { return this.button.onHover; }\r\n get onOut(): FancyButton[\"onOut\"] { return this.button.onOut; }\r\n}\r\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type CheckboxStateKey, type UINode } from "@pixi-ui-editor/schema";
|
|
2
2
|
import { CheckBox } from "@pixi/ui";
|
|
3
|
-
import type { Sound } from "@pixi/sound";
|
|
4
3
|
import { Texture } from "pixi.js";
|
|
5
4
|
import { NodeView, type SceneInteractionMode } from "./NodeView.js";
|
|
5
|
+
import type { SceneAudio } from "../audio/bus.js";
|
|
6
6
|
export type CheckboxNode = Extract<UINode, {
|
|
7
7
|
type: "checkbox";
|
|
8
8
|
}>;
|
|
@@ -20,7 +20,8 @@ export type CheckboxNode = Extract<UINode, {
|
|
|
20
20
|
export declare class CheckboxNodeView extends NodeView {
|
|
21
21
|
private readonly checkbox;
|
|
22
22
|
private readonly interaction;
|
|
23
|
-
private readonly
|
|
23
|
+
private readonly audio;
|
|
24
|
+
private readonly nodeId;
|
|
24
25
|
private soundAssetIds;
|
|
25
26
|
private uncheckedTexture;
|
|
26
27
|
private checkedTexture;
|
|
@@ -28,7 +29,7 @@ export declare class CheckboxNodeView extends NodeView {
|
|
|
28
29
|
private checkedHoverTexture;
|
|
29
30
|
private enabledState;
|
|
30
31
|
private hovering;
|
|
31
|
-
constructor(node: CheckboxNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode,
|
|
32
|
+
constructor(node: CheckboxNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio);
|
|
32
33
|
private hoverTextureFor;
|
|
33
34
|
/** Puts the current hover/non-hover texture on both internal Sprites; switching visibility is Switcher's job. */
|
|
34
35
|
private applyTextures;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxNodeView.d.ts","sourceRoot":"","sources":["../../src/views/CheckboxNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"CheckboxNodeView.d.ts","sourceRoot":"","sources":["../../src/views/CheckboxNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAU,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAEjE;;;;;;;;;;GAUG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,qBAAqB,CAAU;IACvC,OAAO,CAAC,mBAAmB,CAAU;IACrC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,QAAQ,CAAS;IAEzB,YAAY,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,UAAU,EAiCxI;IAED,OAAO,CAAC,eAAe;IAIvB,iHAAiH;IACjH,OAAO,CAAC,aAAa;IAMrB,4GAA4G;IAC5G,OAAO,CAAC,YAAY;IAMpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAsBxE;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,uGAAuG;IACvG,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEjC;IAED,IAAI,KAAK,IAAI,gBAAgB,CAE5B;IAED,IAAI,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAkC;CACrE"}
|
|
@@ -16,7 +16,8 @@ import { NodeView } from "./NodeView.js";
|
|
|
16
16
|
export class CheckboxNodeView extends NodeView {
|
|
17
17
|
checkbox;
|
|
18
18
|
interaction;
|
|
19
|
-
|
|
19
|
+
audio;
|
|
20
|
+
nodeId;
|
|
20
21
|
soundAssetIds;
|
|
21
22
|
uncheckedTexture;
|
|
22
23
|
checkedTexture;
|
|
@@ -24,10 +25,11 @@ export class CheckboxNodeView extends NodeView {
|
|
|
24
25
|
checkedHoverTexture;
|
|
25
26
|
enabledState;
|
|
26
27
|
hovering = false;
|
|
27
|
-
constructor(node, textures, interaction,
|
|
28
|
+
constructor(node, textures, interaction, audio) {
|
|
28
29
|
super(textures);
|
|
29
30
|
this.interaction = interaction;
|
|
30
|
-
this.
|
|
31
|
+
this.audio = audio;
|
|
32
|
+
this.nodeId = node.id;
|
|
31
33
|
this.soundAssetIds = node.sounds;
|
|
32
34
|
const unchecked = this.textureFor(node.states.uncheckedAssetId) ?? Texture.WHITE;
|
|
33
35
|
const checked = this.textureFor(node.states.checkedAssetId) ?? Texture.WHITE;
|
|
@@ -47,12 +49,10 @@ export class CheckboxNodeView extends NodeView {
|
|
|
47
49
|
else {
|
|
48
50
|
this.checkbox.innerView.on("pointerover", () => { this.hovering = true; this.applyTextures(); });
|
|
49
51
|
this.checkbox.innerView.on("pointerout", () => { this.hovering = false; this.applyTextures(); });
|
|
50
|
-
if (
|
|
52
|
+
if (audio !== undefined) {
|
|
51
53
|
this.checkbox.onCheck.connect((checkedState) => {
|
|
52
54
|
const assetId = checkedState ? this.soundAssetIds?.checkAssetId : this.soundAssetIds?.uncheckAssetId;
|
|
53
|
-
|
|
54
|
-
if (result instanceof Promise)
|
|
55
|
-
void result.catch(() => undefined);
|
|
55
|
+
this.audio?.cue(checkedState ? "checkbox.check" : "checkbox.uncheck", this.nodeId, assetId);
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxNodeView.js","sourceRoot":"","sources":["../../src/views/CheckboxNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { CHECKBOX_STATE_KEYS, type CheckboxStateKey, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { CheckBox } from \"@pixi/ui\";\r\nimport type { Sound } from \"@pixi/sound\";\r\nimport { Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type CheckboxNode = Extract<UINode, { type: \"checkbox\" }>;\r\n\r\n/**\r\n * Adapts a checkbox node to `@pixi/ui`'s `CheckBox`, which owns the checked/unchecked switching —\r\n * this class never reimplements it. `group`-based radio exclusivity is wired one layer up, in\r\n * `wireCheckboxGroups` (see scene.ts): this view only exposes `forceCheck` so that wiring can flip\r\n * a sibling without re-emitting `onCheck` and recursing back into itself.\r\n *\r\n * Hover is layered on top of `CheckBox` by hand: unlike `FancyButton`, `CheckBox`/`Switcher` only\r\n * switches between its checked/unchecked views and has no hover state slot of its own. Both of its\r\n * internal Sprites always carry the texture matching the current hover flag — whichever one is\r\n * `visible` at any moment is Switcher's concern, not ours.\r\n */\r\nexport class CheckboxNodeView extends NodeView {\r\n private readonly checkbox: CheckBox;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly sounds: ReadonlyMap<string, Sound> | undefined;\r\n private soundAssetIds: CheckboxNode[\"sounds\"];\r\n private uncheckedTexture: Texture;\r\n private checkedTexture: Texture;\r\n private uncheckedHoverTexture: Texture;\r\n private checkedHoverTexture: Texture;\r\n private enabledState: boolean;\r\n private hovering = false;\r\n\r\n constructor(node: CheckboxNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, sounds?: ReadonlyMap<string, Sound>) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.sounds = sounds;\r\n this.soundAssetIds = node.sounds;\r\n const unchecked = this.textureFor(node.states.uncheckedAssetId) ?? Texture.WHITE;\r\n const checked = this.textureFor(node.states.checkedAssetId) ?? Texture.WHITE;\r\n this.uncheckedTexture = unchecked;\r\n this.checkedTexture = checked;\r\n this.uncheckedHoverTexture = this.hoverTextureFor(node.states.uncheckedHoverAssetId, unchecked);\r\n this.checkedHoverTexture = this.hoverTextureFor(node.states.checkedHoverAssetId, checked);\r\n this.checkbox = new CheckBox({\r\n checked: node.defaultChecked,\r\n style: { unchecked, checked },\r\n });\r\n // Authoring-сцена инертна, как и у button: eventMode \"none\" на верхнем контейнере отключает\r\n // hit-testing всего поддерева, включая `innerView`, который Switcher сам сделал \"static\" — а\r\n // значит и hover в authoring никогда не наступает, так что его незачем отдельно отключать.\r\n if (interaction === \"authoring\") this.checkbox.eventMode = \"none\";\r\n else {\r\n this.checkbox.innerView.on(\"pointerover\", () => { this.hovering = true; this.applyTextures(); });\r\n this.checkbox.innerView.on(\"pointerout\", () => { this.hovering = false; this.applyTextures(); });\r\n if (sounds !== undefined) {\r\n this.checkbox.onCheck.connect((checkedState) => {\r\n const assetId = checkedState ? this.soundAssetIds?.checkAssetId : this.soundAssetIds?.uncheckAssetId;\r\n const result = assetId === undefined ? undefined : this.sounds?.get(assetId)?.play();\r\n if (result instanceof Promise) void result.catch(() => undefined);\r\n });\r\n }\r\n }\r\n this.enabledState = node.enabled;\r\n this.applyEnabled(node.enabled);\r\n this.setContent(this.checkbox);\r\n }\r\n\r\n private hoverTextureFor(assetId: string | undefined, fallback: Texture): Texture {\r\n return (assetId === undefined ? undefined : this.textureFor(assetId)) ?? fallback;\r\n }\r\n\r\n /** Puts the current hover/non-hover texture on both internal Sprites; switching visibility is Switcher's job. */\r\n private applyTextures(): void {\r\n const [uncheckedView, checkedView] = this.checkbox.views;\r\n if (uncheckedView instanceof Sprite) uncheckedView.texture = this.hovering ? this.uncheckedHoverTexture : this.uncheckedTexture;\r\n if (checkedView instanceof Sprite) checkedView.texture = this.hovering ? this.checkedHoverTexture : this.checkedTexture;\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive selectability elsewhere: this view stays inert either way. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"authoring\") return;\r\n this.checkbox.eventMode = enabled ? \"static\" : \"none\";\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"checkbox\") return;\r\n this.soundAssetIds = node.sounds;\r\n\r\n const unchecked = this.textureFor(node.states.uncheckedAssetId) ?? Texture.WHITE;\r\n const checked = this.textureFor(node.states.checkedAssetId) ?? Texture.WHITE;\r\n // `style` rebuilds both internal views, so it's only reassigned when a base texture actually\r\n // changed — same rule ButtonNodeView follows for its state Sprites. A fresh pair of Sprites\r\n // starts out holding the plain (non-hover) textures `style` was given, so `applyTextures` always\r\n // runs afterwards to restore the current hover look.\r\n if (unchecked !== this.uncheckedTexture || checked !== this.checkedTexture) {\r\n this.uncheckedTexture = unchecked;\r\n this.checkedTexture = checked;\r\n this.checkbox.style = { unchecked, checked };\r\n }\r\n this.uncheckedHoverTexture = this.hoverTextureFor(node.states.uncheckedHoverAssetId, unchecked);\r\n this.checkedHoverTexture = this.hoverTextureFor(node.states.checkedHoverAssetId, checked);\r\n this.applyTextures();\r\n for (const view of this.checkbox.views) if (view instanceof Sprite) view.setSize(transform.width, transform.height);\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get checked(): boolean {\r\n return this.checkbox.checked;\r\n }\r\n\r\n set checked(value: boolean) {\r\n this.checkbox.checked = value;\r\n }\r\n\r\n /** Sets checked state without emitting `onCheck` — used by radio-group wiring to avoid re-entrancy. */\r\n forceCheck(checked: boolean): void {\r\n this.checkbox.forceCheck(checked);\r\n }\r\n\r\n get state(): CheckboxStateKey {\r\n return this.checkbox.checked ? CHECKBOX_STATE_KEYS[1] : CHECKBOX_STATE_KEYS[0];\r\n }\r\n\r\n get onCheck(): CheckBox[\"onCheck\"] { return this.checkbox.onCheck; }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"CheckboxNodeView.js","sourceRoot":"","sources":["../../src/views/CheckboxNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { CHECKBOX_STATE_KEYS, type CheckboxStateKey, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { CheckBox } from \"@pixi/ui\";\r\nimport { Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\n\r\nexport type CheckboxNode = Extract<UINode, { type: \"checkbox\" }>;\r\n\r\n/**\r\n * Adapts a checkbox node to `@pixi/ui`'s `CheckBox`, which owns the checked/unchecked switching —\r\n * this class never reimplements it. `group`-based radio exclusivity is wired one layer up, in\r\n * `wireCheckboxGroups` (see scene.ts): this view only exposes `forceCheck` so that wiring can flip\r\n * a sibling without re-emitting `onCheck` and recursing back into itself.\r\n *\r\n * Hover is layered on top of `CheckBox` by hand: unlike `FancyButton`, `CheckBox`/`Switcher` only\r\n * switches between its checked/unchecked views and has no hover state slot of its own. Both of its\r\n * internal Sprites always carry the texture matching the current hover flag — whichever one is\r\n * `visible` at any moment is Switcher's concern, not ours.\r\n */\r\nexport class CheckboxNodeView extends NodeView {\r\n private readonly checkbox: CheckBox;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly audio: SceneAudio | undefined;\r\n private readonly nodeId: string;\r\n private soundAssetIds: CheckboxNode[\"sounds\"];\r\n private uncheckedTexture: Texture;\r\n private checkedTexture: Texture;\r\n private uncheckedHoverTexture: Texture;\r\n private checkedHoverTexture: Texture;\r\n private enabledState: boolean;\r\n private hovering = false;\r\n\r\n constructor(node: CheckboxNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.audio = audio;\r\n this.nodeId = node.id;\r\n this.soundAssetIds = node.sounds;\r\n const unchecked = this.textureFor(node.states.uncheckedAssetId) ?? Texture.WHITE;\r\n const checked = this.textureFor(node.states.checkedAssetId) ?? Texture.WHITE;\r\n this.uncheckedTexture = unchecked;\r\n this.checkedTexture = checked;\r\n this.uncheckedHoverTexture = this.hoverTextureFor(node.states.uncheckedHoverAssetId, unchecked);\r\n this.checkedHoverTexture = this.hoverTextureFor(node.states.checkedHoverAssetId, checked);\r\n this.checkbox = new CheckBox({\r\n checked: node.defaultChecked,\r\n style: { unchecked, checked },\r\n });\r\n // Authoring-сцена инертна, как и у button: eventMode \"none\" на верхнем контейнере отключает\r\n // hit-testing всего поддерева, включая `innerView`, который Switcher сам сделал \"static\" — а\r\n // значит и hover в authoring никогда не наступает, так что его незачем отдельно отключать.\r\n if (interaction === \"authoring\") this.checkbox.eventMode = \"none\";\r\n else {\r\n this.checkbox.innerView.on(\"pointerover\", () => { this.hovering = true; this.applyTextures(); });\r\n this.checkbox.innerView.on(\"pointerout\", () => { this.hovering = false; this.applyTextures(); });\r\n if (audio !== undefined) {\r\n this.checkbox.onCheck.connect((checkedState) => {\r\n const assetId = checkedState ? this.soundAssetIds?.checkAssetId : this.soundAssetIds?.uncheckAssetId;\r\n this.audio?.cue(checkedState ? \"checkbox.check\" : \"checkbox.uncheck\", this.nodeId, assetId);\r\n });\r\n }\r\n }\r\n this.enabledState = node.enabled;\r\n this.applyEnabled(node.enabled);\r\n this.setContent(this.checkbox);\r\n }\r\n\r\n private hoverTextureFor(assetId: string | undefined, fallback: Texture): Texture {\r\n return (assetId === undefined ? undefined : this.textureFor(assetId)) ?? fallback;\r\n }\r\n\r\n /** Puts the current hover/non-hover texture on both internal Sprites; switching visibility is Switcher's job. */\r\n private applyTextures(): void {\r\n const [uncheckedView, checkedView] = this.checkbox.views;\r\n if (uncheckedView instanceof Sprite) uncheckedView.texture = this.hovering ? this.uncheckedHoverTexture : this.uncheckedTexture;\r\n if (checkedView instanceof Sprite) checkedView.texture = this.hovering ? this.checkedHoverTexture : this.checkedTexture;\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive selectability elsewhere: this view stays inert either way. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"authoring\") return;\r\n this.checkbox.eventMode = enabled ? \"static\" : \"none\";\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"checkbox\") return;\r\n this.soundAssetIds = node.sounds;\r\n\r\n const unchecked = this.textureFor(node.states.uncheckedAssetId) ?? Texture.WHITE;\r\n const checked = this.textureFor(node.states.checkedAssetId) ?? Texture.WHITE;\r\n // `style` rebuilds both internal views, so it's only reassigned when a base texture actually\r\n // changed — same rule ButtonNodeView follows for its state Sprites. A fresh pair of Sprites\r\n // starts out holding the plain (non-hover) textures `style` was given, so `applyTextures` always\r\n // runs afterwards to restore the current hover look.\r\n if (unchecked !== this.uncheckedTexture || checked !== this.checkedTexture) {\r\n this.uncheckedTexture = unchecked;\r\n this.checkedTexture = checked;\r\n this.checkbox.style = { unchecked, checked };\r\n }\r\n this.uncheckedHoverTexture = this.hoverTextureFor(node.states.uncheckedHoverAssetId, unchecked);\r\n this.checkedHoverTexture = this.hoverTextureFor(node.states.checkedHoverAssetId, checked);\r\n this.applyTextures();\r\n for (const view of this.checkbox.views) if (view instanceof Sprite) view.setSize(transform.width, transform.height);\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get checked(): boolean {\r\n return this.checkbox.checked;\r\n }\r\n\r\n set checked(value: boolean) {\r\n this.checkbox.checked = value;\r\n }\r\n\r\n /** Sets checked state without emitting `onCheck` — used by radio-group wiring to avoid re-entrancy. */\r\n forceCheck(checked: boolean): void {\r\n this.checkbox.forceCheck(checked);\r\n }\r\n\r\n get state(): CheckboxStateKey {\r\n return this.checkbox.checked ? CHECKBOX_STATE_KEYS[1] : CHECKBOX_STATE_KEYS[0];\r\n }\r\n\r\n get onCheck(): CheckBox[\"onCheck\"] { return this.checkbox.onCheck; }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemTableNodeView.js","sourceRoot":"","sources":["../../src/views/ItemTableNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveItemTableVisibleCount, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\
|
|
1
|
+
{"version":3,"file":"ItemTableNodeView.js","sourceRoot":"","sources":["../../src/views/ItemTableNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveItemTableVisibleCount, type LayoutProfileId, type UINode } from \"@pixi-ui-editor/schema\";\nimport { Container } from \"pixi.js\";\nimport { NodeView } from \"./NodeView.js\";\n\n/**\n * Узел фиксированной вместимости: держит авторский список узлов (`items`, ссылки по адресу — их\n * разрешает `scene.ts`, тем же приёмом, что цели spine-коннекторов) и показывает только первые\n * `visibleCount` из них — остальные скрыты всегда, а не «на этой странице». Автор раскладывает\n * элементы под максимум, а сколько их реально помещается, задаётся на профиль: в разной ориентации\n * экрана на экран влезает разное число строк.\n *\n * Список именно авторский, а не дети: элемент обычно уже лежит там, где его выравнивает layout-группа.\n *\n * Узел намеренно ничего больше не делает. Он не страницы (`PageGroupNodeView` показывает ровно\n * одного ребёнка и растягивает его на себя), не раскладка (позицию элементы сохраняют свою) и ничего не\n * знает ни про какие данные: чем наполнить видимые элементы и когда, решает игровой код через\n * generic API из `controls.ts` (`getItemTableViewVisibleItems`, `getItemTableViewItem`,\n * `setItemTableViewVisibleCount`, `setItemTableViewItemsVisible`). Связка «переключили страницу →\n * перезаполнили элементы» тоже принадлежит игре: `PaginationNodeView.onPageChange` и эта таблица\n * ничего друг о друге не знают.\n *\n * Видимость складывается с авторской: элемент, скрытый в документе, не станет видимым из-за\n * вместимости, а скрытый вместимостью держится флагом `NodeView.hiddenByOwner` (см. `applyVisibility`).\n */\nexport class ItemTableNodeView extends NodeView {\n private itemViews: (Container | undefined)[] = [];\n private authoredVisibleCount = 0;\n /** Транзиентное переопределение от игрового кода; `undefined` — авторское значение профиля. */\n private runtimeVisibleCount?: number;\n /** Транзиентный «скрыть/показать всё» поверх вместимости; `undefined` — вместимость решает сама. */\n private forcedItemsVisible?: boolean;\n\n /**\n * Разрешённые views авторского списка `items`, позиционно выровненные с ним (`scene.ts`). Ссылка,\n * которая ни во что не разрешилась, сохраняет свою дырку `undefined`, чтобы остальные элементы не\n * сдвинулись; сама висячая ссылка — ошибка валидации документа, а не забота этого вида.\n */\n setItems(views: readonly (Container | undefined)[]): void {\n // Выбывшие из списка возвращаются под управление документа: иначе узел, убранный из таблицы,\n // остался бы скрытым её прежней вместимостью навсегда.\n const next = new Set(views);\n for (const previous of this.itemViews) {\n if (previous instanceof NodeView && !next.has(previous)) { previous.hiddenByOwner = false; previous.visible = previous.documentVisible; }\n }\n this.itemViews = [...views];\n this.applyVisibility();\n }\n\n /** Элементы в авторском порядке; нерезолвенные ссылки пропущены. */\n get items(): Container[] {\n return this.itemViews.filter((item): item is Container => item !== undefined);\n }\n\n get visibleCount(): number {\n return this.runtimeVisibleCount ?? this.authoredVisibleCount;\n }\n\n /** Транзиентно меняет вместимость; `undefined` возвращает авторское значение профиля. */\n set visibleCount(value: number | undefined) {\n this.runtimeVisibleCount = value === undefined ? undefined : Math.max(0, Math.round(value));\n this.applyVisibility();\n }\n\n /** Элементы, показанные прямо сейчас, в авторском порядке. */\n get visibleItems(): Container[] {\n return this.items.filter((item) => item.visible);\n }\n\n /** Индекс — позиция в авторском списке, а не среди показанных: адресация не «плавает». */\n itemAt(index: number): Container | undefined {\n return this.itemViews[index];\n }\n\n /** Показывает или прячет все элементы разом; `undefined` возвращает управление вместимости. */\n setItemsVisible(visible: boolean | undefined): void {\n this.forcedItemsVisible = visible;\n this.applyVisibility();\n }\n\n /**\n * Проход по элементам: влезающие включены, остальные выключены. Помимо самого `visible` ставится\n * `hiddenByOwner`, потому что `visible` узла пересчитывается из документа на каждом обновлении —\n * в том числе из колбэка layout-движка, который для элемента внутри layout-группы срабатывает\n * позже прохода таблицы и без флага вернул бы скрытый элемент обратно.\n */\n private applyVisibility(): void {\n const count = this.visibleCount;\n this.itemViews.forEach((item, index) => {\n if (item === undefined) return;\n const enabled = this.forcedItemsVisible ?? index < count;\n if (item instanceof NodeView) {\n item.hiddenByOwner = !enabled;\n item.visible = enabled && item.documentVisible;\n return;\n }\n item.visible = enabled;\n });\n }\n\n protected syncContent(node: UINode, _transform: UINode[\"transform\"], profile: LayoutProfileId): void {\n if (node.type !== \"item-table\") return;\n this.authoredVisibleCount = resolveItemTableVisibleCount(node, profile);\n this.applyVisibility();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaginationNodeView.js","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { type LayoutPadding, type PaginationNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { List } from \"@pixi/ui\";\r\nimport { Container, NineSliceSprite, Sprite, Text, Texture, type TextStyleOptions } from \"pixi.js\";\r\nimport { Signal } from \"typed-signals\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type { PaginationNode };\r\n\r\nconst DEFAULT_NUMBER_STYLE: TextStyleDefinition = { fontFamily: \"Arial\", fontSize: 18, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\", align: \"center\", verticalAlign: \"middle\", wordWrap: false, breakWords: false, letterSpacing: 0 };\r\n\r\n/** Same shape `ValueControlNodeViews.ts`'s own `textStyle` resolves — kept as its own small copy rather\r\n * than shared, the same call ADR 0029 makes for two similar-but-separately-evolving style resolvers. */\r\nfunction numberTextStyle(style: TextStyleDefinition | undefined, fill: string, fonts: ReadonlyMap<string, string> | undefined): Partial<TextStyleOptions> {\r\n const resolved = style ?? DEFAULT_NUMBER_STYLE;\r\n return {\r\n fontFamily: resolved.fontAssetId === undefined ? resolved.fontFamily : fonts?.get(resolved.fontAssetId) ?? resolved.fontFamily,\r\n fontSize: resolved.fontSize,\r\n fontWeight: resolved.fontWeight,\r\n fontStyle: resolved.fontStyle,\r\n fill,\r\n align: resolved.align,\r\n wordWrap: resolved.wordWrap,\r\n breakWords: resolved.breakWords,\r\n lineHeight: resolved.lineHeight,\r\n letterSpacing: resolved.letterSpacing,\r\n stroke: resolved.stroke === undefined ? undefined : { color: resolved.stroke.color, width: resolved.stroke.width },\r\n };\r\n}\r\n\r\n/**\r\n * Кнопка-стрелка пагинатора: ровно та часть `ButtonNodeView`/`StagedButtonNodeView`, которая нужна\r\n * виджету, — нажатие и «доступна ли». Тип объявлен структурно, чтобы этот файл не зависел от обоих\r\n * классов кнопок и не решал, какой из них «настоящий».\r\n */\r\nexport type PaginationArrow = { onPress: { connect(handler: () => void): unknown }; enabled: boolean };\r\n\r\n/** Clamps a page index into the valid `[0, pageCount)` range; an empty widget still shows dot 0. */\r\nfunction clampPage(page: number, pageCount: number): number {\r\n return Math.min(Math.max(0, Math.round(page)), Math.max(0, pageCount - 1));\r\n}\r\n\r\n/**\r\n * One `numbers`-style item: a centered page-number label, plus an optional \"pill\" background shown\r\n * only while it is the current page. `width`/`height` are overridden to the authored `dotSize` — the\r\n * same fixed-footprint trick `ScrollItemContainer` uses — so the `List` spaces every item evenly\r\n * whether or not its (rarely-present) background happens to be attached right now.\r\n */\r\nclass NumberItem extends Container {\r\n private itemWidth = 0;\r\n private itemHeight = 0;\r\n private background?: Sprite | NineSliceSprite;\r\n\r\n // Named `numberText`, not `label`: `Container.label` is pixi.js's own display-object name string.\r\n constructor(readonly numberText: Text) {\r\n super();\r\n numberText.anchor.set(0.5);\r\n super.addChild(numberText);\r\n }\r\n\r\n override get width(): number { return this.itemWidth; }\r\n override set width(value: number) { this.itemWidth = value; }\r\n override get height(): number { return this.itemHeight; }\r\n override set height(value: number) { this.itemHeight = value; }\r\n\r\n resize(width: number, height: number): void {\r\n this.itemWidth = width;\r\n this.itemHeight = height;\r\n this.numberText.position.set(width / 2, height / 2);\r\n this.background?.setSize(width, height);\r\n }\r\n\r\n /** Replaces the pill behind the label (destroying the previous one); `undefined` removes it. */\r\n setBackground(view: Sprite | NineSliceSprite | undefined): void {\r\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); }\r\n this.background = view;\r\n if (view === undefined) return;\r\n view.setSize(this.itemWidth, this.itemHeight);\r\n super.addChildAt(view, 0);\r\n }\r\n}\r\n\r\n/**\r\n * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same\r\n * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never\r\n * reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page\r\n * transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,\r\n * the same relationship a slider or progress bar has to whatever value it displays.\r\n *\r\n * `style` picks between two mutually exclusive, differently-rendered item kinds — image dots\r\n * (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional\r\n * highlight color, plus an optional pill background behind only the current page) — never both.\r\n * Switching `style` rebuilds every item, the same \"view's required *type* changed\" rule\r\n * `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the\r\n * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this\r\n * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself\r\n * is not structural: switching pages only recreates the (one) background view that needs to move.\r\n *\r\n * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active\r\n * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real\r\n * page range keeps its footprint and renders nothing, so the active page never shifts sideways.\r\n *\r\n * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the\r\n * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution\r\n * Spine connector targets use) and steps the page on press. It never draws an arrow itself.\r\n */\r\nexport class PaginationNodeView extends NodeView {\r\n private readonly list: List;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly fonts: ReadonlyMap<string, string> | undefined;\r\n private items: (Sprite | NumberItem)[] = [];\r\n private visibleSlots: number | undefined;\r\n private arrows?: { previous?: PaginationArrow; next?: PaginationArrow };\r\n private styleMode: PaginationNode[\"style\"];\r\n private activeTexture: Texture;\r\n private inactiveTexture: Texture;\r\n private numberStyle: TextStyleDefinition | undefined;\r\n private numberActiveColor: string | undefined;\r\n private numberActiveBackgroundTexture: Texture | undefined;\r\n private numberActiveNineSlice: LayoutPadding | undefined;\r\n private pageCountState: number;\r\n private currentPage: number;\r\n private dotWidth: number;\r\n private dotHeight: number;\r\n private clickableState: boolean;\r\n\r\n /** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */\r\n readonly onPageChange = new Signal<(page: number) => void>();\r\n\r\n constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.fonts = fonts;\r\n this.styleMode = node.style;\r\n this.activeTexture = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n this.inactiveTexture = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.pageCountState = Math.max(1, Math.round(node.pageCount));\r\n this.visibleSlots = node.visiblePageCount;\r\n this.currentPage = clampPage(node.defaultPage, this.pageCount);\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.clickableState = node.clickable;\r\n this.list = new List({ type: node.direction, elementsMargin: node.spacing });\r\n this.buildItems();\r\n this.setContent(this.list);\r\n }\r\n\r\n private createBackgroundView(texture: Texture): Sprite | NineSliceSprite {\r\n return this.numberActiveNineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });\r\n }\r\n\r\n /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */\r\n private get slotCount(): number {\r\n return this.visibleSlots === undefined ? this.pageCount : Math.max(1, Math.round(this.visibleSlots));\r\n }\r\n\r\n /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */\r\n private pageForSlot(slot: number): number {\r\n return this.visibleSlots === undefined ? slot : this.currentPage - Math.floor(this.slotCount / 2) + slot;\r\n }\r\n\r\n private createItem(slot: number): Sprite | NumberItem {\r\n const page = this.pageForSlot(slot);\r\n const exists = page >= 0 && page < this.pageCount;\r\n const isActive = exists && page === this.currentPage;\r\n if (this.styleMode === \"dots\") {\r\n const dot = new Sprite(isActive ? this.activeTexture : this.inactiveTexture);\r\n dot.setSize(this.dotWidth, this.dotHeight);\r\n // An out-of-range slot renders nothing but keeps its size, so `List` still reserves its place.\r\n dot.visible = exists;\r\n return dot;\r\n }\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;\r\n const item = new NumberItem(new Text({ text: exists ? String(page + 1) : \"\", style: numberTextStyle(this.numberStyle, fill, this.fonts) }));\r\n item.resize(this.dotWidth, this.dotHeight);\r\n if (isActive && this.numberActiveBackgroundTexture !== undefined) item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));\r\n return item;\r\n }\r\n\r\n /** Recreates every item for the current `styleMode`/`slotCount`/`dotWidth`/`dotHeight`. */\r\n private buildItems(): void {\r\n this.list.removeChildren();\r\n this.items = [];\r\n for (let slot = 0; slot < this.slotCount; slot++) {\r\n const item = this.createItem(slot);\r\n this.wireItem(item, slot);\r\n this.items.push(item);\r\n this.list.addChild(item);\r\n }\r\n this.applyArrowState();\r\n }\r\n\r\n /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */\r\n private wireItem(item: Sprite | NumberItem, slot: number): void {\r\n if (this.interaction === \"authoring\" || !this.clickableState) { item.eventMode = \"none\"; return; }\r\n item.eventMode = \"static\";\r\n item.cursor = \"pointer\";\r\n // Resolved on click, not captured: a windowed slot points at a different page after every move.\r\n item.on(\"pointertap\", () => {\r\n const page = this.pageForSlot(slot);\r\n if (page >= 0 && page < this.pageCount) this.setPage(page);\r\n });\r\n }\r\n\r\n private applyCurrentPage(): void {\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n this.items.forEach((item, slot) => {\r\n const page = this.pageForSlot(slot);\r\n const exists = page >= 0 && page < this.pageCount;\r\n const isActive = exists && page === this.currentPage;\r\n if (item instanceof NumberItem) {\r\n item.numberText.text = exists ? String(page + 1) : \"\";\r\n item.numberText.style = numberTextStyle(this.numberStyle, isActive ? this.numberActiveColor ?? baseFill : baseFill, this.fonts);\r\n item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);\r\n return;\r\n }\r\n item.texture = isActive ? this.activeTexture : this.inactiveTexture;\r\n item.setSize(this.dotWidth, this.dotHeight);\r\n item.visible = exists;\r\n });\r\n this.applyArrowState();\r\n }\r\n\r\n /**\r\n * Подключает авторские кнопки-стрелки: нажатие шагает на страницу назад/вперёд и эмитит\r\n * `onPageChange`, как клик по самому пункту. Кнопки остаются обычными нодами сцены — виджет только\r\n * подписывается на них и гасит ту, за которой страниц больше нет.\r\n */\r\n setArrows(arrows: { previous?: PaginationArrow; next?: PaginationArrow }): void {\r\n this.arrows = arrows;\r\n arrows.previous?.onPress.connect(() => this.setPage(this.currentPage - 1));\r\n arrows.next?.onPress.connect(() => this.setPage(this.currentPage + 1));\r\n this.applyArrowState();\r\n }\r\n\r\n /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */\r\n private applyArrowState(): void {\r\n if (this.arrows === undefined) return;\r\n if (this.arrows.previous !== undefined) this.arrows.previous.enabled = this.currentPage > 0;\r\n if (this.arrows.next !== undefined) this.arrows.next.enabled = this.currentPage < this.pageCount - 1;\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"pagination\") return;\r\n const active = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n const pageCount = Math.max(1, Math.round(node.pageCount));\r\n this.clickableState = node.clickable;\r\n\r\n const previousSlotCount = this.slotCount;\r\n this.visibleSlots = node.visiblePageCount;\r\n this.pageCountState = pageCount;\r\n const structureChanged = node.style !== this.styleMode || this.slotCount !== previousSlotCount || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;\r\n this.styleMode = node.style;\r\n this.activeTexture = active;\r\n this.inactiveTexture = inactive;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.currentPage = clampPage(this.currentPage, this.pageCount);\r\n\r\n if (this.list.type !== node.direction) this.list.type = node.direction;\r\n if (this.list.elementsMargin !== node.spacing) this.list.elementsMargin = node.spacing;\r\n\r\n if (structureChanged) this.buildItems();\r\n else this.applyCurrentPage();\r\n }\r\n\r\n get pageCount(): number { return this.pageCountState; }\r\n\r\n /** Used by `setPaginationViewPageCount` once game code knows the real content length. */\r\n set pageCount(value: number) {\r\n const next = Math.max(1, Math.round(value));\r\n if (next === this.pageCountState) return;\r\n const previousSlotCount = this.slotCount;\r\n this.pageCountState = next;\r\n this.currentPage = clampPage(this.currentPage, this.pageCount);\r\n if (this.slotCount === previousSlotCount) this.applyCurrentPage();\r\n else this.buildItems();\r\n }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */\r\n set page(value: number) {\r\n const next = clampPage(value, this.pageCountState);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyCurrentPage();\r\n }\r\n\r\n /** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */\r\n private setPage(index: number): void {\r\n const next = clampPage(index, this.pageCountState);\r\n if (next !== this.currentPage) { this.currentPage = next; this.applyCurrentPage(); }\r\n this.onPageChange.emit(next);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"PaginationNodeView.js","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { type LayoutPadding, type PaginationNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\nimport { List } from \"@pixi/ui\";\nimport { Container, NineSliceSprite, Sprite, Text, Texture, type TextStyleOptions } from \"pixi.js\";\nimport { Signal } from \"typed-signals\";\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\n\nexport type { PaginationNode };\n\nconst DEFAULT_NUMBER_STYLE: TextStyleDefinition = { fontFamily: \"Arial\", fontSize: 18, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\", align: \"center\", verticalAlign: \"middle\", wordWrap: false, breakWords: false, letterSpacing: 0 };\n\n/** Same shape `ValueControlNodeViews.ts`'s own `textStyle` resolves — kept as its own small copy rather\n * than shared, the same call ADR 0029 makes for two similar-but-separately-evolving style resolvers. */\nfunction numberTextStyle(style: TextStyleDefinition | undefined, fill: string, fonts: ReadonlyMap<string, string> | undefined): Partial<TextStyleOptions> {\n const resolved = style ?? DEFAULT_NUMBER_STYLE;\n return {\n fontFamily: resolved.fontAssetId === undefined ? resolved.fontFamily : fonts?.get(resolved.fontAssetId) ?? resolved.fontFamily,\n fontSize: resolved.fontSize,\n fontWeight: resolved.fontWeight,\n fontStyle: resolved.fontStyle,\n fill,\n align: resolved.align,\n wordWrap: resolved.wordWrap,\n breakWords: resolved.breakWords,\n lineHeight: resolved.lineHeight,\n letterSpacing: resolved.letterSpacing,\n stroke: resolved.stroke === undefined ? undefined : { color: resolved.stroke.color, width: resolved.stroke.width },\n };\n}\n\n/**\n * Кнопка-стрелка пагинатора: ровно та часть `ButtonNodeView`/`StagedButtonNodeView`, которая нужна\n * виджету, — нажатие и «доступна ли». Тип объявлен структурно, чтобы этот файл не зависел от обоих\n * классов кнопок и не решал, какой из них «настоящий».\n */\nexport type PaginationArrow = { onPress: { connect(handler: () => void): unknown }; enabled: boolean };\n\n/** Clamps a page index into the valid `[0, pageCount)` range; an empty widget still shows dot 0. */\nfunction clampPage(page: number, pageCount: number): number {\n return Math.min(Math.max(0, Math.round(page)), Math.max(0, pageCount - 1));\n}\n\n/**\n * One `numbers`-style item: a centered page-number label, plus an optional \"pill\" background shown\n * only while it is the current page. `width`/`height` are overridden to the authored `dotSize` — the\n * same fixed-footprint trick `ScrollItemContainer` uses — so the `List` spaces every item evenly\n * whether or not its (rarely-present) background happens to be attached right now.\n */\nclass NumberItem extends Container {\n private itemWidth = 0;\n private itemHeight = 0;\n private background?: Sprite | NineSliceSprite;\n\n // Named `numberText`, not `label`: `Container.label` is pixi.js's own display-object name string.\n constructor(readonly numberText: Text) {\n super();\n numberText.anchor.set(0.5);\n super.addChild(numberText);\n }\n\n override get width(): number { return this.itemWidth; }\n override set width(value: number) { this.itemWidth = value; }\n override get height(): number { return this.itemHeight; }\n override set height(value: number) { this.itemHeight = value; }\n\n resize(width: number, height: number): void {\n this.itemWidth = width;\n this.itemHeight = height;\n this.numberText.position.set(width / 2, height / 2);\n this.background?.setSize(width, height);\n }\n\n /** Replaces the pill behind the label (destroying the previous one); `undefined` removes it. */\n setBackground(view: Sprite | NineSliceSprite | undefined): void {\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); }\n this.background = view;\n if (view === undefined) return;\n view.setSize(this.itemWidth, this.itemHeight);\n super.addChildAt(view, 0);\n }\n}\n\n/**\n * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same\n * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never\n * reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page\n * transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,\n * the same relationship a slider or progress bar has to whatever value it displays.\n *\n * `style` picks between two mutually exclusive, differently-rendered item kinds — image dots\n * (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional\n * highlight color, plus an optional pill background behind only the current page) — never both.\n * Switching `style` rebuilds every item, the same \"view's required *type* changed\" rule\n * `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the\n * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this\n * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself\n * is not structural: switching pages only recreates the (one) background view that needs to move.\n *\n * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active\n * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real\n * page range keeps its footprint and renders nothing, so the active page never shifts sideways.\n *\n * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the\n * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution\n * Spine connector targets use) and steps the page on press. It never draws an arrow itself.\n */\nexport class PaginationNodeView extends NodeView {\n private readonly list: List;\n private readonly interaction: SceneInteractionMode;\n private readonly fonts: ReadonlyMap<string, string> | undefined;\n private items: (Sprite | NumberItem)[] = [];\n private visibleSlots: number | undefined;\n private arrows?: { previous?: PaginationArrow; next?: PaginationArrow };\n private styleMode: PaginationNode[\"style\"];\n private activeTexture: Texture;\n private inactiveTexture: Texture;\n private numberStyle: TextStyleDefinition | undefined;\n private numberActiveColor: string | undefined;\n private numberActiveBackgroundTexture: Texture | undefined;\n private numberActiveNineSlice: LayoutPadding | undefined;\n private pageCountState: number;\n private currentPage: number;\n private dotWidth: number;\n private dotHeight: number;\n private clickableState: boolean;\n\n /** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */\n readonly onPageChange = new Signal<(page: number) => void>();\n\n constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined) {\n super(textures);\n this.interaction = interaction;\n this.fonts = fonts;\n this.styleMode = node.style;\n this.activeTexture = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\n this.inactiveTexture = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\n this.numberStyle = node.numberStyle;\n this.numberActiveColor = node.numberActiveColor;\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\n this.numberActiveNineSlice = node.numberActiveNineSlice;\n this.pageCountState = Math.max(1, Math.round(node.pageCount));\n this.visibleSlots = node.visiblePageCount;\n this.currentPage = clampPage(node.defaultPage, this.pageCount);\n this.dotWidth = node.dotSize.width;\n this.dotHeight = node.dotSize.height;\n this.clickableState = node.clickable;\n this.list = new List({ type: node.direction, elementsMargin: node.spacing });\n this.buildItems();\n this.setContent(this.list);\n }\n\n private createBackgroundView(texture: Texture): Sprite | NineSliceSprite {\n return this.numberActiveNineSlice === undefined\n ? new Sprite(texture)\n : new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });\n }\n\n /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */\n private get slotCount(): number {\n return this.visibleSlots === undefined ? this.pageCount : Math.max(1, Math.round(this.visibleSlots));\n }\n\n /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */\n private pageForSlot(slot: number): number {\n return this.visibleSlots === undefined ? slot : this.currentPage - Math.floor(this.slotCount / 2) + slot;\n }\n\n private createItem(slot: number): Sprite | NumberItem {\n const page = this.pageForSlot(slot);\n const exists = page >= 0 && page < this.pageCount;\n const isActive = exists && page === this.currentPage;\n if (this.styleMode === \"dots\") {\n const dot = new Sprite(isActive ? this.activeTexture : this.inactiveTexture);\n dot.setSize(this.dotWidth, this.dotHeight);\n // An out-of-range slot renders nothing but keeps its size, so `List` still reserves its place.\n dot.visible = exists;\n return dot;\n }\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\n const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;\n const item = new NumberItem(new Text({ text: exists ? String(page + 1) : \"\", style: numberTextStyle(this.numberStyle, fill, this.fonts) }));\n item.resize(this.dotWidth, this.dotHeight);\n if (isActive && this.numberActiveBackgroundTexture !== undefined) item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));\n return item;\n }\n\n /** Recreates every item for the current `styleMode`/`slotCount`/`dotWidth`/`dotHeight`. */\n private buildItems(): void {\n this.list.removeChildren();\n this.items = [];\n for (let slot = 0; slot < this.slotCount; slot++) {\n const item = this.createItem(slot);\n this.wireItem(item, slot);\n this.items.push(item);\n this.list.addChild(item);\n }\n this.applyArrowState();\n }\n\n /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */\n private wireItem(item: Sprite | NumberItem, slot: number): void {\n if (this.interaction === \"authoring\" || !this.clickableState) { item.eventMode = \"none\"; return; }\n item.eventMode = \"static\";\n item.cursor = \"pointer\";\n // Resolved on click, not captured: a windowed slot points at a different page after every move.\n item.on(\"pointertap\", () => {\n const page = this.pageForSlot(slot);\n if (page >= 0 && page < this.pageCount) this.setPage(page);\n });\n }\n\n private applyCurrentPage(): void {\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\n this.items.forEach((item, slot) => {\n const page = this.pageForSlot(slot);\n const exists = page >= 0 && page < this.pageCount;\n const isActive = exists && page === this.currentPage;\n if (item instanceof NumberItem) {\n item.numberText.text = exists ? String(page + 1) : \"\";\n item.numberText.style = numberTextStyle(this.numberStyle, isActive ? this.numberActiveColor ?? baseFill : baseFill, this.fonts);\n item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);\n return;\n }\n item.texture = isActive ? this.activeTexture : this.inactiveTexture;\n item.setSize(this.dotWidth, this.dotHeight);\n item.visible = exists;\n });\n this.applyArrowState();\n }\n\n /**\n * Подключает авторские кнопки-стрелки: нажатие шагает на страницу назад/вперёд и эмитит\n * `onPageChange`, как клик по самому пункту. Кнопки остаются обычными нодами сцены — виджет только\n * подписывается на них и гасит ту, за которой страниц больше нет.\n */\n setArrows(arrows: { previous?: PaginationArrow; next?: PaginationArrow }): void {\n this.arrows = arrows;\n arrows.previous?.onPress.connect(() => this.setPage(this.currentPage - 1));\n arrows.next?.onPress.connect(() => this.setPage(this.currentPage + 1));\n this.applyArrowState();\n }\n\n /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */\n private applyArrowState(): void {\n if (this.arrows === undefined) return;\n if (this.arrows.previous !== undefined) this.arrows.previous.enabled = this.currentPage > 0;\n if (this.arrows.next !== undefined) this.arrows.next.enabled = this.currentPage < this.pageCount - 1;\n }\n\n protected syncContent(node: UINode): void {\n if (node.type !== \"pagination\") return;\n const active = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\n const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\n const pageCount = Math.max(1, Math.round(node.pageCount));\n this.clickableState = node.clickable;\n\n const previousSlotCount = this.slotCount;\n this.visibleSlots = node.visiblePageCount;\n this.pageCountState = pageCount;\n const structureChanged = node.style !== this.styleMode || this.slotCount !== previousSlotCount || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;\n this.styleMode = node.style;\n this.activeTexture = active;\n this.inactiveTexture = inactive;\n this.numberStyle = node.numberStyle;\n this.numberActiveColor = node.numberActiveColor;\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\n this.numberActiveNineSlice = node.numberActiveNineSlice;\n this.dotWidth = node.dotSize.width;\n this.dotHeight = node.dotSize.height;\n this.currentPage = clampPage(this.currentPage, this.pageCount);\n\n if (this.list.type !== node.direction) this.list.type = node.direction;\n if (this.list.elementsMargin !== node.spacing) this.list.elementsMargin = node.spacing;\n\n if (structureChanged) this.buildItems();\n else this.applyCurrentPage();\n }\n\n get pageCount(): number { return this.pageCountState; }\n\n /** Used by `setPaginationViewPageCount` once game code knows the real content length. */\n set pageCount(value: number) {\n const next = Math.max(1, Math.round(value));\n if (next === this.pageCountState) return;\n const previousSlotCount = this.slotCount;\n this.pageCountState = next;\n this.currentPage = clampPage(this.currentPage, this.pageCount);\n if (this.slotCount === previousSlotCount) this.applyCurrentPage();\n else this.buildItems();\n }\n\n get page(): number { return this.currentPage; }\n\n /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */\n set page(value: number) {\n const next = clampPage(value, this.pageCountState);\n if (next === this.currentPage) return;\n this.currentPage = next;\n this.applyCurrentPage();\n }\n\n /** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */\n private setPage(index: number): void {\n const next = clampPage(index, this.pageCountState);\n if (next !== this.currentPage) { this.currentPage = next; this.applyCurrentPage(); }\n this.onPageChange.emit(next);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticleEmitterNodeView.js","sourceRoot":"","sources":["../../src/views/ParticleEmitterNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParticleEffectDefinition, UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Particle, ParticleContainer, Texture, type DestroyOptions } from \"pixi.js\";\r\nimport { lerp, ParticleSimulator, type ParticleSlot, type ParticleSpawnContext } from \"../particles.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\n/** Thin Pixi adapter: NodeView continues to own transforms, layout and hit testing. */\r\nexport class ParticleEmitterNodeView extends NodeView {\r\n private readonly contentRoot = new Container();\r\n private readonly simulator: ParticleSimulator<Particle>;\r\n private readonly renderGroups = new Map<Texture[\"source\"], ParticleRenderGroup>();\r\n private simulationSpace: \"local\" | \"world\" = \"local\";\r\n private autoplayHandled = false;\r\n private renderDirty = true;\r\n private tintStart = 0xffffff;\r\n private tintEnd = 0xffffff;\r\n private staticColor = 0xffffffff;\r\n private dynamicProperties: DynamicParticleProperties = { position: true, rotation: false, vertex: false, uvs: false, color: false };\r\n private readonly spawnContext: ParticleSpawnContext = { width: 0, height: 0, space: \"local\" };\r\n private renderSignature = \"\";\r\n private sourceSignature = \"\";\r\n private sourceTextures: readonly (Texture | undefined)[] = [];\r\n\r\n constructor(effect: ParticleEffectDefinition, textures?: ReadonlyMap<string, Texture>) {\r\n super(textures);\r\n this.setContent(this.contentRoot);\r\n this.cacheEffect(effect);\r\n this.simulator = new ParticleSimulator<Particle>(effect, {\r\n createRender: () => {\r\n return new Particle({ texture: Texture.EMPTY, anchorX: 0.5, anchorY: 0.5 });\r\n },\r\n hideRender: () => undefined,\r\n destroyRender: () => undefined,\r\n getWorldTransform: () => this.worldTransform,\r\n });\r\n }\r\n\r\n updateParticles(deltaSeconds: number): void {\r\n this.spawnContext.width = this.layoutWidth;\r\n this.spawnContext.height = this.layoutHeight;\r\n this.spawnContext.space = this.simulationSpace;\r\n const advanced = this.simulator.update(deltaSeconds, this.spawnContext);\r\n // World-space particles must also be reprojected when an ancestor moves between simulation\r\n // steps. Local particles need no work: Pixi applies their container transform itself.\r\n if (advanced || this.renderDirty || (this.simulationSpace === \"world\" && this.simulator.activeSlots.size > 0)) this.syncRender();\r\n }\r\n\r\n play(): void { this.simulator.play(); }\r\n pause(): void { this.simulator.pause(); }\r\n restart(): void { this.simulator.restart(); }\r\n stop(): void { this.simulator.stop(); }\r\n /** Advances exactly one fixed step even while paused, preserving the current playing/paused state. */\r\n step(): void {\r\n this.spawnContext.width = this.layoutWidth;\r\n this.spawnContext.height = this.layoutHeight;\r\n this.spawnContext.space = this.simulationSpace;\r\n this.simulator.step(this.spawnContext);\r\n this.syncRender();\r\n }\r\n dispose(): void {\r\n this.simulator.dispose();\r\n this.destroyRenderGroups();\r\n }\r\n setEmissionMultiplier(value: number): void { this.simulator.setEmissionMultiplier(value); }\r\n getDiagnostics() { return this.simulator.getDiagnostics(); }\r\n\r\n syncEffect(effect: ParticleEffectDefinition): void {\r\n this.simulator.syncEffect(effect);\r\n this.renderDirty ||= this.cacheEffect(effect);\r\n }\r\n\r\n override destroy(options?: DestroyOptions): void {\r\n this.dispose();\r\n super.destroy(options);\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"particle-emitter\") return;\r\n if (this.simulationSpace !== node.simulationSpace) this.renderDirty = true;\r\n this.simulationSpace = node.simulationSpace;\r\n // Autoplay only fires once, right after construction: syncContent also runs on every unrelated\r\n // document edit (via the shared node-sync pass), and re-arming play() there would silently\r\n // override an explicit pause()/stop() the moment the author touches anything else in the project.\r\n if (!this.autoplayHandled) {\r\n this.autoplayHandled = true;\r\n if (node.autoplay) this.simulator.play();\r\n }\r\n }\r\n\r\n private syncRender(): void {\r\n const p = this.simulator.definition.particle;\r\n const source = p.visual.source;\r\n const space = this.simulationSpace;\r\n const inverse = space === \"world\" ? this.worldTransform : undefined;\r\n const determinant = inverse === undefined ? 0 : inverse.a * inverse.d - inverse.b * inverse.c;\r\n const inverseDeterminant = determinant === 0 ? 0 : 1 / determinant;\r\n for (const group of this.renderGroups.values()) {\r\n group.nextCount = 0;\r\n group.dirty ||= this.renderDirty;\r\n }\r\n for (const slot of this.simulator.activeSlots) {\r\n const particle = slot.render;\r\n const t = slot.lifetime > 0 ? Math.min(1, slot.age / slot.lifetime) : 1;\r\n const sourceIndex = source.type === \"single\" ? 0 : source.type === \"random\" ? slot.sourceIndex : sequenceFrame(source, slot);\r\n const texture = this.sourceTextures[sourceIndex] ?? Texture.EMPTY;\r\n const textureChanged = particle.texture !== texture;\r\n if (textureChanged) particle.texture = texture;\r\n const initializeStatic = slot.renderDirty || this.renderDirty;\r\n if (this.dynamicProperties.vertex || initializeStatic) {\r\n const scale = lerp(slot.scaleStart, slot.scaleEnd, t);\r\n particle.scaleX = scale;\r\n particle.scaleY = scale;\r\n }\r\n if (this.dynamicProperties.rotation || initializeStatic) particle.rotation = slot.rotationDegrees * DEG_TO_RAD;\r\n if (this.dynamicProperties.color) particle.color = packParticleColor(lerpRgb(this.tintStart, this.tintEnd, t), lerp(p.visual.alpha.start, p.visual.alpha.end, t));\r\n else if (initializeStatic) particle.color = this.staticColor;\r\n if (space === \"world\" && inverse !== undefined) {\r\n const dx = slot.x - slot.spawnX, dy = slot.y - slot.spawnY;\r\n const worldX = slot.worldSpawnX + slot.spawnMatrixA * dx + slot.spawnMatrixC * dy;\r\n const worldY = slot.worldSpawnY + slot.spawnMatrixB * dx + slot.spawnMatrixD * dy;\r\n // Inline Matrix.applyInverse to avoid allocating one point per particle per rendered frame.\r\n const translatedX = worldX - inverse.tx;\r\n const translatedY = worldY - inverse.ty;\r\n particle.x = (inverse.d * translatedX - inverse.c * translatedY) * inverseDeterminant;\r\n particle.y = (-inverse.b * translatedX + inverse.a * translatedY) * inverseDeterminant;\r\n } else {\r\n particle.x = slot.x;\r\n particle.y = slot.y;\r\n }\r\n const group = this.groupFor(texture, p.visual.blendMode);\r\n group.dirty ||= slot.renderDirty || textureChanged || group.container.particleChildren[group.nextCount] !== particle;\r\n group.container.particleChildren[group.nextCount++] = particle;\r\n slot.renderDirty = false;\r\n }\r\n for (const group of this.renderGroups.values()) {\r\n const children = group.container.particleChildren;\r\n if (children.length !== group.nextCount) {\r\n children.length = group.nextCount;\r\n group.dirty = true;\r\n }\r\n if (group.dirty) group.container.update();\r\n group.dirty = false;\r\n }\r\n this.renderDirty = false;\r\n }\r\n\r\n private cacheEffect(effect: ParticleEffectDefinition): boolean {\r\n const visual = effect.particle.visual;\r\n const sourceIds = visual.source.type === \"single\" ? [visual.source.assetId] : visual.source.assetIds;\r\n const sourceTextures = sourceIds.map((id) => this.textureFor(id));\r\n const signature = JSON.stringify(visual);\r\n const sourceSignature = JSON.stringify(visual.source);\r\n const sourceChanged = sourceSignature !== this.sourceSignature\r\n || sourceTextures.length !== this.sourceTextures.length\r\n || sourceTextures.some((texture, index) => texture !== this.sourceTextures[index]);\r\n const changed = signature !== this.renderSignature\r\n || sourceChanged;\r\n if (!changed) return false;\r\n this.renderSignature = signature;\r\n this.sourceSignature = sourceSignature;\r\n this.sourceTextures = sourceTextures;\r\n // Source edits and late texture loads invalidate the source-keyed groups. Rebuild containers,\r\n // but keep every pooled Particle and live simulation slot intact.\r\n if (sourceChanged) this.destroyRenderGroups();\r\n const dynamicProperties = particleDynamicProperties(effect);\r\n if (!sameDynamicProperties(this.dynamicProperties, dynamicProperties)) {\r\n this.destroyRenderGroups();\r\n this.dynamicProperties = dynamicProperties;\r\n }\r\n this.tintStart = parseRgb(effect.particle.visual.tint.start);\r\n this.tintEnd = parseRgb(effect.particle.visual.tint.end);\r\n this.staticColor = packParticleColor(this.tintStart, effect.particle.visual.alpha.start);\r\n for (const group of this.renderGroups.values()) group.container.blendMode = effect.particle.visual.blendMode;\r\n return true;\r\n }\r\n\r\n private groupFor(texture: Texture, blendMode: ParticleEffectDefinition[\"particle\"][\"visual\"][\"blendMode\"]): ParticleRenderGroup {\r\n let group = this.renderGroups.get(texture.source);\r\n if (group !== undefined) return group;\r\n const container = new ParticleContainer<Particle>({\r\n texture,\r\n dynamicProperties: this.dynamicProperties,\r\n });\r\n container.blendMode = blendMode;\r\n this.contentRoot.addChild(container);\r\n group = { container, nextCount: 0, dirty: true };\r\n this.renderGroups.set(texture.source, group);\r\n return group;\r\n }\r\n\r\n private destroyRenderGroups(): void {\r\n for (const group of this.renderGroups.values()) {\r\n this.contentRoot.removeChild(group.container);\r\n group.container.destroy();\r\n }\r\n this.renderGroups.clear();\r\n }\r\n}\r\n\r\ntype SequenceSource = Extract<ParticleEffectDefinition[\"particle\"][\"visual\"][\"source\"], { type: \"sequence\" }>;\r\ntype ParticleRenderGroup = { container: ParticleContainer<Particle>; nextCount: number; dirty: boolean };\r\ntype DynamicParticleProperties = { position: true; rotation: boolean; vertex: boolean; uvs: boolean; color: boolean };\r\n\r\nfunction sequenceFrame(source: SequenceSource, slot: ParticleSlot<Particle>): number {\r\n const length = source.assetIds.length;\r\n const raw = slot.sequenceStart + Math.floor(slot.age * source.fps);\r\n return source.loop ? ((raw % length) + length) % length : Math.min(raw, length - 1);\r\n}\r\n\r\nfunction parseRgb(hex: string): number { return Number.parseInt(hex.slice(1, 7), 16); }\r\nfunction lerpRgb(start: number, end: number, t: number): number {\r\n const r = Math.round(lerp((start >>> 16) & 0xff, (end >>> 16) & 0xff, t));\r\n const g = Math.round(lerp((start >>> 8) & 0xff, (end >>> 8) & 0xff, t));\r\n const b = Math.round(lerp(start & 0xff, end & 0xff, t));\r\n return (r << 16) | (g << 8) | b;\r\n}\r\n/** Pixi Particle buffers store packed ABGR, unlike the public RGB tint number. */\r\nfunction packParticleColor(rgb: number, alpha: number): number {\r\n const bgr = ((rgb & 0xff) << 16) | (rgb & 0xff00) | ((rgb >>> 16) & 0xff);\r\n return (bgr | (Math.round(Math.max(0, Math.min(1, alpha)) * 255) << 24)) >>> 0;\r\n}\r\n\r\nfunction particleDynamicProperties(effect: ParticleEffectDefinition): DynamicParticleProperties {\r\n const visual = effect.particle.visual;\r\n const angular = visual.rotation.angularVelocityDegrees;\r\n const scale = visual.scale;\r\n return {\r\n position: true,\r\n rotation: angular.min !== 0 || angular.max !== 0,\r\n vertex: !(scale.start.min === scale.start.max && scale.start.min === scale.end.min && scale.start.min === scale.end.max),\r\n uvs: visual.source.type === \"sequence\",\r\n color: visual.tint.start !== visual.tint.end || visual.alpha.start !== visual.alpha.end,\r\n };\r\n}\r\n\r\nfunction sameDynamicProperties(a: DynamicParticleProperties, b: DynamicParticleProperties): boolean {\r\n return a.rotation === b.rotation && a.vertex === b.vertex && a.uvs === b.uvs && a.color === b.color;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ParticleEmitterNodeView.js","sourceRoot":"","sources":["../../src/views/ParticleEmitterNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParticleEffectDefinition, UINode } from \"@pixi-ui-editor/schema\";\nimport { Container, Particle, ParticleContainer, Texture, type DestroyOptions } from \"pixi.js\";\nimport { lerp, ParticleSimulator, type ParticleSlot, type ParticleSpawnContext } from \"../particles.js\";\nimport { NodeView } from \"./NodeView.js\";\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\n/** Thin Pixi adapter: NodeView continues to own transforms, layout and hit testing. */\r\nexport class ParticleEmitterNodeView extends NodeView {\n private readonly contentRoot = new Container();\n private readonly simulator: ParticleSimulator<Particle>;\n private readonly renderGroups = new Map<Texture[\"source\"], ParticleRenderGroup>();\n private simulationSpace: \"local\" | \"world\" = \"local\";\n private autoplayHandled = false;\n private renderDirty = true;\n private tintStart = 0xffffff;\n private tintEnd = 0xffffff;\n private staticColor = 0xffffffff;\n private dynamicProperties: DynamicParticleProperties = { position: true, rotation: false, vertex: false, uvs: false, color: false };\n private readonly spawnContext: ParticleSpawnContext = { width: 0, height: 0, space: \"local\" };\n private renderSignature = \"\";\n private sourceSignature = \"\";\n private sourceTextures: readonly (Texture | undefined)[] = [];\n\r\n constructor(effect: ParticleEffectDefinition, textures?: ReadonlyMap<string, Texture>) {\r\n super(textures);\n this.setContent(this.contentRoot);\n this.cacheEffect(effect);\n this.simulator = new ParticleSimulator<Particle>(effect, {\n createRender: () => {\n return new Particle({ texture: Texture.EMPTY, anchorX: 0.5, anchorY: 0.5 });\n },\n hideRender: () => undefined,\n destroyRender: () => undefined,\n getWorldTransform: () => this.worldTransform,\n });\n }\n\n updateParticles(deltaSeconds: number): void {\n this.spawnContext.width = this.layoutWidth;\n this.spawnContext.height = this.layoutHeight;\n this.spawnContext.space = this.simulationSpace;\n const advanced = this.simulator.update(deltaSeconds, this.spawnContext);\n // World-space particles must also be reprojected when an ancestor moves between simulation\n // steps. Local particles need no work: Pixi applies their container transform itself.\n if (advanced || this.renderDirty || (this.simulationSpace === \"world\" && this.simulator.activeSlots.size > 0)) this.syncRender();\n }\r\n\r\n play(): void { this.simulator.play(); }\r\n pause(): void { this.simulator.pause(); }\r\n restart(): void { this.simulator.restart(); }\r\n stop(): void { this.simulator.stop(); }\r\n /** Advances exactly one fixed step even while paused, preserving the current playing/paused state. */\r\n step(): void {\n this.spawnContext.width = this.layoutWidth;\n this.spawnContext.height = this.layoutHeight;\n this.spawnContext.space = this.simulationSpace;\n this.simulator.step(this.spawnContext);\n this.syncRender();\r\n }\r\n dispose(): void {\n this.simulator.dispose();\n this.destroyRenderGroups();\n }\n setEmissionMultiplier(value: number): void { this.simulator.setEmissionMultiplier(value); }\r\n getDiagnostics() { return this.simulator.getDiagnostics(); }\r\n\r\n syncEffect(effect: ParticleEffectDefinition): void {\n this.simulator.syncEffect(effect);\n this.renderDirty ||= this.cacheEffect(effect);\n }\n\r\n override destroy(options?: DestroyOptions): void {\r\n this.dispose();\r\n super.destroy(options);\r\n }\r\n\r\n protected syncContent(node: UINode): void {\n if (node.type !== \"particle-emitter\") return;\n if (this.simulationSpace !== node.simulationSpace) this.renderDirty = true;\n this.simulationSpace = node.simulationSpace;\n // Autoplay only fires once, right after construction: syncContent also runs on every unrelated\r\n // document edit (via the shared node-sync pass), and re-arming play() there would silently\r\n // override an explicit pause()/stop() the moment the author touches anything else in the project.\r\n if (!this.autoplayHandled) {\r\n this.autoplayHandled = true;\r\n if (node.autoplay) this.simulator.play();\r\n }\r\n }\r\n\r\n private syncRender(): void {\n const p = this.simulator.definition.particle;\r\n const source = p.visual.source;\r\n const space = this.simulationSpace;\r\n const inverse = space === \"world\" ? this.worldTransform : undefined;\n const determinant = inverse === undefined ? 0 : inverse.a * inverse.d - inverse.b * inverse.c;\n const inverseDeterminant = determinant === 0 ? 0 : 1 / determinant;\n for (const group of this.renderGroups.values()) {\n group.nextCount = 0;\n group.dirty ||= this.renderDirty;\n }\n for (const slot of this.simulator.activeSlots) {\n const particle = slot.render;\n const t = slot.lifetime > 0 ? Math.min(1, slot.age / slot.lifetime) : 1;\n const sourceIndex = source.type === \"single\" ? 0 : source.type === \"random\" ? slot.sourceIndex : sequenceFrame(source, slot);\n const texture = this.sourceTextures[sourceIndex] ?? Texture.EMPTY;\n const textureChanged = particle.texture !== texture;\n if (textureChanged) particle.texture = texture;\n const initializeStatic = slot.renderDirty || this.renderDirty;\n if (this.dynamicProperties.vertex || initializeStatic) {\n const scale = lerp(slot.scaleStart, slot.scaleEnd, t);\n particle.scaleX = scale;\n particle.scaleY = scale;\n }\n if (this.dynamicProperties.rotation || initializeStatic) particle.rotation = slot.rotationDegrees * DEG_TO_RAD;\n if (this.dynamicProperties.color) particle.color = packParticleColor(lerpRgb(this.tintStart, this.tintEnd, t), lerp(p.visual.alpha.start, p.visual.alpha.end, t));\n else if (initializeStatic) particle.color = this.staticColor;\n if (space === \"world\" && inverse !== undefined) {\n const dx = slot.x - slot.spawnX, dy = slot.y - slot.spawnY;\n const worldX = slot.worldSpawnX + slot.spawnMatrixA * dx + slot.spawnMatrixC * dy;\n const worldY = slot.worldSpawnY + slot.spawnMatrixB * dx + slot.spawnMatrixD * dy;\n // Inline Matrix.applyInverse to avoid allocating one point per particle per rendered frame.\n const translatedX = worldX - inverse.tx;\n const translatedY = worldY - inverse.ty;\n particle.x = (inverse.d * translatedX - inverse.c * translatedY) * inverseDeterminant;\n particle.y = (-inverse.b * translatedX + inverse.a * translatedY) * inverseDeterminant;\n } else {\n particle.x = slot.x;\n particle.y = slot.y;\n }\n const group = this.groupFor(texture, p.visual.blendMode);\n group.dirty ||= slot.renderDirty || textureChanged || group.container.particleChildren[group.nextCount] !== particle;\n group.container.particleChildren[group.nextCount++] = particle;\n slot.renderDirty = false;\n }\n for (const group of this.renderGroups.values()) {\n const children = group.container.particleChildren;\n if (children.length !== group.nextCount) {\n children.length = group.nextCount;\n group.dirty = true;\n }\n if (group.dirty) group.container.update();\n group.dirty = false;\n }\n this.renderDirty = false;\n }\n\n private cacheEffect(effect: ParticleEffectDefinition): boolean {\n const visual = effect.particle.visual;\n const sourceIds = visual.source.type === \"single\" ? [visual.source.assetId] : visual.source.assetIds;\n const sourceTextures = sourceIds.map((id) => this.textureFor(id));\n const signature = JSON.stringify(visual);\n const sourceSignature = JSON.stringify(visual.source);\n const sourceChanged = sourceSignature !== this.sourceSignature\n || sourceTextures.length !== this.sourceTextures.length\n || sourceTextures.some((texture, index) => texture !== this.sourceTextures[index]);\n const changed = signature !== this.renderSignature\n || sourceChanged;\n if (!changed) return false;\n this.renderSignature = signature;\n this.sourceSignature = sourceSignature;\n this.sourceTextures = sourceTextures;\n // Source edits and late texture loads invalidate the source-keyed groups. Rebuild containers,\n // but keep every pooled Particle and live simulation slot intact.\n if (sourceChanged) this.destroyRenderGroups();\n const dynamicProperties = particleDynamicProperties(effect);\n if (!sameDynamicProperties(this.dynamicProperties, dynamicProperties)) {\n this.destroyRenderGroups();\n this.dynamicProperties = dynamicProperties;\n }\n this.tintStart = parseRgb(effect.particle.visual.tint.start);\n this.tintEnd = parseRgb(effect.particle.visual.tint.end);\n this.staticColor = packParticleColor(this.tintStart, effect.particle.visual.alpha.start);\n for (const group of this.renderGroups.values()) group.container.blendMode = effect.particle.visual.blendMode;\n return true;\n }\n\n private groupFor(texture: Texture, blendMode: ParticleEffectDefinition[\"particle\"][\"visual\"][\"blendMode\"]): ParticleRenderGroup {\n let group = this.renderGroups.get(texture.source);\n if (group !== undefined) return group;\n const container = new ParticleContainer<Particle>({\n texture,\n dynamicProperties: this.dynamicProperties,\n });\n container.blendMode = blendMode;\n this.contentRoot.addChild(container);\n group = { container, nextCount: 0, dirty: true };\n this.renderGroups.set(texture.source, group);\n return group;\n }\n\n private destroyRenderGroups(): void {\n for (const group of this.renderGroups.values()) {\n this.contentRoot.removeChild(group.container);\n group.container.destroy();\n }\n this.renderGroups.clear();\n }\n}\n\ntype SequenceSource = Extract<ParticleEffectDefinition[\"particle\"][\"visual\"][\"source\"], { type: \"sequence\" }>;\ntype ParticleRenderGroup = { container: ParticleContainer<Particle>; nextCount: number; dirty: boolean };\ntype DynamicParticleProperties = { position: true; rotation: boolean; vertex: boolean; uvs: boolean; color: boolean };\n\nfunction sequenceFrame(source: SequenceSource, slot: ParticleSlot<Particle>): number {\n const length = source.assetIds.length;\r\n const raw = slot.sequenceStart + Math.floor(slot.age * source.fps);\r\n return source.loop ? ((raw % length) + length) % length : Math.min(raw, length - 1);\r\n}\n\nfunction parseRgb(hex: string): number { return Number.parseInt(hex.slice(1, 7), 16); }\nfunction lerpRgb(start: number, end: number, t: number): number {\n const r = Math.round(lerp((start >>> 16) & 0xff, (end >>> 16) & 0xff, t));\n const g = Math.round(lerp((start >>> 8) & 0xff, (end >>> 8) & 0xff, t));\n const b = Math.round(lerp(start & 0xff, end & 0xff, t));\n return (r << 16) | (g << 8) | b;\n}\n/** Pixi Particle buffers store packed ABGR, unlike the public RGB tint number. */\nfunction packParticleColor(rgb: number, alpha: number): number {\n const bgr = ((rgb & 0xff) << 16) | (rgb & 0xff00) | ((rgb >>> 16) & 0xff);\n return (bgr | (Math.round(Math.max(0, Math.min(1, alpha)) * 255) << 24)) >>> 0;\n}\n\nfunction particleDynamicProperties(effect: ParticleEffectDefinition): DynamicParticleProperties {\n const visual = effect.particle.visual;\n const angular = visual.rotation.angularVelocityDegrees;\n const scale = visual.scale;\n return {\n position: true,\n rotation: angular.min !== 0 || angular.max !== 0,\n vertex: !(scale.start.min === scale.start.max && scale.start.min === scale.end.min && scale.start.min === scale.end.max),\n uvs: visual.source.type === \"sequence\",\n color: visual.tint.start !== visual.tint.end || visual.alpha.start !== visual.alpha.end,\n };\n}\n\nfunction sameDynamicProperties(a: DynamicParticleProperties, b: DynamicParticleProperties): boolean {\n return a.rotation === b.rotation && a.vertex === b.vertex && a.uvs === b.uvs && a.color === b.color;\n}\n"]}
|