@pixi-ui-editor/runtime-pixi 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controls.d.ts +19 -0
- package/dist/controls.d.ts.map +1 -1
- package/dist/controls.js +40 -0
- package/dist/controls.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/layoutGroups.js.map +1 -1
- package/dist/pageGroup.d.ts +17 -0
- package/dist/pageGroup.d.ts.map +1 -0
- package/dist/pageGroup.js +20 -0
- package/dist/pageGroup.js.map +1 -0
- package/dist/particles.d.ts +5 -2
- package/dist/particles.d.ts.map +1 -1
- package/dist/particles.js +57 -12
- package/dist/particles.js.map +1 -1
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +43 -2
- package/dist/scene.js.map +1 -1
- package/dist/views/NodeView.d.ts +2 -2
- package/dist/views/NodeView.d.ts.map +1 -1
- package/dist/views/NodeView.js.map +1 -1
- package/dist/views/PageGroupNodeView.d.ts +42 -0
- package/dist/views/PageGroupNodeView.d.ts.map +1 -0
- package/dist/views/PageGroupNodeView.js +72 -0
- package/dist/views/PageGroupNodeView.js.map +1 -0
- package/dist/views/PaginationNodeView.d.ts +59 -0
- package/dist/views/PaginationNodeView.d.ts.map +1 -0
- package/dist/views/PaginationNodeView.js +238 -0
- package/dist/views/PaginationNodeView.js.map +1 -0
- package/dist/views/ParticleEmitterNodeView.d.ts +13 -0
- package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -1
- package/dist/views/ParticleEmitterNodeView.js +164 -32
- package/dist/views/ParticleEmitterNodeView.js.map +1 -1
- package/dist/views/SpineNodeView.d.ts +23 -2
- package/dist/views/SpineNodeView.d.ts.map +1 -1
- package/dist/views/SpineNodeView.js +131 -2
- package/dist/views/SpineNodeView.js.map +1 -1
- package/dist/views/basic.d.ts.map +1 -1
- package/dist/views/basic.js +3 -1
- package/dist/views/basic.js.map +1 -1
- package/dist/views/createNodeView.d.ts.map +1 -1
- package/dist/views/createNodeView.js +9 -0
- package/dist/views/createNodeView.js.map +1 -1
- package/package.json +5 -3
- package/dist/assets/spine.test.d.ts +0 -2
- package/dist/assets/spine.test.d.ts.map +0 -1
- package/dist/assets/spine.test.js +0 -42
- package/dist/assets/spine.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -485
- package/dist/index.test.js.map +0 -1
- package/dist/particles.test.d.ts +0 -2
- package/dist/particles.test.d.ts.map +0 -1
- package/dist/particles.test.js +0 -210
- package/dist/particles.test.js.map +0 -1
- package/dist/test.setup.d.ts +0 -2
- package/dist/test.setup.d.ts.map +0 -1
- package/dist/test.setup.js +0 -6
- package/dist/test.setup.js.map +0 -1
- package/dist/views/ParticleEmitterNodeView.test.d.ts +0 -2
- package/dist/views/ParticleEmitterNodeView.test.d.ts.map +0 -1
- package/dist/views/ParticleEmitterNodeView.test.js +0 -148
- package/dist/views/ParticleEmitterNodeView.test.js.map +0 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { NodeView } from "./NodeView.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shows exactly one direct child ("page") at a time and hides the rest; each page fills the group's
|
|
4
|
+
* full resolved rectangle (`PageItemContainer`/`scene.ts`, the same "children don't own their own
|
|
5
|
+
* position" contract a layout group or scroll-view has). Page order is simply hierarchy child order,
|
|
6
|
+
* followed by any pages appended at runtime through `addPage`.
|
|
7
|
+
*
|
|
8
|
+
* This view never decides on its own when to switch pages — it is driven one-way by `setPageGroupPage`
|
|
9
|
+
* from game code, or from the standalone `pagination` widget's `onPageChange` — the same relationship
|
|
10
|
+
* `PaginationNodeView` has with the value it displays. No built-in swipe gesture or transition.
|
|
11
|
+
*
|
|
12
|
+
* Pages are ordinarily authored (one per document child), but the count is not required to be known at
|
|
13
|
+
* authoring time: a growing dataset (e.g. a spin history list appended to during play) can start with
|
|
14
|
+
* zero or a few authored pages and grow through `addPage` — the same "the document is a starting point,
|
|
15
|
+
* not a ceiling" contract `ScrollViewNodeView.addScrollItem` already gives scroll-view content.
|
|
16
|
+
*/
|
|
17
|
+
export class PageGroupNodeView extends NodeView {
|
|
18
|
+
items = [];
|
|
19
|
+
currentPage;
|
|
20
|
+
constructor(node, textures) {
|
|
21
|
+
super(textures);
|
|
22
|
+
this.currentPage = Math.max(0, Math.round(node.defaultPage));
|
|
23
|
+
}
|
|
24
|
+
/** Registers a direct child's wrapper in hierarchy order — called once per child while the scene tree is built. */
|
|
25
|
+
addPageItem(item) {
|
|
26
|
+
this.addChild(item);
|
|
27
|
+
const index = this.items.length;
|
|
28
|
+
this.items.push(item);
|
|
29
|
+
item.visible = index === this.currentPage;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Appends a page built at runtime (e.g. via `buildPrefabView`/`loadPrefabView`, or any hand-built
|
|
33
|
+
* `Container`) after the last one and fits it to the group's current resolved rectangle — a
|
|
34
|
+
* `SceneViewport` root is resized through its own `resize(...)` (the same fit contract Preview and
|
|
35
|
+
* export already rely on); anything else falls back to `Container.width`/`height`. Hidden until
|
|
36
|
+
* switched to via `page`/`setPageGroupViewPage`. Returns the new page's index.
|
|
37
|
+
*/
|
|
38
|
+
addPage(view) {
|
|
39
|
+
const { width, height } = this.layoutRectangle;
|
|
40
|
+
const resizable = view;
|
|
41
|
+
if (typeof resizable.resize === "function")
|
|
42
|
+
resizable.resize({ width, height });
|
|
43
|
+
else {
|
|
44
|
+
view.width = width;
|
|
45
|
+
view.height = height;
|
|
46
|
+
}
|
|
47
|
+
const index = this.items.length;
|
|
48
|
+
this.items.push(view);
|
|
49
|
+
view.visible = index === this.currentPage;
|
|
50
|
+
this.addChild(view);
|
|
51
|
+
return index;
|
|
52
|
+
}
|
|
53
|
+
syncContent() {
|
|
54
|
+
this.applyVisibility();
|
|
55
|
+
}
|
|
56
|
+
applyVisibility() {
|
|
57
|
+
this.items.forEach((item, index) => { item.visible = index === this.currentPage; });
|
|
58
|
+
}
|
|
59
|
+
get pageCount() { return this.items.length; }
|
|
60
|
+
get page() { return this.currentPage; }
|
|
61
|
+
/** External sync from game code (or the pagination widget's `onPageChange`): switches the visible page. */
|
|
62
|
+
set page(value) {
|
|
63
|
+
if (this.items.length === 0)
|
|
64
|
+
return;
|
|
65
|
+
const next = Math.min(Math.max(0, Math.round(value)), this.items.length - 1);
|
|
66
|
+
if (next === this.currentPage)
|
|
67
|
+
return;
|
|
68
|
+
this.currentPage = next;
|
|
69
|
+
this.applyVisibility();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=PageGroupNodeView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageGroupNodeView.js","sourceRoot":"","sources":["../../src/views/PageGroupNodeView.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;IAC5B,KAAK,GAAgB,EAAE,CAAC;IACjC,WAAW,CAAS;IAE5B,YAAY,IAAmB,EAAE,QAAkD;QACjF,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,mHAAmH;IACnH,WAAW,CAAC,IAAuB;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,IAAe;QACrB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAC/C,MAAM,SAAS,GAAG,IAA8E,CAAC;QACjG,IAAI,OAAO,SAAS,CAAC,MAAM,KAAK,UAAU;YAAE,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;aAC3E,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAES,WAAW;QACnB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAErD,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/C,2GAA2G;IAC3G,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;CACF","sourcesContent":["import { type PageGroupNode, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { Container, Texture } from \"pixi.js\";\r\nimport { PageItemContainer } from \"../pageGroup.js\";\r\nimport { NodeView } from \"./NodeView.js\";\r\n\r\nexport type { PageGroupNode };\r\n\r\n/**\r\n * Shows exactly one direct child (\"page\") at a time and hides the rest; each page fills the group's\r\n * full resolved rectangle (`PageItemContainer`/`scene.ts`, the same \"children don't own their own\r\n * position\" contract a layout group or scroll-view has). Page order is simply hierarchy child order,\r\n * followed by any pages appended at runtime through `addPage`.\r\n *\r\n * This view never decides on its own when to switch pages — it is driven one-way by `setPageGroupPage`\r\n * from game code, or from the standalone `pagination` widget's `onPageChange` — the same relationship\r\n * `PaginationNodeView` has with the value it displays. No built-in swipe gesture or transition.\r\n *\r\n * Pages are ordinarily authored (one per document child), but the count is not required to be known at\r\n * authoring time: a growing dataset (e.g. a spin history list appended to during play) can start with\r\n * zero or a few authored pages and grow through `addPage` — the same \"the document is a starting point,\r\n * not a ceiling\" contract `ScrollViewNodeView.addScrollItem` already gives scroll-view content.\r\n */\r\nexport class PageGroupNodeView extends NodeView {\r\n private readonly items: Container[] = [];\r\n private currentPage: number;\r\n\r\n constructor(node: PageGroupNode, textures: ReadonlyMap<string, Texture> | undefined) {\r\n super(textures);\r\n this.currentPage = Math.max(0, Math.round(node.defaultPage));\r\n }\r\n\r\n /** Registers a direct child's wrapper in hierarchy order — called once per child while the scene tree is built. */\r\n addPageItem(item: PageItemContainer): void {\r\n this.addChild(item);\r\n const index = this.items.length;\r\n this.items.push(item);\r\n item.visible = index === this.currentPage;\r\n }\r\n\r\n /**\r\n * Appends a page built at runtime (e.g. via `buildPrefabView`/`loadPrefabView`, or any hand-built\r\n * `Container`) after the last one and fits it to the group's current resolved rectangle — a\r\n * `SceneViewport` root is resized through its own `resize(...)` (the same fit contract Preview and\r\n * export already rely on); anything else falls back to `Container.width`/`height`. Hidden until\r\n * switched to via `page`/`setPageGroupViewPage`. Returns the new page's index.\r\n */\r\n addPage(view: Container): number {\r\n const { width, height } = this.layoutRectangle;\r\n const resizable = view as Partial<{ resize: (size: { width: number; height: number }) => void }>;\r\n if (typeof resizable.resize === \"function\") resizable.resize({ width, height });\r\n else { view.width = width; view.height = height; }\r\n const index = this.items.length;\r\n this.items.push(view);\r\n view.visible = index === this.currentPage;\r\n this.addChild(view);\r\n return index;\r\n }\r\n\r\n protected syncContent(): void {\r\n this.applyVisibility();\r\n }\r\n\r\n private applyVisibility(): void {\r\n this.items.forEach((item, index) => { item.visible = index === this.currentPage; });\r\n }\r\n\r\n get pageCount(): number { return this.items.length; }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or the pagination widget's `onPageChange`): switches the visible page. */\r\n set page(value: number) {\r\n if (this.items.length === 0) return;\r\n const next = Math.min(Math.max(0, Math.round(value)), this.items.length - 1);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyVisibility();\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type PaginationNode, type UINode } from "@pixi-ui-editor/schema";
|
|
2
|
+
import { Texture } from "pixi.js";
|
|
3
|
+
import { Signal } from "typed-signals";
|
|
4
|
+
import { NodeView, type SceneInteractionMode } from "./NodeView.js";
|
|
5
|
+
export type { PaginationNode };
|
|
6
|
+
/**
|
|
7
|
+
* Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same
|
|
8
|
+
* approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never
|
|
9
|
+
* reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page
|
|
10
|
+
* transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,
|
|
11
|
+
* the same relationship a slider or progress bar has to whatever value it displays.
|
|
12
|
+
*
|
|
13
|
+
* `style` picks between two mutually exclusive, differently-rendered item kinds — image dots
|
|
14
|
+
* (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional
|
|
15
|
+
* highlight color, plus an optional pill background behind only the current page) — never both.
|
|
16
|
+
* Switching `style` rebuilds every item, the same "view's required *type* changed" rule
|
|
17
|
+
* `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the
|
|
18
|
+
* item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this
|
|
19
|
+
* view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself
|
|
20
|
+
* is not structural: switching pages only recreates the (one) background view that needs to move.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PaginationNodeView extends NodeView {
|
|
23
|
+
private readonly list;
|
|
24
|
+
private readonly interaction;
|
|
25
|
+
private readonly fonts;
|
|
26
|
+
private items;
|
|
27
|
+
private styleMode;
|
|
28
|
+
private activeTexture;
|
|
29
|
+
private inactiveTexture;
|
|
30
|
+
private numberStyle;
|
|
31
|
+
private numberActiveColor;
|
|
32
|
+
private numberActiveBackgroundTexture;
|
|
33
|
+
private numberActiveNineSlice;
|
|
34
|
+
private pageCountState;
|
|
35
|
+
private currentPage;
|
|
36
|
+
private dotWidth;
|
|
37
|
+
private dotHeight;
|
|
38
|
+
private clickableState;
|
|
39
|
+
/** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */
|
|
40
|
+
readonly onPageChange: Signal<(page: number) => void>;
|
|
41
|
+
constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined);
|
|
42
|
+
private createBackgroundView;
|
|
43
|
+
private createItem;
|
|
44
|
+
/** Recreates every item for the current `styleMode`/`pageCountState`/`dotWidth`/`dotHeight`. */
|
|
45
|
+
private buildItems;
|
|
46
|
+
/** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */
|
|
47
|
+
private wireItem;
|
|
48
|
+
private applyCurrentPage;
|
|
49
|
+
protected syncContent(node: UINode): void;
|
|
50
|
+
get pageCount(): number;
|
|
51
|
+
/** Structural: rebuilds every item. Used both by document edits and `setPaginationViewPageCount`. */
|
|
52
|
+
set pageCount(value: number);
|
|
53
|
+
get page(): number;
|
|
54
|
+
/** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */
|
|
55
|
+
set page(value: number);
|
|
56
|
+
/** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */
|
|
57
|
+
private setPage;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=PaginationNodeView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaginationNodeView.d.ts","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,cAAc,EAA4B,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAExH,OAAO,EAA4C,OAAO,EAAyB,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE,YAAY,EAAE,cAAc,EAAE,CAAC;AAoE/B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAChE,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,6BAA6B,CAAsB;IAC3D,OAAO,CAAC,qBAAqB,CAA4B;IACzD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAU;IAEhC,0GAA0G;IAC1G,QAAQ,CAAC,YAAY,gBAAqB,MAAM,KAAK,IAAI,EAAI;gBAEjD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAqBvK,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,UAAU;IAelB,gGAAgG;IAChG,OAAO,CAAC,UAAU;IAWlB,uGAAuG;IACvG,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,gBAAgB;IAexB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA2BzC,IAAI,SAAS,IAAI,MAAM,CAAgC;IAEvD,qGAAqG;IACrG,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAM1B;IAED,IAAI,IAAI,IAAI,MAAM,CAA6B;IAE/C,4GAA4G;IAC5G,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAKrB;IAED,iHAAiH;IACjH,OAAO,CAAC,OAAO;CAKhB"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { List } from "@pixi/ui";
|
|
2
|
+
import { Container, NineSliceSprite, Sprite, Text, Texture } from "pixi.js";
|
|
3
|
+
import { Signal } from "typed-signals";
|
|
4
|
+
import { NodeView } from "./NodeView.js";
|
|
5
|
+
const DEFAULT_NUMBER_STYLE = { fontFamily: "Arial", fontSize: 18, fontWeight: "normal", fontStyle: "normal", fill: "#FFFFFF", align: "center", verticalAlign: "middle", wordWrap: false, breakWords: false, letterSpacing: 0 };
|
|
6
|
+
/** Same shape `ValueControlNodeViews.ts`'s own `textStyle` resolves — kept as its own small copy rather
|
|
7
|
+
* than shared, the same call ADR 0029 makes for two similar-but-separately-evolving style resolvers. */
|
|
8
|
+
function numberTextStyle(style, fill, fonts) {
|
|
9
|
+
const resolved = style ?? DEFAULT_NUMBER_STYLE;
|
|
10
|
+
return {
|
|
11
|
+
fontFamily: resolved.fontAssetId === undefined ? resolved.fontFamily : fonts?.get(resolved.fontAssetId) ?? resolved.fontFamily,
|
|
12
|
+
fontSize: resolved.fontSize,
|
|
13
|
+
fontWeight: resolved.fontWeight,
|
|
14
|
+
fontStyle: resolved.fontStyle,
|
|
15
|
+
fill,
|
|
16
|
+
align: resolved.align,
|
|
17
|
+
wordWrap: resolved.wordWrap,
|
|
18
|
+
breakWords: resolved.breakWords,
|
|
19
|
+
lineHeight: resolved.lineHeight,
|
|
20
|
+
letterSpacing: resolved.letterSpacing,
|
|
21
|
+
stroke: resolved.stroke === undefined ? undefined : { color: resolved.stroke.color, width: resolved.stroke.width },
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Clamps a page index into the valid `[0, pageCount)` range; an empty widget still shows dot 0. */
|
|
25
|
+
function clampPage(page, pageCount) {
|
|
26
|
+
return Math.min(Math.max(0, Math.round(page)), Math.max(0, pageCount - 1));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One `numbers`-style item: a centered page-number label, plus an optional "pill" background shown
|
|
30
|
+
* only while it is the current page. `width`/`height` are overridden to the authored `dotSize` — the
|
|
31
|
+
* same fixed-footprint trick `ScrollItemContainer` uses — so the `List` spaces every item evenly
|
|
32
|
+
* whether or not its (rarely-present) background happens to be attached right now.
|
|
33
|
+
*/
|
|
34
|
+
class NumberItem extends Container {
|
|
35
|
+
numberText;
|
|
36
|
+
itemWidth = 0;
|
|
37
|
+
itemHeight = 0;
|
|
38
|
+
background;
|
|
39
|
+
// Named `numberText`, not `label`: `Container.label` is pixi.js's own display-object name string.
|
|
40
|
+
constructor(numberText) {
|
|
41
|
+
super();
|
|
42
|
+
this.numberText = numberText;
|
|
43
|
+
numberText.anchor.set(0.5);
|
|
44
|
+
super.addChild(numberText);
|
|
45
|
+
}
|
|
46
|
+
get width() { return this.itemWidth; }
|
|
47
|
+
set width(value) { this.itemWidth = value; }
|
|
48
|
+
get height() { return this.itemHeight; }
|
|
49
|
+
set height(value) { this.itemHeight = value; }
|
|
50
|
+
resize(width, height) {
|
|
51
|
+
this.itemWidth = width;
|
|
52
|
+
this.itemHeight = height;
|
|
53
|
+
this.numberText.position.set(width / 2, height / 2);
|
|
54
|
+
this.background?.setSize(width, height);
|
|
55
|
+
}
|
|
56
|
+
/** Replaces the pill behind the label (destroying the previous one); `undefined` removes it. */
|
|
57
|
+
setBackground(view) {
|
|
58
|
+
if (this.background !== undefined) {
|
|
59
|
+
super.removeChild(this.background);
|
|
60
|
+
this.background.destroy();
|
|
61
|
+
}
|
|
62
|
+
this.background = view;
|
|
63
|
+
if (view === undefined)
|
|
64
|
+
return;
|
|
65
|
+
view.setSize(this.itemWidth, this.itemHeight);
|
|
66
|
+
super.addChildAt(view, 0);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same
|
|
71
|
+
* approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never
|
|
72
|
+
* reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page
|
|
73
|
+
* transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,
|
|
74
|
+
* the same relationship a slider or progress bar has to whatever value it displays.
|
|
75
|
+
*
|
|
76
|
+
* `style` picks between two mutually exclusive, differently-rendered item kinds — image dots
|
|
77
|
+
* (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional
|
|
78
|
+
* highlight color, plus an optional pill background behind only the current page) — never both.
|
|
79
|
+
* Switching `style` rebuilds every item, the same "view's required *type* changed" rule
|
|
80
|
+
* `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the
|
|
81
|
+
* item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this
|
|
82
|
+
* view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself
|
|
83
|
+
* is not structural: switching pages only recreates the (one) background view that needs to move.
|
|
84
|
+
*/
|
|
85
|
+
export class PaginationNodeView extends NodeView {
|
|
86
|
+
list;
|
|
87
|
+
interaction;
|
|
88
|
+
fonts;
|
|
89
|
+
items = [];
|
|
90
|
+
styleMode;
|
|
91
|
+
activeTexture;
|
|
92
|
+
inactiveTexture;
|
|
93
|
+
numberStyle;
|
|
94
|
+
numberActiveColor;
|
|
95
|
+
numberActiveBackgroundTexture;
|
|
96
|
+
numberActiveNineSlice;
|
|
97
|
+
pageCountState;
|
|
98
|
+
currentPage;
|
|
99
|
+
dotWidth;
|
|
100
|
+
dotHeight;
|
|
101
|
+
clickableState;
|
|
102
|
+
/** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */
|
|
103
|
+
onPageChange = new Signal();
|
|
104
|
+
constructor(node, textures, interaction, fonts) {
|
|
105
|
+
super(textures);
|
|
106
|
+
this.interaction = interaction;
|
|
107
|
+
this.fonts = fonts;
|
|
108
|
+
this.styleMode = node.style;
|
|
109
|
+
this.activeTexture = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;
|
|
110
|
+
this.inactiveTexture = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;
|
|
111
|
+
this.numberStyle = node.numberStyle;
|
|
112
|
+
this.numberActiveColor = node.numberActiveColor;
|
|
113
|
+
this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);
|
|
114
|
+
this.numberActiveNineSlice = node.numberActiveNineSlice;
|
|
115
|
+
this.pageCountState = Math.max(1, Math.round(node.pageCount));
|
|
116
|
+
this.currentPage = clampPage(node.defaultPage, this.pageCountState);
|
|
117
|
+
this.dotWidth = node.dotSize.width;
|
|
118
|
+
this.dotHeight = node.dotSize.height;
|
|
119
|
+
this.clickableState = node.clickable;
|
|
120
|
+
this.list = new List({ type: node.direction, elementsMargin: node.spacing });
|
|
121
|
+
this.buildItems();
|
|
122
|
+
this.setContent(this.list);
|
|
123
|
+
}
|
|
124
|
+
createBackgroundView(texture) {
|
|
125
|
+
return this.numberActiveNineSlice === undefined
|
|
126
|
+
? new Sprite(texture)
|
|
127
|
+
: new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });
|
|
128
|
+
}
|
|
129
|
+
createItem(index) {
|
|
130
|
+
if (this.styleMode === "dots") {
|
|
131
|
+
const dot = new Sprite(index === this.currentPage ? this.activeTexture : this.inactiveTexture);
|
|
132
|
+
dot.setSize(this.dotWidth, this.dotHeight);
|
|
133
|
+
return dot;
|
|
134
|
+
}
|
|
135
|
+
const isActive = index === this.currentPage;
|
|
136
|
+
const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;
|
|
137
|
+
const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;
|
|
138
|
+
const item = new NumberItem(new Text({ text: String(index + 1), style: numberTextStyle(this.numberStyle, fill, this.fonts) }));
|
|
139
|
+
item.resize(this.dotWidth, this.dotHeight);
|
|
140
|
+
if (isActive && this.numberActiveBackgroundTexture !== undefined)
|
|
141
|
+
item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));
|
|
142
|
+
return item;
|
|
143
|
+
}
|
|
144
|
+
/** Recreates every item for the current `styleMode`/`pageCountState`/`dotWidth`/`dotHeight`. */
|
|
145
|
+
buildItems() {
|
|
146
|
+
this.list.removeChildren();
|
|
147
|
+
this.items = [];
|
|
148
|
+
for (let index = 0; index < this.pageCountState; index++) {
|
|
149
|
+
const item = this.createItem(index);
|
|
150
|
+
this.wireItem(item, index);
|
|
151
|
+
this.items.push(item);
|
|
152
|
+
this.list.addChild(item);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */
|
|
156
|
+
wireItem(item, index) {
|
|
157
|
+
if (this.interaction === "authoring" || !this.clickableState) {
|
|
158
|
+
item.eventMode = "none";
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
item.eventMode = "static";
|
|
162
|
+
item.cursor = "pointer";
|
|
163
|
+
item.on("pointertap", () => this.setPage(index));
|
|
164
|
+
}
|
|
165
|
+
applyCurrentPage() {
|
|
166
|
+
if (this.styleMode === "dots") {
|
|
167
|
+
this.items.forEach((item, index) => { if (item instanceof Sprite)
|
|
168
|
+
item.texture = index === this.currentPage ? this.activeTexture : this.inactiveTexture; });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;
|
|
172
|
+
this.items.forEach((item, index) => {
|
|
173
|
+
if (!(item instanceof NumberItem))
|
|
174
|
+
return;
|
|
175
|
+
const isActive = index === this.currentPage;
|
|
176
|
+
const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;
|
|
177
|
+
item.numberText.style = numberTextStyle(this.numberStyle, fill, this.fonts);
|
|
178
|
+
item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
syncContent(node) {
|
|
182
|
+
if (node.type !== "pagination")
|
|
183
|
+
return;
|
|
184
|
+
const active = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;
|
|
185
|
+
const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;
|
|
186
|
+
const pageCount = Math.max(1, Math.round(node.pageCount));
|
|
187
|
+
this.clickableState = node.clickable;
|
|
188
|
+
const structureChanged = node.style !== this.styleMode || pageCount !== this.pageCountState || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;
|
|
189
|
+
this.styleMode = node.style;
|
|
190
|
+
this.activeTexture = active;
|
|
191
|
+
this.inactiveTexture = inactive;
|
|
192
|
+
this.numberStyle = node.numberStyle;
|
|
193
|
+
this.numberActiveColor = node.numberActiveColor;
|
|
194
|
+
this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);
|
|
195
|
+
this.numberActiveNineSlice = node.numberActiveNineSlice;
|
|
196
|
+
this.pageCountState = pageCount;
|
|
197
|
+
this.dotWidth = node.dotSize.width;
|
|
198
|
+
this.dotHeight = node.dotSize.height;
|
|
199
|
+
this.currentPage = clampPage(this.currentPage, pageCount);
|
|
200
|
+
if (this.list.type !== node.direction)
|
|
201
|
+
this.list.type = node.direction;
|
|
202
|
+
if (this.list.elementsMargin !== node.spacing)
|
|
203
|
+
this.list.elementsMargin = node.spacing;
|
|
204
|
+
if (structureChanged)
|
|
205
|
+
this.buildItems();
|
|
206
|
+
else
|
|
207
|
+
this.applyCurrentPage();
|
|
208
|
+
}
|
|
209
|
+
get pageCount() { return this.pageCountState; }
|
|
210
|
+
/** Structural: rebuilds every item. Used both by document edits and `setPaginationViewPageCount`. */
|
|
211
|
+
set pageCount(value) {
|
|
212
|
+
const next = Math.max(1, Math.round(value));
|
|
213
|
+
if (next === this.pageCountState)
|
|
214
|
+
return;
|
|
215
|
+
this.pageCountState = next;
|
|
216
|
+
this.currentPage = clampPage(this.currentPage, next);
|
|
217
|
+
this.buildItems();
|
|
218
|
+
}
|
|
219
|
+
get page() { return this.currentPage; }
|
|
220
|
+
/** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */
|
|
221
|
+
set page(value) {
|
|
222
|
+
const next = clampPage(value, this.pageCountState);
|
|
223
|
+
if (next === this.currentPage)
|
|
224
|
+
return;
|
|
225
|
+
this.currentPage = next;
|
|
226
|
+
this.applyCurrentPage();
|
|
227
|
+
}
|
|
228
|
+
/** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */
|
|
229
|
+
setPage(index) {
|
|
230
|
+
const next = clampPage(index, this.pageCountState);
|
|
231
|
+
if (next !== this.currentPage) {
|
|
232
|
+
this.currentPage = next;
|
|
233
|
+
this.applyCurrentPage();
|
|
234
|
+
}
|
|
235
|
+
this.onPageChange.emit(next);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=PaginationNodeView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaginationNodeView.js","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"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","sourcesContent":["import { type LayoutPadding, type PaginationNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { List } from \"@pixi/ui\";\r\nimport { Container, NineSliceSprite, Sprite, Text, Texture, type TextStyleOptions } from \"pixi.js\";\r\nimport { Signal } from \"typed-signals\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type { PaginationNode };\r\n\r\nconst DEFAULT_NUMBER_STYLE: TextStyleDefinition = { fontFamily: \"Arial\", fontSize: 18, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\", align: \"center\", verticalAlign: \"middle\", wordWrap: false, breakWords: false, letterSpacing: 0 };\r\n\r\n/** Same shape `ValueControlNodeViews.ts`'s own `textStyle` resolves — kept as its own small copy rather\r\n * than shared, the same call ADR 0029 makes for two similar-but-separately-evolving style resolvers. */\r\nfunction numberTextStyle(style: TextStyleDefinition | undefined, fill: string, fonts: ReadonlyMap<string, string> | undefined): Partial<TextStyleOptions> {\r\n const resolved = style ?? DEFAULT_NUMBER_STYLE;\r\n return {\r\n fontFamily: resolved.fontAssetId === undefined ? resolved.fontFamily : fonts?.get(resolved.fontAssetId) ?? resolved.fontFamily,\r\n fontSize: resolved.fontSize,\r\n fontWeight: resolved.fontWeight,\r\n fontStyle: resolved.fontStyle,\r\n fill,\r\n align: resolved.align,\r\n wordWrap: resolved.wordWrap,\r\n breakWords: resolved.breakWords,\r\n lineHeight: resolved.lineHeight,\r\n letterSpacing: resolved.letterSpacing,\r\n stroke: resolved.stroke === undefined ? undefined : { color: resolved.stroke.color, width: resolved.stroke.width },\r\n };\r\n}\r\n\r\n/** Clamps a page index into the valid `[0, pageCount)` range; an empty widget still shows dot 0. */\r\nfunction clampPage(page: number, pageCount: number): number {\r\n return Math.min(Math.max(0, Math.round(page)), Math.max(0, pageCount - 1));\r\n}\r\n\r\n/**\r\n * One `numbers`-style item: a centered page-number label, plus an optional \"pill\" background shown\r\n * only while it is the current page. `width`/`height` are overridden to the authored `dotSize` — the\r\n * same fixed-footprint trick `ScrollItemContainer` uses — so the `List` spaces every item evenly\r\n * whether or not its (rarely-present) background happens to be attached right now.\r\n */\r\nclass NumberItem extends Container {\r\n private itemWidth = 0;\r\n private itemHeight = 0;\r\n private background?: Sprite | NineSliceSprite;\r\n\r\n // Named `numberText`, not `label`: `Container.label` is pixi.js's own display-object name string.\r\n constructor(readonly numberText: Text) {\r\n super();\r\n numberText.anchor.set(0.5);\r\n super.addChild(numberText);\r\n }\r\n\r\n override get width(): number { return this.itemWidth; }\r\n override set width(value: number) { this.itemWidth = value; }\r\n override get height(): number { return this.itemHeight; }\r\n override set height(value: number) { this.itemHeight = value; }\r\n\r\n resize(width: number, height: number): void {\r\n this.itemWidth = width;\r\n this.itemHeight = height;\r\n this.numberText.position.set(width / 2, height / 2);\r\n this.background?.setSize(width, height);\r\n }\r\n\r\n /** Replaces the pill behind the label (destroying the previous one); `undefined` removes it. */\r\n setBackground(view: Sprite | NineSliceSprite | undefined): void {\r\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); }\r\n this.background = view;\r\n if (view === undefined) return;\r\n view.setSize(this.itemWidth, this.itemHeight);\r\n super.addChildAt(view, 0);\r\n }\r\n}\r\n\r\n/**\r\n * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same\r\n * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never\r\n * reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page\r\n * transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,\r\n * the same relationship a slider or progress bar has to whatever value it displays.\r\n *\r\n * `style` picks between two mutually exclusive, differently-rendered item kinds — image dots\r\n * (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional\r\n * highlight color, plus an optional pill background behind only the current page) — never both.\r\n * Switching `style` rebuilds every item, the same \"view's required *type* changed\" rule\r\n * `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the\r\n * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this\r\n * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself\r\n * is not structural: switching pages only recreates the (one) background view that needs to move.\r\n */\r\nexport class PaginationNodeView extends NodeView {\r\n private readonly list: List;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly fonts: ReadonlyMap<string, string> | undefined;\r\n private items: (Sprite | NumberItem)[] = [];\r\n private styleMode: PaginationNode[\"style\"];\r\n private activeTexture: Texture;\r\n private inactiveTexture: Texture;\r\n private numberStyle: TextStyleDefinition | undefined;\r\n private numberActiveColor: string | undefined;\r\n private numberActiveBackgroundTexture: Texture | undefined;\r\n private numberActiveNineSlice: LayoutPadding | undefined;\r\n private pageCountState: number;\r\n private currentPage: number;\r\n private dotWidth: number;\r\n private dotHeight: number;\r\n private clickableState: boolean;\r\n\r\n /** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */\r\n readonly onPageChange = new Signal<(page: number) => void>();\r\n\r\n constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.fonts = fonts;\r\n this.styleMode = node.style;\r\n this.activeTexture = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n this.inactiveTexture = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.pageCountState = Math.max(1, Math.round(node.pageCount));\r\n this.currentPage = clampPage(node.defaultPage, this.pageCountState);\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.clickableState = node.clickable;\r\n this.list = new List({ type: node.direction, elementsMargin: node.spacing });\r\n this.buildItems();\r\n this.setContent(this.list);\r\n }\r\n\r\n private createBackgroundView(texture: Texture): Sprite | NineSliceSprite {\r\n return this.numberActiveNineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });\r\n }\r\n\r\n private createItem(index: number): Sprite | NumberItem {\r\n if (this.styleMode === \"dots\") {\r\n const dot = new Sprite(index === this.currentPage ? this.activeTexture : this.inactiveTexture);\r\n dot.setSize(this.dotWidth, this.dotHeight);\r\n return dot;\r\n }\r\n const isActive = index === this.currentPage;\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;\r\n const item = new NumberItem(new Text({ text: String(index + 1), style: numberTextStyle(this.numberStyle, fill, this.fonts) }));\r\n item.resize(this.dotWidth, this.dotHeight);\r\n if (isActive && this.numberActiveBackgroundTexture !== undefined) item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));\r\n return item;\r\n }\r\n\r\n /** Recreates every item for the current `styleMode`/`pageCountState`/`dotWidth`/`dotHeight`. */\r\n private buildItems(): void {\r\n this.list.removeChildren();\r\n this.items = [];\r\n for (let index = 0; index < this.pageCountState; index++) {\r\n const item = this.createItem(index);\r\n this.wireItem(item, index);\r\n this.items.push(item);\r\n this.list.addChild(item);\r\n }\r\n }\r\n\r\n /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */\r\n private wireItem(item: Sprite | NumberItem, index: number): void {\r\n if (this.interaction === \"authoring\" || !this.clickableState) { item.eventMode = \"none\"; return; }\r\n item.eventMode = \"static\";\r\n item.cursor = \"pointer\";\r\n item.on(\"pointertap\", () => this.setPage(index));\r\n }\r\n\r\n private applyCurrentPage(): void {\r\n if (this.styleMode === \"dots\") {\r\n this.items.forEach((item, index) => { if (item instanceof Sprite) item.texture = index === this.currentPage ? this.activeTexture : this.inactiveTexture; });\r\n return;\r\n }\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n this.items.forEach((item, index) => {\r\n if (!(item instanceof NumberItem)) return;\r\n const isActive = index === this.currentPage;\r\n const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;\r\n item.numberText.style = numberTextStyle(this.numberStyle, fill, this.fonts);\r\n item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);\r\n });\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"pagination\") return;\r\n const active = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n const pageCount = Math.max(1, Math.round(node.pageCount));\r\n this.clickableState = node.clickable;\r\n\r\n const structureChanged = node.style !== this.styleMode || pageCount !== this.pageCountState || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;\r\n this.styleMode = node.style;\r\n this.activeTexture = active;\r\n this.inactiveTexture = inactive;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.pageCountState = pageCount;\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.currentPage = clampPage(this.currentPage, pageCount);\r\n\r\n if (this.list.type !== node.direction) this.list.type = node.direction;\r\n if (this.list.elementsMargin !== node.spacing) this.list.elementsMargin = node.spacing;\r\n\r\n if (structureChanged) this.buildItems();\r\n else this.applyCurrentPage();\r\n }\r\n\r\n get pageCount(): number { return this.pageCountState; }\r\n\r\n /** Structural: rebuilds every item. Used both by document edits and `setPaginationViewPageCount`. */\r\n set pageCount(value: number) {\r\n const next = Math.max(1, Math.round(value));\r\n if (next === this.pageCountState) return;\r\n this.pageCountState = next;\r\n this.currentPage = clampPage(this.currentPage, next);\r\n this.buildItems();\r\n }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */\r\n set page(value: number) {\r\n const next = clampPage(value, this.pageCountState);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyCurrentPage();\r\n }\r\n\r\n /** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */\r\n private setPage(index: number): void {\r\n const next = clampPage(index, this.pageCountState);\r\n if (next !== this.currentPage) { this.currentPage = next; this.applyCurrentPage(); }\r\n this.onPageChange.emit(next);\r\n }\r\n}\r\n"]}
|
|
@@ -5,8 +5,18 @@ import { NodeView } from "./NodeView.js";
|
|
|
5
5
|
export declare class ParticleEmitterNodeView extends NodeView {
|
|
6
6
|
private readonly contentRoot;
|
|
7
7
|
private readonly simulator;
|
|
8
|
+
private readonly renderGroups;
|
|
8
9
|
private simulationSpace;
|
|
9
10
|
private autoplayHandled;
|
|
11
|
+
private renderDirty;
|
|
12
|
+
private tintStart;
|
|
13
|
+
private tintEnd;
|
|
14
|
+
private staticColor;
|
|
15
|
+
private dynamicProperties;
|
|
16
|
+
private readonly spawnContext;
|
|
17
|
+
private renderSignature;
|
|
18
|
+
private sourceSignature;
|
|
19
|
+
private sourceTextures;
|
|
10
20
|
constructor(effect: ParticleEffectDefinition, textures?: ReadonlyMap<string, Texture>);
|
|
11
21
|
updateParticles(deltaSeconds: number): void;
|
|
12
22
|
play(): void;
|
|
@@ -22,5 +32,8 @@ export declare class ParticleEmitterNodeView extends NodeView {
|
|
|
22
32
|
destroy(options?: DestroyOptions): void;
|
|
23
33
|
protected syncContent(node: UINode): void;
|
|
24
34
|
private syncRender;
|
|
35
|
+
private cacheEffect;
|
|
36
|
+
private groupFor;
|
|
37
|
+
private destroyRenderGroups;
|
|
25
38
|
}
|
|
26
39
|
//# sourceMappingURL=ParticleEmitterNodeView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticleEmitterNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ParticleEmitterNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,
|
|
1
|
+
{"version":3,"file":"ParticleEmitterNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ParticleEmitterNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAA0C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,uFAAuF;AACvF,qBAAa,uBAAwB,SAAQ,QAAQ;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqD;IAClF,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,iBAAiB,CAA2G;IACpI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiE;IAC9F,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,cAAc,CAAwC;gBAElD,MAAM,EAAE,wBAAwB,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC;IAcrF,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAU3C,IAAI,IAAI,IAAI;IACZ,KAAK,IAAI,IAAI;IACb,OAAO,IAAI,IAAI;IACf,IAAI,IAAI,IAAI;IACZ,sGAAsG;IACtG,IAAI,IAAI,IAAI;IAOZ,OAAO,IAAI,IAAI;IAIf,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1C,cAAc;IAEd,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI;IAKzC,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;IAKhD,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAazC,OAAO,CAAC,UAAU;IAyDlB,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,mBAAmB;CAO5B"}
|