@pixi-ui-editor/runtime-pixi 0.12.0 → 0.13.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.
@@ -32,6 +32,7 @@ export declare class ButtonNodeView extends NodeView {
32
32
  */
33
33
  private static paintPlaceholder;
34
34
  private static createStateView;
35
+ private static applyStateAppearance;
35
36
  /**
36
37
  * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view
37
38
  * after construction, so any change to a view's *type* — nine-slice toggled, or an asset
@@ -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;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IA8BnB,uGAAuG;IACvG,OAAO,CAAC,YAAY;IAMpB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAkDxE;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,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"}
@@ -49,6 +49,10 @@ export class ButtonNodeView extends NodeView {
49
49
  ? new Sprite(texture)
50
50
  : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });
51
51
  }
52
+ static applyStateAppearance(view, node, state) {
53
+ view.tint = node.states[`${state}Tint`] ?? "#ffffff";
54
+ view.alpha = node.states[`${state}Opacity`] ?? 1;
55
+ }
52
56
  /**
53
57
  * (Re)builds `FancyButton` and its four state views. `FancyButton` has no API to replace a view
54
58
  * after construction, so any change to a view's *type* — nine-slice toggled, or an asset
@@ -66,6 +70,7 @@ export class ButtonNodeView extends NodeView {
66
70
  const viewFor = (state, assetId) => {
67
71
  const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;
68
72
  const view = ButtonNodeView.createStateView(texture, nineSlice, resolvedSize);
73
+ ButtonNodeView.applyStateAppearance(view, node, state);
69
74
  stateViews[state] = view;
70
75
  return view;
71
76
  };
@@ -149,6 +154,7 @@ export class ButtonNodeView extends NodeView {
149
154
  else if (view instanceof Graphics) {
150
155
  ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);
151
156
  }
157
+ ButtonNodeView.applyStateAppearance(view, node, state);
152
158
  }
153
159
  }
154
160
  // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport type { Sound } from \"@pixi/sound\";\r\nimport { Container, Graphics, NineSliceSprite, Sprite, Texture } from \"pixi.js\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type ButtonNode = Extract<UINode, { type: \"button\" }>;\r\n\r\nconst FANCY_STATE_BY_KEY = { normal: \"default\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\nconst KEY_BY_FANCY_STATE = { default: \"normal\", hover: \"hover\", pressed: \"pressed\", disabled: \"disabled\" } as const;\r\n\r\n/**\r\n * Adapts a button node to `@pixi/ui`'s `FancyButton`, which owns the pointer state machine —\r\n * this class never reimplements it. Optional states fall back to the normal image, and runtime\r\n * changes to `enabled` or the current state stay in the view: they never touch the document.\r\n *\r\n * `nineSlice`, when set, applies the same borders to all four state views (`NineSliceSprite`\r\n * instead of `Sprite`) — the button's frame shape is normally the same regardless of which state\r\n * image is currently shown.\r\n */\r\nexport class ButtonNodeView extends NodeView {\r\n private button!: FancyButton;\r\n private stateViews!: Record<ButtonStateKey, Container>;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly sounds: ReadonlyMap<string, Sound> | undefined;\r\n private soundAssetIds: ButtonNode[\"sounds\"];\r\n private enabledState: boolean;\r\n\r\n constructor(node: ButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, sounds?: ReadonlyMap<string, Sound>) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.sounds = sounds;\r\n this.soundAssetIds = node.sounds;\r\n this.enabledState = node.enabled;\r\n this.buildButton(node);\r\n this.applyEnabled(node.enabled);\r\n }\r\n\r\n /**\r\n * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry\r\n * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:\r\n * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to\r\n * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default\r\n * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.\r\n */\r\n private static paintPlaceholder(graphics: Graphics, width: number, height: number): void {\r\n graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });\r\n }\r\n\r\n private static createStateView(texture: Texture | undefined, nineSlice: LayoutPadding | undefined, size: { width: number; height: number }): Container {\r\n if (texture === undefined) {\r\n const graphics = new Graphics();\r\n ButtonNodeView.paintPlaceholder(graphics, size.width, size.height);\r\n return graphics;\r\n }\r\n return nineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });\r\n }\r\n\r\n /**\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 stateViews[state] = view;\r\n return view;\r\n };\r\n\r\n const button = new FancyButton({\r\n defaultView: viewFor(\"normal\", node.states.normalAssetId),\r\n hoverView: viewFor(\"hover\", node.states.hoverAssetId),\r\n pressedView: viewFor(\"pressed\", node.states.pressedAssetId),\r\n disabledView: viewFor(\"disabled\", node.states.disabledAssetId),\r\n });\r\n // Authoring-сцена инертна: FancyButton уже включил себе eventMode \"static\", снимаем его до applyEnabled.\r\n // Выделение и drag при этом не страдают: попадание ловит hitArea базового NodeView, а не это поддерево.\r\n if (this.interaction === \"authoring\") button.eventMode = \"none\";\r\n else if (this.sounds !== undefined) {\r\n button.onPress.connect(() => { const result = this.soundAssetIds?.pressAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.pressAssetId)?.play(); if (result instanceof Promise) void result.catch(() => undefined); });\r\n button.onHover.connect(() => { const result = this.soundAssetIds?.hoverAssetId === undefined ? undefined : this.sounds?.get(this.soundAssetIds.hoverAssetId)?.play(); if (result instanceof Promise) void result.catch(() => undefined); });\r\n }\r\n this.button = button;\r\n this.stateViews = stateViews;\r\n this.setContent(button);\r\n }\r\n\r\n /** In authoring mode `enabled` may only drive the visuals: `FancyButton` couples it to `eventMode`. */\r\n private applyEnabled(enabled: boolean): void {\r\n this.enabledState = enabled;\r\n if (this.interaction === \"runtime\") this.button.enabled = enabled;\r\n else this.button.setState(enabled ? \"default\" : \"disabled\");\r\n }\r\n\r\n protected syncContent(node: UINode, transform: UINode[\"transform\"]): void {\r\n if (node.type !== \"button\") return;\r\n this.soundAssetIds = node.sounds;\r\n const nineSlice = node.nineSlice;\r\n const normalTexture = this.textureFor(node.states.normalAssetId);\r\n\r\n // A state view's required *type* (Graphics/Sprite/NineSliceSprite) may no longer match what's\r\n // needed — nine-slice toggled, or a texture finished loading after this view had to fall back\r\n // to Graphics. FancyButton can't swap a view after construction, so that goes through a full\r\n // rebuild; everything else (texture identity, border values, size) updates the live views in\r\n // place, which is the path a nine-slice gizmo drag runs every frame.\r\n let needsRebuild = false;\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n const view = this.stateViews[state];\r\n const wantsNineSlice = texture !== undefined && nineSlice !== undefined;\r\n const matches = texture === undefined ? view instanceof Graphics : wantsNineSlice ? view instanceof NineSliceSprite : view instanceof Sprite && !(view instanceof NineSliceSprite);\r\n if (!matches) { needsRebuild = true; break; }\r\n }\r\n\r\n if (needsRebuild) {\r\n this.buildButton(node, transform);\r\n } else {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n const assetId = node.states[`${state}AssetId`];\r\n const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;\r\n // Set the texture before the layout size: Sprite/NineSliceSprite preserve scale when their\r\n // texture changes, so sizing first would shift visual bounds for a differently-sized source.\r\n if (view instanceof NineSliceSprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n if (nineSlice !== undefined) {\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Sprite) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n view.setSize(transform.width, transform.height);\r\n } else if (view instanceof Graphics) {\r\n ButtonNodeView.paintPlaceholder(view, transform.width, transform.height);\r\n }\r\n }\r\n }\r\n\r\n // Только на изменение документа: иначе любой пересчёт layout сбрасывал бы transient preview state.\r\n if (node.enabled !== this.enabledState) this.applyEnabled(node.enabled);\r\n }\r\n\r\n /** Editor-only live preview of nine-slice border edits while dragging the canvas gizmo. */\r\n previewNineSlice(nineSlice: LayoutPadding): void {\r\n for (const state of BUTTON_STATE_KEYS) {\r\n const view = this.stateViews[state];\r\n if (!(view instanceof NineSliceSprite)) continue;\r\n view.leftWidth = nineSlice.left;\r\n view.topHeight = nineSlice.top;\r\n view.rightWidth = nineSlice.right;\r\n view.bottomHeight = nineSlice.bottom;\r\n }\r\n }\r\n\r\n get enabled(): boolean {\r\n return this.enabledState;\r\n }\r\n\r\n set enabled(value: boolean) {\r\n this.applyEnabled(value);\r\n }\r\n\r\n get state(): ButtonStateKey {\r\n return KEY_BY_FANCY_STATE[this.button.state];\r\n }\r\n\r\n /** Forces a visual state without changing `enabled`, so a disabled button still emits no press. */\r\n setState(state: ButtonStateKey): void {\r\n this.button.setState(FANCY_STATE_BY_KEY[state]);\r\n }\r\n\r\n get onPress(): FancyButton[\"onPress\"] { return this.button.onPress; }\r\n get onDown(): FancyButton[\"onDown\"] { return this.button.onDown; }\r\n get onUp(): FancyButton[\"onUp\"] { return this.button.onUp; }\r\n get onHover(): FancyButton[\"onHover\"] { return this.button.onHover; }\r\n get onOut(): FancyButton[\"onOut\"] { return this.button.onOut; }\r\n}\r\n"]}
1
+ {"version":3,"file":"ButtonNodeView.js","sourceRoot":"","sources":["../../src/views/ButtonNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { BUTTON_STATE_KEYS, type ButtonStateKey, type LayoutPadding, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { FancyButton } from \"@pixi/ui\";\r\nimport 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"]}
@@ -51,6 +51,7 @@ export declare class StagedButtonNodeView extends NodeView {
51
51
  */
52
52
  private static paintPlaceholder;
53
53
  private static createStateView;
54
+ private static applyStateAppearance;
54
55
  /**
55
56
  * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,
56
57
  * sizes the freshly built views immediately — needed because a stage change may happen well outside
@@ -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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"}
@@ -74,6 +74,10 @@ export class StagedButtonNodeView extends NodeView {
74
74
  ? new Sprite(texture)
75
75
  : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });
76
76
  }
77
+ static applyStateAppearance(view, stage, state) {
78
+ view.tint = stage.states[`${state}Tint`] ?? "#ffffff";
79
+ view.alpha = stage.states[`${state}Opacity`] ?? 1;
80
+ }
77
81
  /**
78
82
  * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,
79
83
  * sizes the freshly built views immediately — needed because a stage change may happen well outside
@@ -90,6 +94,7 @@ export class StagedButtonNodeView extends NodeView {
90
94
  const viewFor = (state, assetId) => {
91
95
  const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;
92
96
  const view = StagedButtonNodeView.createStateView(texture, this.nineSlice, resolvedSize);
97
+ StagedButtonNodeView.applyStateAppearance(view, stage, state);
93
98
  stateViews[state] = view;
94
99
  return view;
95
100
  };
@@ -193,6 +198,7 @@ export class StagedButtonNodeView extends NodeView {
193
198
  if (texture !== undefined && view.texture !== texture)
194
199
  view.texture = texture;
195
200
  }
201
+ StagedButtonNodeView.applyStateAppearance(view, stage, state);
196
202
  }
197
203
  this.applySizes(width, height);
198
204
  }
@@ -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 {\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 /**\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 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) {\r\n if (texture !== undefined && view.texture !== texture) view.texture = texture;\r\n }\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"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixi-ui-editor/runtime-pixi",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "PixiJS runtime that renders Pixi UI Editor scene documents in a game.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -30,7 +30,7 @@
30
30
  "pixi.js": "^8.19.0",
31
31
  "typed-signals": "^2.5.0",
32
32
  "yoga-layout": "^3.2.1",
33
- "@pixi-ui-editor/schema": "0.12.0"
33
+ "@pixi-ui-editor/schema": "0.13.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.2.0"