@pixi-ui-editor/runtime-pixi 0.13.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.
Files changed (57) hide show
  1. package/dist/assets/bitmapFonts.d.ts +2 -0
  2. package/dist/assets/bitmapFonts.d.ts.map +1 -1
  3. package/dist/assets/bitmapFonts.js +6 -2
  4. package/dist/assets/bitmapFonts.js.map +1 -1
  5. package/dist/assets/sounds.d.ts +1 -7
  6. package/dist/assets/sounds.d.ts.map +1 -1
  7. package/dist/assets/sounds.js +7 -90
  8. package/dist/assets/sounds.js.map +1 -1
  9. package/dist/assets/textures.d.ts +10 -0
  10. package/dist/assets/textures.d.ts.map +1 -1
  11. package/dist/assets/textures.js +10 -2
  12. package/dist/assets/textures.js.map +1 -1
  13. package/dist/audio/bus.d.ts +60 -0
  14. package/dist/audio/bus.d.ts.map +1 -0
  15. package/dist/audio/bus.js +38 -0
  16. package/dist/audio/bus.js.map +1 -0
  17. package/dist/audio/director.d.ts +35 -0
  18. package/dist/audio/director.d.ts.map +1 -0
  19. package/dist/audio/director.js +137 -0
  20. package/dist/audio/director.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/layout.d.ts +3 -1
  26. package/dist/layout.d.ts.map +1 -1
  27. package/dist/layout.js +13 -0
  28. package/dist/layout.js.map +1 -1
  29. package/dist/scene.d.ts +6 -2
  30. package/dist/scene.d.ts.map +1 -1
  31. package/dist/scene.js +5 -2
  32. package/dist/scene.js.map +1 -1
  33. package/dist/transformSpace.d.ts +119 -0
  34. package/dist/transformSpace.d.ts.map +1 -0
  35. package/dist/transformSpace.js +487 -0
  36. package/dist/transformSpace.js.map +1 -0
  37. package/dist/views/ButtonNodeView.d.ts +4 -3
  38. package/dist/views/ButtonNodeView.d.ts.map +1 -1
  39. package/dist/views/ButtonNodeView.js +9 -8
  40. package/dist/views/ButtonNodeView.js.map +1 -1
  41. package/dist/views/CheckboxNodeView.d.ts +4 -3
  42. package/dist/views/CheckboxNodeView.d.ts.map +1 -1
  43. package/dist/views/CheckboxNodeView.js +7 -7
  44. package/dist/views/CheckboxNodeView.js.map +1 -1
  45. package/dist/views/StagedButtonNodeView.d.ts +4 -3
  46. package/dist/views/StagedButtonNodeView.d.ts.map +1 -1
  47. package/dist/views/StagedButtonNodeView.js +7 -9
  48. package/dist/views/StagedButtonNodeView.js.map +1 -1
  49. package/dist/views/basic.d.ts +1 -1
  50. package/dist/views/basic.d.ts.map +1 -1
  51. package/dist/views/basic.js +13 -12
  52. package/dist/views/basic.js.map +1 -1
  53. package/dist/views/createNodeView.d.ts +2 -2
  54. package/dist/views/createNodeView.d.ts.map +1 -1
  55. package/dist/views/createNodeView.js +5 -5
  56. package/dist/views/createNodeView.js.map +1 -1
  57. 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,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAgD,OAAO,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE,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,MAAM,CAAyC;IAChE,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,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAQvJ;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;IA+BnB,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"}
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
- sounds;
20
+ audio;
21
+ nodeId;
21
22
  soundAssetIds;
22
23
  enabledState;
23
- constructor(node, textures, interaction, sounds) {
24
+ constructor(node, textures, interaction, audio) {
24
25
  super(textures);
25
26
  this.interaction = interaction;
26
- this.sounds = sounds;
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.sounds !== undefined) {
88
- button.onPress.connect(() => { const result = this.soundAssetIds?.pressAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.pressAssetId)?.play(); if (result instanceof Promise)
89
- void result.catch(() => undefined); });
90
- button.onHover.connect(() => { const result = this.soundAssetIds?.hoverAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.hoverAssetId)?.play(); if (result instanceof Promise)
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 {\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 }\n\n private static applyStateAppearance(view: Container, node: ButtonNode, state: ButtonStateKey): void {\n view.tint = node.states[`${state}Tint`] ?? \"#ffffff\";\n view.alpha = node.states[`${state}Opacity`] ?? 1;\n }\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;\n const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);\n ButtonNodeView.applyStateAppearance(view, node, state);\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) {\n const view = this.stateViews[state];\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) {\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\n }\n ButtonNodeView.applyStateAppearance(view, node, state);\n }\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 sounds;
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, sounds?: ReadonlyMap<string, Sound>);
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,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAU,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE,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,MAAM,CAAyC;IAChE,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,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAiCzJ;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"}
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
- sounds;
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, sounds) {
28
+ constructor(node, textures, interaction, audio) {
28
29
  super(textures);
29
30
  this.interaction = interaction;
30
- this.sounds = sounds;
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 (sounds !== undefined) {
52
+ if (audio !== undefined) {
51
53
  this.checkbox.onCheck.connect((checkedState) => {
52
54
  const assetId = checkedState ? this.soundAssetIds?.checkAssetId : this.soundAssetIds?.uncheckAssetId;
53
- const result = assetId === undefined ? undefined : this.sounds?.get(assetId)?.play();
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":"AAAA,OAAO,EAAE,mBAAmB,EAAsC,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAA6B,MAAM,eAAe,CAAC;AAIpE;;;;;;;;;;GAUG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAC3B,QAAQ,CAAW;IACnB,WAAW,CAAuB;IAClC,MAAM,CAAyC;IACxD,aAAa,CAAyB;IACtC,gBAAgB,CAAU;IAC1B,cAAc,CAAU;IACxB,qBAAqB,CAAU;IAC/B,mBAAmB,CAAU;IAC7B,YAAY,CAAU;IACtB,QAAQ,GAAG,KAAK,CAAC;IAEzB,YAAY,IAAkB,EAAE,QAAkD,EAAE,WAAiC,EAAE,MAAmC;QACxJ,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACjF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7E,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;QAChG,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAC1F,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,OAAO,EAAE,IAAI,CAAC,cAAc;YAC5B,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;SAC9B,CAAC,CAAC;QACH,4FAA4F;QAC5F,6FAA6F;QAC7F,2FAA2F;QAC3F,IAAI,WAAW,KAAK,WAAW;YAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC;aAC7D,CAAC;YACJ,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;oBAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC;oBACrG,MAAM,MAAM,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;oBACrF,IAAI,MAAM,YAAY,OAAO;wBAAE,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACpE,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC;QACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAEO,eAAe,CAAC,OAA2B,EAAE,QAAiB;QACpE,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC;IACpF,CAAC;IAED,iHAAiH;IACzG,aAAa;QACnB,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACzD,IAAI,aAAa,YAAY,MAAM;YAAE,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAChI,IAAI,WAAW,YAAY,MAAM;YAAE,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IAC1H,CAAC;IAED,4GAA4G;IACpG,YAAY,CAAC,OAAgB;QACnC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW;YAAE,OAAO;QAC7C,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IACxD,CAAC;IAES,WAAW,CAAC,IAAY,EAAE,SAA8B;QAChE,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;QAEjC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACjF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7E,6FAA6F;QAC7F,4FAA4F;QAC5F,iGAAiG;QACjG,qDAAqD;QACrD,IAAI,SAAS,KAAK,IAAI,CAAC,gBAAgB,IAAI,OAAO,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3E,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;QAChG,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAC1F,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK;YAAE,IAAI,IAAI,YAAY,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAEpH,mGAAmG;QACnG,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,CAAC,KAAc;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO,CAAC,KAAc;QACxB,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAChC,CAAC;IAED,uGAAuG;IACvG,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,OAAO,KAA0B,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;CACrE","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,9 +1,9 @@
1
1
  import { type ButtonStateKey, type LayoutPadding, type StagedButtonNode, type UINode } from "@pixi-ui-editor/schema";
2
2
  import { FancyButton } from "@pixi/ui";
3
- import type { Sound } from "@pixi/sound";
4
3
  import { Texture } from "pixi.js";
5
4
  import { Signal } from "typed-signals";
6
5
  import { NodeView, type SceneInteractionMode } from "./NodeView.js";
6
+ import type { SceneAudio } from "../audio/bus.js";
7
7
  export type { StagedButtonNode };
8
8
  /**
9
9
  * Adapts a staged-button node to `@pixi/ui`'s `FancyButton`, exactly like `ButtonNodeView` does for a
@@ -20,7 +20,8 @@ export declare class StagedButtonNodeView extends NodeView {
20
20
  private button;
21
21
  private stateViews;
22
22
  private readonly interaction;
23
- private readonly sounds;
23
+ private readonly audio;
24
+ private readonly nodeId;
24
25
  private soundAssetIds;
25
26
  private nineSlice;
26
27
  private stagesData;
@@ -40,7 +41,7 @@ export declare class StagedButtonNodeView extends NodeView {
40
41
  index: number;
41
42
  value: string;
42
43
  }) => void>;
43
- constructor(node: StagedButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, sounds?: ReadonlyMap<string, Sound>);
44
+ constructor(node: StagedButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, audio?: SceneAudio);
44
45
  private currentStage;
45
46
  /**
46
47
  * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry
@@ -1 +1 @@
1
- {"version":3,"file":"StagedButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/StagedButtonNodeView.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StagedButtonNodeView.d.ts","sourceRoot":"","sources":["../../src/views/StagedButtonNodeView.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,8 @@ export class StagedButtonNodeView extends NodeView {
19
19
  button;
20
20
  stateViews;
21
21
  interaction;
22
- sounds;
22
+ audio;
23
+ nodeId;
23
24
  soundAssetIds;
24
25
  nineSlice;
25
26
  stagesData;
@@ -36,10 +37,11 @@ export class StagedButtonNodeView extends NodeView {
36
37
  onHover = new Signal();
37
38
  onOut = new Signal();
38
39
  onStageChange = new Signal();
39
- constructor(node, textures, interaction, sounds) {
40
+ constructor(node, textures, interaction, audio) {
40
41
  super(textures);
41
42
  this.interaction = interaction;
42
- this.sounds = sounds;
43
+ this.audio = audio;
44
+ this.nodeId = node.id;
43
45
  this.soundAssetIds = node.sounds;
44
46
  this.nineSlice = node.nineSlice;
45
47
  this.stagesData = node.stages;
@@ -111,17 +113,13 @@ export class StagedButtonNodeView extends NodeView {
111
113
  else {
112
114
  button.onPress.connect((source, event) => {
113
115
  this.next();
114
- const result = this.soundAssetIds?.pressAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.pressAssetId)?.play();
115
- if (result instanceof Promise)
116
- void result.catch(() => undefined);
116
+ this.audio?.cue("button.press", this.nodeId, this.soundAssetIds?.pressAssetId);
117
117
  this.onPress.emit(source, event);
118
118
  });
119
119
  button.onDown.connect((source, event) => this.onDown.emit(source, event));
120
120
  button.onUp.connect((source, event) => this.onUp.emit(source, event));
121
121
  button.onHover.connect((source, event) => {
122
- const result = this.soundAssetIds?.hoverAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.hoverAssetId)?.play();
123
- if (result instanceof Promise)
124
- void result.catch(() => undefined);
122
+ this.audio?.cue("button.hover", this.nodeId, this.soundAssetIds?.hoverAssetId);
125
123
  this.onHover.emit(source, event);
126
124
  });
127
125
  button.onOut.connect((source, event) => this.onOut.emit(source, event));
@@ -1 +1 @@
1
- {"version":3,"file":"StagedButtonNodeView.js","sourceRoot":"","sources":["../../src/views/StagedButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type StagedButtonNode, 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 { Signal } from \"typed-signals\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type { StagedButtonNode };\r\ntype StagedButtonStage = StagedButtonNode[\"stages\"][number];\r\ntype FancyButtonEventHandler = Parameters<FancyButton[\"onPress\"][\"connect\"]>[0];\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a staged-button node to `@pixi/ui`'s `FancyButton`, exactly like `ButtonNodeView` does for a\r\n * plain button — this class never reimplements its pointer state machine either. It is a deliberately\r\n * separate component (see TASK-057): it does not extend or share behavior with `ButtonNodeView`.\r\n *\r\n * A click at runtime advances the current stage (`next()`), which respects `wrap`. Four state views\r\n * are created once and reused across stages: changing stage only reassigns their textures/size, never\r\n * replacing the view type — a full `FancyButton` rebuild only happens when a view's required *type*\r\n * changes (nine-slice toggled, or a texture just finished loading), because `FancyButton` gives no way\r\n * to swap a view after construction.\r\n */\r\nexport class StagedButtonNodeView 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: StagedButtonNode[\"sounds\"];\r\n private nineSlice: LayoutPadding | undefined;\r\n private stagesData: StagedButtonStage[];\r\n private currentStageId: string;\r\n private defaultStageId: string;\r\n private wrapState: boolean;\r\n private enabledState: boolean;\r\n /** Последнее editor-only визуальное состояние из `setState`: переживает пересборку `FancyButton`. */\r\n private forcedState: ButtonStateKey | undefined;\r\n\r\n /** Stable public signals: subscriptions survive an internal `FancyButton` rebuild. */\r\n readonly onPress: FancyButton[\"onPress\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onDown: FancyButton[\"onDown\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onUp: FancyButton[\"onUp\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onHover: FancyButton[\"onHover\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onOut: FancyButton[\"onOut\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onStageChange = new Signal<(stage: { index: number; value: string }) => void>();\r\n\r\n constructor(node: StagedButtonNode, 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.nineSlice = node.nineSlice;\r\n this.stagesData = node.stages;\r\n this.wrapState = node.wrap;\r\n this.defaultStageId = node.defaultStageId;\r\n this.currentStageId = node.stages.some((stage) => stage.id === node.defaultStageId) ? node.defaultStageId : node.stages[0]!.id;\r\n this.enabledState = node.enabled;\r\n // Explicit size, not the `this.layoutRectangle` default `buildButton()` would otherwise fall back\r\n // to: no layout pass has run yet at construction time, so that getter still reads `{0, 0}`.\r\n this.buildButton({ width: node.transform.width, height: node.transform.height });\r\n }\r\n\r\n private currentStage(): StagedButtonStage {\r\n return this.stagesData.find((stage) => stage.id === this.currentStageId) ?? this.stagesData[0]!;\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 {\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n StagedButtonNodeView.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 }\n\n private static applyStateAppearance(view: Container, stage: StagedButtonStage, state: ButtonStateKey): void {\n view.tint = stage.states[`${state}Tint`] ?? \"#ffffff\";\n view.alpha = stage.states[`${state}Opacity`] ?? 1;\n }\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,\r\n * sizes the freshly built views immediately — needed because a stage change may happen well outside\r\n * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards. The\r\n * constructor also always passes it explicitly: `this.layoutRectangle` is still `{0, 0}` before the\r\n * first layout pass, and an initial placeholder painted at that size would freeze a zero-size,\r\n * permanently unclickable `hitArea` on `FancyButton` (see `paintPlaceholder`).\r\n */\r\n private buildButton(size?: { width: number; height: number }): void {\r\n const stage = this.currentStage();\r\n const normalTexture = this.textureFor(stage.states.normalAssetId);\r\n const resolvedSize = size ?? this.layoutRectangle;\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;\n const view = StagedButtonNodeView.createStateView(texture, this.nineSlice, resolvedSize);\n StagedButtonNodeView.applyStateAppearance(view, stage, state);\n stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", stage.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", stage.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", stage.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", stage.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна, как и у обычной кнопки: клики не должны крутить стадию, а попадание по\r\n // ноде остаётся ответственностью NodeView.containsPoint.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else {\r\n button.onPress.connect((source, event) => {\r\n this.next();\r\n const result = this.soundAssetIds?.pressAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.pressAssetId)?.play();\r\n if (result instanceof Promise) void result.catch(() => undefined);\r\n this.onPress.emit(source, event);\r\n });\r\n button.onDown.connect((source, event) => this.onDown.emit(source, event));\r\n button.onUp.connect((source, event) => this.onUp.emit(source, event));\r\n button.onHover.connect((source, event) => {\r\n const result = this.soundAssetIds?.hoverAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.hoverAssetId)?.play();\r\n if (result instanceof Promise) void result.catch(() => undefined);\r\n this.onHover.emit(source, event);\r\n });\r\n button.onOut.connect((source, event) => this.onOut.emit(source, event));\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n\r\n this.applySizes(resolvedSize.width, resolvedSize.height);\r\n\r\n // Пересборка — деталь реализации `FancyButton`, а не действие пользователя: transient enabled и\r\n // визуальное состояние восстанавливаются на новом инстансе, иначе переключение nine-slice или\r\n // догрузка текстуры сбрасывали бы их.\r\n this.applyEnabled(this.enabledState);\r\n if (this.forcedState !== undefined) this.button.setState(FANCY_STATE_BY_KEY[this.forcedState]);\r\n }\r\n\r\n /**\r\n * Sizes the four state views to the resolved layout rectangle without touching their textures.\r\n *\r\n * `NineSliceSprite` проверяется отдельно: в PixiJS 8 он наследуется от `ViewContainer`, а не от\r\n * `Sprite`, поэтому одна ветка `instanceof Sprite` его молча пропускает.\r\n */\r\n private applySizes(width: number, height: number): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (view instanceof NineSliceSprite) view.setSize(width, height);\r\n else if (view instanceof Sprite) view.setSize(width, height);\r\n else if (view instanceof Graphics) StagedButtonNodeView.paintPlaceholder(view, width, height);\r\n }\r\n }\r\n\r\n /**\r\n * Applies the current stage's textures/border to the existing state views (or rebuilds them if a\r\n * view's required type no longer matches, the same rule `ButtonNodeView.syncContent` follows).\r\n */\r\n private refreshStateViews(width: number, height: number): void {\r\n const stage = this.currentStage();\r\n const normalTexture = this.textureFor(stage.states.normalAssetId);\r\n\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = stage.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 && this.nineSlice !== undefined;\r\n // `NineSliceSprite` не наследуется от `Sprite` в PixiJS 8, поэтому ветки не пересекаются.\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite;\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton({ width, height });\r\n return;\r\n }\r\n\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = stage.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 (this.nineSlice !== undefined) {\r\n view.leftWidth = this.nineSlice.left;\r\n view.topHeight = this.nineSlice.top;\r\n view.rightWidth = this.nineSlice.right;\r\n view.bottomHeight = this.nineSlice.bottom;\r\n }\r\n } else if (view instanceof Sprite) {\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\n }\n StagedButtonNodeView.applyStateAppearance(view, stage, state);\n }\n this.applySizes(width, height);\r\n }\r\n\r\n private applyStage(stageId: string): void {\r\n this.currentStageId = stageId;\r\n const { width, height } = this.layoutRectangle;\r\n this.refreshStateViews(width, height);\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 !== \"staged-button\") return;\r\n this.soundAssetIds = node.sounds;\r\n this.nineSlice = node.nineSlice;\r\n this.wrapState = node.wrap;\r\n this.defaultStageId = node.defaultStageId;\r\n\r\n // Сохраняет текущую стадию, если она ещё существует после изменения документа; если стадию\r\n // удалили — переходит на ближайшую валидную по прежнему индексу.\r\n const previousIndex = this.stagesData.findIndex((stage) => stage.id === this.currentStageId);\r\n this.stagesData = node.stages;\r\n if (!node.stages.some((stage) => stage.id === this.currentStageId)) {\r\n const clampedIndex = Math.min(Math.max(previousIndex, 0), node.stages.length - 1);\r\n this.currentStageId = node.stages[clampedIndex]!.id;\r\n }\r\n\r\n this.refreshStateViews(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 /** 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 stage(): number {\r\n const index = this.stagesData.findIndex((stage) => stage.id === this.currentStageId);\r\n return index === -1 ? 0 : index;\r\n }\r\n\r\n get value(): string {\r\n return this.currentStage().value;\r\n }\r\n\r\n get stageCount(): number {\r\n return this.stagesData.length;\r\n }\r\n\r\n /** Moves to the stage at `index` and emits `onStageChange`; an out-of-range index is a no-op. */\r\n setStage(index: number): void {\r\n const target = this.stagesData[index];\r\n if (target === undefined) return;\r\n this.applyStage(target.id);\r\n this.onStageChange.emit({ index, value: target.value });\r\n }\r\n\r\n /** Moves to the stage at `index` without emitting — used by editor preview to avoid feedback loops. */\r\n forceStage(index: number): void {\r\n const target = this.stagesData[index];\r\n if (target === undefined) return;\r\n this.applyStage(target.id);\r\n }\r\n\r\n /** Moves to the first stage whose `value` matches; an unknown value is ignored. */\r\n setValue(value: string): void {\r\n const index = this.stagesData.findIndex((stage) => stage.value === value);\r\n if (index === -1) return;\r\n this.setStage(index);\r\n }\r\n\r\n /** Advances one stage, as a click does; respects `wrap` at the last stage. */\r\n next(): void {\r\n const nextIndex = this.stage + 1;\r\n if (nextIndex >= this.stagesData.length) {\r\n if (!this.wrapState) return;\r\n this.setStage(0);\r\n return;\r\n }\r\n this.setStage(nextIndex);\r\n }\r\n\r\n /** Returns to `defaultStageId`, emitting `onStageChange`. */\r\n reset(): void {\r\n const index = this.stagesData.findIndex((stage) => stage.id === this.defaultStageId);\r\n this.setStage(index === -1 ? 0 : index);\r\n }\r\n\r\n /** Forces an editor-only visual state without changing `enabled`, mirroring `ButtonNodeView.setState`. */\r\n setState(state: ButtonStateKey): void {\r\n this.forcedState = state;\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"StagedButtonNodeView.js","sourceRoot":"","sources":["../../src/views/StagedButtonNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA+E,MAAM,wBAAwB,CAAC;AACxI,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAa,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAW,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,QAAQ,EAA6B,MAAM,eAAe,CAAC;AAOpE,MAAM,kBAAkB,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAW,CAAC;AAEpH;;;;;;;;;;GAUG;AACH,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IACxC,MAAM,CAAe;IACrB,UAAU,CAAqC;IACtC,WAAW,CAAuB;IAClC,KAAK,CAAyB;IAC9B,MAAM,CAAS;IACxB,aAAa,CAA6B;IAC1C,SAAS,CAA4B;IACrC,UAAU,CAAsB;IAChC,cAAc,CAAS;IACvB,cAAc,CAAS;IACvB,SAAS,CAAU;IACnB,YAAY,CAAU;IAC9B,qGAAqG;IAC7F,WAAW,CAA6B;IAEhD,sFAAsF;IAC7E,OAAO,GAA2B,IAAI,MAAM,EAA2B,CAAC;IACxE,MAAM,GAA0B,IAAI,MAAM,EAA2B,CAAC;IACtE,IAAI,GAAwB,IAAI,MAAM,EAA2B,CAAC;IAClE,OAAO,GAA2B,IAAI,MAAM,EAA2B,CAAC;IACxE,KAAK,GAAyB,IAAI,MAAM,EAA2B,CAAC;IACpE,aAAa,GAAG,IAAI,MAAM,EAAqD,CAAC;IAEzF,YAAY,IAAsB,EAAE,QAAkD,EAAE,WAAiC,EAAE,KAAkB;QAC3I,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;QAC/H,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC;QACjC,kGAAkG;QAClG,4FAA4F;QAC5F,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACnF,CAAC;IAEO,YAAY;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;IAClG,CAAC;IAED;;;;;;OAMG;IACK,MAAM,CAAC,gBAAgB,CAAC,QAAkB,EAAE,KAAa,EAAE,MAAc;QAC/E,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,OAA4B,EAAE,SAAoC,EAAE,IAAuC;QACxI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;YAChC,oBAAoB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACzE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,SAAS,KAAK,SAAS;YAC5B,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;YACrB,CAAC,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACzJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,IAAe,EAAE,KAAwB,EAAE,KAAqB;QAClG,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACK,WAAW,CAAC,IAAwC;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAClE,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC;QAClD,MAAM,UAAU,GAAG,EAAuC,CAAC;QAC3D,MAAM,OAAO,GAAG,CAAC,KAAqB,EAAE,OAA2B,EAAa,EAAE;YAChF,MAAM,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC;YAChG,MAAM,IAAI,GAAG,oBAAoB,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACzF,oBAAoB,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9D,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;YAC1D,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC;YACtD,WAAW,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC;YAC5D,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;SAChE,CAAC,CAAC;QACH,kGAAkG;QAClG,yDAAyD;QACzD,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW;YAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;aAC3D,CAAC;YACJ,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBACvC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;gBAC/E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YAC1E,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YACtE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBACvC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;gBAC/E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAExB,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QAEzD,gGAAgG;QAChG,8FAA8F;QAC9F,sCAAsC;QACtC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACjG,CAAC;IAED;;;;;OAKG;IACK,UAAU,CAAC,KAAa,EAAE,MAAc;QAC9C,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,IAAI,YAAY,eAAe;gBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;iBAC5D,IAAI,IAAI,YAAY,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;iBACxD,IAAI,IAAI,YAAY,QAAQ;gBAAE,oBAAoB,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,KAAa,EAAE,MAAc;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAElE,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC;YAChG,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,cAAc,GAAG,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;YAC7E,0FAA0F;YAC1F,MAAM,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,YAAY,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,YAAY,eAAe,CAAC,CAAC,CAAC,IAAI,YAAY,MAAM,CAAC;YAC7I,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAC,YAAY,GAAG,IAAI,CAAC;gBAAC,MAAM;YAAC,CAAC;QAC/C,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,aAAa,CAAC;YAChG,2FAA2F;YAC3F,6FAA6F;YAC7F,IAAI,IAAI,YAAY,eAAe,EAAE,CAAC;gBACpC,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO;oBAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC9E,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBACjC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;oBACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;oBACvC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,YAAY,MAAM,EAAE,CAAC;gBAClC,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO;oBAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YAChF,CAAC;YACD,oBAAoB,CAAC,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAEO,UAAU,CAAC,OAAe;QAChC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,uGAAuG;IAC/F,YAAY,CAAC,OAAgB;QACnC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;;YAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC;IAES,WAAW,CAAC,IAAY,EAAE,SAA8B;QAChE,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe;YAAE,OAAO;QAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAE1C,2FAA2F;QAC3F,iEAAiE;QACjE,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7F,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACnE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAClF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAE,CAAC,EAAE,CAAC;QACtD,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAE1D,mGAAmG;QACnG,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,2FAA2F;IAC3F,gBAAgB,CAAC,SAAwB;QACvC,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,CAAC,IAAI,YAAY,eAAe,CAAC;gBAAE,SAAS;YACjD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC;YAChC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC;YAClC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC;QACvC,CAAC;IACH,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,CAAC,KAAc;QACxB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK;QACP,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC;QACrF,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,iGAAiG;IACjG,QAAQ,CAAC,KAAa;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,uGAAuG;IACvG,UAAU,CAAC,KAAa;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QACjC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,mFAAmF;IACnF,QAAQ,CAAC,KAAa;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAC1E,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACjC,IAAI,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,OAAO;YAC5B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,6DAA6D;IAC7D,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC;QACrF,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,0GAA0G;IAC1G,QAAQ,CAAC,KAAqB;QAC5B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,CAAC;CACF","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type StagedButtonNode, 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 { Signal } from \"typed-signals\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\nimport type { SceneAudio } from \"../audio/bus.js\";\r\n\r\nexport type { StagedButtonNode };\r\ntype StagedButtonStage = StagedButtonNode[\"stages\"][number];\r\ntype FancyButtonEventHandler = Parameters<FancyButton[\"onPress\"][\"connect\"]>[0];\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a staged-button node to `@pixi/ui`'s `FancyButton`, exactly like `ButtonNodeView` does for a\r\n * plain button — this class never reimplements its pointer state machine either. It is a deliberately\r\n * separate component (see TASK-057): it does not extend or share behavior with `ButtonNodeView`.\r\n *\r\n * A click at runtime advances the current stage (`next()`), which respects `wrap`. Four state views\r\n * are created once and reused across stages: changing stage only reassigns their textures/size, never\r\n * replacing the view type — a full `FancyButton` rebuild only happens when a view's required *type*\r\n * changes (nine-slice toggled, or a texture just finished loading), because `FancyButton` gives no way\r\n * to swap a view after construction.\r\n */\r\nexport class StagedButtonNodeView 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: StagedButtonNode[\"sounds\"];\r\n private nineSlice: LayoutPadding | undefined;\r\n private stagesData: StagedButtonStage[];\r\n private currentStageId: string;\r\n private defaultStageId: string;\r\n private wrapState: boolean;\r\n private enabledState: boolean;\r\n /** Последнее editor-only визуальное состояние из `setState`: переживает пересборку `FancyButton`. */\r\n private forcedState: ButtonStateKey | undefined;\r\n\r\n /** Stable public signals: subscriptions survive an internal `FancyButton` rebuild. */\r\n readonly onPress: FancyButton[\"onPress\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onDown: FancyButton[\"onDown\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onUp: FancyButton[\"onUp\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onHover: FancyButton[\"onHover\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onOut: FancyButton[\"onOut\"] = new Signal<FancyButtonEventHandler>();\r\n readonly onStageChange = new Signal<(stage: { index: number; value: string }) => void>();\r\n\r\n constructor(node: StagedButtonNode, 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.nineSlice = node.nineSlice;\r\n this.stagesData = node.stages;\r\n this.wrapState = node.wrap;\r\n this.defaultStageId = node.defaultStageId;\r\n this.currentStageId = node.stages.some((stage) => stage.id === node.defaultStageId) ? node.defaultStageId : node.stages[0]!.id;\r\n this.enabledState = node.enabled;\r\n // Explicit size, not the `this.layoutRectangle` default `buildButton()` would otherwise fall back\r\n // to: no layout pass has run yet at construction time, so that getter still reads `{0, 0}`.\r\n this.buildButton({ width: node.transform.width, height: node.transform.height });\r\n }\r\n\r\n private currentStage(): StagedButtonStage {\r\n return this.stagesData.find((stage) => stage.id === this.currentStageId) ?? this.stagesData[0]!;\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 StagedButtonNodeView.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, stage: StagedButtonStage, state: ButtonStateKey): void {\r\n view.tint = stage.states[`${state}Tint`] ?? \"#ffffff\";\r\n view.alpha = stage.states[`${state}Opacity`] ?? 1;\r\n }\r\n\r\n /**\r\n * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,\r\n * sizes the freshly built views immediately — needed because a stage change may happen well outside\r\n * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards. The\r\n * constructor also always passes it explicitly: `this.layoutRectangle` is still `{0, 0}` before the\r\n * first layout pass, and an initial placeholder painted at that size would freeze a zero-size,\r\n * permanently unclickable `hitArea` on `FancyButton` (see `paintPlaceholder`).\r\n */\r\n private buildButton(size?: { width: number; height: number }): void {\r\n const stage = this.currentStage();\r\n const normalTexture = this.textureFor(stage.states.normalAssetId);\r\n const resolvedSize = size ?? this.layoutRectangle;\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 = StagedButtonNodeView.createStateView(texture, this.nineSlice, resolvedSize);\r\n StagedButtonNodeView.applyStateAppearance(view, stage, 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\", stage.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", stage.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", stage.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", stage.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна, как и у обычной кнопки: клики не должны крутить стадию, а попадание по\r\n // ноде остаётся ответственностью NodeView.containsPoint.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else {\r\n button.onPress.connect((source, event) => {\r\n this.next();\r\n this.audio?.cue(\"button.press\", this.nodeId, this.soundAssetIds?.pressAssetId);\r\n this.onPress.emit(source, event);\r\n });\r\n button.onDown.connect((source, event) => this.onDown.emit(source, event));\r\n button.onUp.connect((source, event) => this.onUp.emit(source, event));\r\n button.onHover.connect((source, event) => {\r\n this.audio?.cue(\"button.hover\", this.nodeId, this.soundAssetIds?.hoverAssetId);\r\n this.onHover.emit(source, event);\r\n });\r\n button.onOut.connect((source, event) => this.onOut.emit(source, event));\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n\r\n this.applySizes(resolvedSize.width, resolvedSize.height);\r\n\r\n // Пересборка — деталь реализации `FancyButton`, а не действие пользователя: transient enabled и\r\n // визуальное состояние восстанавливаются на новом инстансе, иначе переключение nine-slice или\r\n // догрузка текстуры сбрасывали бы их.\r\n this.applyEnabled(this.enabledState);\r\n if (this.forcedState !== undefined) this.button.setState(FANCY_STATE_BY_KEY[this.forcedState]);\r\n }\r\n\r\n /**\r\n * Sizes the four state views to the resolved layout rectangle without touching their textures.\r\n *\r\n * `NineSliceSprite` проверяется отдельно: в PixiJS 8 он наследуется от `ViewContainer`, а не от\r\n * `Sprite`, поэтому одна ветка `instanceof Sprite` его молча пропускает.\r\n */\r\n private applySizes(width: number, height: number): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (view instanceof NineSliceSprite) view.setSize(width, height);\r\n else if (view instanceof Sprite) view.setSize(width, height);\r\n else if (view instanceof Graphics) StagedButtonNodeView.paintPlaceholder(view, width, height);\r\n }\r\n }\r\n\r\n /**\r\n * Applies the current stage's textures/border to the existing state views (or rebuilds them if a\r\n * view's required type no longer matches, the same rule `ButtonNodeView.syncContent` follows).\r\n */\r\n private refreshStateViews(width: number, height: number): void {\r\n const stage = this.currentStage();\r\n const normalTexture = this.textureFor(stage.states.normalAssetId);\r\n\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = stage.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 && this.nineSlice !== undefined;\r\n // `NineSliceSprite` не наследуется от `Sprite` в PixiJS 8, поэтому ветки не пересекаются.\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite;\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton({ width, height });\r\n return;\r\n }\r\n\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = stage.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 (this.nineSlice !== undefined) {\r\n view.leftWidth = this.nineSlice.left;\r\n view.topHeight = this.nineSlice.top;\r\n view.rightWidth = this.nineSlice.right;\r\n view.bottomHeight = this.nineSlice.bottom;\r\n }\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n }\r\n StagedButtonNodeView.applyStateAppearance(view, stage, state);\r\n }\r\n this.applySizes(width, height);\r\n }\r\n\r\n private applyStage(stageId: string): void {\r\n this.currentStageId = stageId;\r\n const { width, height } = this.layoutRectangle;\r\n this.refreshStateViews(width, height);\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 !== \"staged-button\") return;\r\n this.soundAssetIds = node.sounds;\r\n this.nineSlice = node.nineSlice;\r\n this.wrapState = node.wrap;\r\n this.defaultStageId = node.defaultStageId;\r\n\r\n // Сохраняет текущую стадию, если она ещё существует после изменения документа; если стадию\r\n // удалили — переходит на ближайшую валидную по прежнему индексу.\r\n const previousIndex = this.stagesData.findIndex((stage) => stage.id === this.currentStageId);\r\n this.stagesData = node.stages;\r\n if (!node.stages.some((stage) => stage.id === this.currentStageId)) {\r\n const clampedIndex = Math.min(Math.max(previousIndex, 0), node.stages.length - 1);\r\n this.currentStageId = node.stages[clampedIndex]!.id;\r\n }\r\n\r\n this.refreshStateViews(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 /** 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 stage(): number {\r\n const index = this.stagesData.findIndex((stage) => stage.id === this.currentStageId);\r\n return index === -1 ? 0 : index;\r\n }\r\n\r\n get value(): string {\r\n return this.currentStage().value;\r\n }\r\n\r\n get stageCount(): number {\r\n return this.stagesData.length;\r\n }\r\n\r\n /** Moves to the stage at `index` and emits `onStageChange`; an out-of-range index is a no-op. */\r\n setStage(index: number): void {\r\n const target = this.stagesData[index];\r\n if (target === undefined) return;\r\n this.applyStage(target.id);\r\n this.onStageChange.emit({ index, value: target.value });\r\n }\r\n\r\n /** Moves to the stage at `index` without emitting — used by editor preview to avoid feedback loops. */\r\n forceStage(index: number): void {\r\n const target = this.stagesData[index];\r\n if (target === undefined) return;\r\n this.applyStage(target.id);\r\n }\r\n\r\n /** Moves to the first stage whose `value` matches; an unknown value is ignored. */\r\n setValue(value: string): void {\r\n const index = this.stagesData.findIndex((stage) => stage.value === value);\r\n if (index === -1) return;\r\n this.setStage(index);\r\n }\r\n\r\n /** Advances one stage, as a click does; respects `wrap` at the last stage. */\r\n next(): void {\r\n const nextIndex = this.stage + 1;\r\n if (nextIndex >= this.stagesData.length) {\r\n if (!this.wrapState) return;\r\n this.setStage(0);\r\n return;\r\n }\r\n this.setStage(nextIndex);\r\n }\r\n\r\n /** Returns to `defaultStageId`, emitting `onStageChange`. */\r\n reset(): void {\r\n const index = this.stagesData.findIndex((stage) => stage.id === this.defaultStageId);\r\n this.setStage(index === -1 ? 0 : index);\r\n }\r\n\r\n /** Forces an editor-only visual state without changing `enabled`, mirroring `ButtonNodeView.setState`. */\r\n setState(state: ButtonStateKey): void {\r\n this.forcedState = state;\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n}\r\n"]}
@@ -129,7 +129,7 @@ export declare class BitmapTextNodeView extends NodeView {
129
129
  private lastAlign;
130
130
  private lastVerticalAlign;
131
131
  constructor(fonts?: ReadonlyMap<string, string> | undefined);
132
- protected syncContent(node: UINode, transform: UINode["transform"]): void;
132
+ protected syncContent(node: UINode, transform: UINode["transform"], profile: LayoutProfileId): void;
133
133
  /**
134
134
  * Updates the rendered bitmap text without reapplying the node transform. This lets game code
135
135
  * refresh counters that are temporarily attached to a Spine connector without dislodging them.
@@ -1 +1 @@
1
- {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/views/basic.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { applyTextCase } from "@pixi-ui-editor/schema";
2
2
  import { BitmapText, Container, Graphics, NineSliceSprite, Sprite, Text } from "pixi.js";
3
3
  import { NodeView } from "./NodeView.js";
4
- import { resolveTextStyle } from "../layout.js";
4
+ import { resolveBitmapTextStyle, resolveTextStyle } from "../layout.js";
5
5
  export class ContainerNodeView extends NodeView {
6
6
  syncContent() { }
7
7
  }
@@ -334,13 +334,14 @@ export class BitmapTextNodeView extends NodeView {
334
334
  this.fonts = fonts;
335
335
  this.setContent(new Graphics());
336
336
  }
337
- syncContent(node, transform) {
337
+ syncContent(node, transform, profile) {
338
338
  if (node.type !== "bitmap-text")
339
339
  return;
340
+ const style = resolveBitmapTextStyle(node, profile);
340
341
  this.lastTransform = transform;
341
- this.lastAlign = node.align;
342
- this.lastVerticalAlign = node.verticalAlign;
343
- const family = this.fonts?.get(node.assetId);
342
+ this.lastAlign = style.align;
343
+ this.lastVerticalAlign = style.verticalAlign;
344
+ const family = this.fonts?.get(style.assetId);
344
345
  if (family === undefined) {
345
346
  if (!(this.content instanceof Graphics))
346
347
  this.setContent(new Graphics());
@@ -348,11 +349,11 @@ export class BitmapTextNodeView extends NodeView {
348
349
  return;
349
350
  }
350
351
  if (!(this.content instanceof BitmapText))
351
- this.setContent(new BitmapText({ text: node.text, style: { fontFamily: family, fontSize: node.fontSize, fill: node.fill } }));
352
+ this.setContent(new BitmapText({ text: node.text, style: { fontFamily: family, fontSize: style.fontSize, fill: style.fill } }));
352
353
  const bitmapText = this.content;
353
354
  if (bitmapText.text !== node.text)
354
355
  bitmapText.text = node.text;
355
- this.applyFittedStyle(bitmapText, node, family, transform);
356
+ this.applyFittedStyle(bitmapText, node, style, family, transform);
356
357
  this.align();
357
358
  }
358
359
  /**
@@ -372,8 +373,8 @@ export class BitmapTextNodeView extends NodeView {
372
373
  * closed-form scale, because word-wrapped text re-flows at every size: a smaller font can fit more
373
374
  * words per line, so height doesn't shrink linearly with font size the way unwrapped bounds would.
374
375
  */
375
- applyFittedStyle(bitmapText, node, family, transform) {
376
- const baseStyle = { fontFamily: family, fill: node.fill, align: node.align, letterSpacing: node.letterSpacing, wordWrap: node.wordWrap, wordWrapWidth: transform.width };
376
+ applyFittedStyle(bitmapText, node, style, family, transform) {
377
+ const baseStyle = { fontFamily: family, fill: style.fill, align: style.align, letterSpacing: style.letterSpacing, wordWrap: style.wordWrap, wordWrapWidth: transform.width };
377
378
  const fits = (fontSize) => {
378
379
  bitmapText.style = { ...baseStyle, fontSize };
379
380
  // Headless loaders and schema tests have no browser canvas to measure against; they keep the
@@ -390,13 +391,13 @@ export class BitmapTextNodeView extends NodeView {
390
391
  // just the shrink-check's fast path. Written as `||` short-circuit, `fits(node.fontSize)` would
391
392
  // never execute while `autoSize` is off, leaving `bitmapText.style` frozen at whatever the
392
393
  // constructor set it to and silently dropping every later fill/align/letterSpacing/wordWrap edit.
393
- const fitsAtAuthoredSize = fits(node.fontSize);
394
+ const fitsAtAuthoredSize = fits(style.fontSize);
394
395
  if (node.autoSize !== true || fitsAtAuthoredSize)
395
396
  return;
396
- const minFontSize = Math.min(node.minFontSize ?? 1, node.fontSize);
397
+ const minFontSize = Math.min(node.minFontSize ?? 1, style.fontSize);
397
398
  if (!fits(minFontSize))
398
399
  return; // Best effort: even the floor overflows, so it stays at the floor.
399
- let lo = minFontSize, hi = node.fontSize;
400
+ let lo = minFontSize, hi = style.fontSize;
400
401
  for (let i = 0; i < 8; i++) {
401
402
  const mid = (lo + hi) / 2;
402
403
  if (fits(mid))