@pixi-ui-editor/runtime-pixi 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/SceneViewport.d.ts.map +1 -1
  2. package/dist/assets/bitmapFonts.js.map +1 -1
  3. package/dist/assets/fonts.js.map +1 -1
  4. package/dist/assets/sounds.js.map +1 -1
  5. package/dist/assets/spine.js.map +1 -1
  6. package/dist/assets/textures.js.map +1 -1
  7. package/dist/controls.d.ts +25 -1
  8. package/dist/controls.d.ts.map +1 -1
  9. package/dist/controls.js +42 -2
  10. package/dist/controls.js.map +1 -1
  11. package/dist/document.d.ts.map +1 -1
  12. package/dist/index.d.ts +2 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/layoutGroups.d.ts.map +1 -1
  17. package/dist/layoutGroups.js.map +1 -1
  18. package/dist/localization.d.ts.map +1 -1
  19. package/dist/localization.js.map +1 -1
  20. package/dist/pageGroup.d.ts.map +1 -1
  21. package/dist/pageGroup.js.map +1 -1
  22. package/dist/particles.d.ts.map +1 -1
  23. package/dist/particles.js.map +1 -1
  24. package/dist/scene.d.ts.map +1 -1
  25. package/dist/scene.js +36 -0
  26. package/dist/scene.js.map +1 -1
  27. package/dist/scrollView.d.ts.map +1 -1
  28. package/dist/scrollView.js.map +1 -1
  29. package/dist/views/ButtonNodeView.d.ts +12 -0
  30. package/dist/views/ButtonNodeView.d.ts.map +1 -1
  31. package/dist/views/ButtonNodeView.js +25 -7
  32. package/dist/views/ButtonNodeView.js.map +1 -1
  33. package/dist/views/CheckboxNodeView.d.ts.map +1 -1
  34. package/dist/views/InputNodeView.d.ts.map +1 -1
  35. package/dist/views/ItemTableNodeView.d.ts +57 -0
  36. package/dist/views/ItemTableNodeView.d.ts.map +1 -0
  37. package/dist/views/ItemTableNodeView.js +100 -0
  38. package/dist/views/ItemTableNodeView.js.map +1 -0
  39. package/dist/views/NodeView.d.ts +15 -1
  40. package/dist/views/NodeView.d.ts.map +1 -1
  41. package/dist/views/NodeView.js +19 -2
  42. package/dist/views/NodeView.js.map +1 -1
  43. package/dist/views/PageGroupNodeView.d.ts.map +1 -1
  44. package/dist/views/PaginationNodeView.d.ts +38 -2
  45. package/dist/views/PaginationNodeView.d.ts.map +1 -1
  46. package/dist/views/PaginationNodeView.js +85 -28
  47. package/dist/views/PaginationNodeView.js.map +1 -1
  48. package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -1
  49. package/dist/views/ScrollViewNodeView.d.ts.map +1 -1
  50. package/dist/views/SpineNodeView.d.ts.map +1 -1
  51. package/dist/views/StagedButtonNodeView.d.ts +12 -1
  52. package/dist/views/StagedButtonNodeView.d.ts.map +1 -1
  53. package/dist/views/StagedButtonNodeView.js +27 -9
  54. package/dist/views/StagedButtonNodeView.js.map +1 -1
  55. package/dist/views/ValueControlNodeViews.d.ts.map +1 -1
  56. package/dist/views/basic.d.ts +27 -1
  57. package/dist/views/basic.d.ts.map +1 -1
  58. package/dist/views/basic.js +44 -0
  59. package/dist/views/basic.js.map +1 -1
  60. package/dist/views/createNodeView.d.ts.map +1 -1
  61. package/dist/views/createNodeView.js +8 -1
  62. package/dist/views/createNodeView.js.map +1 -1
  63. package/package.json +5 -2
@@ -3,6 +3,17 @@ import { Texture } from "pixi.js";
3
3
  import { Signal } from "typed-signals";
4
4
  import { NodeView, type SceneInteractionMode } from "./NodeView.js";
5
5
  export type { PaginationNode };
6
+ /**
7
+ * Кнопка-стрелка пагинатора: ровно та часть `ButtonNodeView`/`StagedButtonNodeView`, которая нужна
8
+ * виджету, — нажатие и «доступна ли». Тип объявлен структурно, чтобы этот файл не зависел от обоих
9
+ * классов кнопок и не решал, какой из них «настоящий».
10
+ */
11
+ export type PaginationArrow = {
12
+ onPress: {
13
+ connect(handler: () => void): unknown;
14
+ };
15
+ enabled: boolean;
16
+ };
6
17
  /**
7
18
  * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same
8
19
  * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never
@@ -18,12 +29,22 @@ export type { PaginationNode };
18
29
  * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this
19
30
  * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself
20
31
  * is not structural: switching pages only recreates the (one) background view that needs to move.
32
+ *
33
+ * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active
34
+ * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real
35
+ * page range keeps its footprint and renders nothing, so the active page never shifts sideways.
36
+ *
37
+ * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the
38
+ * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution
39
+ * Spine connector targets use) and steps the page on press. It never draws an arrow itself.
21
40
  */
22
41
  export declare class PaginationNodeView extends NodeView {
23
42
  private readonly list;
24
43
  private readonly interaction;
25
44
  private readonly fonts;
26
45
  private items;
46
+ private visibleSlots;
47
+ private arrows?;
27
48
  private styleMode;
28
49
  private activeTexture;
29
50
  private inactiveTexture;
@@ -40,15 +61,30 @@ export declare class PaginationNodeView extends NodeView {
40
61
  readonly onPageChange: Signal<(page: number) => void>;
41
62
  constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined);
42
63
  private createBackgroundView;
64
+ /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */
65
+ private get slotCount();
66
+ /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */
67
+ private pageForSlot;
43
68
  private createItem;
44
- /** Recreates every item for the current `styleMode`/`pageCountState`/`dotWidth`/`dotHeight`. */
69
+ /** Recreates every item for the current `styleMode`/`slotCount`/`dotWidth`/`dotHeight`. */
45
70
  private buildItems;
46
71
  /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */
47
72
  private wireItem;
48
73
  private applyCurrentPage;
74
+ /**
75
+ * Подключает авторские кнопки-стрелки: нажатие шагает на страницу назад/вперёд и эмитит
76
+ * `onPageChange`, как клик по самому пункту. Кнопки остаются обычными нодами сцены — виджет только
77
+ * подписывается на них и гасит ту, за которой страниц больше нет.
78
+ */
79
+ setArrows(arrows: {
80
+ previous?: PaginationArrow;
81
+ next?: PaginationArrow;
82
+ }): void;
83
+ /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */
84
+ private applyArrowState;
49
85
  protected syncContent(node: UINode): void;
50
86
  get pageCount(): number;
51
- /** Structural: rebuilds every item. Used both by document edits and `setPaginationViewPageCount`. */
87
+ /** Used by `setPaginationViewPageCount` once game code knows the real content length. */
52
88
  set pageCount(value: number);
53
89
  get page(): number;
54
90
  /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */
@@ -1 +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"}
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;AAuB/B;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE;QAAE,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AA+CvG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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,YAAY,CAAqB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAyD;IACxE,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;IAE7D,YAAY,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,EAoBtK;IAED,OAAO,CAAC,oBAAoB;IAM5B,gGAAgG;IAChG,OAAO,KAAK,SAAS,GAEpB;IAED,0GAA0G;IAC1G,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAmBlB,2FAA2F;IAC3F,OAAO,CAAC,UAAU;IAYlB,uGAAuG;IACvG,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,gBAAgB;IAmBxB;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,eAAe,CAAC;QAAC,IAAI,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAK9E;IAED,mFAAmF;IACnF,OAAO,CAAC,eAAe;IAMvB,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA2BxC;IAED,IAAI,SAAS,IAAI,MAAM,CAAgC;IAEvD,yFAAyF;IACzF,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,EAQ1B;IAED,IAAI,IAAI,IAAI,MAAM,CAA6B;IAE/C,4GAA4G;IAC5G,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAKrB;IAED,iHAAiH;IACjH,OAAO,CAAC,OAAO;CAKhB"}
@@ -81,12 +81,22 @@ class NumberItem extends Container {
81
81
  * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this
82
82
  * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself
83
83
  * is not structural: switching pages only recreates the (one) background view that needs to move.
84
+ *
85
+ * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active
86
+ * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real
87
+ * page range keeps its footprint and renders nothing, so the active page never shifts sideways.
88
+ *
89
+ * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the
90
+ * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution
91
+ * Spine connector targets use) and steps the page on press. It never draws an arrow itself.
84
92
  */
85
93
  export class PaginationNodeView extends NodeView {
86
94
  list;
87
95
  interaction;
88
96
  fonts;
89
97
  items = [];
98
+ visibleSlots;
99
+ arrows;
90
100
  styleMode;
91
101
  activeTexture;
92
102
  inactiveTexture;
@@ -113,7 +123,8 @@ export class PaginationNodeView extends NodeView {
113
123
  this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);
114
124
  this.numberActiveNineSlice = node.numberActiveNineSlice;
115
125
  this.pageCountState = Math.max(1, Math.round(node.pageCount));
116
- this.currentPage = clampPage(node.defaultPage, this.pageCountState);
126
+ this.visibleSlots = node.visiblePageCount;
127
+ this.currentPage = clampPage(node.defaultPage, this.pageCount);
117
128
  this.dotWidth = node.dotSize.width;
118
129
  this.dotHeight = node.dotSize.height;
119
130
  this.clickableState = node.clickable;
@@ -126,57 +137,97 @@ export class PaginationNodeView extends NodeView {
126
137
  ? new Sprite(texture)
127
138
  : new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });
128
139
  }
129
- createItem(index) {
140
+ /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */
141
+ get slotCount() {
142
+ return this.visibleSlots === undefined ? this.pageCount : Math.max(1, Math.round(this.visibleSlots));
143
+ }
144
+ /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */
145
+ pageForSlot(slot) {
146
+ return this.visibleSlots === undefined ? slot : this.currentPage - Math.floor(this.slotCount / 2) + slot;
147
+ }
148
+ createItem(slot) {
149
+ const page = this.pageForSlot(slot);
150
+ const exists = page >= 0 && page < this.pageCount;
151
+ const isActive = exists && page === this.currentPage;
130
152
  if (this.styleMode === "dots") {
131
- const dot = new Sprite(index === this.currentPage ? this.activeTexture : this.inactiveTexture);
153
+ const dot = new Sprite(isActive ? this.activeTexture : this.inactiveTexture);
132
154
  dot.setSize(this.dotWidth, this.dotHeight);
155
+ // An out-of-range slot renders nothing but keeps its size, so `List` still reserves its place.
156
+ dot.visible = exists;
133
157
  return dot;
134
158
  }
135
- const isActive = index === this.currentPage;
136
159
  const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;
137
160
  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) }));
161
+ const item = new NumberItem(new Text({ text: exists ? String(page + 1) : "", style: numberTextStyle(this.numberStyle, fill, this.fonts) }));
139
162
  item.resize(this.dotWidth, this.dotHeight);
140
163
  if (isActive && this.numberActiveBackgroundTexture !== undefined)
141
164
  item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));
142
165
  return item;
143
166
  }
144
- /** Recreates every item for the current `styleMode`/`pageCountState`/`dotWidth`/`dotHeight`. */
167
+ /** Recreates every item for the current `styleMode`/`slotCount`/`dotWidth`/`dotHeight`. */
145
168
  buildItems() {
146
169
  this.list.removeChildren();
147
170
  this.items = [];
148
- for (let index = 0; index < this.pageCountState; index++) {
149
- const item = this.createItem(index);
150
- this.wireItem(item, index);
171
+ for (let slot = 0; slot < this.slotCount; slot++) {
172
+ const item = this.createItem(slot);
173
+ this.wireItem(item, slot);
151
174
  this.items.push(item);
152
175
  this.list.addChild(item);
153
176
  }
177
+ this.applyArrowState();
154
178
  }
155
179
  /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */
156
- wireItem(item, index) {
180
+ wireItem(item, slot) {
157
181
  if (this.interaction === "authoring" || !this.clickableState) {
158
182
  item.eventMode = "none";
159
183
  return;
160
184
  }
161
185
  item.eventMode = "static";
162
186
  item.cursor = "pointer";
163
- item.on("pointertap", () => this.setPage(index));
187
+ // Resolved on click, not captured: a windowed slot points at a different page after every move.
188
+ item.on("pointertap", () => {
189
+ const page = this.pageForSlot(slot);
190
+ if (page >= 0 && page < this.pageCount)
191
+ this.setPage(page);
192
+ });
164
193
  }
165
194
  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
195
  const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;
172
- this.items.forEach((item, index) => {
173
- if (!(item instanceof NumberItem))
196
+ this.items.forEach((item, slot) => {
197
+ const page = this.pageForSlot(slot);
198
+ const exists = page >= 0 && page < this.pageCount;
199
+ const isActive = exists && page === this.currentPage;
200
+ if (item instanceof NumberItem) {
201
+ item.numberText.text = exists ? String(page + 1) : "";
202
+ item.numberText.style = numberTextStyle(this.numberStyle, isActive ? this.numberActiveColor ?? baseFill : baseFill, this.fonts);
203
+ item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);
174
204
  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);
205
+ }
206
+ item.texture = isActive ? this.activeTexture : this.inactiveTexture;
207
+ item.setSize(this.dotWidth, this.dotHeight);
208
+ item.visible = exists;
179
209
  });
210
+ this.applyArrowState();
211
+ }
212
+ /**
213
+ * Подключает авторские кнопки-стрелки: нажатие шагает на страницу назад/вперёд и эмитит
214
+ * `onPageChange`, как клик по самому пункту. Кнопки остаются обычными нодами сцены — виджет только
215
+ * подписывается на них и гасит ту, за которой страниц больше нет.
216
+ */
217
+ setArrows(arrows) {
218
+ this.arrows = arrows;
219
+ arrows.previous?.onPress.connect(() => this.setPage(this.currentPage - 1));
220
+ arrows.next?.onPress.connect(() => this.setPage(this.currentPage + 1));
221
+ this.applyArrowState();
222
+ }
223
+ /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */
224
+ applyArrowState() {
225
+ if (this.arrows === undefined)
226
+ return;
227
+ if (this.arrows.previous !== undefined)
228
+ this.arrows.previous.enabled = this.currentPage > 0;
229
+ if (this.arrows.next !== undefined)
230
+ this.arrows.next.enabled = this.currentPage < this.pageCount - 1;
180
231
  }
181
232
  syncContent(node) {
182
233
  if (node.type !== "pagination")
@@ -185,7 +236,10 @@ export class PaginationNodeView extends NodeView {
185
236
  const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;
186
237
  const pageCount = Math.max(1, Math.round(node.pageCount));
187
238
  this.clickableState = node.clickable;
188
- const structureChanged = node.style !== this.styleMode || pageCount !== this.pageCountState || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;
239
+ const previousSlotCount = this.slotCount;
240
+ this.visibleSlots = node.visiblePageCount;
241
+ this.pageCountState = pageCount;
242
+ const structureChanged = node.style !== this.styleMode || this.slotCount !== previousSlotCount || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;
189
243
  this.styleMode = node.style;
190
244
  this.activeTexture = active;
191
245
  this.inactiveTexture = inactive;
@@ -193,10 +247,9 @@ export class PaginationNodeView extends NodeView {
193
247
  this.numberActiveColor = node.numberActiveColor;
194
248
  this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);
195
249
  this.numberActiveNineSlice = node.numberActiveNineSlice;
196
- this.pageCountState = pageCount;
197
250
  this.dotWidth = node.dotSize.width;
198
251
  this.dotHeight = node.dotSize.height;
199
- this.currentPage = clampPage(this.currentPage, pageCount);
252
+ this.currentPage = clampPage(this.currentPage, this.pageCount);
200
253
  if (this.list.type !== node.direction)
201
254
  this.list.type = node.direction;
202
255
  if (this.list.elementsMargin !== node.spacing)
@@ -207,14 +260,18 @@ export class PaginationNodeView extends NodeView {
207
260
  this.applyCurrentPage();
208
261
  }
209
262
  get pageCount() { return this.pageCountState; }
210
- /** Structural: rebuilds every item. Used both by document edits and `setPaginationViewPageCount`. */
263
+ /** Used by `setPaginationViewPageCount` once game code knows the real content length. */
211
264
  set pageCount(value) {
212
265
  const next = Math.max(1, Math.round(value));
213
266
  if (next === this.pageCountState)
214
267
  return;
268
+ const previousSlotCount = this.slotCount;
215
269
  this.pageCountState = next;
216
- this.currentPage = clampPage(this.currentPage, next);
217
- this.buildItems();
270
+ this.currentPage = clampPage(this.currentPage, this.pageCount);
271
+ if (this.slotCount === previousSlotCount)
272
+ this.applyCurrentPage();
273
+ else
274
+ this.buildItems();
218
275
  }
219
276
  get page() { return this.currentPage; }
220
277
  /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */
@@ -1 +1 @@
1
- {"version":3,"file":"PaginationNodeView.js","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAyB,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,QAAQ,EAA6B,MAAM,eAAe,CAAC;AAIpE,MAAM,oBAAoB,GAAwB,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;AAEpP;wGACwG;AACxG,SAAS,eAAe,CAAC,KAAsC,EAAE,IAAY,EAAE,KAA8C;IAC3H,MAAM,QAAQ,GAAG,KAAK,IAAI,oBAAoB,CAAC;IAC/C,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,UAAU;QAC9H,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,IAAI;QACJ,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE;KACnH,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,SAAS,SAAS,CAAC,IAAY,EAAE,SAAiB;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAW,SAAQ,SAAS;IAMX;IALb,SAAS,GAAG,CAAC,CAAC;IACd,UAAU,GAAG,CAAC,CAAC;IACf,UAAU,CAA4B;IAE9C,kGAAkG;IAClG,YAAqB,UAAgB;QACnC,KAAK,EAAE,CAAC;QADW,eAAU,GAAV,UAAU,CAAM;QAEnC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,IAAa,KAAK,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,IAAa,KAAK,CAAC,KAAa,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7D,IAAa,MAAM,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,IAAa,MAAM,CAAC,KAAa,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC;IAE/D,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,gGAAgG;IAChG,aAAa,CAAC,IAA0C;QACtD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QACrG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC7B,IAAI,CAAO;IACX,WAAW,CAAuB;IAClC,KAAK,CAA0C;IACxD,KAAK,GAA4B,EAAE,CAAC;IACpC,SAAS,CAA0B;IACnC,aAAa,CAAU;IACvB,eAAe,CAAU;IACzB,WAAW,CAAkC;IAC7C,iBAAiB,CAAqB;IACtC,6BAA6B,CAAsB;IACnD,qBAAqB,CAA4B;IACjD,cAAc,CAAS;IACvB,WAAW,CAAS;IACpB,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,cAAc,CAAU;IAEhC,0GAA0G;IACjG,YAAY,GAAG,IAAI,MAAM,EAA0B,CAAC;IAE7D,YAAY,IAAoB,EAAE,QAAkD,EAAE,WAAiC,EAAE,KAA8C;QACrK,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7H,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACnI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACxJ,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACpE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAEO,oBAAoB,CAAC,OAAgB;QAC3C,OAAO,IAAI,CAAC,qBAAqB,KAAK,SAAS;YAC7C,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;YACrB,CAAC,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7N,CAAC;IAEO,UAAU,CAAC,KAAa;QAC9B,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC/F,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC;QACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/H,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,QAAQ,IAAI,IAAI,CAAC,6BAA6B,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACpJ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gGAAgG;IACxF,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,uGAAuG;IAC/F,QAAQ,CAAC,IAAyB,EAAE,KAAa;QACvD,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAAC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;YAAC,OAAO;QAAC,CAAC;QAClG,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,YAAY,MAAM;gBAAE,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5J,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC;gBAAE,OAAO;YAC1C,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;YAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;YACtE,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/J,CAAC,CAAC,CAAC;IACL,CAAC;IAES,WAAW,CAAC,IAAY;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACvH,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7H,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QAErC,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC;QAC9K,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACxJ,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAE1D,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QACvE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC;QAEvF,IAAI,gBAAgB;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAEvD,qGAAqG;IACrG,IAAI,SAAS,CAAC,KAAa;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,IAAI,CAAC,cAAc;YAAE,OAAO;QACzC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/C,4GAA4G;IAC5G,IAAI,IAAI,CAAC,KAAa;QACpB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,iHAAiH;IACzG,OAAO,CAAC,KAAa;QAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAAC,CAAC;QACpF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF","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"]}
1
+ {"version":3,"file":"PaginationNodeView.js","sourceRoot":"","sources":["../../src/views/PaginationNodeView.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAyB,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,QAAQ,EAA6B,MAAM,eAAe,CAAC;AAIpE,MAAM,oBAAoB,GAAwB,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;AAEpP;wGACwG;AACxG,SAAS,eAAe,CAAC,KAAsC,EAAE,IAAY,EAAE,KAA8C;IAC3H,MAAM,QAAQ,GAAG,KAAK,IAAI,oBAAoB,CAAC;IAC/C,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,UAAU;QAC9H,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,IAAI;QACJ,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE;KACnH,CAAC;AACJ,CAAC;AASD,oGAAoG;AACpG,SAAS,SAAS,CAAC,IAAY,EAAE,SAAiB;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAW,SAAQ,SAAS;IAMX,UAAU;IALvB,SAAS,GAAG,CAAC,CAAC;IACd,UAAU,GAAG,CAAC,CAAC;IACf,UAAU,CAA4B;IAE9C,kGAAkG;IAClG,YAAqB,UAAgB;QACnC,KAAK,EAAE,CAAC;0BADW,UAAU;QAE7B,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,IAAa,KAAK,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,IAAa,KAAK,CAAC,KAAa,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7D,IAAa,MAAM,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,IAAa,MAAM,CAAC,KAAa,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC;IAE/D,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,gGAAgG;IAChG,aAAa,CAAC,IAA0C;QACtD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QACrG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC7B,IAAI,CAAO;IACX,WAAW,CAAuB;IAClC,KAAK,CAA0C;IACxD,KAAK,GAA4B,EAAE,CAAC;IACpC,YAAY,CAAqB;IACjC,MAAM,CAA0D;IAChE,SAAS,CAA0B;IACnC,aAAa,CAAU;IACvB,eAAe,CAAU;IACzB,WAAW,CAAkC;IAC7C,iBAAiB,CAAqB;IACtC,6BAA6B,CAAsB;IACnD,qBAAqB,CAA4B;IACjD,cAAc,CAAS;IACvB,WAAW,CAAS;IACpB,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,cAAc,CAAU;IAEhC,0GAA0G;IACjG,YAAY,GAAG,IAAI,MAAM,EAA0B,CAAC;IAE7D,YAAY,IAAoB,EAAE,QAAkD,EAAE,WAAiC,EAAE,KAA8C;QACrK,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7H,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACnI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACxJ,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAEO,oBAAoB,CAAC,OAAgB;QAC3C,OAAO,IAAI,CAAC,qBAAqB,KAAK,SAAS;YAC7C,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;YACrB,CAAC,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7N,CAAC;IAED,gGAAgG;IAChG,IAAY,SAAS;QACnB,OAAO,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACvG,CAAC;IAED,0GAA0G;IAClG,WAAW,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3G,CAAC;IAEO,UAAU,CAAC,IAAY;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC;QACrD,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC7E,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,+FAA+F;YAC/F,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC;QACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5I,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,QAAQ,IAAI,IAAI,CAAC,6BAA6B,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACpJ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2FAA2F;IACnF,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,uGAAuG;IAC/F,QAAQ,CAAC,IAAyB,EAAE,IAAY;QACtD,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAAC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;YAAC,OAAO;QAAC,CAAC;QAClG,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,gGAAgG;QAChG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAClD,MAAM,QAAQ,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC;YACrD,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;gBAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChI,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBAC7J,OAAO;YACT,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,MAA8D;QACtE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,mFAAmF;IAC3E,eAAe;QACrB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO;QACtC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QAC5F,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACvG,CAAC;IAES,WAAW,CAAC,IAAY;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QACvH,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC;QAC7H,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QAErC,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC;QACjL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAChD,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,6BAA6B,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACxJ,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAE/D,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QACvE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC;QAEvF,IAAI,gBAAgB;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAEvD,yFAAyF;IACzF,IAAI,SAAS,CAAC,KAAa;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,IAAI,CAAC,cAAc;YAAE,OAAO;QACzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB;YAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;;YAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/C,4GAA4G;IAC5G,IAAI,IAAI,CAAC,KAAa;QACpB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,iHAAiH;IACzG,OAAO,CAAC,KAAa;QAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAAC,CAAC;QACpF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF","sourcesContent":["import { type LayoutPadding, type PaginationNode, type TextStyleDefinition, type UINode } from \"@pixi-ui-editor/schema\";\r\nimport { List } from \"@pixi/ui\";\r\nimport { Container, NineSliceSprite, Sprite, Text, Texture, type TextStyleOptions } from \"pixi.js\";\r\nimport { Signal } from \"typed-signals\";\r\nimport { NodeView, type SceneInteractionMode } from \"./NodeView.js\";\r\n\r\nexport type { PaginationNode };\r\n\r\nconst DEFAULT_NUMBER_STYLE: TextStyleDefinition = { fontFamily: \"Arial\", fontSize: 18, fontWeight: \"normal\", fontStyle: \"normal\", fill: \"#FFFFFF\", align: \"center\", verticalAlign: \"middle\", wordWrap: false, breakWords: false, letterSpacing: 0 };\r\n\r\n/** Same shape `ValueControlNodeViews.ts`'s own `textStyle` resolves — kept as its own small copy rather\r\n * than shared, the same call ADR 0029 makes for two similar-but-separately-evolving style resolvers. */\r\nfunction numberTextStyle(style: TextStyleDefinition | undefined, fill: string, fonts: ReadonlyMap<string, string> | undefined): Partial<TextStyleOptions> {\r\n const resolved = style ?? DEFAULT_NUMBER_STYLE;\r\n return {\r\n fontFamily: resolved.fontAssetId === undefined ? resolved.fontFamily : fonts?.get(resolved.fontAssetId) ?? resolved.fontFamily,\r\n fontSize: resolved.fontSize,\r\n fontWeight: resolved.fontWeight,\r\n fontStyle: resolved.fontStyle,\r\n fill,\r\n align: resolved.align,\r\n wordWrap: resolved.wordWrap,\r\n breakWords: resolved.breakWords,\r\n lineHeight: resolved.lineHeight,\r\n letterSpacing: resolved.letterSpacing,\r\n stroke: resolved.stroke === undefined ? undefined : { color: resolved.stroke.color, width: resolved.stroke.width },\r\n };\r\n}\r\n\r\n/**\r\n * Кнопка-стрелка пагинатора: ровно та часть `ButtonNodeView`/`StagedButtonNodeView`, которая нужна\r\n * виджету, — нажатие и «доступна ли». Тип объявлен структурно, чтобы этот файл не зависел от обоих\r\n * классов кнопок и не решал, какой из них «настоящий».\r\n */\r\nexport type PaginationArrow = { onPress: { connect(handler: () => void): unknown }; enabled: boolean };\r\n\r\n/** Clamps a page index into the valid `[0, pageCount)` range; an empty widget still shows dot 0. */\r\nfunction clampPage(page: number, pageCount: number): number {\r\n return Math.min(Math.max(0, Math.round(page)), Math.max(0, pageCount - 1));\r\n}\r\n\r\n/**\r\n * One `numbers`-style item: a centered page-number label, plus an optional \"pill\" background shown\r\n * only while it is the current page. `width`/`height` are overridden to the authored `dotSize` — the\r\n * same fixed-footprint trick `ScrollItemContainer` uses — so the `List` spaces every item evenly\r\n * whether or not its (rarely-present) background happens to be attached right now.\r\n */\r\nclass NumberItem extends Container {\r\n private itemWidth = 0;\r\n private itemHeight = 0;\r\n private background?: Sprite | NineSliceSprite;\r\n\r\n // Named `numberText`, not `label`: `Container.label` is pixi.js's own display-object name string.\r\n constructor(readonly numberText: Text) {\r\n super();\r\n numberText.anchor.set(0.5);\r\n super.addChild(numberText);\r\n }\r\n\r\n override get width(): number { return this.itemWidth; }\r\n override set width(value: number) { this.itemWidth = value; }\r\n override get height(): number { return this.itemHeight; }\r\n override set height(value: number) { this.itemHeight = value; }\r\n\r\n resize(width: number, height: number): void {\r\n this.itemWidth = width;\r\n this.itemHeight = height;\r\n this.numberText.position.set(width / 2, height / 2);\r\n this.background?.setSize(width, height);\r\n }\r\n\r\n /** Replaces the pill behind the label (destroying the previous one); `undefined` removes it. */\r\n setBackground(view: Sprite | NineSliceSprite | undefined): void {\r\n if (this.background !== undefined) { super.removeChild(this.background); this.background.destroy(); }\r\n this.background = view;\r\n if (view === undefined) return;\r\n view.setSize(this.itemWidth, this.itemHeight);\r\n super.addChildAt(view, 0);\r\n }\r\n}\r\n\r\n/**\r\n * Standalone page indicator: N procedurally generated items arranged by `@pixi/ui`'s `List` (the same\r\n * approach `ScrollViewNodeView`/`scrollView.ts` use for arranging children) — this view never\r\n * reimplements arrangement. Deliberately not wired to any scroll-view: game code owns the actual page\r\n * transition and drives the widget one-way through `setPaginationViewPage`/`setPaginationViewPageCount`,\r\n * the same relationship a slider or progress bar has to whatever value it displays.\r\n *\r\n * `style` picks between two mutually exclusive, differently-rendered item kinds — image dots\r\n * (`Sprite`, two states) or rendered page-number text (`NumberItem`: a label, base style + an optional\r\n * highlight color, plus an optional pill background behind only the current page) — never both.\r\n * Switching `style` rebuilds every item, the same \"view's required *type* changed\" rule\r\n * `StagedButtonNodeView` follows for its state views; `pageCount`/`dotSize` changes do too, since the\r\n * item count/footprint is a runtime fact about this control, not scene topology — it only rebuilds this\r\n * view's own item children, never the owning `NodeView` or the wider scene tree. The active pill itself\r\n * is not structural: switching pages only recreates the (one) background view that needs to move.\r\n *\r\n * With `visiblePageCount` set, the indicator becomes a fixed strip of that many slots with the active\r\n * page always in the middle one (4 pages, page 3 active → 2-3-4). A slot pointing outside the real\r\n * page range keeps its footprint and renders nothing, so the active page never shifts sideways.\r\n *\r\n * The prev/next arrows are ordinary authored button nodes placed wherever the layout needs them; the\r\n * widget only takes their views (`scene.ts`'s `wireNodeReferences`, the same address → view resolution\r\n * Spine connector targets use) and steps the page on press. It never draws an arrow itself.\r\n */\r\nexport class PaginationNodeView extends NodeView {\r\n private readonly list: List;\r\n private readonly interaction: SceneInteractionMode;\r\n private readonly fonts: ReadonlyMap<string, string> | undefined;\r\n private items: (Sprite | NumberItem)[] = [];\r\n private visibleSlots: number | undefined;\r\n private arrows?: { previous?: PaginationArrow; next?: PaginationArrow };\r\n private styleMode: PaginationNode[\"style\"];\r\n private activeTexture: Texture;\r\n private inactiveTexture: Texture;\r\n private numberStyle: TextStyleDefinition | undefined;\r\n private numberActiveColor: string | undefined;\r\n private numberActiveBackgroundTexture: Texture | undefined;\r\n private numberActiveNineSlice: LayoutPadding | undefined;\r\n private pageCountState: number;\r\n private currentPage: number;\r\n private dotWidth: number;\r\n private dotHeight: number;\r\n private clickableState: boolean;\r\n\r\n /** Fires only from a click on an item (when `clickable`); setting `page` programmatically never emits. */\r\n readonly onPageChange = new Signal<(page: number) => void>();\r\n\r\n constructor(node: PaginationNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, fonts: ReadonlyMap<string, string> | undefined) {\r\n super(textures);\r\n this.interaction = interaction;\r\n this.fonts = fonts;\r\n this.styleMode = node.style;\r\n this.activeTexture = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n this.inactiveTexture = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.pageCountState = Math.max(1, Math.round(node.pageCount));\r\n this.visibleSlots = node.visiblePageCount;\r\n this.currentPage = clampPage(node.defaultPage, this.pageCount);\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.clickableState = node.clickable;\r\n this.list = new List({ type: node.direction, elementsMargin: node.spacing });\r\n this.buildItems();\r\n this.setContent(this.list);\r\n }\r\n\r\n private createBackgroundView(texture: Texture): Sprite | NineSliceSprite {\r\n return this.numberActiveNineSlice === undefined\r\n ? new Sprite(texture)\r\n : new NineSliceSprite({ texture, leftWidth: this.numberActiveNineSlice.left, topHeight: this.numberActiveNineSlice.top, rightWidth: this.numberActiveNineSlice.right, bottomHeight: this.numberActiveNineSlice.bottom });\r\n }\r\n\r\n /** How many indicator slots are drawn: the fixed authored window, or one slot per real page. */\r\n private get slotCount(): number {\r\n return this.visibleSlots === undefined ? this.pageCount : Math.max(1, Math.round(this.visibleSlots));\r\n }\r\n\r\n /** The page a slot points at. Windowed slots slide with the current page, which keeps its middle seat. */\r\n private pageForSlot(slot: number): number {\r\n return this.visibleSlots === undefined ? slot : this.currentPage - Math.floor(this.slotCount / 2) + slot;\r\n }\r\n\r\n private createItem(slot: number): Sprite | NumberItem {\r\n const page = this.pageForSlot(slot);\r\n const exists = page >= 0 && page < this.pageCount;\r\n const isActive = exists && page === this.currentPage;\r\n if (this.styleMode === \"dots\") {\r\n const dot = new Sprite(isActive ? this.activeTexture : this.inactiveTexture);\r\n dot.setSize(this.dotWidth, this.dotHeight);\r\n // An out-of-range slot renders nothing but keeps its size, so `List` still reserves its place.\r\n dot.visible = exists;\r\n return dot;\r\n }\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n const fill = isActive ? this.numberActiveColor ?? baseFill : baseFill;\r\n const item = new NumberItem(new Text({ text: exists ? String(page + 1) : \"\", style: numberTextStyle(this.numberStyle, fill, this.fonts) }));\r\n item.resize(this.dotWidth, this.dotHeight);\r\n if (isActive && this.numberActiveBackgroundTexture !== undefined) item.setBackground(this.createBackgroundView(this.numberActiveBackgroundTexture));\r\n return item;\r\n }\r\n\r\n /** Recreates every item for the current `styleMode`/`slotCount`/`dotWidth`/`dotHeight`. */\r\n private buildItems(): void {\r\n this.list.removeChildren();\r\n this.items = [];\r\n for (let slot = 0; slot < this.slotCount; slot++) {\r\n const item = this.createItem(slot);\r\n this.wireItem(item, slot);\r\n this.items.push(item);\r\n this.list.addChild(item);\r\n }\r\n this.applyArrowState();\r\n }\r\n\r\n /** Authoring canvas stays inert like every other control; a clickable item is only live at runtime. */\r\n private wireItem(item: Sprite | NumberItem, slot: number): void {\r\n if (this.interaction === \"authoring\" || !this.clickableState) { item.eventMode = \"none\"; return; }\r\n item.eventMode = \"static\";\r\n item.cursor = \"pointer\";\r\n // Resolved on click, not captured: a windowed slot points at a different page after every move.\r\n item.on(\"pointertap\", () => {\r\n const page = this.pageForSlot(slot);\r\n if (page >= 0 && page < this.pageCount) this.setPage(page);\r\n });\r\n }\r\n\r\n private applyCurrentPage(): void {\r\n const baseFill = this.numberStyle?.fill ?? DEFAULT_NUMBER_STYLE.fill;\r\n this.items.forEach((item, slot) => {\r\n const page = this.pageForSlot(slot);\r\n const exists = page >= 0 && page < this.pageCount;\r\n const isActive = exists && page === this.currentPage;\r\n if (item instanceof NumberItem) {\r\n item.numberText.text = exists ? String(page + 1) : \"\";\r\n item.numberText.style = numberTextStyle(this.numberStyle, isActive ? this.numberActiveColor ?? baseFill : baseFill, this.fonts);\r\n item.setBackground(isActive && this.numberActiveBackgroundTexture !== undefined ? this.createBackgroundView(this.numberActiveBackgroundTexture) : undefined);\r\n return;\r\n }\r\n item.texture = isActive ? this.activeTexture : this.inactiveTexture;\r\n item.setSize(this.dotWidth, this.dotHeight);\r\n item.visible = exists;\r\n });\r\n this.applyArrowState();\r\n }\r\n\r\n /**\r\n * Подключает авторские кнопки-стрелки: нажатие шагает на страницу назад/вперёд и эмитит\r\n * `onPageChange`, как клик по самому пункту. Кнопки остаются обычными нодами сцены — виджет только\r\n * подписывается на них и гасит ту, за которой страниц больше нет.\r\n */\r\n setArrows(arrows: { previous?: PaginationArrow; next?: PaginationArrow }): void {\r\n this.arrows = arrows;\r\n arrows.previous?.onPress.connect(() => this.setPage(this.currentPage - 1));\r\n arrows.next?.onPress.connect(() => this.setPage(this.currentPage + 1));\r\n this.applyArrowState();\r\n }\r\n\r\n /** На краях диапазона соответствующая стрелка недоступна — она никуда не ведёт. */\r\n private applyArrowState(): void {\r\n if (this.arrows === undefined) return;\r\n if (this.arrows.previous !== undefined) this.arrows.previous.enabled = this.currentPage > 0;\r\n if (this.arrows.next !== undefined) this.arrows.next.enabled = this.currentPage < this.pageCount - 1;\r\n }\r\n\r\n protected syncContent(node: UINode): void {\r\n if (node.type !== \"pagination\") return;\r\n const active = node.activeAssetId === undefined ? Texture.WHITE : this.textureFor(node.activeAssetId) ?? Texture.WHITE;\r\n const inactive = node.inactiveAssetId === undefined ? Texture.WHITE : this.textureFor(node.inactiveAssetId) ?? Texture.WHITE;\r\n const pageCount = Math.max(1, Math.round(node.pageCount));\r\n this.clickableState = node.clickable;\r\n\r\n const previousSlotCount = this.slotCount;\r\n this.visibleSlots = node.visiblePageCount;\r\n this.pageCountState = pageCount;\r\n const structureChanged = node.style !== this.styleMode || this.slotCount !== previousSlotCount || node.dotSize.width !== this.dotWidth || node.dotSize.height !== this.dotHeight;\r\n this.styleMode = node.style;\r\n this.activeTexture = active;\r\n this.inactiveTexture = inactive;\r\n this.numberStyle = node.numberStyle;\r\n this.numberActiveColor = node.numberActiveColor;\r\n this.numberActiveBackgroundTexture = node.numberActiveBackgroundAssetId === undefined ? undefined : this.textureFor(node.numberActiveBackgroundAssetId);\r\n this.numberActiveNineSlice = node.numberActiveNineSlice;\r\n this.dotWidth = node.dotSize.width;\r\n this.dotHeight = node.dotSize.height;\r\n this.currentPage = clampPage(this.currentPage, this.pageCount);\r\n\r\n if (this.list.type !== node.direction) this.list.type = node.direction;\r\n if (this.list.elementsMargin !== node.spacing) this.list.elementsMargin = node.spacing;\r\n\r\n if (structureChanged) this.buildItems();\r\n else this.applyCurrentPage();\r\n }\r\n\r\n get pageCount(): number { return this.pageCountState; }\r\n\r\n /** Used by `setPaginationViewPageCount` once game code knows the real content length. */\r\n set pageCount(value: number) {\r\n const next = Math.max(1, Math.round(value));\r\n if (next === this.pageCountState) return;\r\n const previousSlotCount = this.slotCount;\r\n this.pageCountState = next;\r\n this.currentPage = clampPage(this.currentPage, this.pageCount);\r\n if (this.slotCount === previousSlotCount) this.applyCurrentPage();\r\n else this.buildItems();\r\n }\r\n\r\n get page(): number { return this.currentPage; }\r\n\r\n /** External sync from game code (or editor preview): highlights an item without emitting `onPageChange`. */\r\n set page(value: number) {\r\n const next = clampPage(value, this.pageCountState);\r\n if (next === this.currentPage) return;\r\n this.currentPage = next;\r\n this.applyCurrentPage();\r\n }\r\n\r\n /** An item click: highlights immediately, then notifies game code — the same order a checkbox/slider follows. */\r\n private setPage(index: number): void {\r\n const next = clampPage(index, this.pageCountState);\r\n if (next !== this.currentPage) { this.currentPage = next; this.applyCurrentPage(); }\r\n this.onPageChange.emit(next);\r\n }\r\n}\r\n"]}
@@ -1 +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,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"}
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;IAE9D,YAAY,MAAM,EAAE,wBAAwB,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAYpF;IAED,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAQ1C;IAED,IAAI,IAAI,IAAI,CAA2B;IACvC,KAAK,IAAI,IAAI,CAA4B;IACzC,OAAO,IAAI,IAAI,CAA8B;IAC7C,IAAI,IAAI,IAAI,CAA2B;IACvC,sGAAsG;IACtG,IAAI,IAAI,IAAI,CAMX;IACD,OAAO,IAAI,IAAI,CAGd;IACD,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAiD;IAC3F,cAAc,kDAA8C;IAE5D,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAGjD;IAEQ,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAG/C;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAWxC;IAED,OAAO,CAAC,UAAU;IAyDlB,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,mBAAmB;CAO5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollViewNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ScrollViewNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB;IAwBvH,aAAa,CAAC,CAAC,SAAS,SAAS,EAAE,EAAE,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAI1D,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI;IAezE,IAAI,OAAO,IAAI,MAAM,CAAmC;IACxD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAqC;IAC9D,IAAI,OAAO,IAAI,MAAM,CAAmC;IACxD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAqC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IACjC,SAAS,IAAI,IAAI;IACjB,YAAY,IAAI,IAAI;IACpB,IAAI,QAAQ,IAAI,SAAS,CAAC,UAAU,CAAC,CAAoC;CAC1E"}
1
+ {"version":3,"file":"ScrollViewNodeView.d.ts","sourceRoot":"","sources":["../../src/views/ScrollViewNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IAEtC,YAAY,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAsBtH;IAED,aAAa,CAAC,CAAC,SAAS,SAAS,EAAE,EAAE,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAEzD;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAaxE;IAED,IAAI,OAAO,IAAI,MAAM,CAAmC;IACxD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAqC;IAC9D,IAAI,OAAO,IAAI,MAAM,CAAmC;IACxD,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAAqC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAwC;IACzE,SAAS,IAAI,IAAI,CAAgC;IACjD,YAAY,IAAI,IAAI,CAAmC;IACvD,IAAI,QAAQ,IAAI,SAAS,CAAC,UAAU,CAAC,CAAoC;CAC1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"SpineNodeView.d.ts","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC1H,OAAO,EAAE,SAAS,EAAoB,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,KAAK,uBAAuB,GAAG,gBAAgB,GAAG,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAqB9I,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IACjD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,oBAAoB,CAAS;gBAEzB,YAAY,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM;IAwBnO,gGAAgG;IAChG,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,IAAI,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAEvC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAAG,IAAI;IAOrE,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAwC9C,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI;IA+C7B,OAAO,CAAC,uBAAuB;IAiB/B,iBAAiB,CAAC,cAAc,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI;IAIxE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;CA2BpG"}
1
+ {"version":3,"file":"SpineNodeView.d.ts","sourceRoot":"","sources":["../../src/views/SpineNodeView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC1H,OAAO,EAAE,SAAS,EAAoB,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,KAAK,gBAAgB,GAAG,cAAc,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAC/D,KAAK,uBAAuB,GAAG,gBAAgB,GAAG,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAqB9I,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IACjD,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,oBAAoB,CAAS;IAErC,YAAY,YAAY,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,EAsBlO;IAED,gGAAgG;IAChG,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,IAAI,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAEvC;IAED,0FAA0F;IAC1F,iBAAiB,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAAG,IAAI,CAKpE;IAED,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAsC7C;IAED,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI,CA6C5B;IAED,OAAO,CAAC,uBAAuB;IAiB/B,iBAAiB,CAAC,cAAc,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI,CAEvE;IAED,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CA0BlG;CACF"}
@@ -42,11 +42,22 @@ export declare class StagedButtonNodeView extends NodeView {
42
42
  }) => void>;
43
43
  constructor(node: StagedButtonNode, textures: ReadonlyMap<string, Texture> | undefined, interaction: SceneInteractionMode, sounds?: ReadonlyMap<string, Sound>);
44
44
  private currentStage;
45
+ /**
46
+ * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry
47
+ * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:
48
+ * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to
49
+ * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default
50
+ * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.
51
+ */
52
+ private static paintPlaceholder;
45
53
  private static createStateView;
46
54
  /**
47
55
  * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,
48
56
  * sizes the freshly built views immediately — needed because a stage change may happen well outside
49
- * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards.
57
+ * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards. The
58
+ * constructor also always passes it explicitly: `this.layoutRectangle` is still `{0, 0}` before the
59
+ * first layout pass, and an initial placeholder painted at that size would freeze a zero-size,
60
+ * permanently unclickable `hitArea` on `FancyButton` (see `paintPlaceholder`).
50
61
  */
51
62
  private buildButton;
52
63
  /**
@@ -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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"}
@@ -47,14 +47,29 @@ export class StagedButtonNodeView extends NodeView {
47
47
  this.defaultStageId = node.defaultStageId;
48
48
  this.currentStageId = node.stages.some((stage) => stage.id === node.defaultStageId) ? node.defaultStageId : node.stages[0].id;
49
49
  this.enabledState = node.enabled;
50
- this.buildButton();
50
+ // Explicit size, not the `this.layoutRectangle` default `buildButton()` would otherwise fall back
51
+ // to: no layout pass has run yet at construction time, so that getter still reads `{0, 0}`.
52
+ this.buildButton({ width: node.transform.width, height: node.transform.height });
51
53
  }
52
54
  currentStage() {
53
55
  return this.stagesData.find((stage) => stage.id === this.currentStageId) ?? this.stagesData[0];
54
56
  }
55
- static createStateView(texture, nineSlice) {
56
- if (texture === undefined)
57
- return new Graphics();
57
+ /**
58
+ * Invisible (alpha 0) but still hit-testable: Pixi's `containsPoint` hit-tests the fill's geometry
59
+ * regardless of its alpha. Painted with a real size *before* the view ever reaches `FancyButton`:
60
+ * `FancyButton` reads `defaultView`'s bounds exactly once, synchronously during construction, to
61
+ * freeze its own `hitArea` — it never re-reads them afterwards. A `Graphics` still at its default
62
+ * (0, 0) size at that moment would freeze a zero-size, permanently unclickable hit area.
63
+ */
64
+ static paintPlaceholder(graphics, width, height) {
65
+ graphics.clear().rect(0, 0, width, height).fill({ color: 0x000000, alpha: 0 });
66
+ }
67
+ static createStateView(texture, nineSlice, size) {
68
+ if (texture === undefined) {
69
+ const graphics = new Graphics();
70
+ StagedButtonNodeView.paintPlaceholder(graphics, size.width, size.height);
71
+ return graphics;
72
+ }
58
73
  return nineSlice === undefined
59
74
  ? new Sprite(texture)
60
75
  : new NineSliceSprite({ texture, leftWidth: nineSlice.left, topHeight: nineSlice.top, rightWidth: nineSlice.right, bottomHeight: nineSlice.bottom });
@@ -62,15 +77,19 @@ export class StagedButtonNodeView extends NodeView {
62
77
  /**
63
78
  * (Re)builds `FancyButton` and its four state views for the current stage. `size`, when provided,
64
79
  * sizes the freshly built views immediately — needed because a stage change may happen well outside
65
- * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards.
80
+ * a `syncContent` pass (e.g. a runtime click), where nothing else would resize them afterwards. The
81
+ * constructor also always passes it explicitly: `this.layoutRectangle` is still `{0, 0}` before the
82
+ * first layout pass, and an initial placeholder painted at that size would freeze a zero-size,
83
+ * permanently unclickable `hitArea` on `FancyButton` (see `paintPlaceholder`).
66
84
  */
67
85
  buildButton(size) {
68
86
  const stage = this.currentStage();
69
87
  const normalTexture = this.textureFor(stage.states.normalAssetId);
88
+ const resolvedSize = size ?? this.layoutRectangle;
70
89
  const stateViews = {};
71
90
  const viewFor = (state, assetId) => {
72
91
  const texture = (assetId === undefined ? undefined : this.textureFor(assetId)) ?? normalTexture;
73
- const view = StagedButtonNodeView.createStateView(texture, this.nineSlice);
92
+ const view = StagedButtonNodeView.createStateView(texture, this.nineSlice, resolvedSize);
74
93
  stateViews[state] = view;
75
94
  return view;
76
95
  };
@@ -105,8 +124,7 @@ export class StagedButtonNodeView extends NodeView {
105
124
  this.button = button;
106
125
  this.stateViews = stateViews;
107
126
  this.setContent(button);
108
- const resolved = size ?? this.layoutRectangle;
109
- this.applySizes(resolved.width, resolved.height);
127
+ this.applySizes(resolvedSize.width, resolvedSize.height);
110
128
  // Пересборка — деталь реализации `FancyButton`, а не действие пользователя: transient enabled и
111
129
  // визуальное состояние восстанавливаются на новом инстансе, иначе переключение nine-slice или
112
130
  // догрузка текстуры сбрасывали бы их.
@@ -128,7 +146,7 @@ export class StagedButtonNodeView extends NodeView {
128
146
  else if (view instanceof Sprite)
129
147
  view.setSize(width, height);
130
148
  else if (view instanceof Graphics)
131
- view.clear().rect(0, 0, width, height).fill(0x4a5568).stroke({ width: 1, color: 0x94a3b8 });
149
+ StagedButtonNodeView.paintPlaceholder(view, width, height);
132
150
  }
133
151
  }
134
152
  /**